Mark W.
Mark W.

Reputation: 221

Mercurial: Merge in accidentally created subfolder

TLDR: I seem to have created a separate repository in a subfolder of my main project. How can I combine them?

I have a project folder, let's call it BOB. I cloned (hg clone) BOB to a new folder called BOB2. To add new features, I created a subfolder on BOB2 called BOB-newfeatures. I have been working on this BOB-newfeatures folder for a while, with many checkins.

Today I realized that somehow I created a separate repository for BOB-newfeatures (I hadn't changed anything on BOB2 main until today so I hadn't noticed that changes weren't being tracked). If I do hg status on BOB2, it doesn't know about changes in the subfolder and vice versa.

Is there a way to stitch these together? I know I could hg add all of the files in BOB-newfeatures to BOB but then I think I lose all of my checkin history.

Upvotes: 1

Views: 97

Answers (2)

Lazy Badger
Lazy Badger

Reputation: 97355

OK, I reconstructed (I hope) your case, with your names, starting from

BOB2>hg log -T "{node|short}\tFiles: {join(files, ', ')}\n"
25a16a8fea5e    Files: Sub/3.txt
bf3c6cacb4a4    Files: 1.txt, 2.txt
ff71a2b1bbe3    Files: 1.txt

and nested repo

BOB2\BOB-newfeatures>hg log -T "{node|short}\tFiles: {join(files, ', ')}\n"
acac7d413ed2    Files: f1.txt
15a1f9cacf25    Files: f2.txt
f3055921fa01    Files: f1.txt

As a additional confirmation of invisibility of BOB-newfeatures inside BOB2

BOB2>hg manifest
1.txt
2.txt
Sub/3.txt

Method of solving problem - using Convert extension with --filemap in inversed, compared to Wiki, direction: it's example transform subdir of repo into separate repository, I'll move repository-root into subfolder

  • map-file, prepared for conversion
rename . BOB-newfeatures
  • conversion
hg convert --filemap map z:\BOB2\BOB-newfeatures z:\BOB-newfeatures-conv
initializing destination z:\BOB-newfeatures-conv repository
scanning source...
sorting...
converting...
2 New feature started
1 Change 1
0 Change 2
  • Testing results
BOB-newfeatures-conv>hg log -T "{node|short}\tFiles: {join(files, ', ')}\n"
a3b2c462a3b9    Files: BOB-newfeatures/f1.txt
f5f1168cfe2f    Files: BOB-newfeatures/f2.txt
da27a50a5cb6    Files: BOB-newfeatures/f1.txt

compare file-paths with log from nested repo, note different hashes for changesets

  • Next bad news: you can't just pull from BOB|BOB2 into converted repository missing parts easy
BOB-newfeatures-conv>hg pull ../BOB2
pulling from ../BOB2
searching for changes
abort: repository is unrelated

Even with --force (because repositories are really unrelated and doesn't share history) you'll get "dirty" combined repository (changes in root and in BOB-newfeatures/ are two separate lines of changes with own roots and tips)

BOB-newfeatures-conv>hg pull ../BOB2 -f
pulling from ../BOB2
searching for changes
warning: repository is unrelated
requesting all changes
adding changesets
adding manifests
adding file changes
added 3 changesets with 4 changes to 3 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)

Force pull result

And at last step you have to re-link two histories into one common. In my case due to my actions (pulling to converted repository with pre-existing history of BOB-newfeatures) I had to link 0-1-2 revisions after 3-4-5 (historically earlier changes) and I don't know more elegant way to do it, than again convert (HG->HG) repository, with --splicemap this time

With log output

>hg log -T "{rev} {node}\n"
5 25a16a8fea5e5b4dac42a0a6b2c8e82890c220a3
4 bf3c6cacb4a4c22cb5720ddeab1ec5f8238a98c9
3 ff71a2b1bbe30a56c9dabc9a7ddb2bbccad840af
2 a3b2c462a3b917b3ba58daee3df2632875baee17
1 f5f1168cfe2f4b6c67d0af8a9259665ae2d40bd5
0 da27a50a5cb6246c03c6af7485ac7ffc33e62738

splicemap for rule "0 after 5" can be created (with format of oneliner "ChildHash ParentHash")

da27a50a5cb6246c03c6af7485ac7ffc33e62738 25a16a8fea5e5b4dac42a0a6b2c8e82890c220a3

and last conversion performed

>hg convert  --splicemap z:\map z:\BOB-newfeatures-conv z:\BOB3
scanning source...
sorting...
converting...
5 Initial data
4 Changes
3 More changes
2 New feature started
spliced in 25a16a8fea5e5b4dac42a0a6b2c8e82890c220a3 as parents of da27a50a5cb6246c03c6af7485ac7ffc33e62738
1 Change 1
0 Change 2

with expected good results

Final Repo

Upvotes: 2

planetmaker
planetmaker

Reputation: 6044

You simply created a separate repository. As such you can pull from that repository like from any other. In this case, in your main repository in BOB2, you could do:

hg pull ./BOB-newfeatures

In order to avoid confusion, I'd first move BOB-newfeatures to the same directory level as BOB2 and pull then giving the new relative path ../BOB-newfeatures; but that's more for cosmetics and to keep your BOB2 repository clean; strictly speaking it should not be needed.

(Basically you used a feature of hg: you can create a new repo in any sub-path which will be an independent repo which knows nothing of the parent and vice versa. It's used for instance for libraries needed by the main repo but which you do not want to tie directly to your main; they then are found in the expected relative path and it's easy to operate on)

Upvotes: 1

Related Questions