I'm new to mercurial and I read that it's not possible to merge only a separate changeset from another branch.
Then I don't know what's the best approach to solve that:
I start with an stable revision R1
I continue developing on R1: CS1,CS2,CS3
At some point I need to solve bug from my stable revision R1. And I want to apply only one changeset from developing line (fe CS2)
What's the best aproach? As merging didn't work what I've done is make a patch of CS2 and then apply the patch in the new stable branch to fix the bug. That's the Mercurial way?
Cheers,
UPDATE: No need for any extension anymore as of Hg 2.0
As 'CAD bloke' pointed out, this is exactly what the graft command is for which was introduced in Hg 2.0.
SourceTree
The easiest way to do this is with a GUI like SourceTree, just double-click on the TARGET branch to switch, then press the right mouse button on any other revision and select the 'Graft' command (strangely it can also be a revision of the current branch).
If there are no conflicts SourceTree will immediately create a new revision for the current branch.
TortoiseHg
Exactly the same, select TARGET Branch, then rmb over the revision you want to graft: How to graft with TortoiseHg
Command Line
To do this with the command line just switch to the TARGET branch and then execute
hg graft -r {revision_number}
with {revision_number} obviously being the number of the revision you want to incorporate into you current branch. This will create a new changeset in you current branch with all the files from the revision whose number you used in the command.
To find out more about the graft command read this thread here on stackoverflow
The transplant extension automates what you've done to a single command.
But I think the preferred way (which depending on the scenario isn't always possible) is to make the fix on top of R1 in the first place, and then merge that to your development tip.
That is:
Start with stable revision R1.
You do some work, cs1...csN.
An important fix is needed for stable on top of R1, so you hg update R1.
Do the fix, this yields R2.
Go back to where you left off, hg update csN.
Merge stable so you have the fix, hg merge R2, hg commit...
Continue working on csN+1.
Related
We've just spent two weeks working down the wrong path on a problem (with all the commits to our SVN repository that go with that). We've now come up with the right solution (which needs our code base to go back to what it was two weeks ago). We should have branched two weeks ago, but that is irrelevant now.
Clearly, I can make a second checkout of the project and then copy that over the current version of the repository and check that in.
Is there a cleaner way to do this without a second checkout?
There are many ways to do what you want. The simplest would be to check out a new copy of the codebase to a dev machine, specifying the revision for the commit made just before you went down the wrong development path. Then, simply check that code back in as the latest revision. Not only do you effectively "revert" the codebase to that revision, if you find out that some element of your wrong solution was useful after all, you still have easy access to those elements.
Also, as was said, you can branch the codebase at any time, at any revision. Simply cut a branch of the revision before you began your work, and continue along your new dev path. Keep in mind that merging this branch back into the trunk could be problematic; you'd want the end result of development in the branch to replace the codebase of the trunk wholesale. That's possible but it can get messy.
There are a few ways of handling this:
Revert your changes:
$ svn merge -r$rev2:$rev1 .
This is assuming that $rev2 > $rev1. This will back out the changes between these two revisions. If you're backing out a single revision, you can use this:
$ svn merge -c -$rev .
That is, the revision should be a negative number. This will back out just that one revision.
Recreate the Branch
If this work was not done on trunk, but on a branch, and you pretty much want to toss out that branch, you can simply recreate the branch, and even delete the old bad one. Branches (and tags) can be created from any point in time:
$ svn cp -r$rev $REPO/branches/$bad_branch/$proj $REPO/branches/$new_branch
$ svn delete $REPO/branches/$bad_branch
The solution provided by Mike works for me.
In a separate branch
$ svn merge -r 303:302 http://svn.example.com/repos/calc/trunk
(this undoes the change between 302 and 303).
Then you can commit the changes in your branch, test and then merge back to the trunk as normal.
I created a stable but I accidentally changed a file while working with stable branch. I committed and now my default (which is development) doesn't have it. I tried hg pull -r <changset> where changeset is the latest commit.
What should I do?
hg merge stable
This will merge the two together.
Visit https://www.mercurial-scm.org/guide and go to Merge the named branch.
You don't have to close it.
We have two heads. One is our main development head and the other is one that I forgot about until today. We found a bug and fixed it in our main development branch, and I just realized it should be fixed in the older branch as well.
I think it would have been better to make the change on the older branch and merge that with the up-to-date branch, but we didn't do it that way. Can mercurial handle this? We haven't tried to do anything like this and I can't really wrap my head around how it would be done.
Yes, you have two good options:
Graft: new in Mercurial 2.0
This version introduced the graft command which can backport changes in an intelligent way. The "intelligence" is that it will use merges internally and this means that you get
Support for renames: Imagine that you fixed the bug in file foo.c on the development branch. In the older maintenance branch foo.c was called bar.c. Using hg graft, the change to foo.c can be correctly merged into the old bar.c.
Three-way merges: Grafting involves twisting the graph around and merging in that temporary graph. The advantage of three-way merges is that you can use your normal graphical merge tool to resolve conflicts.
To copy the tip of default onto old-branch you simply run
$ hg update old-branch
$ hg graft default
Transplant: older versions
Before we had the graft command, the transplant extension was the way to go. This simple extension will export a changeset as a patch and try to apply the patch onto some other revision.
Because we're dealing with "dumb" patches things like renames will not be taken into account and you will not get support for your merge tool since there is no three-way merge. Despite of this, I've found that transplant works really well in practice.
Using transplant is simple:
$ hg update old-branch
$ hg transplant default
This is very close to running
$ hg update old-branch
$ hg export default | hg import -
except that transplant also adds a piece of meta data that records the original changeset in the transplanted changeset. This can be used to skip future transplants.
I'm trying to do some work on a project called NS-3, but my problem isn't project specific so I thought I'd ask here as well as the relevant mailing list.
Basically, a copy of the then current project code was made, and a fresh repo made of that code. Work was done on both the 'forked' version and the trunk.
So cloned the forked source, cd in, and hg pull <latest-dev>, hg merge, and while it wasn't a perfect merge, the changes that were unmergable were all related to one library change, so easily fixed (in theory). Naturally this optimistic attempt failed to build.
Now I'm not entirely sure where to go from here, I'm new to DCVS so please; ideas directed towards a 5 year old!
How can I find out which changeset of the forked version was last merged against the dev-trunk since they're separate but related repos?
The Case Where You Started With a Copy Not a Clone:
If this is what happened:
Project Exists
Copy (not clone) of project is made
hg init is run in each separate copy, creating two unrelated repositories
work is done in both copies
Then to merge them you want to do this in the newest of the two unrelated repos:
hg update 0, which jumps the repository back to its earliest point -- the point where it last looked identical to the other
copy in the contents of the working directory from the other repository
hg commit, which creates a new head
hg merge, which merges the two heads and also provides a base revision, which helps the merge process.
The key is getting a base revision involved if possible. What DVCS systems bring to the table that CVS and SVN don't is that every merge is a 3-way merge between two heads and the most recent common ancestor. Faking that common ancestor by creating the new head off the last point the two repos looked the same (revision 0 in the copy) simulates a base revision.
The Case Where You Started With a Clone Not a Copy
This is the classic DVCS case and there shouldn't be much you need to do. Just go into one of the clones, hg pull from the other and fire off the hg merge. If the merge requires input you'll use hg resolve to provide it, and when you're done hg commit.
If at this point your code isn't building/running then you need to just start debugging. Use hg blame to see what was being done near the lines that won't compile and try to suss out what was being done and how to work on it.
The merge process is much easier the more frequently you do it. Pull in up-stream changes daily, not monthly.
You can turn on the GraphLog extension and use the hg log -G command to see the point at which the two lines of development diverged, but in the end merging is development, and you just need to approach a non-building merge like you would any other software defect.
I want to go back in my bazaar history (change working tree) to find the commit that introduced a certain bug.
I do not want to delete any commits, just change my working tree until I found the bug, and then I want to go back to the latest revision to work on.
What are the two commands for that (going back to an earlier commit and afterwards checking out the latest revision again)?
Thanks in advance.
To revert the working tree back to a specific revision N:
bzr revert -rN
To revert the working tree to the latest revision in the branch:
bzr revert
There are two ways to take your working tree back in time to revision N. The first has been mentioned by other answers here:
bzr revert -rN
That will modify all the files necessary to make your working tree match the contents of revision N. If you run bzr status it will show all those files as changed. If you run bzr commit then all those backward changes would get committed and your HEAD revision would now look like revision N.
To come back to the latest version in your branch:
bzr revert
You could also run bzr update, but that might get some newer revisions if your branch is a checkout.
The other option for going back in time is this:
bzr update -rN
The difference between the two is that bzr update makes it look as though no changes have been made. It's just that your working tree is out of date.
To come back to the latest version in your branch:
bzr update
Other commenters who answered with bzr revert -rN are certainly correct in the sense that that is the direct answer to the question as it was asked, however if you have a large number of commits to check through in order to test for the presence of a bug, it is vastly more efficient to use bisection. One time I was presented with a bug where the last known-good commit was 300 commits ago, and bisection found the guilty commit in only 8 passes (I mean, I only had to check 8 commits out of 300 in order to find the one that introduced the bug).
http://doc.bazaar.canonical.com/plugins/en/bisect-plugin.html
If you're feeling overwhelmed by the number of possible commits you need to check, this should reduce the amount of effort involved significantly!
To change the working tree to the state that it had in a previous revision N
bzr revert -r N
To update your working copy to the state it has in the latest revision:
bzr up
Bazaar Quick Reference Card
you can use bzr log --forward to see your previous versions with DESC sorting
and you can use bzr revert -r for change your version to the
if you want to revert to the last version just do bzr revert