Josh Smeaton
Josh Smeaton

Reputation: 48720

Can I point a branch to a new HEAD in mercurial?

We have two major release branches - 'stable' and 'beta'. Over time, the 'beta' branch has received changes that didn't progress to stable, but were never removed.

What I'd like to do is sync beta with stable again so they are exactly the same. Is this possible with mercurial while keeping the same branch names?

We have rudimentary deployment set up for beta where a receive commit on the branch pushes out to all the webservers. I could just start a new branch off stable, but that would cause confusion.

Essentially I want to do this:

hg update stable
hg branch beta --overwrite

Upvotes: 2

Views: 285

Answers (2)

Lazy Badger
Lazy Badger

Reputation: 97282

Backout-solution

In order to exclude from result (not in history of branch) you can a) backout "stalled" changesets in beta branch b) merge stable to beta

Rebase-solution

Create additional branch, rebase unwanted changesets to this branch, merge stable to beta

MQ-solution

Install mq, convert changesets-in-question into MQ-patches, unapply all mq-pathes, merge stable to beta

Addition

If unwanted changesets in beta are unknown

(Ry4an graph used as source for commands)

Diff-patch way

Idea: adding "correcting changeset" on top of beta, which bring bring beta to a the state, identical to state of branch stable@6

Implementation: hg up beta & hg diff -r beta -r stable | hg import - & hg commit -m "Beta synced"

New branch way

Idea: forgot about old outdated branch beta, create beta from scratch, current state of stable

Implementation: hg up beta & hg commit -m "Closing branch" --close-branch & hg up stable & hg branch -F beta & ... & hg commit -m "Reopen new beta"

Upvotes: 2

Ry4an Brase
Ry4an Brase

Reputation: 78330

If you were using Mercurial bookmarks, then yes. Bookmarks are pointers to changesets, so you can force them to point anywhere you want (they're a lot like git branches if you know those). Mercurial named branches though are indelible labels attached to every changeset. When you're talking named branches the "head" is the "most tipward" (essentially newest) changeset that has that branch name, so you can't make an older changeset be the head without removing all of its ancestors that have that branch name.

Here's a diagram that might help. For each changeset "branch" is its branch name (every changeset has one, but if it's default it's not shown in most UI contexts):

  [0]  (branch: default)
   |
  [1]  (branch: default)
   | \
  [2] \    (branch: default)
   |   [3]   (branch: beta)
  [4]   |    (branch: stable)
   |   [5]   (branch: beta
  [6]        (branch: stable)

In this diagram there are 2 topological heads, changesets 6 and 5, but 3 total heads, 2, 5, and 6.

Changeset 5 is the head of branch beta because it's the "newest" changeset w/ that branch name. Changeset 6 is the head of branch stable because it's the "newest" changeset w/ that branch name. And, changeset 2 is the head of branch default because it's the newest changeset w/ that name.

So, if I understand your question you can't make changeset 6, which is one branch stable, also be the head of branch beta because every changeset is on one and only one branch -- thus a single changeset can't be the head of two different named branches.

You do, however, have plenty of options:

Create a new changeset on branch beta that looks exactly like the current head of stable:

 hg checkout stable # makes the working directory look like changeset 6
 hg branch beta     # tell mercurial that the next changeset created should be on branch 'beta'
 hg commit         # creates changeset 7 on branch beta w/ contents of changeset 6

you may need to make some tiny change before you can commit there (to avoid "no changes"), but that's the gist of it. Since your new changeset has the files from 6 but has the branch label 'beta' and is newer than 5... poof it's the new head of 'beta'.

or

Switch to using bookmarks -- they're more like how you're imagining branches work. They're pointers to changesets and multiple pointers can point to the same changeset.

Upvotes: 2

Related Questions