211

I want a diff of all changes in a branch that is not merged to master yet.

I tried:

git diff master
git diff branch..master
git diff branch...master

However, in each of these cases the diff contains content in master that has not been merged into my branch yet.

Is there a way to do a diff between my branch and master that excludes changes in master that have not been merged into my branch yet?

Palec
  • 10,298
  • 7
  • 52
  • 116
pillarOfLight
  • 7,182
  • 15
  • 51
  • 82
  • 10
    If you flip around the second version, you get what you want: `git diff master..branch`. You can shorten it to `git diff master..` if you're on branch. The `r1..r2` syntax is short for `^r1 r2` which means "show me everything that descends from `r2` and is not reachable from `r1`". `git help gitrevisions` has information on the various syntaxes you can use. – John Szakmeister Dec 28 '13 at 10:05
  • 2
    I expanded my answer after I read more on the `...` syntax of `git diff`. Your comment is wrong, @jszakmeister, because revision ranges as described in `gitrevisions` have nothing to do with `git diff`. Diff compares two points in history, cannot work with a range. – Palec Sep 02 '14 at 16:17
  • You are correct. I always forget that `git diff` works differently than the other commands... a fact that I find frustrating. :-( – John Szakmeister Sep 02 '14 at 16:47
  • ensure that you update the local copy of master before comparing – joe Jun 03 '20 at 14:18

4 Answers4

272
git diff `git merge-base master branch`..branch

Merge base is the point where branch diverged from master.

Git diff supports a special syntax for this:

git diff master...branch

You must not swap the sides because then you would get the other branch. You want to know what changed in branch since it diverged from master, not the other way round.

Loosely related:


Note that .. and ... syntax does not have the same semantics as in other Git tools. It differs from the meaning specified in man gitrevisions.

Quoting man git-diff:

  • git diff [--options] <commit> <commit> [--] [<path>…]

    This is to view the changes between two arbitrary <commit>.

  • git diff [--options] <commit>..<commit> [--] [<path>…]

    This is synonymous to the previous form. If <commit> on one side is omitted, it will have the same effect as using HEAD instead.

  • git diff [--options] <commit>...<commit> [--] [<path>…]

    This form is to view the changes on the branch containing and up to the second <commit>, starting at a common ancestor of both <commit>. "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B". You can omit any one of <commit>, which has the same effect as using HEAD instead.

Just in case you are doing something exotic, it should be noted that all of the <commit> in the above description, except in the last two forms that use ".." notations, can be any <tree>.

For a more complete list of ways to spell <commit>, see "SPECIFYING REVISIONS" section in gitrevisions[7]. However, "diff" is about comparing two endpoints, not ranges, and the range notations ("<commit>..<commit>" and "<commit>...<commit>") do not mean a range as defined in the "SPECIFYING RANGES" section in gitrevisions[7].

Palec
  • 10,298
  • 7
  • 52
  • 116
  • For me `$ git diff master...branch` produced `fatal: ambiguous argument 'master...branch': unknown revision or path not in the working tree.`- is this a version dependent command? – Joel Peltonen Sep 09 '16 at 07:32
  • Actually, I just realized that "branch" must be the name of your branch, I thought it was a reference to the current branch – Joel Peltonen Sep 09 '16 at 07:33
  • 4
    You are right, my answer relies on the branch being called `branch`. I chose to stick with the name the OP had chosen in the question. If you want to use current branch, replace `branch` with `HEAD`. – Palec Sep 09 '16 at 07:38
  • 14
    Note that you can use `git diff master...` to avoid specifying the branch (the current one will be taken). – VasiliNovikov Dec 06 '16 at 15:20
  • Yes, `HEAD` (the current branch) is implicit, @VasyaNovikov. The same holds in many other places. – Palec Dec 06 '16 at 16:04
  • `git diff devel...bugfix/API-353-api-allows-database-access-when` `fatal: ambiguous argument 'devel...bugfix/API-353-api-allows-database-access-when': unknown revision or path not in the working tree.` `Use '--' to separate paths from revisions, like this:` `'git [...] -- [...]'` – ChrisGuest Aug 02 '17 at 01:16
  • This answer is not working for me with `git version 2.11.0 (Apple Git-81)` – ChrisGuest Aug 02 '17 at 01:17
  • OK. I've figured this out. I obviously need to checkout the branch as this is a local comparison. `git checkout devel` – ChrisGuest Aug 02 '17 at 01:36
  • 1
    Does the original command work after you checked out `devel`, @ChrisGuest? Probably, Git created the branch for you during checkout, as a local copy of a remote branch (typically `origin/devel`). If that was the case, `git diff origin/devel...bugfix/API-353-api-allows-database-access-when` would have worked even before the checkout. – Palec Aug 02 '17 at 09:30
  • Yep the original command worked after I checked out `devel`. Thanks for pointing this out - I will do probably create a bash function that does `git diff origin/devel...$1` as it is a very useful command when I am coding. – ChrisGuest Aug 03 '17 at 03:15
  • `git diff origin/develop...HEAD`, works perfectly! Thanks. – s.meijer Jul 21 '19 at 17:39
57

Here's what worked for me:

git diff origin/master...

This shows only the changes between my currently selected local branch and the remote master branch, and ignores all changes in my local branch that came from merge commits.

Jeshurun
  • 21,639
  • 5
  • 75
  • 88
  • For reference, if you need the commit refs of commits that contain these changes, use `git cherry origin/master`. – jaytibann May 15 '19 at 08:22
  • If this shows a bunch of garbage you didn't expect, `master` may have rebased a set of commits out from under you. – Michael Nov 19 '19 at 16:19
26

As also noted by John Szakmeister and VasiliNovikov, the shortest command to get the full diff from master's perspective on your branch is:

git diff master...

This uses your local copy of master.

To compare a specific file use:

git diff master... filepath

Output example:

Example usage

Andrew Schreiber
  • 12,208
  • 6
  • 40
  • 52
1

According to Documentation

git diff Shows changes between the working tree and the index or a tree, changes between the index and a tree, changes between two trees, changes resulting from a merge, changes between two blob objects, or changes between two files on disk.

In git diff - There's a significant difference between two dots .. and 3 dots ... in the way we compare branches or pull requests in our repository. I'll give you an easy example which demonstrates it easily.

Example: Let's assume we're checking out new branch from master and pushing some code in.

  G---H---I feature (Branch)
 /
A---B---C---D master (Branch)
  • Two dots - If we want to show the diffs between all changes happened in the current time on both sides, We would use the git diff origin/master..feature or just git diff origin/master
    ,output: ( H, I against A, B, C, D )

  • Three dots - If we want to show the diffs between the last common ancestor (A), aka the check point we started our new branch ,we use git diff origin/master...feature,output: (H, I against A ).

  • I'd rather use the 3 dots in most circumstances.

avivamg
  • 5,638
  • 1
  • 37
  • 32