0

I made some changes (A) to the main (and only) branch. Then my colleague made some other changes (B). Then I found out that changes (A) are hopelessly broken, and I decided to abandon them completely. Changes (B), on the other hand, are perfectly fine, and luckily are completely independent from chanegs (A). Changes (B) are far smaller in volume than changes (A).

Normally, I'd simply hg commit --close-branch as described here. But then I lose changes (B), and will need to recreate them in the new active branch. I can do that, by simply identifying the files affected (by hand), and updating them (by hand), and then committing. This is obviously not perfect, since it requires two manual steps, and also creates a misleading commit in the repository (misleading because the changes are made by my colleague a while ago, but would look as if they were made today by me). I suppose it's not the end of the world, but is there a more elegant solution?

Note: If Mercurial supported applying just the differences from one commit to another location in the revision tree, it would have worked. But I suspect this feature doesn't exist, for a good reason: it's very rare that the diffs vs existing parent changeset are useful when applied verbatim to another parent changeset.

Community
  • 1
  • 1
max
  • 49,282
  • 56
  • 208
  • 355
  • 2
    “If Mercurial supported applying just the differences from one commit to another location in the revision tree, it would have worked.” – It does, the command for that is called `graft`. Also `rebase --keep` does a similar thing. – Laurens Holst Dec 03 '12 at 09:46

1 Answers1

4
  1. --close-branch have another rationale, than discarding bad changeset
  2. You can undo any changeset, presented in earlier history by providing "undoing-changeset", read hg help backout, in common hg backout CSET-HASH reverse changes, done in CSET-HASH for the cost of additional commit in repo

Example of using backout for killing effect of old changeset (rev. 7 undo rev.3)

>hg log -r 3:7 --template "{rev}:{node|short}\n{desc}\n\n"
3:2f09429039a6
Немного более русские даты

4:97419f57d7db
Заготовки под перевод

5:674a76db96fd
UTF8 и перевод assigncategories

6:9cd6b52df09f
Подчистки локализации

7:c2a2812d11ad
Backed out changeset: 2f09429039a6
  1. You can cherry-pick changeset(s) between branches, read hg help graft (merge-based logic of injecting instead of old hg transplant). Usefulness or uselessness is a problem of human-choice, workability of grafted changeset on top of new parent (no merge conflics) is a responsibility of graft itself

If a graft merge results in conflicts, the graft process is interrupted so that the current merge can be manually resolved.

Lazy Badger
  • 94,711
  • 9
  • 78
  • 110
  • Sorry, didn't understand your comment 1. Do you mean I shouldn't be using `--close-branch` for this purpose; if so, why? Or do you mean that it can *also* be used for other purposes; if so, which purposes? – max Dec 02 '12 at 06:08
  • 1
    @Max - yes, you **must not** use --close-branch for this purpose, just because it doesn't help. --close-branch on commit just mark *this head of branch* as closed, i.e *hidden from* `hg heads` (default) *output* – Lazy Badger Dec 02 '12 at 06:17