How do I return to a certain changeset (or tag) and branch out from that commit?
Once I branch out and committed changes won't affect the original branch?
|
tag-----------------
| \
branch-1 branch-2
hg update branch-1
hg branch branch-2
edit
hg commit
Note that this is named branches and there are other ways to branch in Mercurial.
Related
I have local branch and master branch. I use hg merge local branch with master branch, after that I find that master branch version is modified and I have to merge with new master branch.
I don't know how to back local branch status and merge new master branch.
If you committed the merge and then found that there were new changesets on master, you could do either of:
hg pull the new changesets, then hg merge again, then push the two merges.
hg strip your merge, then hg pull and hg merge <localbranch> again.
If you haven't committed first merge yet, you could hg update default -C to throw out the merge changes, then hg pull and hg merge <localbranch> again.
I already read topics like How to correctly close a feature branch in Mercurial?
But I want remove branches reference.
Example
hg branch my-branch
hg commit -m "commit" --close-branch
hg branches -c
hg branches -c displays my-branch in the list. And I can't create a new branch named my-branch.
hg branch my-branch
Mercurial shows me an error :
abort: a branch of the same name already exists
Do you know how to remove branch reference definitively ?
hg help branch
...
options:
-f --force set branch name even if it shadows an existing branch
...
With mercurial it is easy to create a tag at a certain revision: hg tag -r <revision> <tag-name>. But how to create a branch at a certain revision?
Preface: Mercurial branches are two types:
named branch
anonymous
Named Branch
In order to get named branch BRANCHNAME, starting at REV
hg update REV
hg branch BRANCHNAME
...
hg commit
commit is a must, because
the branch will not exist in the repository until the next commit
as noted in hg help branch
Anonymous branch
hg update REV
...
hg commit
and current branch get additional head
And as a last step, use the following command to create a remote branch and push the changesets.
hg push --new-branch
You could you hg clone -r <rev>. From the command line help (run hg -v help clone):
- create a repository without changesets after a particular revision:
hg clone -r 04e544 experimental/ good/
For Mercurial, right now there is default branch and newfeature branch... is it true that if I am on
the newfeature branch, and do an hg pull and hg update, it will always ask me to merge? (if there are changesets that I pulled)
Also, it seems that I cannot just do hg merge? I need to use hg heads and then look at what the newfeature branch's head is (say it is revision 6880),
then I need to hg merge -r 6880? Because otherwise, will Mercurial merge the newfeature branch with the default branch automatically? I cannot do hg merge -b newfeature, it seems, as there is no -b option for hg merge.
Is there an easier way other than using hg heads to look for the revision to merge? Isn't there a more automatic way?
You've got two questions there, let me take them one at a time (with a little paraphrasing):
Q. When I hg pull and get a new head Mercurial suggest I hg merge. Do I have to?
A. No. Mercurial is just warning you you have more heads than than you did, and that if you don't like that arrangement you can merge to stop it. Named branches are heads, so you'll see that warning if pulling gets you a new head
Q. If I want to merge one named branch into another do I have to provide the revision number?
A. No. It's true that hg merge will only automatically select heads on the same named branch, but you can do hg merge -r newfeature and that merges in the changeset from the point of divergence up to the head on newfeature (6880 in your example) exactly the same as hg update -r 6880 would.
In either case, after committing that merge you'll have no heads on newfeature (the new, resulting head is on default because that was the branch name of your parent before you started the merge. However, just doing this after the merge:
hg update newfeature
...code....
hg commit
will create a new head on the newfeature branch, and you're right back as you were before the merge, except all of the changes that were on new feature are also available in default now.
If you pull a changeset or changesets from one branch into another branch that share the same root changeset. Mercurial will have multiple heads as you have so noticed. It will only suggest that you merge when you do an hg update on one of the branches.
You shouldn't have to specify which revision to merge to, assuming that you want to merge the tips of each of the branches. hg merge should suffice.
Your command structure should look as follow
hg pull -b 'branchYouWantToPullFrom`
hg update
hg merge
hg commit
hg merge works in your working copy, which is always connected to a specific branch.
You have to specify a branch name only if you want to merge your current branch with another branch: hg merge branch_name.
hg pull updates your repository with all remote changes. Then you have to update your working copy, that is connected to a specific branch. So, when you type hg update command, you update your working copy with all changes in your current branch.
If you want to switch to another branch you have to type hg update branch_name. You can type hg branch to know your current branch.
The only reason to merge with a specific revision is when you have three or more heads, a strange situation probably caused by some hg push -f (extremely bad practice). If you are in this situation, the right way to know which revisions you have to merge is hg heads. In a normal situation hg heads returns one head per branch, so you don't have to merge two heads of different branches if you don't want.
If you're working on a branch and someone has committed and pushed some changes on the same branch, you have to pull and merge before your push, simply with hg merge, no revision or branch.
I hope this will help you.
I'm trying to figure out how to merge branches from a separate repo into the current.
I have the following:
PJT1
- contains branches default and foodog
PJT2
- contains branch default
from PJT2, I do the following:
$ hg fetch -y ../PJT1 -r foodog -m "this is a test"
Now, if I look in PJT2, I see the correct files and changes. However, I if I do hg branches, I get the following:
[someone#myhome pjt2]$ hg branches
foodog 1:c1e14fde816b
default 0:7b1adb938f71 (inactive)
and hg branch reveals the following:
[someone#myhome pjt2]$ hg branch
foodog
How do I get the contents from PJT1's foodog branch into PJT2's default branch?
You need to merge, but keep in mind changes on branch foodog will always be on foodog -- branches never go away but they can be hidden. This sequence of commands is as close as you'll get to what you're asking:
cd PJT2
hg update default # just in case you were somewhere else
hg pull ../PJT1 -r foodog # that gets you foodog
hg merge foodog # that merges the changes into default
hg commit # commit the merge
hg update foodog # go to the most recent change in foodog (note: it is not a 'head')
hg commit --close-branch
After the merge hg branches will still show foodog unless you do hg branches --active which only shows branches that have heads on them. After the commit --close-branch you won't see foodog unless you do hg branches --closed.
It's because branches in Mercurial never go away entirely (a design feature) that they're often reserved only for life-long things like release-1.0 or stable. For short-lived efforts like bugs and features consider using bookmarks instead. Here's a great comparison of the two: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial
You could also try using the rebase extension. It would look something like this:
hg fetch -y ../PJT1 -r foodog -m "this is a test"
hg rebase --source <sRev> --dest <dRev>
The rebase action will detatch changeset sRev and all descendents and apply the group of changes to changeset dRev. By default, the changes will be applied on the default branch. So, in your case, sRev would be the first changeset on branch foodog and dRev would be the default changeset you want to apply them to.
Finally, If you want to override this and preserve the source branch name you can use rebase option --keepbranches. Your questions indicates that this is exactly what you do not want to do, but it should still be noted.