First I had a repository:
A---B---C
I pulled some changes from another repo:
A---B---C
\
--D---E---F
Then I grafted necessary changes from another branch:
A---B---C---E'--F'
\
--D---E---F
Now I have 2 default branch heads. I want to continue working on the original.
What should I do with pulled head? Close it or leave it open? Are there any
problems with either option in the future?
I don't have any problem having the other branch there. I may or may not pull and graft more changes in the future.
There's no problem at all keeping the other head on the 'default' branch open. Once you do another commit after F', say G', that will be the "newest" (technically "most tip-ward") head on 'default' so that's what you'll always get when you say "default" (example: hg update default).
If you want to close F you can do it with a 'hg commit --close-branch` but there's no need to do so.
Related
I sometimes but not always end up with two heads on my default branch. The sequence of events is something like:
hg pull
hg update -C default
hg branch mybranch
hg merge default //merge in default
hg commit -m"merged mybranch into default"
hg heads -default //shows 2 heads
hg push --branch default //won't let ne. create 2 heads
The 'rival' head appears to be a changeset committed to default earlier in the day.
What I don't understand is why this happens sometimes and not other times.
The explanation I am usually offered is that the other guy pushed a change after I did a pull (my first action in the list above). But I think this happens in other cases e.g. when he pushed his changeset before I started.
I would have thought that when I pull default with his commit I get default with one head. My merge/commit should just create a new head after that. Why does it create a second head?
First of all, this is a totally normal situation. It's not a problem, or an error, or something to be avoided -- it's how a DVCS works.
In brief: you get two heads whenever two people start working from the same commit and do different things. It doesn't matter if they do it in their own (named) branch (as you're doing above) or on default. Once you merge your work back to default and someone else has done work on default you've got two heads and someone has to merge. It's just how things are.
Before you push do a hg pull and then a hg merge and you'll integrate your work with yours, by creating a new merge commit, with two parents -- your work and their work -- and then you push and you'll not see that warning.
Incidentally, you might want to check out the bookmarks feature. It's better suited for per-feature branches like you appear to be doing above than the named branches you're using, but it in no way saves you from having to deal with multiple heads.
check state of repository immediately after pull (pull can bring new head in default for you) with hg heads
hg branch without commit do nothing (you haven't mybranch)
Even if you'll create mybranch and merge it with default's tip (according to your syntax), it will not eliminate 2-nd head in default
I'm not sure why this is so hard to figure out or google, but I am trying to take changes I made to a private branch and push them to the default branch.
In other words:
I pulled from the default branch a few weeks back and made major changes
Since then, I have finished my work
I then merged the code from the original default branch (just the code, the HG is still set to the "NewBranch"
Now that the code works, I want to commit and push these changes back to the default branch and continue my development from there.
But I can't find any information on how to do that. If I switch branches, I lose all my changesets since I am still in the NewBranch. I can't figure out what rebase or transplant do and can't find guides that explain scenarios on what they could be used for... So hopefully someone here knows what to do!
I am specifically using Mercurial on Eclipse but I am fine doing this on command line if its easier.
merge is the way to get changes from one branch into another. I know you merged default into feature, but now you go the other way. Here's an example where numbered changesets come from other people and lettered changesets comes from you:
Before you do anything you clone and have this:
[1]---[2]---[3]---[4] (default branch)
then you create your branch named 'feature' and do two commits on it, yielding:
[1]---[2]---[3]---[4] (default branch)
\
[A]---[B] ('feature' branch)
then you hg pull to get changes to default since you diverged down in your local repository:
[1]---[2]---[3]---[4]---[5]---[6] (default branch)
\
[A]---[B] ('feature' branch)
now you want their changes (5 and 6) integrated into your branch so you do:
hg checkout feature # make sure you're looking at the he head of your branch
hg merge default # merge default into your branch
which yields:
[1]---[2]---[3]---[4]---[5]---[6] (default branch)
\ \
[A]---[B]---[C] ('feature' branch)
If I'm understanding correctly, you've already done all that, so now you just need to bring your branch, including the new merge commit, C, into default, which again is done via a merge:
hg checkout default # hop back to default, files look like [6] and [A] and [B] are missing
hg merge feature # merge feature into default brining [A] and [B] in
that yields:
[1]---[2]---[3]---[4]---[5]---[6]---[7] (default branch)
\ \ /
[A]---[B]---[C] ('feature' branch)
That looks like a lot of work drawn out that way, but in practice it's usually just:
hg branch feature
....work....
hg commit
hg pull
hg merge default
hg checkout default
hg merge feature
and if the pull didn't bring down any new work from other you can skip the merging of default into yours.
That does create two new merge changesets. They're easily hidden on hg log if you find them unhelpful (some people love having a record of which direction each merge went), but if you want to avoid them entirely you can use bookmarks (very similar to git branches) instead of "named branches" for your features -- then you'll avoid a merge changeset when coming back since it would be the spiritual equivalent of what git calls a "fast forward" merge.
I had a change in my branch and after unseccessfull merge, I tried to revert that unsuccessefull merge with hg up -c but it created a new branch instead. I can merge it into current or discard it or what to do with it?
EDIT:
actually I did the following, I had a branch and committed changes there there. then I wanted to push my changes to server, so I pulled changes, and tried to merge with them, but there were a conflict I couldn't resolve myself and I thought: I'll revert all changes back and merge again - so used hg up -C which I thought, will revert everything I changed during my unfinished merge. But what actually happened, another branch with the same name was created, containing only that changes I committed previously and with the same name as a branch I was working in and I was switched to the branch where I was working, which didn't have my changes. So two questions here: what actually happened and why another branch with the same name was created?
Having multiple heads on the same branch, which I think is what you're saying with "a branch with the same name as current" is a normal situation and, yes, you can use hg merge to consolidate them into one head. Use the hg heads command to find the hashes of the two heads of branch X. Then:
hg update REVISION_ID_OF_ONE_HEAD # changes your working directory to match one of the heads
hg merge REVISION_ID_OF_THE_OTHER_HEAD # merges that head's changes in
hg commit # create a new changeset that is the child of both those heads thus reducing the head count by one
Also #ringding is correct that hg update never creates branches. You either already had them and didn't know or received another head when you pulled.
I've come across a difficulty at work (as presented in the simplified sketch below). During the creation of a branch the default for some reason got stuck as a parent to a branch, but still keeping a default branch separately (that is the default branch we're using going forward). This has left us with two default branches.
Someone mistook how to commit changes before branching, so we ended up merging changes made in branch1 into a branch2.
I've been looking into Mercurial: the definitive guide to see if this is a resolvable issue, but couldn't find out what commands regarding backing out or closing that would help. The easiest way would be if it's somehow possible to rename the left-over default branch.
What is the best and/or easiest way to resolve this?
I'm preparing the merging of development branches into the correct default branch and want to have this headache fixed before I start any major merging that could make it even more difficult to fix this in the future.
Remember that the branch names are just labels put on the commits — there's nothing really broken about your graph. The branch names doesn't affect what happens when you merge, only the file content is important when merging.
That being said, you can close the extra head on default, the one below branch1:
$ hg update "min(heads(branch(default)))"
$ hg commit --close-branch -m "closing this head"
That will leave a dangling close changeset in your graph, which is fine. The close changeset will hide the head from hg heads and commands such as hg merge will then no longer suggest to merge with this head.
Old question, but I though this might be useful to someone.
..this occurs when a single branch diverges, usually when someone does an hg push -f instead of pulling and updating. In your case, the forced head happens to be also on another branch, but this can happen on a single branch as well. My solution would be to let it sit until the branches are merged -- at least, if there's a plan to merge them at some point. This solution is more clean than closing the erroneous head, in my opinion.
However, doing hg update default will take you to the newest commit with the 'default' name. Although I think this idea is the right one in your case, this is because the "default" that you actually want is the newest commit with the "default" branch name, so there should be no problem.
However, if the erroneous head were newer, hg update default would take people to the erroneous head, which could be quite confusing.
In either case, this would resolve the issue:
hg update <revision number of correct 'default' head>
hg merge <branch the erroneous 'default' head is on>
So in this case, hg update default will update to the erroneous head:
1-2(default)
\
3(default)-4(branch1)
You would need to do:
hg update 2
hg merge branch1
# results in this graph:
# 1-2---5(default)
# \ /
# 3-4(branch1)
whereas below, hg update default will update to the one you actually want anyways:
1-2------------5(default)
\
3(default)-4(branch1)
..and you could just ignore the erroneous default, because it won't affect anyone. ..then, once someone does an hg update default; hg merge branch1, the erroneous head will silently disappear, because at that point it's an ancestor of the erroneous 'default'. ..which would result in something like this:
1-2-5----------11(default)
\ /
3-4-[...]-10(branch1)
..you could also do a useless commit on your desired default, and then it will be the newest, and it would be the one people get when they do hg update default, but I don't really like having junk commits in the history.
I've just got a problem with hg push command. What I did - Firstly I created 2 branches hot-fix-1 and hot-fix-2 made some changes in each branche, merged it back to default and closed those branches with the command:
hg commit --close-branch
If I start hg branches I have the following output:
default 29:e62a2c57b17c
hg branches -c gives me:
default 29:e62a2c57b17c
hot-fix-2 27:42f7bf715392 (closed)
hot-fix-1 26:dd98f50934b0 (closed)
Thus hot-fix-* branches seems to be closed. However if I try to push the changes I have the next error message:
pushing to /Users/user1/projects/mercurial/mytag
searching for changes
abort: push creates new remote branches: hot-fix-1, hot-fix-2!
(use 'hg push --new-branch' to create new remote branches)
and it does not matter which command I use hg push -b . or hg push -b default
So the question is how I can push those changes to repository without creating new branches.
P.S I used to work with git and was hoping that similar branching model can be used in Mercurial. Thanks
First, as many others have pointed out, using a named branch for short lived work is not a recommended practice. Named branches are predominantly for long lived features, or for release management.
Given that you are in this situation, there are a few options available. All of them involve modifying history (as you're obviously trying to change something you've done).
One is to just push the branches as is, learn from the experience, and move on. If the rest of the team is fine with this, then it's a case of adding --new-branch to your push command.
If the rest of the team, or you, really want the history to be clean, then you'll need to dig deeper.
If you aren't pushing, then definitely make a clone of your current repo. This way you have a copy of the original work to fall back on.
I see 2 main approaches here. Strip off the merges and rebase your branches onto default. This will get rid of the named branches or graft/transplant your changes. Both will be the same end result, but the implementation is slightly different.
If you merely want to use graft, that is now a built-in function starting with HG 2.0. It replaces the transplant plugin, and is much nicer to work with as it uses your usual merge tool if there are conflicts.
To use it, update to the default branch. Then, use the command:
hg graft -D "2085::2093 and not 2091"
the string after -D is an hg revision selection query. In your case, you'd likely only need '{start}::{end}' where start is the changeset at the start of the branch, and end is the end changeset of the branch (ignoring the merge).
If you did several merges, you'd have to pick and choose the changesets more precisely.
The other option is to strip the final merges, and use the rebase command that is part of the mq plugin.
You'll have to strip your merge changesets to get rid of them, and then update to the tip of the branch you want to keep. Select the start of the first named branch, and do a rebase. This will change the parentage of the branch (if you're familiar with Git, then this is very much like it's rebase).
Then repeat for the second branch. You should now have one long branch with the name default.
Just do the:
hg push --new-branch
It will send over those branches, but they'll be closed on the receiving end too, so no one should be bothered.
See my comment on the question for why Named Branches are best saved for long-lived entities like 'stable' and anonymous branches, bookmarks, or clones are more suitable for short lived things like hot-fixes and new features.
Your hot-fix changes were made on branches. Regardless of whether the branch is active or closed, it does exist.
To push the changes to the server (without rewriting history), you must use the --new-branch option (e.g. hg push --new-branch`).
Since you merged the branches into default, there will still only be one head (as you have already seen in your local repo).
If you really can't live with pushing the branches to the server, then you must rewrite your local history as suggested in Mikezx6r's answer.
In addition to the methods he mentioned, you can also import the changesets into a patch queue and apply them to the tip of your default.