Show TortoiseGit 3 way merge for a past merge commit - merge

During merging, TortoiseGit offers a handy GUI to compare changes of both versions with the base file.
After resolving all conflicts and committing them, you can see the changes of a merge commit relative to both parents. Is there also a way to re-show the 3 way merge window for a merge commit from somebody else? Just seeing the individual changes makes it hard to judge, if the merge was performed correctly.
What I see now is two lists where I can check the changes with each parent, what I want is a list that only contains files changed in both branches and where I can see, how these changes where merged together.
I am aware, that I can manually check out the three files, open the three hand merge tool and load them (and delete the files afterwards). However this is rather tedious and not what you want to do, if you just want to quickly check a merge commit.

Related

Ignore specific commit in svn when showing annotation

I use the "show annotation" functionality quite often. Now, I accidentally crushed the svn and solved it by making a re-commit of everything. Now, every time I use the "show annotation" function, it shows this last commit on every line.
Can I revert this somehow?
I'm assuming you didn't kill the entire SVN and "solved" that by starting over from rev 1. I'm assuming some intermediate revision got corrupted and you had to touch and commit every file in a new revision, but older revisions are visible and accessible in the SVN history. The Annotations feature, and Plan B both rely on that.
What the textbook offers
Excluding a single mid-range revision is not possible, given a certain history. You can only exclude head or tail ranges by specifying revisions other than 1 for the "From" and HEAD for the "To".
Say the "repair" revision you want to exclude is r1000. To exclude it, you can choose to consider either (from-to) r1-r999 or r1001-HEAD, leaving out r1000. So you are confined to either viewing the changes before or after the repair.
You can read up on the possibilities and options of what's internally called svn blame in the SVN documentation.
Plan B
Now, that's not really satisfying, I imagine. Here's something else you can try, but please create a backup of your repo first.
With the help of the SVN history viewer, or log viewer, find the last revision before the corrupted revision, say r997.
Make a branch based off that last good revision.
Then delete or move the current trunk, using the corresponding SVN commands.
In the last step, move or branch(=copy) the branch back to the trunk location.
You have effectively cut out the corrupt revisions. The branch-now-trunk has a "hole" in its revision numbers, because branching off r997 created a new revision younger than the corrupted and repairing revisions. Afterwards, showing annotations on that new trunk will work like before, but wont include the corruption and your "repair".
Here, I made an illustration for you:
This operation can screw up some ancestry operations like merging, but I've done it successfully before, even with large merging operations later on, so you might as well try it, too. Good luck!

Merge in local, base or other?

I have a project in which I've set up a bitbucket repo using mercurial.
We're actually 3 to work on it, so we're using branches.
When we did merges, we did them quite randomly so many times it failed.
Actually, I'm using Meld, and I don't really know in "which" part of the repo I have to choose which part of the source code I want to merge.
So, when I do merge, where should I do it ?
I'm not really sure if I have to do it on local, base or other, even though I know local corresponds to my last modifications, other corresponds to the last modifications of the branch I want to merge, and well, actually I'm not really sure about what is other ...
On careful review, I have found it out. You want to merge into local
Please correct me if I'm wrong but I am pretty sure after doing some tests
Local
The correct place to merge change to. The local files that will result from the merge. This will likely contain a mix of some auto-merged lines already.
Base
Where you are merging into.
Other
The merges you're pulling
This may not be the "right" answer, but when in doubt, I make them ALL match by making them look ALL merged 'correctly' (sometimes I have to discuss with my coworkers what the 'correct' look is based on their changes).
By doing this, I ensure the merge will be successful because meld cannot and will not actually change upstream data in mercurial. So there's no downside. For the life of me I also cannot tell which pane to merge into (mostly because the term 'base vs local' is ambiguous). So this is kind of an odd way to do it, but it works

How to push only a subset of committed files?

We recently switched from svn to mercurial. We're using Aptana as our IDE with the MercurialEclipse plugin, along with BitBucket for our repositories and SourceTree as our (additional) source control GUI.
I created 2 new files in Aptana, and committed each of them. Now in the Synchronize view, where the 2 files are listed as "outgoing", I'd like to push only one of them. I avoided using the "push all" icon at the top which would push all outgoing changes - instead I right-clicked a specific file in the outgoing list and chose "push" from the context menu. However, this caused both outgoing changes to be pushed. I can't seem to find any option to push only a specific file or subset of files of the committed changes. Is there any way to accomplish this in Aptana?
Note: My answer doesn't relate to Aptana, but instead covers what I think your issue is.
I think the main problem is a misunderstanding of how Mercurial stores its changes, which coming from a Subversion background is perfectly reasonable.
In Subversion, change history can be considered to be stored per file. That is, if you change two files and commit them, you can easily, and often do, have a situation where files in your working copy are at different versions.
In Mercurial, change history is stored across the whole repository. Committing will create a new "Changeset", which stores the state of the entire repository at that time. When you decide to push a change out to another repository, all modifications (or adds, or deletes, or...) will be pushed out with that change.
A caveat is that when you decide to commit a new changeset to your repository, you can selectively include or exclude files. Files not included will remain in your working copy as pending modifications, which can be committed in a new changeset.
I hope that makes sense to you - if you already understand it, it's a logical concept, but I find it tricky to explain.
So, on to your problem.
Lets say you have two files in your repository, file1 and file2 (it's that or foo and bar). You've changed them both, but they relate to different issues - they can be committed as different changesets:
$ hg log
changeset 0:....
summary: First commit
$ hg st
M file1
M file2
$ hg commit -I file1 -m "Changed file1"
$ hg log
changeset 1:....
summary: Changed file1
changeset 0:....
summary: First commit
$ hg st
M file2
Here you can see that we've committed only one file into the repository, and it's made a new changeset with the complete state of the repository at that time, minus the changes to file2. We can now do the same, committing file2, which will create another changeset. The problem with this approach is that changesets are ordered according to their parent, and so you couldn't easily push just the change to file2, without also pushing its parent - but it may be closer to what you're after.
TL;DR : SVN stores the state of individual files, Mercurial stores the state of the repository as a whole.
I very much recommend reading Mercurial: The Definitive Guide. It's a little out-of-date in places, but I think it will do a much better job of getting the concept across.

TFS - Merging code out of the normal routine

The typical process we use is:
Write code
Checkin changes with a description of what they are
merge forward (dev to QA)
We have been working on a series of changes. Management decided they want us to move up a small set of these changes. These changes are all over the place. I can't simply merge the changes by checkin/changeset as I normally do.
The only solution I can think of is to manually copy paste the changes I do want into QA. This breaks my documentation and normal flow. But, in the future the merge tool should pickup what has already been moved forward; that is when we revert back to the normal flow.
What would you do?
If I understand you, try to use baseless merge:
Use baseless merge to merge items that are not directly branched from
each other. To perform a baseless merge, you must use the tf merge
command. When you perform a baseless merge, Team Foundation does not
have any information about the relationship of the files in the
braches. In a baseless merge, you must perform manual conflict
resolutions. After you have performed the baseless merge and resolved
any conflicts, Team Foundation records the merge history and
establishes a relationship between the folders and files.
Improvements to baseless merge in TFS 2010 SP1
You might want to look at WIMBI. What WIMBI does, is it merges by work items associated with the changeset(s).
What might work for you is to:
Associate the relevant changesets with a work item representing the unit of work (i.e. task) that needs to be ported (ideally, you would have done so when checking it in)
Create a release branch from your code from before the changes you need to merge (and before the changes you do not want to merge
Use WIMBI or cherry pick the changesets to perform the forward integrate your changes to the new release branch.
Hope this helps,
Assaf.

What am I doing wrong with SVN merging?

When SVN with merge tracking works, it's really nice, I love it. But it keeps getting twisted up. We are using TortoiseSVN. We continuously get the following message:
Error: Reintegrate can only be used if revisions 1234 through 2345 were previously merged from /Trunk to the reintegrate source, but this is not the case
For reference, this is the method we are using:
Create a Branch
Develop in the branch
Occasionally Merge a range of revisions from the Trunk to the Branch
When branch is stable, Reintegrate a branch from the branch to the trunk
Delete the branch
I Merge a range of revisions from the trunk to the branch (leaving the range blank, so it should be all revisions) just prior to the reintegrate operation, so the branch should be properly synced with the trunk.
Right now, the Trunk has multiple SVN merge tracking properties associated with it. Should it? Or should a Reintegrate not add any merge tracking info?
Is there something wrong with our process? This is making SVN unusable - 1 out of every 3 reintegrates forces me to dive in and hack at the merge tracking info.
This problem sometimes happens when a parial merge has been done from trunk to branch in the past. A partial merge is when you perform a merge on the whole tree but only commit part of it. This will give you files in your tree that have mergeinfo data that is out of sync with the rest of the tree.
The --reintegrate error message above should list the files that svn is having a problem with (at least it does in svn 1.6).
You can either:
Merge the problem files manually from trunk to branch, using the range from the error message. Note: you must subtract 1 from the start of the range, so the command you'd run would be:
cd <directory of problem file in branch working copy>
svn merge -r1233:2345 <url of file in trunk>
svn commit
or
If you're certain that the contents of the files in your branch are correct and you just want to mark the files as merged, you could use the --record-only flag to svn merge:
cd <directory of problem file in branch working copy>
svn merge --record-only -r1233:2345 <url of file in trunk>
svn commit
(I think you can use --record-only on the entire tree, but I haven't tried it and you'd have to be absolutely sure that there are no real merges that need to come from trunk)
Bunny hopping might be the solution.
Basically, instead of continuously merging trunk changes into a single branch (branches/foo, let's call it), when you want to pull those changes from trunk:
Copy trunk to a new branch (branches/foo2).
Merge in the changes from the old branch (merge branches/foo into branches/foo2).
Delete the old branch (delete branches/foo).
Your problem is that you're trying to use Reintegrate merge on a branch that has been 'corrupted' by having a 'half merge' already done on it. My advice is to ignore reintegrate and stick to plain on revision merging if this is your workflow.
However, the big reason you get errors is because SVN is performing some checks for you. In this case, if the merge has extra mergeinfo from individual files in there, then svn will throw a wobbly and prevent you from merging - mainly because this case can product errors that you might not notice. This is called a subtree merge in svn reintegrate terminology (read the Reintegrate to the Rescue section, particularly the controversial reintegrate check at the end).
You can stop recording mergeinfo when you perform your intermediary merges, or just leave the branch alone until its ready - then the merge will pick up changes made to trunk. I think you can also byass this check by only ever merging the entire trunk to branch, not individual files thus keeping mergeinfo safe for the final reintegrate at the end.
EDIT:
#randomusername: I think (never looked too closely) at moving is that it falls into the 'partial merge' trap. One cool feature of SVN is that you can do a sparse checkout - only get a partial copy of a tree. When you merge a partial tree in, SVN cannot say that the entire thing was merged as it obviously wasn't, so it records the mergeinfo slightly differently. This doesn't help with reintegrate as the reintegrate has to merge everything back to the trunk, and now it finds that some bits were modified without being merged, so it complains. A move appears kind of the same thing - a piece of the branched tree now appears differently in the mergeinfo than it expects. I would not bother with reintegrate, and stick with the normal revision range merge. Its a nice idea, but it trying to be too many things to too many users in too many different circumstances.
The full story for mergeinfo is here.
I suspect you're not following the merge instructions correctly:
"Now, use svn merge with the --reintegrate option to replicate your branch changes back into the trunk. You'll need a working copy of /trunk. You can get one by doing an svn checkout, dredging up an old trunk working copy from somewhere on your disk, or using svn switch (see the section called “Traversing Branches”). Your trunk working copy cannot have any local edits or contain a mixture of revisions (see the section called “Mixed-revision working copies”). While these are typically best practices for merging anyway, they are required when using the --reintegrate option.
Once you have a clean working copy of the trunk, you're ready to merge your branch back into it:"
I have few problems with merging.