Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Splicing over discontinuities in Mercurial repository timeline

I converted a Subversion repository to Mercurial a few months back and I wound up leaving two meaningless gaps in my revision history. I'm trying to figure out if I can just splice over the gaps, but I haven't been able to get the tools to do precisely what I want.

I had reorganized the Subversion repo twice in the early days of the project: first to convert a single project root to trunk/branches/tags layout, and then to add a second related project in a second root folder with it's own trunk/branches/tags.

By the time I decided to switch to Mercurial there had been no significant development activity outside of the trunk of the first, original project. I was able to use the Mercurial conversion utilities and path mapping to reassemble a single sensible trunk in the new Mercurial repository, or so I thought.

Now I realize that I have two extra heads, each corresponding to where the change history essentially starts over:

r0 ... r16 | (r17) r18 ... r61 | (r62) r63 ... tip

The results of the two revisions after the breaks, r17 and r62, are identical in content to the corresponding revision before the breaks -- they consist entirely of file add operations with exactly the same contents as the previous revisions. Meaningful changes only start at the next revisions (r18 and r63 respectively).

I've messed with the Mercurial Transplant extension in an attempt to splice over r17 and r62, but it winds up concatenating the spliced changesets all the way at the tip of the default branch (r405 at this point).

These extra heads are not really hurting my development activities, so I've let it go for a while. What's pushing me to resolve this is that MercurialEclipse complains about these extra heads every time I pull from my remote repository.

Can anyone offer any advice on how to approach this? Am I just getting the command flags wrong, or am I using the wrong tool? Should I be using the Rebase extension instead? What about some sort of dump-edit dumpfile-reload process that we all used to do with Subversion?

While I've published the project to my development server, there are only a couple of clones out there, so destroying those copies and recloning shouldn't be a big deal.

like image 410
bpanulla Avatar asked Mar 01 '11 01:03

bpanulla


1 Answers

The extension commands rebase and collapse should do the trick. Consider the following small repository as an example:

$ hg glog -p

o  changeset:   3:bc701d12d956
|  tag:         tip
|  summary:     hack
|
|  diff --git a/file b/file
|  --- a/file
|  +++ b/file
|  @@ -1,1 +1,1 @@
|  -hello world
|  +hello big world
|
o  changeset:   2:2bb8c95d978e
   parent:      -1:000000000000
   summary:     history breaking svn reorganization

   diff --git a/file b/file
   new file mode 100644
   --- /dev/null
   +++ b/file
   @@ -0,0 +1,1 @@
   +hello world

@  changeset:   1:b578b2ec776b
|  summary:     hack
|
|  diff --git a/file b/file
|  --- a/file
|  +++ b/file
|  @@ -1,1 +1,1 @@
|  -hello
|  +hello world
|
o  changeset:   0:c3d20f0b7072
   summary:     initial

   diff --git a/file b/file
   new file mode 100644
   --- /dev/null
   +++ b/file
   @@ -0,0 +1,1 @@
   +hello

It basically resembles your situation, i.e. there are two unrelated lines of history, where the first revision of the second line (r2) is a plain add of everything present at the last revision of the first line (r1).

You can put the second line onto the first one with rebase:

$ hg rebase -s 2 -d 1
$ hg glog

@  changeset:   3:020d1b20caa8
|  summary:     hack
|
o  changeset:   2:2a44eb4b74c3
|  summary:     history breaking svn reorganization (empty changeset now)
|
o  changeset:   1:b578b2ec776b
|  summary:     hack
|
o  changeset:   0:c3d20f0b7072
   summary:     initial

As you see, the two lines have been joined. Revision 2 now is an obsolete empty changeset. You can get rid of it by using the collapse command to combine revisions 1 and 2:

$ hg collapse -r 1:2
<edit commit message>
$ hg glog -p

@  changeset:   2:d283fe96a5e6
|  tag:         tip
|  summary:     hack
|
|  diff --git a/file b/file
|  --- a/file
|  +++ b/file
|  @@ -1,1 +1,1 @@
|  -hello world
|  +hello big world
|
o  changeset:   1:c486d8191bf0
|  summary:     hack
|
|  diff --git a/file b/file
|  --- a/file
|  +++ b/file
|  @@ -1,1 +1,1 @@
|  -hello
|  +hello world
|
o  changeset:   0:c3d20f0b7072
   summary:     initial

   diff --git a/file b/file
   new file mode 100644
   --- /dev/null
   +++ b/file
   @@ -0,0 +1,1 @@
   +hello

Now the unrelated lines of history are joined in a meaningful way.

like image 100
Oben Sonne Avatar answered Sep 18 '22 17:09

Oben Sonne