I am using Mercurial. I have a file X that has two versions in two different branches. I have a version in the R1 branch and an updated version with bugfixes in the R0 branch. I have merged the fixes from R0 into R1, but somehow file X was not properly merged.
I now want to move the version of X that is in my R0 branch into the R1 branch.
How can I do this?
Update to the target branch, revert the file to the the revision of the other branch, then commit.
hg update R1
hg revert -r R0 X
hg commit
Consider graft as well (NOTE: I don't know enough about the state of your repository after the merges, but graft has helped me when I had to transfer changesets from one branch to another)
Related
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.
I have two branches named X and Y. X is previously created and y is the latest one. Now I am at branch 'Y' and I have modified some files. I need to commit the files which I have modified and I need to commit the changes to 'X' branch instead of 'Y' branch. How can I do this with Mercury Hg or Tortoise Hg? (How to Switch to 'x' branch and commit the changes?)
You could
Commit it to Y branch
Then transplant/grave it to X branch
Then strip changeset from Y branch
As result it's look like you commited it to X instead of Y
If you have not committed the changes then you should be able to do the following:
hg update X
hg commit
Unless you've changed some of the same files in the same places within the file, this should be sufficient. If you have, then your hg update X command should fail. You have a few options at this point.
You can use Mercurial Queues (mq).
You can put your current changes into a patch queue:
hg qnew stufftomove -e
You'll be presented with whatever editor you use to create a commit message. Go ahead and fill in your commit message with whatever you want it to be when it is ultimately committed. If you don't use -e, it will just create the patch queue with no commit message. Later you can make a commit message with hg qrefresh -e if you want.
After the patch queue is created, pop it off with:
hg qpop
Now move to the X branch:
hg update X
Now push the patch queue on. This will apply the patch file:
hg qpush
This can either go on cleanly, or if you did have merge conflicts, you'll get a message that .rej files have been created. Those show you the parts of the changes that could not be applied automatically.
If you have .rej files, manually apply the pieces that didn't work and then run
hg qrefresh
This will update the patch file with the new changes.
When everything looks like what you want it to, you can convert the patch queue to a real commit with
hg qfinish stufftomove
Your file changes should now be committed on the branch you want them to be on.
Alternatively, if you already committed the changes on the wrong branch, and have not pushed your changes (or had them pulled) to a remote repository, you can do this:
hg qimport -r <revision to import>
At this point, continue the above instructions starting with hg qpop.
If you can be more specific about the state of the files and branches, I can help more specifically. In any case, I hope this helps.
Side note: If you've got merge conflicts in the steps above and don't like dealing with .rej files, you can use hg rebase which will allow you to resolve the conflicts in your favorite merge tool (or whatever tool you've got configured). Hope this helps.
I use Shelving for such operation: https://tortoisehg.bitbucket.io/manual/2.9/shelve.html
While you're on 'Y' branch, put all your changes to shelf. Then switch to 'X' branch and restore changes from your shelf.
If i want to pull changes from local branch to my main stream branch and don't want interim changeset history of local branch in main branch. How we can do it?
You can't rewrite changesets history on push to server
You can rewrite local history in local repository before push
You can perform partial push and send only specific branch(es) hg push -b ..., not the whole repo
Consolidation of 1-3 means
You have to have new, separate pushable branch
You'll merge to this branch and collapse it's history (MQ-patches, add extension: histedit|collapse)
Push this branch only
since it is not possible omit changesets when pushing, you can try this solution, it is not clear at all, but you can do it this way. Imagine your local hg log like this:
5: top (this changeset you want to have in main branch)
4: (local changeset)
3: (local changeset)
2: (local changeset)
1: Change set what already is in main branch and should be parent of newly pushed changeset from local
If I had this issue I would update to 1, then revert all changest from 5 (so I will have working directory same as 5 is) then do temporarily commit (6), and this temporarily commit(same as changeset 5) I would push into main. In your local you can then merge 5 and 6 and continue, but there will allways be outgoing changesets from your local into main. Commands would look like this:
hg up 1
hg revert -r 5 -a
(now you have your working dir same as 5)
hg ci -m "Name of commit that will be shown in main branch"
hg push -r 6 main_branch_path
But proper solution, is, as we use it this way, to keep all your devel changesets in main too. HTH
I am working with a repository with stable and experimental branches. Sometimes I add a file on the experimental branch that is not yet ready for the stable branch. When I merge, I want to merge the changes in the files that are common to both branches, but ignore the files that don't exist on one of the branches.
Here's a simple example:
hg init
hg branch stable
(create file A)
hg add A
hg commit -m "Added A"
hg branch exp
(create file B)
hg add B
hg commit -m "Added B, which is really experimental"
(modify file A)
hg commit -m "Some changes to A"
hg update stable
hg merge exp
However I change the merge tool configuration, Mercurial always seems to take B along with the merge. Since it doesn't exist on the stable branch, it's never a conflict.
I could do the following:
hg update stable
hg merge exp
hg commit -m "Merged"
hg revert -r 0 B
but that requires me to know which files need reverting.
Any thoughts on the simplest way to make the merge ignore files that don't exist on one branch, and preferably do it automatically?
You cannot ask Mercurial to do what you want.
You do not merge individual files, you merge the entire branch, which means that all the files that are part of the branch becomes part of the merge. This is how Mercurial is designed and how it operates.
Now, you could revert/forget/delete the files you don't want before you commit, but then you're just setting yourself up for disaster later.
I recommend you separate things you want to keep from things you don't know if you want to keep so that you can merge one branch and let the other be separate for now.
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.