- In-between changes: What happens when after creating a bundle (Step 1) and before applying it remotely (Step 2) a changes occurs on the remote machine B? I had a case where it just overwrote the changes with the new bundle without conflict warning or merge suggestion.
If a change is made on machine B, then this change will have been made in parallel with the changes you bundled from machine A. It doesn't really matter if the changes are made before or after you create the bundle (time-wise), it only matters that the changes on machine B don't have the head from machine A as their ancestor.
In other words, the world looks like this when the two machines are in sync:
A: ... [a]
B: ... [a]
You then create some new commits on machine A:
A: ... [a] --- [b] --- [c]
B: ... [a]
You bundle using [a]
as base, so you get a bundle with [b]
and [c]
. Let us now say that someone (perhaps yourself) makes a commit on machine B:
A: ... [a] --- [b] --- [c]
( bundled )
B: ... [a] --- [x]
So far nothing has been exchanged between the two repositories, so this is just a normal case of people working in parallel. This is the norm in a distributed version control system — people working in parallel is that creates the need for merge commits.
The need for a merge is not evident in either repository at this point, they both have linear histories. However, when you unbundle on machine B, you see the divergence:
A: ... [a] --- [b] --- [c]
( bundled )
B: ... [a] --- [x]
\
[b] --- [c]
( unbundled )
It is helpful to realize that hg unbundle
is exactly like hg pull
, except that it can be done offline. That is, the data stored in a bundle is really just the data that hg pull
would have transferred if you had had an online connection between the two repositories.
You would now proceed by merging the two heads [x]
and [c]
to create [y]
on machine B:
A: ... [a] --- [b] --- [c]
B: ... [a] --- [x] --- [y]
\ /
[b] --- [c]
on machine B your last bundle was created with [a]
as a base. However, you also know that machine A has commit [c]
, so you can specify that as an additional base if you like:
$ hg bundle --base a --base c stuff-from-machine-b.hg
That will put [x]
and [y]
into the bundle:
bundle: (a) --- [x] --- [y]
/
(c)
Here I use (a)
and (c)
to denote the required bases of the bundle. You can only unbundle this bundle if you have both [a]
and [c]
in your repository. If you leave out the second base (only use [a]
), you will also bundle [b]
and [c]
:
bundle: (a) --- [x] --- [y]
\ /
[b] --- [c]
Here you included everything except [a]
in the bundle. Bundling too much is okay, as we will see next.
- Double-applying of bundle: What happens when by accident a bundle is applied twice? Would be needed to record the applied bundles somehow with local tags?
Applying a bundle twice is exactly like running hg pull
twice: nothing happens the second time. When unbundling, Mercurial looks in the bundle and imports the missing changesets. So if you unbundle twice, there is nothing to do the second time.