Question

I have the following situation:

  • I have site A, which has it's Mercurial repo, and we've been developing it for a while. Let's say A has had 5 revisions.
  • We now has to create Site B, which is almost identical to site A, except for graphical design, mostly. So I cloned the repo, started site B, and now B's repo has all of A's history, plus a bunch of changesets that should never go back to A (mostly CSS and images). Let's say these changes took me 3 revisions.
  • Finally, I've now made a change to B that I would like to move back to A because it belongs on both sites. This is revision 9 in B's repo.

The question is: How can I move revision 9 from B's repo into A's repo, without also moving revisions 6-8?

  • I've tried regular pushing/pulling, but that moves all the changesets.
  • I've tried exporting bundles or patches, but those refuse to import in A because of the missing parent.

I thought one of the beauties of DVCS was that I could do this kind of thing easily (which in the "centralized" VCS world I could fix easily with branches and merging, I've done it with Vault a lot and it's pretty easy).

Am I missing something here?

NOTE: I looked into "MQ", but that seems to be a big can of worms, and it looks like it'll affect the regular commit cycle just for being enabled. Is this correct?

Any help or pointers will be greatly appreciated. Thank you!

Daniel

Was it helpful?

Solution

https://www.mercurial-scm.org/wiki/wiki/TransplantExtension

See under "Using transplant to cherrypick a set of changesets":

Transplant can manage multiple changesets or changeset ranges like this:

hg transplant REV1:REV2 REV3

This example would cherrypick the range of changesets specified by REV1:REV2 and the additional changeset REV3 upon the working directory revision.

Ideally you would do this with branches though?

OTHER TIPS

I think of the commands this way:

  • hg bundle gives you a binary version of a changeset and hg unbundle will turn the bundle into exactly the same changeset on the receiving side.

    Bundle and unbundle are there to transfer changesets over, say, email and the binary patch depend on the parent changesets to be present..

  • hg export gives you a text representation of a changeset, and unless you use the --exact command line flag to hg import, then applying this patch wont create the exact same changeset on the receiving side.

    The advantage of not using --exact is precisely that you can apply such a patch anywhere as long as there are no textual conflicts.

  • hg transplant is just a thin wrapper around hg export and hg import.

If you ever want to "fold" or skip history in a mercurial repo, you simply update to the base revision (before the section you want to fold). If you want to fold everything above that into a single changeset (this appears to be what you want), you just revert to the head of that branch and commit this (or commit just the files you want). This will create a new changeset with the stuff you want so you can push this to your site A. The stuff you don't want, you just ignore (or strip it if you can't ignore it).

If you have multiple changesets above your fold which you want to keep, you should rebase. Enable the rebase extension and rebase #9 on to #5. If there's any children of #9, these will get moved with it. Rebase is preferable to transplant (which does a similar thing) because rebase uses 3-way merge machinery to migrate changesets, making it more likely to succeed. Transplant is more-or-less just a dumb export-import so it ignores common history.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top