Mercurial update will overwrite my changes instead of merging - mercurial

I am coming from CVS background.
Currently, I have 2 mercurial repositories developed parallel. hello-world-bugfix and hello-world-feature (This one is being cloned from hello-world-bugfix)
Now, I want to merge the bug fixed code from hello-world-bugfix into hello-world-feature, so that end of the day, I will get a merged file.
[BUG2 BUG2 BUG2]
START
[BUG1 BUG1 BUG1]
[FEATURE2 FEATURE2 FEATURE2]
Here is how all the things looks like before, pulling and merging. The below two files had already been committed.
Now, I perform pull from hello-world-feature, to pull changes from hello-world-bugfix.
Then, I perform update, with always merge options turned on.
Here is my merged file???
[BUG2 BUG2 BUG2]
START
[BUG1 BUG1 BUG1]
It seems that my previous committed [FEATURE2 FEATURE2 FEATURE2] being overwritten.
It seems that I shouldn't perform update step, which will not merge feature with bug, but overwrite feature away with bug. What is the next correct step I should do after pulling? (through TortoiseHg), so that I can get bug fix code, and remain feature code there?
Here is the final repository view of hello-world-feature

The "always merge" option doesn't do what you think it does.
It only merges uncommitted changes.
When you update, committed files are replaced with the new version.
To merge committed changes, ie. merge branches, you need to do an explicit merge.
So, I would select the BUG2 BUG2 BUG2 changeset in the log, then right-click on the FEATURE2 FEATURE2 FEATURE2 changeset and click Merge, and follow the instructions.
Let me expand on what the "Always merge" checkbox does.
Let's say I have two changesets in my repository, I update to the first of them, then I start modifying one of the files.
At some point I decide it would be better to have started from the other changeset instead, so I want to update to it, keeping my modifications.
If I simply do an update, with uncommitted changes, I get this dialog box when I try to update:
However, if I check the "Always merge (when possible)" checkbox, it will simply assume that I clicked on the Merge button in that dialog and not prompt me.
So the "Always merge" does not have any function at all on committed files, it won't introduce merges for you, it will only try to move your local changes along with the update.

Related

TortoiseHg removing added files during merge

I have a repository in which there are two branches MAIN and FEATURE1. Soon after I branched, I needed to make a bug fix and then I tagged MAIN with a version number. These are the only changes on MAIN after the branch. I've been working in FEATURE1 and have added several files.
1--2----4--5
\
3--------6--7--8
3 - Branch created
4 - Bug fix
5 - Tag added
6-8 - Feature changes
Note There is a single conflicting change between the bug fix and the feature.
Now, my feature is complete, and I want to merge FEATURE1 (8) into MAIN (5). But when I perform the merge, it doesn't appear that any of my changes are moved into the MAIN branch.
When I performed the merge without committing, I noticed a few things:
All of the files that were added in the source branch (FEATURE1) are marked to be removed.
There are a lot of .orig files (I have no idea what these are). These are marked ? (unknown action) and are not committed.
Existing files are marked 'M' (modified) as expected, but the changes aren't migrated.
It's almost as if it's taking MAIN as the source and FEATURE1 as the destination, but I'm sure I'm merging into MAIN. I update to MAIN (5), right-click FEATURE1 (8), and select Merge to Local.... The resulting branch appears as part of MAIN as expected.
I've never branched using TortoiseHg or Mercurial before. I'm used to TFS, and I feel like I'm getting the opposite behavior.
Basically, I want the changes I made in FEATURE1 to be present in MAIN.
So apparently, TortoiseHg was working correctly. My frustration was the result of misreading the UI.
Whenever you update to a different revision in TortoiseHg, it gives you a dialog with a checkbox which allows you to discard the uncommitted changes in the current branch.
Discard local changes, no backup (-C/--clean)
When merging, the message is similar but carries a very different meaning.
Discard all changes from merge target (other) revision
While the first means that you want to undo uncommitted changes, the second means that you want to merge the branches without bringing over any of the changes.
On a side note, I can't figure out why that feature is there. Why would you merge branches without migrating the changes? It seems easier to just close the branch.

How to revert a file to an earlier version in Mercurial?

I made some changes to a file and committed it. (In fact there were several commits).
Then I wanted to revert to the earlier version and lose all those changes.
I did something like:
hg update -r nnn where nnn was the reversion number of the changeset I wanted to go back to.
That worked. I was happy.
Then, later, I had to push my local repository to the remote. But when I did hg push I got a message about there being two heads on this branch and one of them not being known to the remote repositiory. It suggested I merge before pushing. (I think).
I googled this and found a page that suggested I do "hg merge". I did that. Now the resultant file is back to where I started. I.e. it contains all the changes I wanted to throw away.
Where did i go wrong?
EDIT:
I have found this post Mercurial — revert back to old version and continue from there
where it says:
If later you commit, you will effectively create a new branch. Then
you might continue working only on this branch or eventually merge the
existing one into it.
That sounds like my case. Something went wrong at the merging stage it seems. Was I on the wrong branch when I did "hg merge"?
You're past this point now but if it happens again, and it's just a single file you want to revert then consider:
hg revert --rev REVISION_YOU_LIKED path/to/just/one/file.txt
That doesn't update you whole repository to a different revision, and it doesn't create any commits. It just takes a single file in your working directory and makes it look like it used to. After doing that you can just commit and you're set.
That's not the way to go if you want to undo all the changes you've made to all files, but for reverting a single file use revert and avoid multiple heads and merging entirely.
No, nothing went wrong at the merge stage – Mercurial did exactly what you asked it to...
What merge means is that you take the changes on your current branch, and the changes on the 'other' branch, and you merge them. Since your original changes were in the 'other' branch, Mercurial carefully merged them back into your current branch.
What you needed to do was to discard the 'other' branch. There are various ways of doing that. The Mercurial help pages discuss the various techniques, but there are pointers in other SO questions: see for example Discard a local branch in Mercurial before it is pushed and Remove experimental branch.
(Edit) Afterthought: the reason you got a warning about there being two heads on the branch is because having two heads is often a temporary situation, so pushing them to a remote repository is something you don't want to do accidentally. Resolutions are (i) you did mean to push them, so use --force to create two heads in the remote repository; (ii) ooops!, you meant to merge them before pushing, so do that; or (iii) ooops!, you'd abandoned the 'other' one, so get rid of it. Your case was (iii).

mercurial merge files missing

I was doing pull with mercurial eclipse plugin. Dialog 'merge with two heads' appeared and it took a long time, nothing was happening, so I clicked again on 'merge with two haeds' but then it wouldn't show files with conflicts in 'Mercurial merge' view. It pulled changes, but can not resolve conflicts. Then I tried to do pull again, 'merge with two heads' appears but this time it says I have uncomitted changes that will be discarded so I said 'No' (I am scared I will lose my previously comitted changes). Can someone please give some advice? What shall I do?
You "should" be fine to discard the uncommitted changes; the failed merge would create "uncomitted changesets". I have had to do the same on failed merges before before by using hg update -C where the -C means "Clean it up and throw away all changes that aren't committed".
Regarding your fear of losing your committed changes: once you have committed your changes, it is very hard to get rid of them without hg extensions that let you edit history. So you should be safe. (You do have a backup plan in place, right?) If you hadn't committed important changes before you started the merge you only have yourself to blame! :)
To try to sort things out, you could clone the repo to an adjacent location, such as \repo2\ and verify that it has the changes you expect. You can also attempt the merge in \repo2\ first and only pull the merged changeset into \repo\ once it is successful.

Mercurial via TortoiseHg - Merge a named branch then close it

I have a named branch, NewFeature, that I made off of the default branch. I've made a couple commits to that branch, and now I'd like to merge it to rejoin the default branch.
Now (each letter is a commit):
default: A---B
NewFeature: \--C---D
What I'd like:
default: A---B-----------E
NewFeature: \--C---D--/
I tried right clicking the directory and selecting "Hg Commit...". I then selected "Close Current Named Branch". I got this error: abort: can only close branch heads
I also looked for a "close branch" option in the repository explorer, but I couldn't find anything.
Could someone please help?
Thanks in advance!
Edit: I posted an issue to TortoiseHg
The example you give is more a Merge than really a Close. Also, if it's that simple, you probably don't want/need to create a named branch.
But if you really want to close a branch through TortoiseHg, eg
you created the NewFeature branch
then both the Default branch and NewFeature branches were modified
then if the NewFeature branch takes quite some time you might have also already merged several time Default into NewFeature (to avoid having too many differences when you'll want to finally merge the NewFeature branch into the Default one)
eventually your new feature is entirely implemented or stable enough, you merged the NewFeature branch into the Default one
From now on, no one is supposed to commit anything on the NewFeature branch, so you'd like to close it.
You can do so in TortoiseHg (I have version 2.3.2):
click Hg Commit... when you are on your NewFeature branch (no need to have anything to commit - or you do it with your final merge)
click "Branch: NewFeature" (it's at the top in bold)
select "Close current branch".
To merge, you need a clean working copy - no uncommitted changes. The merge will be placed in the working copy for review and then you commit the working copy to "complete" the merge.
If you have uncommitted changes you are not prepared to commit, you can see about shelving those changes temporarily (if you have that appropriate extension) or checkout a new working copy somewhere else to use for the merge.
Using the Repository Explorer:
Update the working copy to rev B.
Select rev D row in the revision history.
Right-click on rev D and choose Merge with.... The dialog should show rev B should be the local rev and D should be the other rev.
Click Merge in the merge dialog and resolve any conflicts, if any.
Up to now, nothing has been changed in the repository - your merge is in the working copy. So if something is wrong, you can cancel the merge, revert your working directory, and start over at later time or after making some other additional branch or trunk changes.
If everything is good after steps 1-4, click Commit in the merge dialog to commit the merge.
For anyone that's confused by the answers to this question, here are the instructions on how to do this from within the TortoiseHg Workbench:
How to Merge Feature Branch and Close Branch
Open TortoiseHg Workbench.
Select your repository from the Registry Repository.
Switch to the branch that you would like merge your branch into (default in this example):
Right mouse click the branch that you'd like to merge and close (NewFeature in this example) and choose Merge with Local. This will merge the branch changes from the NewFeature branch into default:
You will see a confirmation box that confirms that your changes will be merged from one branch to another, click through the steps Next, Commit Now and Finish:
Now you can see from the Graph that the changes have been merged in, we can now close the NewFeature branch as we no longer need it:
Update your local to the branch you would like to close, in this case it is NewFeature:
Click commit, the big green tick at the top of the workbench.
In the commit window, you should see the branch that you want to close above the comment text box. Click the branch name:
A window will pop up and select close current branch:
Now click commit. Your graph should show that the branch is closed:
In TortoiseHg, your working copy must be updated to the tip of the branch you want to close before using the commit dialog.
Closing a branch will create a new changeset on top of the branch tip.
The error you described (abort: can only close branch heads) typically occurs if you have updated to a changeset not at the tip of a named branch.
You also seem to get this error is the branch is already closed, i.e. trying to close a closed branch. A more helpful error message would be useful.

What is the best way to do a code review across multiple commits, with TortoiseHg?

The problem that I'm running into is that I have some code reviews to do, with ~10 commits per review. It's an active repo with constant commits from developers. I have TortoiseHg filtering my changesets so that I am looking only at the ones that I care about.
What I would like to see is the difference between the changeset before the first change, and the last (without all the non-related changesets showing). I simply want to see the final results of all these changes. I don't care that there was some horrible code in changeset 1, that was fixed in 3. I just want to see the diff of what ultimately got merged through all these changesets.
I feel like I'm missing the obvious, and this isn't a bright question. Nevertheless, I'm asking anyways. Anyone?
I'm not sure about 1.1.8, as I'm using the 1.9/2.0 candidate release, but I believe you could left-click on changeset1, right-click on revision3 and select visual Diff. This should open your diff tool of choice and only show you the diffs between the 2 versions.
When I did this in the newer tortoise, it opened BeyondCompare in directory compare mode, with revision1 on one side, and revision2 on the other.
Don't merge in between commits and diff off the developers clone between start and finish changesets.
Or If merges occured, update and merge everything and then take the entire codebase (or just changed files) and dump it onto a clean tip clone (make sure you are working with the same version to avoid overwriting anything). Recommit all at once.