213

We now have a "stiging" branch, where "staging" seems to be a far better semantic fit. What's a good strategy for handling this?

KevDog
  • 5,763
  • 9
  • 42
  • 73

5 Answers5

228

Update to the stiging branch and create a new branch off of it. Then close the old branch.

In summary:

hg update stiging
hg branch staging
hg commit -m"Changing stiging branch to staging."
hg update stiging
hg commit --close-branch -m"This was a typo; use staging instead."
hg push --new-branch
Elliot Cameron
  • 5,235
  • 2
  • 27
  • 34
  • 1
    This is the best way to do this that I have found. Closing the branch prevents others from accidentally using it because it doesn't show up in the output of "hg branches". It still allows you to access it later if you know the name. – Utensil Sep 14 '11 at 15:39
  • 2
    Will Mercurial allow reusing a closed branch's name? I.e., if you have a v3 branch, can you use the technique above to rename it to v4 and then fork off a _new_ v3 branch despite having left behind a closed v3? – Joshua Goldberg Jun 25 '12 at 18:05
  • 1
    No, branches are permanent. If you commit to a closed branch, Mercurial will re-open it. If you want "light-weight" branches (like git's), use bookmarks instead. – Elliot Cameron Jun 26 '12 at 21:52
  • 4
    @JoshuaGoldberg, 3noch is wrong. Mercurial *will* allow you to reuse a closed branch's name if you use `--force`. For example: `hg branch --force v3`. This will result in `hg update v3` updating to the new `v3` branch, as you wanted. – Gili Jun 30 '14 at 17:11
  • 2
    confirmed @Gili's comment with hg help branch: "--force set branch name even if it shadows an existing branch" – Joshua Goldberg Jun 30 '14 at 21:53
  • @Gili "Not entirely correct" might be a better twist on it since you do need to "--force" Mercurial to do that. ;) But strictly speaking, you're right! Thanks for pointing that out! – Elliot Cameron Jul 11 '14 at 14:49
  • 8
    If you close `stiging` before branching, you don't get a "loose end" – Habizzle Aug 13 '14 at 13:19
64

For future readers: With the rebase extension, you can make a new branch with the same parent as stiging and move the entire branch history to it, like this:

hg update -r "parents(min(branch('stiging')))"
hg branch staging
hg commit
hg rebase --source "min(branch('stiging'))" --dest staging

This assumes that stiging has only one parent. Of course you can just use explicit revision numbers instead.

Note 1: If branch stiging includes merges with other branches, I think that this will preserve them, as long as staging and stiging have the same parent. But I'd certainly double-check.

Note 2: Since this edits the history, the old branch won't simply disappear from cloned repositories (see the rebase documentation). Unless everyone can clone anew, it might not be a very practical solution for a large group.

Note3/Edit (courtesy of @JasonRCoombs): Now that phases are standard in mercurial, rebase will refuse to modify changesets that have already been pushed. Either fool it by changing the phase back to draft (with hg phases), or let the old branch stay where it is, and just make a properly named copy (e.g., with `hg rebase --keep').

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
alexis
  • 48,685
  • 16
  • 101
  • 161
  • +1 for small teams where you can force the users to clone this is a good idea -- or use `hg convert` instead. – hochl Apr 03 '12 at 08:34
  • 5
    With late versions of Mercurial, the rebase command will fail with "can't rebase immutable changeset" if the changes to be moved are "public". Either force them to be draft (with hg phases) or pass `--keep` to the rebase command, which will copy instead of move the changes. – Jason R. Coombs Oct 30 '13 at 17:47
  • At step 4: `abort: can't rebase immutable changeset 11b1e2b7dc4f`. Note that I have grafted changesets from another branch into this one. Besides that, it's split and merge free. – Mark Jeronimus Sep 28 '14 at 15:14
  • @Mark, take a look at Note 3 above. – alexis Sep 28 '14 at 15:32
  • 7
    Instead of committing a changeset on the new branch and then rebasing on top of it, you can omit that and use `.` for your `--dest` value and the rebase will take on the new branch name automatically. – weberc2 Nov 25 '14 at 23:07
16

Make a new branch called "staging" and forget the other...

Martin Geisler
  • 72,968
  • 25
  • 171
  • 229
lctr30
  • 526
  • 1
  • 4
  • 17
  • +1 that's what i'd do. The old changesets will still have the old branche name, but the new ones will have the new branch name. – barjak Dec 08 '10 at 12:53
16

If you have changesets on it, then you'll have to use the convert extension with a branchmap to rename it. Everyone will then have to clone the new repo or strip off the old branch.

Gili
  • 86,244
  • 97
  • 390
  • 689
tghw
  • 25,208
  • 13
  • 70
  • 96
8

This modifies the history and is only for advanced Mercurial users. Don't do this if you don't know what that means.

If stiging is local only, you can change it to staging with a combination of graft and strip. Start by updating to the ancestor changeset where stiging had diverged. Create the staging branch and graft each commit from stiging to staging. Staging should now be a copy of stiging. Lastly, destroy stiging by stripping its first commit.

hg update {SHA-1 of the ancestor changeset}
hg branch staging
hg graft {first changeset in stiging} ... {stiging head-1} {stiging head}
hg strip {first changeset in stiging}
hg push --new-branch
AWrightIV
  • 553
  • 7
  • 15
  • 1
    For step 3 you can use `hg graft {first changeset in stiging}..{stiging head}` – KCD Jul 22 '19 at 21:05