Can I revert a changeset and keep the later changeset intact - mercurial

Suppose we have
changeset 14
changeset 15
changeset 16
and I am on changeset 16 and I need to take out the changes I made in changeset #14 but keeping #15 and #16 intact.
Can I do this with hg? I feel like it's impossible because changeset #15 and #16 depends on #14.... I heard about queue patches. Is it relevant?
Thanks

Take a look at the backout command. It does just what you want. It'll remove the changes in chageset 14 and attempt to apply the later changes, asking you if it can't make sense due to lost information.

Related

With Mercurial, how do you hg log a branch with cross-branch ancestors?

In Mercurial, I'm wanting to build a changelog of all commit messages for revisions my stable branch. Currently, I'm using:
hg log -r <oldid>::<newid>
where is the revision id of the changeset from the last time we pushed out code, and is stable's tip. This works great for code changes that are only on the stable branch, but if I'm merging another branch (such as a new major version which had its own development branch), all those commit messages are omitted! Instead I only get the 1 commit from where it merged into stable. I would like some way (preferably w/ hg log) to see these as well.
I do NOT want to get any "unpublished" commits in this list - that is, commits on any branches which haven't been merged into stable.
Here is an example of what I'm looking for:
In this example, the last pushed revision is 540. Because of this, I don't want anything at 540 or below. There are several branches out into default and back in to stable, and I want all of these (539, 541-557 in green). However, there are some changes NOT merged back into stable (558-563) which I wish to omit. Pay special attention to Revision 539; it was NOT merged into stable when 540 was published, and therefore was not included. But now it has since been merged into stable, so I would like to include it!
Any advice you guys have would be greatly appreciated. Thanks!
Not 100% sure if this will work:
hg log -r '::stable - ::540'
I'm uncertain about it because I would have thought the command you provided would mostly be correct, except for changeset 539. You're not passing -b stable to hg log by mistake, are you?
Have a look at revsets. Kevin posted the short form of what you want - here's the long form:
hg log -r "ancestors('stable') and not ancestors(540)"
Revsets are incredibly powerful, and you can just enter them into the filter bar of TortoiseHg.

Merging/Removing a commit

I have a commit i pushed earlier today that i learned i had messed up on by not adding the correct files before pushing. I fixed the revision and re-pushed it, so now i have a revision containing literally nothing new and my real revision. This could really confuse my other team members working, so i would like to either merge both together or remove my 'blank' revision.
Here is a picture of my problem:
http://img525.imageshack.us/img525/3929/revisionproblem.png
Note that i cannot undo/rollback, it tells me the transaction is not available.
If you've pushed it there's very little you can do. You could hg strip it from your local repo, but you'll get it back the next time you pull. You could edit history with hg histedit or merge two changesets with hg collapse, but none of that will get rid of the changeset you've pushed.
That said, the comment in your screenshot, "I just rolled back my latest push...", has me thinking you might have hg push and hg commit confused. They're entirely different and hg push can't be rolled back (locally). A hg push sends your local changesets out to the world -- no takebacks. A hg commit creates a new local changeset.
If you've misstated your problem and you've merely hg commited a changeset you regret you have all the extension-based options I listed above available to you. If you've really pushed it -- welcome to DVCS usage: once it's out there it's out there, and the best you can do it correct it in a subsequent commit.

Mercurial undo three hg push

I'm using mercurial VCS, I've mistakenly pushed three commits and I want them to be undone, can this be achieved?
I'm pretty sure no changes were propagated to anyone from the repository I pushed to, so I'm confident that this won't break anyones code...
I've tried hg rollback but since I have pushed I cannot undo anything in the right way. Also I know about hg backout, but I'm not sure if I should use this one for what I need...
Thanks!
EDIT
This is the graph log, I forgot to mention that some commits were part of a merge, but they too need to be undone...
tip
|
a
| \
| b
| /
c
|
d
I need to return the tip to c, or d if there is no other way to prevent that because of the merge...
If it's already pushed, there are only two things that you can do now:
1) If you are able to delete the central repository and replace it by another one:
You can clone the central repository, but tell Mercurial to clone only up to changeset "c".
Then you can take this repository (which doesn't have the wrong changes) and replace the "old" central repository (the one which does have the wrong changes) with it.
Disadvantage: if someone already pulled the unwanted commits and later pushes again, they are in the repository again.
So you need to make sure that either no one pulled the mistakes, or everybody who did deletes his clone.
2) If option 1 is not possible, you can use hg backout to undo the effects of the wrong changes - not the changesets themselves.
Quote from the link:
Backout works by applying a changeset that's the opposite of the changeset to be backed out. That new changeset is committed to the repository, and eventually merged.
So the three wrong changesets will remain in the repository, plus another three will be added, each of them reverting the effects of one of the three wrong changesets.
If you do it like this, it doesn't matter if someone else already pulled the wrong changes...as soon as he pulls the three "backout" changesets as well, everything is okay again.
If you're positive the push is the last thing that happened to that remote repository, meaning neither you nor anyone else has pushed to it, you can login to that system and run hg rollback.
If it's a repository on a machine to which you can ssh you can run this command on your local system:
ssh you#there hg -R /path/to/the/repo rollback
As always please do be really careful with rollback. It undoes the last action on the repository without altering the working directory at all, and it's not always clear what the last action was. For example, this is datalosss:
...hack...
hg commit -m 'important work'
hg update somewhere else
hg rollback
Yikes!

Mercurial: back out last change so codebase is clean?

I've just messed something up in Mercurial.
How do I back out the last change so that the codebase is clean - specifically so that if someone else does 'hg pull', they'll have a working codebase?
Two ways:
hg rollback as mentioned by Fred; if you've already pushed, too late. hg rollback is only suitable for local use. hg strip (also as mentioned by Fred) works the same way and is (excepting its support for backing up) equivalent to doing hg rollback a number of times, till you get back to that revision.
hg backout for when you have already pushed and just want to revert the effects of the commit (if you've accidentally pushed out sensitive data, you'll need to take more drastic measures, but if you just want it to work, use this).
If the commit is not the last-committed revision, say so and we can get into deeper stuff (or search - it's been answered before).
Another way is to clone from a specific revision. Say checkin 6 was the mistake. You can clone your repository up to revision 5:
hg clone -r 5 myrepobad myrepoclean
now in myrepoclean you are back to where you were before the bad checkin. Obviously you need to be aware that anyone who has pulled the bad checkin is now liable to push it back in.
$ hg rollback --help
hg rollback
roll back the last transaction (dangerous)
This command should be used with care. There is only one level of rollback,
and there is no way to undo a rollback. It will also restore the dirstate at
the time of the last transaction, losing any dirstate changes since that
time. This command does not alter the working directory.
...
You should also look at the strip command.

hg transplant fails - how do I 'fix up the merge' as it suggests?

My branch2274 was branched from default. Rev. 415 was the first commit and it shares an ancestor with the rev. 412 on the default branch.
Branch2274 is a bug fix which needs merging into default soon BUT I did a very silly thing - I merged in changes from a feature branch (at rev. 418)
In simple terms, I need to undo whatever changes were brought in by rev. 418. There seems to be a lot of ways to attempt this but I'm struggling to get any of them to work:
Mercurial queues attempt:
I've tried importing revs 415, 416, 417, (skipping 418), 421, 428 into a patch queue so I can apply it to rev 425.
Problem: tortoisehg will only allow me to import revs 428, 421 but importing 417 is greyed out but importing 418 just gives me the error "abort: cannot import merge revision 418"
Transplant attempt:
patching file Portal/Instructor/Login.aspx.vb
Hunk #1 FAILED at 18
1 out of 1 hunks FAILED -- saving rejects to file Portal/Instructor/Login.aspx.vb.rej
applying 66b6b089ee01
abort: Fix up the merge and run hg transplant --continue
patch failed to apply
[command interrupted]
Login.aspx.vb has been changed on default and I understand why the merge has failed.
How do I 'fix up' the merge?
Alternatively, is there a simpler way for me to take rev. 418 and tell mercurial to undo the changes it brought in with a new commit on case2274?
In the interests of not leaving a question unanswered (!), I managed to resolve this and the ultimate answer is that there's no simple way to resolve it automatically. Transplant deals in patches, differences between two files but doesn't take into account the common ancestry of the two files so struggles to know what to do when a file has been changed by two people in the same place.
The solution is to load the file in your text editor and load the .rej file which lists the failed parts of the patch. I just had to put my additions in a sensible place in the code file.
Running:
hg transplant --continue
..allowed me to apply the other patches.
If anyone cares to spend some time expanding this answer with a little insight or a few relevant links, then the answer is theirs.