Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mercurial merge repository as branch

I have two Mercurial repositories that are for different major revisions of the same project. The latter version is a massive change to the functionality, and especially the UI, of the project, but it will still have a lot of common code with the earlier version. (For shorthand I'll call these versions 4.6 and 5.0 and the repositories project-4.x and project-5.x going forward; that's basically what I'm dealing with.)[1]

As we thought more carefully about the structure of our repository, and thinking especially about how to handle the related code, it became apparent that we wanted to simply pull the repositories together and used named branches for the ongoing work in each (from which people can branch or bookmark and merge as necessary). To do that, we decided we basically need to pull the project-5.x repository into the project-4.x repository. From what I can see, combining the repositories should be fairly straightforward:

$ hg pull -f project-5.x   # in project-4.x
$ hg merge

So far, so good. My concern is handling the branching issue.[2] These are going to come in as two completely unrelated chains (which is fine), but I'd like the branch structure to look something like this:

---4.6-----   }
  \           } original project-4.x
   5.0-----   }
       /
-------       } original project-5.x

The problem is, I'm not exactly sure how to do it.

Edit: See below; the answer I devised worked.


Footnotes

  1. If you're wondering why this is only coming up now… well, the project only got version controlled as of starting 4.6. Which, yes, is a little bit crazy. And I'd never been in charge of a major version change like this before, so I decided originally to make a new repo entirely, which I of course now regret. Live and learn.
  2. Answers I've already read on the subject (but which left me unsure how to do this exactly):
    • Mercurial - merging branches
    • How do I merge two Mercurial repos into a single one
    • How can I import a mercurial repo (including history) into another mercurial repo as a subdirectory, without using subrepos?
like image 227
Chris Krycho Avatar asked May 07 '13 23:05

Chris Krycho


People also ask

How do I merge branches in Mercurial?

To merge two branches, you pull their heads into the same repository, update to one of them and merge the other, and then commit the result once you're happy with the merge. The resulting changeset has two parents.

How do you combine two Mercurial heads?

To start a merge between the two heads, we use the hg merge command. We resolve the contents of hello. c This updates the working directory so that it contains changes from both heads, which is reflected in both the output of hg parents and the contents of hello.


1 Answers

I originally thought I'd need some way to pull into just the branch, but after chewing on it some more, I concluded the best way to do this is roughly as follows:

  1. Create the desired new branch structure (i.e. create the 4.6 and 5.0 branches).
  2. Remove the old default branch into the 4.6 branch in the base repository.
  3. Pull the project-5.x repository into the project-4.x repository.
  4. Merge the default (or in the case of this repository, experimental) baseline, which is pulled in during the merge, into the 5.0 branch, closing out the experimental branch along the way.
  5. Restrict write access to the old repository's central push/pull location; we still have it for historical reasons, but people can't accidentally push to it.

Preparation (steps 1–2)

$ cd <project-4.x directory>
$ hg branch 4.6
$ hg ci -m "New 4.0 baseline"
$ hg branch 5.0
$ hg ci -m "New 5.0 baseline"
$ hg up default
$ hg ci --close-branch -m "Close default branch going forward.
$ hg up 4.6
$ hg merge default
$ hg ci -m "branch merge default -> 4.6"

At this point, the repository is set up: it has the new baseline branches and has removed the old default branch we wanted to get rid of.

After this, I made the changes to get the repository structure looking more the way it needed to for the 5.0 branch in the project-4.x repository (since massive restructuring is part of the version change effort).

Repository merge (steps 3–4)

The next step was actually merging the repositories together and pushing the content from the old repository into the desired branch.

$ hg pull -f <path to project-5.x repository>   # still in project-4.x repository
$ hg merge -m "Merge in project-5.x repository"
$ hg up experimental   # experimental is the name of the "default" branch
$ hg ci --close-branch -m "Close experimental branch"
$ hg up 5.0
$ hg merge experimental
$ hg ci -m "Merge old experimental into new 5.0 baseline"

This proceeded perfectly, with no merge conflicts whatsoever (except that I needed to resolve some small differences in my .hgignore file).

like image 176
Chris Krycho Avatar answered Sep 30 '22 16:09

Chris Krycho