90

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).

0

7 Answers 7

90

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.

4
  • 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. Commented Jun 30, 2010 at 6:34
  • My bad, the format is "<commit1>..<commit2>" instead of "<commit1> <commit2>".
    – igorw
    Commented Jun 30, 2010 at 13:54
  • Thanks, a little awkward but it will do.
    – Andrew
    Commented Jul 1, 2010 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). Commented Jul 27, 2015 at 20:53
81

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.

3
  • 4
    More specifically, git diff --stat <commit1> <commit2>. Commented Jun 30, 2010 at 6: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
    Commented Jun 30, 2010 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
    Commented Nov 17, 2014 at 16:13
21

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.

1
  • This is the way to do it! Commented Aug 13, 2021 at 21:45
2

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.

1
  • 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
    Commented Jun 21, 2023 at 14:56
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.

4
  • I just tested this command. It took around 10 seconds to process then began to spew a huge file list.
    – ostler.c
    Commented Oct 31, 2012 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. Commented Oct 31, 2012 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
    Commented Oct 31, 2012 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. Commented Nov 1, 2012 at 9: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
1
  • Note that on the MINGW64 Git for Windows bash, this needs to be ... > C:\\folder\\file.txt (double backslash)
    – AlainD
    Commented Nov 7, 2022 at 15:28
-1

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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.