Reverting several commits and rolling back - mercurial

The image shows that I was working after revision 323 when I realized that revisions 323 and 322 were completely garbage.
So, I updated to revision 321 and I now realize that this is perfect and I would like to start fresh from here.
Without using strip, is there a clean way of destroying revisions 322 and 323 and then working and building on top of revision 321?

Assuming that you already have pushed these changes, (which is why you don't want to use strip)
Option 1
Just commit on top of 321, after you have done that, update to 323 and close the branch. Then update back to where you were and keep working.
Option 2
use backout on 323, then 322, then continue committing.
Otherwise
If you haven't pushed, and there is some other reason you don't want to use strip, you could just change the phase of 322 + 323 to secret, and continue working off 321. That way they won't ever be pushed, and so never seen by anyone else.

Related

Remove a revision in TortoiseHG

I know this question has been asked and I know it´s against version control. But we have done some minor changes in the layout etc. and would like to remove the history of 30 revisions.
Is it possible to just remove these 30 revisions or merge them into one revision?
Like 160 was the last big one and then now we are on 195 but the 35 in beetween are all relatively small css changes so not really necessary for us. Is it possible to just get them into like 161 and then go from there?
I find using hg revert -r REV is a much easier approach that using histedit.
Don't do this if you have already pushed your changes.
Observe that the changesets that are being merged are all 'draft' phases.
Update to parent of the first changeset in set of changes you want to fold.
"hg revert -r REV -all" (where rev is the last change you want to fold) (ie. the tip - if its not the tip then you will have to do a rebase step between step 3 and step 4).
Commit.
Use strip to remove old changesets
And the final result:
It would be really nice to be able to do step 2 directly from the thg gui but I haven't found a way of doing it.
If you want to drop the revisions and all their descendants, you can just enable the strip extension, then right click->modify history->strip the changesets.
If you'd prefer to fold them together, and you haven't pushed yet, you can do this:
Enable the histedit extension in TortiseHG's settings.
Open a terminal with the terminal button.
Type hg histedit 160 and press enter. Replace 160 with the appropriate revision number. This part may take several seconds, so don't panic if the terminal seems to freeze.
A text editor window will open with a list of the changes since 160. Change the text in front of each line you want to merge from pick to fold, to combine that changeset with the one above it. You'll also be prompted to edit the commit message after each fold. You can use drop to remove the changesets instead of folding them.
If you have pushed, modifying history is more complicated; see hg phases for details.

Patch corruption or loss after rebase

I just lost all of the changes in a Mercurial patch (fortunately, I had a backup), and I would like to figure out what went wrong.
The Setup
I had a pair of patches, call them patch1.diff and patch2.diff. They were both based on revision 123, but affected completely different files, with no overlap. So, my repository looked something like this in TortoiseHg (where p is a patch and r is a regular revision):
Graph Rev Branch Tags Message
p 125 develop patch2.diff Change to existing file baz.php
p 124 develop patch1.diff Add new files foo.php and bar.php
r 123 develop Last committed changeset
|
r 122 develop Old changes
...
What I Did
I wanted to switch the order of the patches, because my work on patch2.diff was complete and I wanted to commit those changes. So I tried rebasing that patch onto revision 123. That didn't work, and I ended up with something like this:
Graph Rev Branch Tags Message
r Working directory - not a head revision!
r 126 develop Change to existing file baz.php
|
p | 125 develop patch2.diff Change to existing file baz.php
|
p | 124 develop patch1.diff Add new files foo.php and bar.php
|
r-+ 123 develop Last committed changeset
|
r 122 develop Old changes
...
That was clearly wrong. I now had a revision 126 with the same changes as those in patch2.diff, but I also still had a patch2.diff, which wasn't rebased as I expected. On top of that, I was getting the "not a head revision" message, even though there weren't actually any changes in my working directory.
So I stripped revision 126. At that point, things went completely off the rails, leaving me with this:
Graph Rev Branch Tags Message
p 125 develop patch2.diff Change to existing file baz.php
p 124 develop patch1.diff
r 123 develop Last committed changeset
|
r 122 develop Old changes
...
patch1.diff still appeared in TortoiseHg, but the changes and commit message were gone. I tried hg qpush --all, and got these messages:
applying patch1.diff
unable to read patch1.diff
I couldn't even find patch1.diff on my file system anymore. Ultimately, I had to run hg qdelete --keep patch1.diff and then restore my lost changes from offsite backups.
I ended up where I wanted to be, but nearly lost hours of work on a new feature. I was able to recover only because I had an offsite backup of the new files. That was terrifying.
The Question
What in the world happened? Why did I lose patch1.diff? I could understand if I lost the changes in patch2.diff given the way I used hg strip, but I have no idea why patch1.diff got nuked.
You stumbled over the issues why mq might very soon not be recommended anymore. It wants to retain control over csets it controls and it looses that, when you modify history under mq control. Thus mq does not work well with rebase, strip, histedit...
The better way is to simply stop using mq at all. Make your default phase for new commits secret (or draft). Commit your patches as normal changesets - then mq cannot interfer with proper working of rebase and what you did try to do would simply have worked.
hg rebase -s125 -d123
hg rebase -s124 -d126
(given the state of your repo as in the first quote, just asusming r124, r125 are normal csets, not under mq control)
And if you're a little daring, you take a look at the evolve extension which is very useful for people who maintain patch queues with respect to upstream repos or juggle draft changesets with collaborators.
See http://www.logilab.org/blogentry/88203 for an introduction to mercurial phases

mercurial collaboration results in multiple commits of the same changes when using central repository

I've been using mercurial with a central repository. As two or more of us work on changes we commit locally. At some point we push these changes back to the central repository.
The problem comes in when I do a pull. Often there are files that were modified and pushed by another developer and those come down to my repository with a pull. I am then required to merge, which shows me the difference between my local repository and the files that were committed.
What bothers me is that I have to merge and commit. That gets pushed back up to the central server which appears to have committed the same changes twice, once as me as a merge and once as a changeset from the other developer.
Is there some way in mercurial to update my repository and have files that I haven't touched just be updated rather than recording the exact same change twice, once from the original developer and once in my merge?
This question seems to raise the same point, but doesn't provide an answer to my question:
Why is mercurial dumb when merging? How can I make pulling/merging changes simpler?
Mercurial works in terms of changesets and revisions.
A changeset is a snapshot of the changes that went into making a revision.
If you were to succeed in only updating the files that were changed, when you pulled, you wouldn't have an actual revision in your working folder, you would have a bastard revision, and only you and your machine would know how that came to be. Someone else that pulls at a different time would get a different bastard revision, and they wouldn't line up.
So no, Mercurial is designed to work exactly like you say it does, except that it doesn't really show the changes as happening twice, there must be something you're doing wrong if it appears to do that.
In other words, if I change something, and commit, then I pull down your changes, do a merge, and commit that, the merge commit would only contain any changes I have to do in order to resolve the merge. If the merge was automatic, no conflicts that needed to be resolved, it would look like you're just committing an empty changesets, with two parents.
Now, there are ways to mitigate all the branches, you can use rebase for instance.
What would happen is the following:
central: 1---2---3---4
local: 1---2---3---4
You change something
central: 1---2---3---4
local: 1---2---3---4---5
Someone else changes something, and push:
central: 1---2---3---4---5'--6'
local: 1---2---3---4---5
(I use ' after the 5 to show that while it is revision number 5 in that repository, it's not the same as revision number 5 in the other repository.)
Then when you pull, it looks like this:
central: 1---2---3---4---5'--6' <-- corresponds to these <--+
|
local: 1---2---3---4---5 |
\ |
6'---7' <-- note that these gets renumbered
Then you rebase 5 to be on top of 7', and you get this:
local: 1---2---3---4---6'--7'--5
if needs be, a merge happens when you rebase, if you have done conflicting changes. After the rebase, you can push. It basically makes your revision history look like you took turns working.
The short answer is "don't worry about it". It looks to you like the change that person did is again done by you in a subsequent merge, but that's just because 'diff' doesn't have a great way to show merges in any VCS. The change is theirs, the combination is yours, and the whole thing works out. Two people suing a DVCS end up with a history that looks like a braided rope, and that's okay.

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.

Mercurial: Fix a borked history

So working on a project recently (by myself - no other developers), I somehow managed to seriously bork the history with some (apparently) bad merges from cloned repositories.
What I would like to do - need to do - is fix this by just deleting the last 8 commits (according to hg glog)
Yes, I have made a few changes to the code after the borking began, however, only a few tweaks here or there - nothing I can't fix fresh from memory.
How can I get rid of the last 8 commits and start over from where I messed up?
Make a clone of your repository - when you do this, you can specify the last commit that should be cloned.
So, if your repository has 100 changesets and you want to get rid of changesets 93 to 100, just do this:
hg clone -r 92 BadRepository CleanRepository
--> the CleanRepository will only contain changesets 1 to 92.
If you use TortoiseHG, you can do the same in the Clone dialog (there is a textbox "Clone to revision:")