Reputation: 73
Scenario: I have two Mercurial repositories, let's call them "Original" and "NewProduct".
Original has 1072 revisions of history. NewProduct was created as follows:
In essence, the current state of Original was used to create a new product without the history of Original.
Due to unexpected changes in the direction of both products, they will be much more similar than originally thought. Many upcoming changes will be compatible with both products. Therefore, it would be extremely useful to be able to graft changesets between them.
Question: I would like to have NewProduct as a named branch in the Original repository. Is this possible and how would I go about doing it?
Attempts at a solution:
There are questions on SO that appear similar, such as Mercurial merge repository as branch. The key difference in my scenario is that the other repository is not a clone of the first one - it's been created based on the working directory of the first one. Therefore, the solutions don't seem to apply.
My first attempt at solving this was to use patches.
I figured that if the files in NewProduct/r0 are identical to those in Original/r1072, any changesets made from NewProduct/r1 onwards could theoretically be applied on top of Original/r1072.
So here's what I did:
This process stopped at the first merge changeset in NewProduct. I hadn't understood that a patch isn't the same thing as a changeset - a patch only has one parent, while a merge changeset has two.
Note: I'm working primarily in TortoiseHg, so if the solution can be accomplished using the GUI, that would be preferable, but command line is acceptable too.
Upvotes: 2
Views: 333
Reputation: 73
Aha! I was able to get to the desired result by using ConvertExtension (https://www.mercurial-scm.org/wiki/ConvertExtension) with the splicemap, branchmap and hg.startrev options. The process wasn't quite intuititve, so here's what I did.
1) Create a file named splicemap.txt that contains two full 40-digit hashes:
splicemap.txt
first-revision-of-to-be-converted-history tip-of-existing-history
In my scenario, first-revision-of-to-be-converted-history
is NewProduct/r1, since r0 was copied as a working directory. tip-of-existing-history
is Original/r1077 (the blank commit that opened the named branch NewProduct).
2) Create a file named branchmap.txt with the following line:
branchmap.txt
default new_product_branch
This causes NewProduct's changesets in the default branch to be imported into the Original repository's branch named new_product_branch.
3) Execute the following command:
hg --config hg.convert.hg.startrev=1 convert --splicemap splicemap.txt --branchmap branchmap.txt path/to/newproduct path/to/original
Note the extra option --config convert.hg.startrev=1
. This is required for excluding NewProduct/r0 from being imported.
When I first ran the command without that option, NewProduct/r0 was copied over and became a dangling changeset with no parents or descendants. The splicemap option doesn't prevent changesets from being converted, it just defines which imported changeset gets connected to existing history. To exclude earlier changesets from being imported, the hg.startrev option was needed as well.
Upvotes: 1