87

A riff on git: show all changed files between two commits: I want a listing of all files that have been changed between two commits, even if they are now the same (ie, changed and then changed back).

Community
  • 1
  • 1
Andrew
  • 5,611
  • 3
  • 27
  • 29

7 Answers7

89

This is the best I could come up with:

git log --name-only --pretty=oneline --full-index HEAD^^..HEAD | grep -vE '^[0-9a-f]{40} ' | sort | uniq

Replace HEAD^^ and HEAD with the commits you want to compare.

My attempt uses git log with --name-only to list all files of each commit between the specified ones. --pretty=oneline makes the part above the file listing consist only of the commit SHA and message title. --full-index makes the SHA be the full 40 characters. grep filters out anything looking like a SHA followed by a space. Unless you have files beginning with a SHA followed by a space, the result should be accurate.

igorw
  • 27,759
  • 5
  • 78
  • 90
  • When I run that command against HEAD^ and HEAD, I get a list of what looks like every single file in the repository; even those that haven't changed. – Blair Holloway Jun 30 '10 at 06:34
  • My bad, the format is ".." instead of " ". – igorw Jun 30 '10 at 13:54
  • Thanks, a little awkward but it will do. – Andrew Jul 01 '10 at 17:39
  • 2
    Definitely awkward. I had to put 3 dots between the commit SHAs (not 2 as shown) to get it to work. I think Bryce's answer is simpler (i.e. using --stat on git diff command) and it provides a little more information (summary of number of files changed plus number of lines changed in each file). – Daniel Goldfarb Jul 27 '15 at 20:53
78

I think this command is your answer:

git diff --stat abc123 xyz123  # where abc123 and xyz123 are SHA1 hashes of commit objects

Straight from the git community book:

If you don't want to see the whole patch, you can add the '--stat' option, which will limit the output to the files that have changed along with a little text graph depicting how many lines changed in each file.

waldyrious
  • 3,683
  • 4
  • 33
  • 41
brycemcd
  • 4,343
  • 3
  • 26
  • 29
  • 4
    More specifically, `git diff --stat `. – Blair Holloway Jun 30 '10 at 06:35
  • 4
    No, this is exactly not what he wanted. Git diff does a direct diff between the trees, it does not consider the commits. If you create a new file with contents "A", then change the contents to "B", then change them back to "A", `git diff --stat HEAD^^ HEAD` will give you a blank output. – igorw Jun 30 '10 at 13:57
  • 3
    `git diff --name-only` is probably better than `git diff --stat` but as pointed out `git diff` isn't doing what the OP wanted. – nnutter Nov 17 '14 at 16:13
20

If just want to see the file names where commit b is chronologically after a:

git diff <a commit sha1>...<b commit sha2> --name-only # b is after a in time

If you want to see all the file names and what was changed from commit a to commit b then drop the last argument.

git diff <a commit sha1>...<b commit sha2> # shows file names and what changed in each file

An example of <commit sha1> are the commit id's like 675ee6860d2c273bcc6c6a0536634a107e2a3d9f. Generally the first 8-10 digits will work on most projects, but may need more if the project has oodles of commits. Typically I use the output of the id from git log --oneline.

When you get a difference of a...b and b is later than a in time it's easy to see what was changed in each file chronologically.

Lloyd Rochester
  • 689
  • 8
  • 7
1

This one is similar to igorw's, but it avoids the removal of the SHA via grep:

git log --pretty='format:' --name-only HEAD^^..HEAD | sort -u

If you additionally want to see how the files were modified, replace --name-only with --name-status.

Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
  • I just tested this command. It took around 10 seconds to process then began to spew a huge file list. – ostler.c Oct 31 '12 at 19:43
  • @ostler.c: Did you pass in the revision range in `"$@"`? Otherwise, it'll show existing changes, which is a lot :-) I've revised my answer to use an example, like in the other answers. – Ingo Karkat Oct 31 '12 at 20:14
  • Alright that makes sense. I am surprised I didn't know "$@". Although, I don't find it to be very useful for most commands. – ostler.c Oct 31 '12 at 22:04
  • @ostler.c: I have this line in a `git-showfiles` script, and the `"$@"` inserts all passed arguments; though a little bit obscure (like much in shell scripting), this is pretty standard stuff. – Ingo Karkat Nov 01 '12 at 09:11
1

I'd use; taking the first 8 of the commit hash. If you wanted you could pipe into a file as per the below:

git log 12345678..87654321 > C:\GitChanges.txt
slm
  • 15,396
  • 12
  • 109
  • 124
craig Rickett
  • 428
  • 1
  • 5
  • 17
  • Note that on the MINGW64 `Git for Windows` bash, this needs to be `... > C:\\folder\\file.txt` (double backslash) – AlainD Nov 07 '22 at 15:28
0

An alternative way:

git checkout <commit 1>
git checkout -b temporal_branch
git reset --soft <commit 2>
git status

'git reset' changes the head of your branch to a certain commit (or branch or tag). The '--soft' option conservates the changes between both commits in the stage. Therefore, with git status, all the changed files will appear in the stage.

  • As it’s currently written your answer gives a solution, but doesn't give any information as to how it functions. Please [edit] to add additional details that will help others understand how this addresses the question asked. Many of the readers may not be familiar enough with the commands recommended to immediately know how they work together to provide a solution. – Patrick vD Jun 21 '23 at 14:56
-2

I use this command to compare all changes between two commits:

git difftool -d <commit hash1> <commit hash2>

Like a git rebase to squash all local commits into one.

codewarrior
  • 723
  • 7
  • 22