138

When I run "git pull" I often want to know what changed between the last version of a file and the new one. Say I want to know what someone else committed to a particular file.

How is that done?

I'm assuming it's "git diff" with some parameters for commit x versus commit y but I can't seem to get the syntax. I also find "git log" confusing a bit and am not sure where to get the commit ID of my latest version of the file versus the new one.

Liam
  • 27,717
  • 28
  • 128
  • 190
doug
  • 1,789
  • 3
  • 12
  • 5
  • 1
    You might find the gitk graphical tool more to your tastes. – crazyscot Mar 11 '10 at 20:09
  • http://stackoverflow.com/questions/61002/how-can-i-generate-a-git-diff-of-whats-changed-since-the-last-time-i-pulled might be similar to this one – VonC Mar 11 '10 at 20:12

4 Answers4

176

There are all kinds of wonderful ways to specify commits - see the specifying revisions section of man git-rev-parse for more details. In this case, you probably want:

git diff HEAD@{1}

The @{1} means "the previous position of the ref I've specified", so that evaluates to what you had checked out previously - just before the pull. You can tack HEAD on the end there if you also have some changes in your work tree and you don't want to see the diffs for them.

I'm not sure what you're asking for with "the commit ID of my latest version of the file" - the commit "ID" (SHA1 hash) is that 40-character hex right at the top of every entry in the output of git log. It's the hash for the entire commit, not for a given file. You don't really ever need more - if you want to diff just one file across the pull, do

git diff HEAD@{1} filename

This is a general thing - if you want to know about the state of a file in a given commit, you specify the commit and the file, not an ID/hash specific to the file.

Cascabel
  • 479,068
  • 72
  • 370
  • 318
  • VonC's linked previous post says essentially the same thing as this, but the explanation's a bit different, so I'll leave this for now. (It also uses `@{1}` as a shorthand for `HEAD@{1}`) – Cascabel Mar 11 '10 at 20:15
  • true, but I also like the explanation. +1 – VonC Mar 11 '10 at 20:22
  • This is exactly what I was searching for. Thank you for explanation. – lucapette Mar 05 '11 at 15:13
  • +1 for what I was googling. Would be awesome if this was selected as the answer and bumped to the top... :) – longda Mar 29 '13 at 22:36
  • @longda If you're sorting by votes (which I thought was default) it should already be at the top. – Cascabel Mar 29 '13 at 23:10
  • @Jefromi - Trying to get you some more points my man! Somehow my tabs were set to Active rather than Votes. That selection is sticky so once Votes is selected it will be displayed like that for all questions on the site. In some cases though, the OP's selected answer can have less points but still be at the top (doesn't apply in this case cause OP did not select an answer). This is probably TLDR; – longda Mar 29 '13 at 23:37
67

I like to use:

git diff HEAD^

Or if I only want to diff a specific file:

git diff HEAD^ -- /foo/bar/baz.txt
cadizm
  • 896
  • 7
  • 4
  • 5
    -1: `HEAD^` is the parent commit, not the commit before `pull` – CharlesB Apr 23 '12 at 06:43
  • 1
    If `HEAD` is a merge commit, `HEAD^` is the first parent commit, so yes, it can be the commit before the `pull`. To get the other parent (for a two-way merge), use `HEAD^2`. But then, above answer is not really answering the question in the first place, so leaving the -1 ;-) – Michael Wild Apr 23 '12 at 07:22
  • Thanks for the clarification. Didn't read the question very carefully, as I was googling for something else and this link came up high on the results page. I thought I'd chime in since I'm a new user and don't have any karma (if that is what it is called on SO). My fault =) – cadizm Apr 23 '12 at 18:12
  • 4
    @MichaelWild it might not be what the asker was asking, but it was what I was looking for when I found this. It was useful for me. Upvoting. – John Dvorak Mar 28 '14 at 07:49
  • This one is what TortoiseGit "Diff with previous version" does. And is what I'd been looking for. – Fabien Haddadi Nov 08 '18 at 03:59
  • What about `git diff HEAD~ -- /foo/bar/baz.txt` – run_the_race Apr 01 '20 at 13:01
15

If you do a straight git pull then you will either be 'fast-forwarded' or merge an unknown number of commits from the remote repository. This happens as one action though, so the last commit that you were at immediately before the pull will be the last entry in the reflog and can be accessed as HEAD@{1}. This means that you can do:

git diff HEAD@{1}

However, I would strongly recommend that if this is something you find yourself doing a lot then you should consider just doing a git fetch and examining the fetched branch before manually merging or rebasing onto it. E.g. if you're on master and were going to pull in origin/master:

git fetch

git log HEAD..origin/master

 # looks good, lets merge

git merge origin/master
CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • Nice use of `git log` instead of `git diff` here (even if the syntax is a bit incoherent between the '..' for `git log` and the '...' for `git diff` ;) +1 See http://stackoverflow.com/questions/53569/how-to-get-the-changes-on-a-branch-in-git/53573#53573 and http://stackoverflow.com/questions/850607/difference-in-git-log-origin-master-vs-git-log-origin-master/850695#850695 – VonC Mar 11 '10 at 20:18
  • Fortunately if you use the '..' syntax in a git diff command git "does the right thing". – CB Bailey Mar 11 '10 at 20:20
1

If you want to see the difference only on a file. You can try the commands to compare it with the last version.

git diff HEAD@{1} filename

git diff HEAD@{1} -- path/filename

Note: -- is needed if your file is not in the current directory. Otherwise, you may get following error.

fatal: ambiguous argument 'path/filename': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git [...] -- [...]'

Henry S.
  • 432
  • 1
  • 3
  • 8
  • 1
    When to use `--` – rob Aug 23 '23 at 10:41
  • When you try to the command from your terminal, you can run the command `ls` to see whether the file you want to see the difference on is in your current directory. If the file is not listed, you need to specify the path with `--`. Note: you can run the command `pwd` to know your current directory. – Henry S. Aug 25 '23 at 19:59