Mercurial - Pull changes after Clone - mercurial

Say I cloned a remote repository and called it "A"
Then I cloned another remote repository and called it "B"
"B" has the .hg folder and src folder , and "A" only has the .hg folder.
If I pull changes from "B" to "A", should now "A" also contain the src folder? Because that's exactly what I did and it did not

You mix the concepts of 'repository' with the working directory, the actually checked-out changeset, which indicates the state of the repository at a particular revision.
If the two repositories A and B are pulled into one repository, all changesets are present there, but they are present in different changesets. If you want to bring them together, you have to merge two changesets; most likely you want to merge the two heads you have, the one from repository A and the one from repository B. For example:
# check heads:
hg heads --template="{rev}:{node|short} {desc}\n"
2332:d69c8aaf6db6 Doc: Changelog as it should have been
2128:6f38df710194 Added tag 0.2.5 for changeset 6d89bb9ad3f6
Update to one head and then merge the other. Make sure to use the actual revisions:
hg up -r2332
hg merge -r2128
Whether or not that works without any conflicts depends on how A and B look like.

Does src contain any files? You cannot add an empty directory to a mercurial repo. If you tried hg add src and src was empty, you won't get an error but nothing happens. If that's really what you want, there are ways, but it sounds like you're just experimenting.
More specifically: You can only add files, and the directories that contain them are added implicitly. After you create a file in src, add the file to the repo and commit the change (along with anything else you may want to bring along). Now you have a changeset you can push or pull to repository "B".
Once the changeset has become part of "B"'s history (check with hg log), you need to update to it (hg update); or, if you've ended up with a branch, merge it to your current branch.

Related

TortoiseHG, fork with subrepos - force commit&push .hgsubstate only

There is public repo on mercurial (not mine). It contains two subrepos. I've made a fork for both main repo nad two subrepos. I want to create pull requests from time to time, but I can't make subrepos work properly.
When I clone my forked repo, it will be downloaded, but two subrepos will remain original, not my forked one. If I'll replace them with forked, I won't be able to make a pull request cos I don't want to switch original repo to my subrepos. But I want to change both repo and subrepo.
Once I've found a solution. I've modified hgrc file in .hg folder of subrepo.
It was:
[paths]
default = ssh://hg#bitbucket.org/originator/subrepo
It become:
[paths]
Me = ssh://hg#bitbucket.org/Me/subrepo
Original = ssh://hg#bitbucket.org/originator/subrepo
It was working exactly as it should. I've changed code, pushed to my subrepo, created pull request for subrepo. Then I've pushed changes in my main repo and it simply worked. .hgsubstate is now reffering to commit that exist on forked repo, but not on original one. When orignator will megre both pull requests, everything would work.
Is I said, it worked before, but not now. For some weird reason I can't just push .hgsubstate that point to new subrepo revision that exists on forked subrepo. I simply can't include it in commit. I click "commit", but in result commit it's not included. And I don't know how to force is being included - HG too "smart" about it. Also TortoiseHG marks my subrepo as dirty. But if I'll try to add both .hgsubstate and my dirty repo, it for some reason tries to push changes to originator's repo. It seems like my HG just can't commit .hgsubstate without pushing changes to subrepo on itself.
Any way to solve this? Everything I want is to commit and push .hgsubstate without doing anything else.
Did you adjust your .hgsub accordingly so that it works for both, your local paths as well as the remote paths to which you push to the server?
It's advisable to add to your .hgsub sections which describe the paths in an absolute sense. I used to struggle with that when I had the subrepos as the same level in the dir structure on the server but wanted them as sub-dirs on my own computer. It helped me to add to .hgsub a subpaths section:
[subpaths]
ssh://user#host.org/path/subrepo1 = ssh://user#host.org/subrepo1
ssh://user#host.org/path/subrepo2 = ssh://user#host.org/subrepo2
/home/user/project/subrepo1 = /home/user/subrepo1
/home/user/project/subrepo2 = /home/user/subrepo2
project/subrepo1 = subrepo1
project/subrepo2 = subrepo2

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.
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)
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
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)

Is it possible to pull from multiple Mercurial repositories at the same time?

I'd like to be able to do something like this:
hg pull http://server/repo1 http://server/repo2 http://otherserver/repo
and have all of the changesets come down at once, with the "added x changesets with y changes to z files" message aggregating the results of all of the pulls. I'm currently doing this with a (marginally complex) bash script, but is there a way to do it with a single mercurial command (or an already-existing plugin) that I've missed?
As #James noted, if your repository have
PATH1 - REPO1
PATH2 - REPO2
...
structure, you can use "super-repo" idea and pull all included repos at once (but instead of subrepo extension I'll suggest GuestRepo)
In case of common base in you repo for pull sources and combined changeset is a must, you must to use intermediate repository as collector. I.e
Create intermediate repository
hg clone WORK MEDIATOR
Pull externals (from MEDIATOR)
hg pull EXTERNAL1 & hg pull EXTERNAL2 ... hg pull EXTERNALN
Pull mediator (from WORK)
hg pull MEDIATOR

"Side-Pull" a mercurial repo into main project

I have a repo in my VCS called CodingStandards. In it is a checkstyle.xml file along with findbugs.xml and it will no doubt grow in the future.
What I want to do is in my project FunkyApp is pull CodingStandards into the project and maintain the link to CodingStandards so that if I change it, I can pull & update in my FunkyApp.
Subrepositories are what you are looking for.
However they forces you to have these files in a subdirectory of your project. There's no way to add juste one file to a repository from another.
First of all setup the CodingStandards repo in .hg/hgrc to make life easier
[paths]
default = https://url/FunkyApp
standards = https://url/CodingStandards
Then you can force pull into your repository
hg pull -f standards
This will create two heads in your repo that need to be merged with hg merge and then committed into your main repo.
To be clear CodingStandards will be unchanged. FunkyApp will have all the files from CodingStandards imported in it. Anyone else who clones FunkyApp will get the files without knowing about CodingStandards.

Mercurial: Multiple Change sets at once?

Before, when I was using perforce, I could work on multiple bugs at once as long as the code did not affect the same files, by having multiple change sets open at once.
Changeset 1:
A.txt
B.txt
C.txt
Changeset 2:
D.txt
E.txt
F.txt
I could submit changeset 2 to the repository without submitting changeset 1 (because it's still in progress)
Is this possible with Mercurial? other than doing each file as a separate commit?
You can always just do: hg commit D.txt E.txt F.txt to commit just those files which will leave A.txt, B.txt, and C.txt uncommited. Using the -I option to commit lets you do those with patterns if they're, for example, in a common directory: hg commit -I 'dir1/**'
You can have two separate branches (working copies) and make one change in and the other in the other. That's one way.
Another is to use Mercurial Queues. You can use qpush --move to change the order of changesets if they have no dependencies on one another, so you can then use qfinish to 'commit' the first changeset that's ready.
You don't actually hold changesets "open" in Mercurial.
Either you've committed your changes, or you haven't.
You can, however, have multiple files with uncommitted changes, and only commit a few of them. It is even possible to commit parts of files, chunks, instead of the whole file.
If I was to do what you're asking I would simply make another clone locally from my first one, and work on the two different fixes in two different working folders. Then I have all the freedom I need to combine the two (push/pull locally), push to the server, etc.
In Mercurial, cloning is a cheap operation when done locally. Just clone the repository for each thing you are working on. Push back to the main repository as each thing is ready:
hg clone http://project project
hg clone project project-bugfix // uses hardlinks and is inexpensive.
hg clone project project-feature
<edit bugfix and feature as needed>
But remember that the default push location is the project cloned from, so you'll either need to edit .hg\hgrc's default push path for the "project" clones, or make sure to hg push http://project from "project-bugfix" and "project-feature" when complete.
Even if your modifications touches the same file you can select what to include (hunk by hunk). You just have to activate the record extension (it's installed by not activated by default).
To activate the record extension, put this in the [extensions] section of your .hgrc:
[extensions]
hgext.record=
Then to commit, replace hg commit by hg record. Let's assume your example change sets with a G.txt file that have changes for both change sets. Commit with:
hg record D.txt E.txt F.txt G.txt
Answer questions, for example:
2 hunks, 6 lines changed
examine changes to 'D.txt'? [Ynsfdaq?] f # f for full file (help with ?)
... skipped file E and F
6 hunks, 35 lines changed
examine changes to 'G.txt'? [Ynsfdaq?] y
## ... (patch hunk here)
record change 6/16 to 'G.txt'? [Ynsfdaq?] y # y to include the hunk, n to skip