I find myself recurrently in a situation, where I want to see the diff of all changes, that a branch introduced since branching off. The naive
$ git diff ..branch
doesn't work well, because changes in master
are taken into account as well. What I'm looking for is basically a nicer way to run
$ git diff $(git merge-base master branch)..branch
or expressed in graphics:
---A---B---C---D---E <== master \ F---G---H <== branch
How do I elegantly find the diff between B
and H
?
Edit: As noted in my answer below, master...branch
is a solution to my problem. However, I still don't know, why that's the case, given the quoted man page snippet.
Why does diff master...branch
only show the differences from the merge base, while man rev-parse
says, it should include master
's commits, too?
Why does diff master..branch
show the diff between the current state of master
and branch
, while man rev-parse
says, it should ignore the master
-only commits?
The git diff command returns a list of all the changes in all the files between our last commit and our current repository. If you want to retrieve the changes made to a specific file in a repository, you can specify that file as a third parameter.
git merge-base finds best common ancestor(s) between two commits to use in a three-way merge. One common ancestor is better than another common ancestor if the latter is an ancestor of the former. A common ancestor that does not have any better common ancestor is a best common ancestor, i.e. a merge base.
Diffing is a function that takes two input data sets and outputs the changes between them. git diff is a multi-use Git command that when executed runs a diff function on Git data sources. These data sources can be commits, branches, files and more.
The main difference between the commands is that git diff is specially aimed at comparisons, and it's very powerful at that: It can compare commits, branches, a single file across revisions or branches, etc. On the other hand, git status is specifically for the status of the working tree.
After extensively looking at git help rev-parse
and experimenting around, I found this piece of information:
<rev1>..<rev2> Include commits that are reachable from <rev2> but exclude those that are reachable from <rev1>. When either <rev1> or <rev2> is omitted, it defaults to HEAD. <rev1>...<rev2> Include commits that are reachable from either <rev1> or <rev2> but exclude those that are reachable from both. When either <rev1> or <rev2> is omitted, it defaults to HEAD.
Somehow I was always under the impression, that master..branch
is what I need and forgot about master...branch
(with three dots).
But experimenting with it showed, that the three-dot notation is exactly what I'm looking for:
$ git diff master...branch
shows only the differences of branch
relative to where it took off of master
.
I know this is not the answer you're looking for here, but it might help someone else. Using a graphical tool like gitk, you can:
Now you see all updated files to the right, and all the modified lines (per file) to the left.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With