I'm trying to get in the habit of doing code reviews, but merges have been making the process difficult because I don't know how to ask Mercurial to "show only changes introduced by the merge which were not present in either of its parents."
Or, slightly more formally (thanks to Steve Losh):
Show me every hunk in the merge that wasn't present in either of its parents, and show me every hunk present in either of its parents that isn't also present in 3.
For example, assume I have a repository with two files, a and b. If "a" is changed in revision 1, "b" is changed in revision 2 (which is on a separate branch) and these two changes are merged in revision 3, I'll get a history which looks like this:
@ changeset: 3 |\ summary: Merged. | | | o changeset: 2 | | summary: Changing b | | o | changeset: 1 |/ summary: Changing a | o changeset: 0 summary: Adding a and b
But if I ask to see the changes introduced by revision 3, hg di -c 3
, Mercurial will show me the same thing as if I asked to see the changes introduced in revision 1, hg di -c 1
:
$ hg di -c 3 --- a/a +++ b/a @@ -1,1 +1,1 @@ -a +Change to a $ hg di -c 1 --- a/a +++ b/a @@ -1,1 +1,1 @@ -a +Change to a开发者_开发技巧
But, obviously, this isn't very helpful - instead, I would like to be told that no new changes were introduced by revision 3 (or, if there was a conflict during the merge, I would like to see only the resolution to that conflict). Something like:
$ hg di -c 3 $
So, how can I do this?
ps: I know that I can reduce the number of merges in my repository using rebase
… But that's not my problem - my problem is figuring out what was changed with a merge.
The short answer: you can't do this with any stock Mercurial command.
Running hg diff -c 3
will show you the changes between 3
and its first parent -- i.e. the changeset you were at when you ran hg merge
.
This makes sense when you think of branches as more than just simple changesets. When you run hg up 1 && hg merge 2
you're telling Mercurial: "Merge changeset 2
into changeset 1
".
It's more obvious if you're using named branches. Say changeset 2
in your example was on a named branch called rewrite-ui
. When you run hg update 1 && hg merge rewrite-ui
you're effectively saying: "Merge all the changes in the rewrite-ui
branch into the current branch." When you later run hg diff -c
on this changeset it's showing you everything that was introduced to the default
branch (or whatever branch 1
happens to be on) by the merge, which makes sense.
From your question, though, it looks like you're looking for a way to say:
Show me every hunk in this changeset that wasn't present in either of its parents, and show me every hunk present in either of its parents that isn't also present in
3
.
This isn't a simple thing to calculate (I'm not even sure I got the description right just now). I can definitely see how it would be useful, though, so if you can define it unambiguously you might convince one of us Mercurial contributors that read SO to implement it.
In order to do code reviews you really want to see just the changes in the project that you are reviewing. To that end we use a new branch for each story and use pull requests to spotlight the changes, having merged all changes into the story branch before creating the pull request. We host our code on bitbucket and the review / pull request tools are really very good, offering a side by side diff.
Pull requests with side-by-side diffs
精彩评论