224

I have a repo with file foo in the master branch. I switched to bar branch and made some changes to foo. How can I now run a git diff between this copy (which isn't committed yet) and the copy of the master branch?

mfaani
  • 33,269
  • 19
  • 164
  • 293
Dogbert
  • 212,659
  • 41
  • 396
  • 397

8 Answers8

214

The following works for me:

git diff master:foo foo

In the past, it may have been:

git diff foo master:foo

Cymen
  • 14,079
  • 4
  • 52
  • 72
Mark Longair
  • 446,582
  • 72
  • 411
  • 327
  • 11
    Each time I see an answer of yours regarding `git diff`, I always think of http://stackoverflow.com/questions/5256249/git-diff-doesnt-show-enough/5257065#5257065 – VonC Feb 02 '12 at 14:12
  • @VonC: thanks, it's nice to know it was worth drawing those :) Incidentally, do you happen to understand the oddity I updated my answer with? – Mark Longair Feb 02 '12 at 15:16
  • 2
    Did you try with a `--` in order to separate parameters from path arguments? `git diff -- master:foo foo` – VonC Feb 02 '12 at 16:13
  • @VonC: if I do that (`git diff -- master:foo foo`), then I just get the same as `git diff foo`, or `git diff -- nonexistent foo`, for that matter. Curiouser and curiouser... – Mark Longair Feb 02 '12 at 16:53
  • I just ran across the same problem, but in my case `git diff foo master:foo` gives the fatal error and `git diff master:foo foo` is the working version! Typing `--` makes them both work. Any explanations yet? – Łukasz Kożuchowski Nov 29 '13 at 16:09
  • 1
    On 1.8, `git diff -- master:foo foo` doesn't work - it seems to treat the arg `master:foo` as a non-existent filename (and ignores it) instead of a file-in-a-branch. Try switching the last 2 args - if it worked, the diff comparison should be reversed, but the output doesn't change. – Kelvin Sep 11 '14 at 20:24
  • 9
    For me it's the opposite -- I can do `git diff master:foo foo` but not vice versa. I don't understand it either. With git 1.7.9.5 / Ubuntu 12.04 I can at least do `git diff -R master:foo foo` to get the diff I actually want. When I try that with msysgit 1.9.4 / Windows 7 x64 I get `fatal: unable to read 0000000000000000000000000000000000000000`. Without `-R` I get the same error message as you with git 1.7.9.5, but with 1.9.4 I get `fatal: master:foo: no such path in the working tree`. – JMM Nov 21 '14 at 22:28
  • 2nd version (`git diff master:foo foo`) worked for me (git version 2.6.2, OS X 10.11.1). – nickb Nov 20 '15 at 07:38
  • You need to explicitly specify branch or commit for both files: `git diff branch1:foo branch2:foo` or `git diff HEAD:foo master:foo` – SergA Mar 18 '19 at 12:48
  • this answer fails to work today ... instead see answer below from @JordanBrough – Scott Stensland Mar 27 '19 at 01:21
  • I think I found the magic: `git diff master:foo -- foo` works for me. – AndyH Jul 29 '19 at 16:51
  • In bash, you can also do `git diff {master:,}foo` if you do not want to write the path twice. – Christoph Thiede Aug 24 '21 at 15:35
  • `master:... no such path in the working tree.` – Cerin Oct 24 '22 at 03:50
129

You're trying to compare your working tree with a particular branch name, so you want this:

git diff master -- foo

Which is from this form of git-diff (see the git-diff manpage)

   git diff [--options] <commit> [--] [<path>...]
       This form is to view the changes you have in your working tree
       relative to the named <commit>. You can use HEAD to compare it with
       the latest commit, or a branch name to compare with the tip of a
       different branch.

FYI, there is also a --cached (aka --staged) option for viewing the diff of what you've staged, rather than everything in your working tree:

   git diff [--options] --cached [<commit>] [--] [<path>...]
       This form is to view the changes you staged for the next commit
       relative to the named <commit>.
       ...
       --staged is a synonym of --cached.
Jordan Brough
  • 6,808
  • 3
  • 31
  • 31
  • 2
    Thanks. No idea why, but only this answer worked for me with git 1.8.1 in Linux. – srking Apr 30 '14 at 21:38
  • Excellent, thank you. I got hung up on wanting to include the name of my current branch in the diff command, but I see that's not needed. – yoyo Feb 24 '15 at 20:55
  • This worked for me a few months ago, but doesn't seem to be now. Currently I'm at git version 2.7.4 (Apple Git-66); I don't know what I had before. – hBrent Jun 13 '16 at 16:40
  • @hBrent this still works for me on OSX 10.11 with git 2.7.3. Here's a quick sample repo with instructions if that's helpful: https://github.com/jordan-brough/git-diff-test/ – Jordan Brough Jun 14 '16 at 16:04
  • Thanks @JordanBrough. – hBrent Jun 14 '16 at 17:27
  • Works well for files that are in subdirectories of project. Other suggested methods don't find files unless you write out whole path. – pauljohn32 Aug 13 '18 at 14:47
18
git difftool tag/branch filename
Adir
  • 181
  • 1
  • 4
  • This is the only answer that worked for me for comparison between a local working copy of a file, and that file version in a remote repo (not "origin"). Thanks, Adir and Baz – Mouse May 06 '18 at 01:44
  • `git difftool` has no `-v` option according to docs https://git-scm.com/docs/git-difftool. Did you mean `-y`? – ks1322 Sep 04 '19 at 10:21
15

Also: git diff master..feature foo

Since git diff foo master:foo doesn't work on directories for me.

ArtBIT
  • 3,931
  • 28
  • 39
10
git diff mybranch master -- file

should also work

Naoise Golden
  • 8,793
  • 4
  • 49
  • 65
  • 6
    This only works for files committed to mybranch, not current working copy of the file. – yoyo Feb 24 '15 at 20:56
  • what does "--" mean above – Pushparaj Jan 08 '20 at 15:51
  • This allows compare in both directions: `git diff deployment master -- file` and `git diff master deployment -- file` are work as expected **with any 2 branches**. – viktorkho Jun 30 '20 at 10:18
  • @Pushparaj "--" is an optional separator between the rest of the command and the path to the file. This can be useful to avoid ambiguity, for instance if you had a file and a branch with the same name. – Tim Goodman Sep 01 '23 at 23:40
10

What also works:

git diff master ./relative-path-to-foo
Vojtech Kaiser
  • 131
  • 1
  • 4
5

To see local changes compare to your current branch

git diff .

To see local changed compare to any other existing branch

git diff <branch-name> .

To see changes of a particular file

git diff <branch-name> -- <file-path>

Make sure you run git fetch at the beginning.

kta
  • 19,412
  • 7
  • 65
  • 47
0

lets say you have a branch named master and a branch named feature, and you want to check a specific file called my_file, then:

  1. git diff master..feature /Path/to/my_file shows the diff between the commited versions of my_file on branch master and feature.
  2. git diff master -- /Path/to/my_file shows the difference between the working directory (the un-staged files) and the branch master of my_file.
Meysam Sadeghi
  • 1,483
  • 2
  • 17
  • 23