Backing out a rename
Greg Ward
gerg.ward+hg at gmail.com
Mon Oct 27 19:14:34 UTC 2008
I'm playing around with using "hg backout" to revert a changeset that
renamed and patched a file. I love how the original changeset knows
that it's a rename with a patch, and you can see that in "hg view" or with
"hg diff --git". But when I backout the rename, that information is
lost: now all I see is addition and removal of whole files.
Example: first, I setup the repository and add the file that will be
at the centre of things:
$ hg init test
$ cd test
$ cat > frob.c
/* frob.c
*
* frob the whizzbobulator until it begs for mercy
*/
...code...
^D
$ hg add frob.c
$ hg ci -m"Add code to frob the whizzbobulator." frob.c
Here comes the changeset that I'm going to backout: I rename frob.c and
edit so its content reflects the rename:
$ hg mv frob.c klob.c
$ [edit klob.c, changing "frob" to "klob"]
$ hg ci -m"Terminology fix: it's klob, not frob."
What I *like* is that before that commit, "hg diff --git" knows that I
am doing a rename+patch. Take that, CVS. And after the commit,
"hg diff -r1 -r2 --git" shows the same thing, as does "hg view". Rock on.
Now I decide my rename was bad, and the right terminology is in fact
"frob" not "klob". So I backout r1:
$ hg backout 1
Since there's no merge required, the backout is committed immediately as
r2. But when I run "hg diff --git -r1 -r2", hg no longer realizes that
the changeset is a rename+patch; it thinks it's just one file being
added and another being removed. ;-(
Here's the *good* diff, i.e. of the original rename+patch:
$ hg diff --git -r0 -r1
diff --git a/frob.c b/klob.c
rename from frob.c
rename to klob.c
--- a/frob.c
+++ b/klob.c
@@ -1,6 +1,6 @@
-/* frob.c
+/* klob.c
*
- * frob the whizzbobulator until it begs for mercy
+ * klob the whizzbobulator until it begs for mercy
*/
...code...
And here is the diff of the backout, where hg has forgotten that the
change was a rename+patch:
$ hg diff --git -r1 -r2
diff --git a/frob.c b/frob.c
new file mode 100644
--- /dev/null
+++ b/frob.c
@@ -0,0 +1,6 @@
+/* frob.c
+ *
+ * frob the whizzbobulator until it begs for mercy
+ */
+
+...code...
diff --git a/klob.c b/klob.c
deleted file mode 100644
--- a/klob.c
+++ /dev/null
@@ -1,6 +0,0 @@
-/* klob.c
- *
- * klob the whizzbobulator until it begs for mercy
- */
-
-...code...
I can workaround this by manually backing out the rename:
$ hg rollback # undo the commit done by "hg backout"
$ hg up -C # throw away work done by "hg backout"
$ hg mv klob.c frob.c
$ hg diff --git -r0 -r1 | patch -p1 -R
patching file frob.c
$ hg ci -m"Revert terminology fix: it really is frob, not klob."
This way, hg correctly realizes that both changesets are rename+patch
operations.
Is this a bug in backout? (Oh yeah, I'm using hg 1.0.1. Same behaviour
with my build of 1.0.1 under Python 2.5.1 on Fedora Core 4 or Ubuntu's
build on Ubuntu 8.04 (hardy).)
Greg
More information about the Mercurial
mailing list