How can I diff a file, say pom.xml
, from the master branch to an arbitrary older version in Git?
14 Answers
You can do:
git diff master~20:pom.xml pom.xml
... to compare your current pom.xml
to the one from master
20 revisions ago through the first parent. You can replace master~20
, of course, with the object name (SHA1sum) of a commit or any of the many other ways of specifying a revision.
Note that this is actually comparing the old pom.xml
to the version in your working tree, not the version committed in master
. If you want that, then you can do the following instead:
git diff master~20:pom.xml master:pom.xml

- 446,582
- 72
- 411
- 327
-
22Note that this doesn't just work for files, it also works for (sub)directories as well, for example `git diff
:foo/ HEAD:foo/`. – Jul 05 '14 at 18:59 -
2Also note that on windows you need to use forward slashes for directories if you are using a revision specifier or git will give you an error about the file/directory not existing in that revision. – Dylan Nissley Nov 21 '14 at 13:38
-
1@DylanNissley or it will give you no error and no diff. That's what I see. In any case, thank you for the hint about using forward slashes instead of backslashes. – Gary Sheppard Aug 17 '17 at 20:05
-
1With windows files I've found it easier to change directory and then call git diff master~20:./pom.xml ./pom.xml – lloyd Aug 24 '18 at 06:16
-
Some version of git require "--" between the
& – Josh Apr 27 '20 at 03:36
git diff <revision> <path>
For example:
git diff b0d14a4 foobar.txt

- 27,594
- 16
- 81
- 105
-
does not work for version 1.7.11 if file is not in current directory. Example: 'git diff f76d078 test/Config' yields "error: Could not access 'test/f76d078'" – simpleuser Dec 04 '13 at 21:21
-
2@user1663987 just pass a full path relative to the project root: `git diff
root/path/file`. – Jun 27 '14 at 17:23 -
1test/Config *is* relative to the root (as in test is a sub-directory of the root). but then your example root/path/file would seem to INCLUDE the root? – simpleuser Jun 29 '14 at 05:55
If you want to see the difference between the last commit of a single file you can do:
git log -p -1 filename
This will give you the diff of the file in git, is not comparing your local file.

- 7,457
- 3
- 22
- 17
-
2
-
@AndreiCristianProdan Then you have no changes there. You can increment the `-1` step by step until you get the changes. – kaiser Oct 30 '14 at 11:30
-
This is very nice. I created a bash function that might be useful: `gitlog () { git log -${3:-p} -${2:-1} $1; }` Used like: `gitlog Rakefile` or `gitlog Rakefile 5` and `gitlog Rakefile 10 s`. The first shows one diff; the second shows five diffs; the third shows ten `--no-patch`. – auxbuss Jun 07 '18 at 13:12
To see what was changed in a file in the last commit:
git diff HEAD~1 -- path/to/file
You can change the number (~1) to the n-th commit which you want to diff with.

- 21,738
- 2
- 113
- 124

- 2,618
- 1
- 25
- 21
-
This answer is really just a specific case of [this more general answer](http://stackoverflow.com/a/5586434/456814), where `HEAD~1` is substituted for `
`, which makes this answer a duplicate. – Jul 17 '14 at 21:52 -
2this isn't working! fatal: ambiguous argument 'HEAD~1': unknown revision or path not in the working tree. Use '--' to separate paths from revisions – Andrei Cristian Prodan Oct 17 '14 at 12:04
-
-
Generic Syntax :
$git diff oldCommit..newCommit -- **FileName.xml > ~/diff.txt
for all files named "FileName.xml" anywhere in your repo.
Notice the space between "--" and "**"
Answer for your question:
$git checkout master
$git diff oldCommit..HEAD -- **pom.xml
or
$git diff oldCommit..HEAD -- relative/path/to/pom.xml
as always with git, you can use a tag/sha1/"HEAD^" to id a commit.
Tested with git 1.9.1 on Ubuntu.

- 1,078
- 3
- 19
- 32
git diff -w HEAD origin/master path/to/file
-w ignores whitespaces

- 1,604
- 20
- 20
-
You could at least give some explanation as to what the -w flag means. Writing a solution that works is great, but I personally wouldn't use some random command without knowing what each flag in it means. – Tal Kohavy Apr 20 '23 at 12:58
-
1@TalKohavy You are right, I wrote that in a hurry, I have updated the answer. – CatalinBerta Apr 21 '23 at 15:07
If neither commit is your HEAD then bash's brace expansion proves really useful, especially if your filenames are long, the example above:
git diff master~20:pom.xml master:pom.xml
Would become
git diff {master~20,master}:pom.xml
More on Brace expansion with bash.

- 6,893
- 2
- 41
- 40
For comparing to 5 commit to the current one, both on master
, just simply do:
git diff master~5:pom.xml master:pom.xml
Also you can refer to commit hash number, for example if the hash number is x110bd64
, you can do something like this to see the difference:
git diff x110bd64 pom.xml

- 100,211
- 27
- 269
- 172
git diff master~20 -- pom.xml
Works if you are not in master branch too.

- 2,331
- 23
- 23
If you are fine using a graphical tool (or even prefer it) you can:
gitk pom.xml
In gitk you can then click any commit (to "select" it) and right click any other commit to select "Diff this -> selected" or "Diff selected -> this" in the popup menu, depending on what order you prefer.

- 17,357
- 9
- 82
- 98
For people interested in doing the same from GitHub, see comparing commits across time.

- 6,976
- 4
- 60
- 76
lets say you want to diff the file interrupt.c
located in firmware/src/
difftool between working area (what yet to be committed or staged) and latest commit:
git difftool head firmware/src/interrupt.c
or
git difftool head *interrupt.c
Note: to diff x versions before the last committed version replace "head" with head~x. For example replace "head" with "head~2" to diff between working area and 2 versions prior to the latest commit
difftool between two specific committed versions:
first get the ids for the versions you want to compare by using next line
git log --oneline
you will get a list of all your committed version. choose two and copy their id's.
enter the ids inside {}
:
git difftool {2fae9e6,a21dd00} firmware/src/interrupt.c
or
git difftool {2fae9e6,a21dd00} *interrupt.c
Note: if there is no difference between the files, nothing will open. You will just get an empty line in the git bash

- 1,333
- 1
- 13
- 27
If you need to diff on a single file in a stash for example you can do
git diff stash@{0} -- path/to/file

- 10,623
- 4
- 31
- 48
If you are looking for the diff on a specific commit and you want to use the github UI instead of the command line (say you want to link it to other folks), you can do:
https://github.com/<org>/<repo>/commit/<commit-sha>/<path-to-file>
For example:
Note the Previous and Next links at the top right that allow you to navigate through all the files in the commit.
This only works for a specific commit though, not for comparing between any two arbitrary versions.

- 210
- 2
- 11