Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Mercurial's strip command not rewrite history?

Tags:

mercurial

The Mercurial help text says, that the "strip command removes the specified changesets and all their descendants." This sounds very much like rewriting history to me, and that it must cause problems if somebody has based his work on one of the changesets that suddenly is removed. But the help text also says that the command "is not a history-rewriting operation and can be used on changesets in the public phase." I am sure that the person who wrote the help text knew very well what he was doing, so what am I missing to understand this?

like image 706
Iodnas Avatar asked Dec 07 '12 01:12

Iodnas


People also ask

What does hg amend do?

The easiest and probably one of the most important history editing commands is hg commit --amend . This command doesn't create a completely new changeset. Instead, it takes any new changes in your working directory and combines them with the parent of the working directory.

How do I revert a changeset in Mercurial?

Revert changes already committed To backout a specific changeset use hg backout -r CHANGESET . This will prompt you directly with a request for the commit message to use in the backout. To revert a file to a specific changeset, use hg revert -r CHANGESET FILENAME . This will revert the file without committing it.


2 Answers

The key point is that if you strip a public changeset, and then pull it again from somewhere, you haven't caused any issues. You just get the original changeset back.

If you (for example) collapse two public changesets together, and then pull the original from somewhere, you now have two branches. One with the original two changesets, and one with the collapsed changeset, but both have the same changes. At that point hell breaks loose and child eating monsters roam the earth.

Hence 'history re-writing' isn't the same as 'history stripping'.


davidmc24 pointed out this post by Matt Mackall (Mercurial's father) in which he says basically the same thing

like image 101
Paul S Avatar answered Oct 12 '22 15:10

Paul S


I can't say it with certainty, but my guess is that it's "grandfathered in". hg strip started out as part of mq which predates the addition of phases by at least three years.

Likely better phrasing would be:

is not *considered *a history-rewriting operation and can be used on changesets in the public phase

When phases were added a huge amount of care was taken to break no one's existing workflow. Commits start out in the draft phase and become public once pushed. Any phase-aware commands knows that after pushing the commit's phase is public and not to allow modification if it (unless the push was to a non-publishing repository...).

However, there were people already using strip manually and in scripts to remove changesets that had been pushed, and if strip had after an upgrade suddenly said "Hey, you can't strip that it's public!" then those people would have had their backward-compatibility promise broken.

Phases is slowly growing into a pretty amazing evolve system that will be a much better choice than mq for almost all cases, but I still doubt we'll ever get Matt to remove mq and strip -- he still insists on maintaining a Python 2.4 compatible codebase and that's 9 years old!

Tl;Dr: Even though strip was always a disabled extension, too many people use it to change it's behavior w/ the advent of phases.

like image 43
Ry4an Brase Avatar answered Oct 12 '22 15:10

Ry4an Brase