1231

SVN's log has a "-v" mode that outputs filenames of files changed in each commit, like so:

jes5199$ svn log -v
------------------------------------------------------------------------
r1 |   jes5199 | 2007-01-03 14:39:41 -0800 (Wed, 03 Jan 2007) | 1 line
Changed paths:
   A /AUTHORS
   A /COPYING
   A /ChangeLog
   A /EVOLUTION
   A /INSTALL
   A /MacOSX

Is there a quick way to get a list of changed files in each commit in Git?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jes5199
  • 18,324
  • 12
  • 36
  • 40

13 Answers13

1903

For full path names of changed files:

git log --name-only

For full path names and status of changed files:

git log --name-status

For abbreviated pathnames and a diffstat of changed files:

git log --stat

There are a lot more options. Check out the documentation.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • 29
    I use `git log --numstat`. See `git help log` for more options. – ma11hew28 Jan 04 '15 at 18:17
  • 54
    `git log --name-only --oneline` is pretty spiffy too - one colored line for the commit, and one file per line. http://stackoverflow.com/a/14227496/1995714 – cp.engr Oct 15 '15 at 22:00
  • 4
    With git 2.7.3, I had to use `git log --name-status --find-renames` for it to show renamed files instead of addition + deletion. – Suzanne Soy Apr 05 '16 at 11:01
  • 2
    Note that `--stat` abbreviates long paths; width is configurable but wrapped histograms are harder to read. Other formats like `--numstat` always print full paths. – Beni Cherniavsky-Paskin Nov 20 '19 at 10:14
  • 3
    @ma11hew28 Thanks. `--numstat` is at line 946 of that man page as of git 2.22.00. That's a *lot* more options than most people need. – Martin Schröder Jan 05 '20 at 23:21
  • You also need the `-m --first-parent` options to get the files affected by a merge. Otherwise, e.g. if files have been added in a merge, they seem to come from nowhere in the subsequent commits. See [Using git log to display files changed during merge](https://stackoverflow.com/questions/37801342/using-git-log-to-display-files-changed-during-merge). – vinc17 Feb 05 '20 at 15:17
  • Actually `--first-parent` should not be used, just `-m`. Otherwise some important commits do not appear in the history. But this yields duplicate merge commits. – vinc17 Feb 05 '20 at 15:36
146

NOTE: git whatchanged is deprecated, use git log instead

New users are encouraged to use git-log[1] instead. The whatchanged command is essentially the same as git-log[1] but defaults to show the raw format diff output and to skip merges.

The command is kept primarily for historical reasons; fingers of many people who learned Git long before git log was invented by reading Linux kernel mailing list are trained to type it.


You can use the command git whatchanged --stat to get a list of files that changed in each commit (along with the commit message).

References

slm
  • 15,396
  • 12
  • 109
  • 124
mipadi
  • 398,885
  • 90
  • 523
  • 479
61

git show is also a great command.

It's kind of like svn diff, but you can pass it a git commit hash and see that diff.

ptc
  • 1,018
  • 8
  • 12
58

If you want to get the file names only without the rest of the commit message you can use:

git log --name-only --pretty=format: <branch name>

This can then be extended to use the various options that contain the file name:

git log --name-status --pretty=format: <branch name>

git log --stat --pretty=format: <branch name>

One thing to note when using this method is that there are some blank lines in the output that will have to be ignored. Using this can be useful if you'd like to see the files that have been changed on a local branch, but is not yet pushed to a remote branch and there is no guarantee the latest from the remote has already been pulled in. For example:

git log --name-only --pretty=format: my_local_branch --not origin/master

Would show all the files that have been changed on the local branch, but not yet merged to the master branch on the remote.

Hazok
  • 5,373
  • 4
  • 38
  • 48
  • 1
    Note on whitespace in the above examples - it's like, `git log --stat --pretty="format:" $branchName`. So for example, `git log --stat --pretty="format:" $(git rev-parse --abbrev-ref HEAD)`. While I'm at it, here's the exact incantation that wound up being relevant to my purpose: `git log --name-only --pretty="format: " master..$(git rev-parse --abbrev-ref HEAD)` – floer32 May 10 '17 at 05:44
51

I use this on a daily basis to show history with files that changed:

git log --stat --pretty=short --graph

To keep it short, add an alias in your .gitconfig by doing:

git config --global alias.ls 'log --stat --pretty=short --graph'
cxw
  • 16,685
  • 2
  • 45
  • 81
xsor
  • 1,074
  • 11
  • 11
  • 2
    Mine is very close to that, git log --pretty=oneline --graph --name-status. I find it more concise, just showing the list of the files that changed. – Peter Suwara Jun 05 '19 at 17:56
  • @Thanks, the --stat flag part causes showing the files and total stats number of changed files, whereas yours --name-status part similarly, but even better, showing only files – FantomX1 Oct 01 '21 at 12:45
  • I created an alias for @PeterSuwara's version with `git config --global alias.shortlog 'log --pretty=oneline --graph --name-status'`. Does anyone know why the output from using the alias is different from the output using `git log --pretty=oneline --graph --name-status` directly? – nabrown Jan 06 '23 at 14:23
  • UPDATE: Nevermind I just realized `shortlog` is already a git command! – nabrown Jan 06 '23 at 14:29
  • That one doesn't include the date – malhal Jul 27 '23 at 11:57
30

This short command is very helpful to list all the files changed per commit.

git log --name-only --oneline

--name-only

Show only names of changed files. The file names are often encoded in UTF-8. For more information see the discussion about encoding in the git-log1 manual page.

--oneline

This is a shorthand for "--pretty=oneline --abbrev-commit" used together.

Output Output

Amitesh Bharti
  • 14,264
  • 6
  • 62
  • 62
16

I use this:

git log --name-status <branch>..<branch> | grep -E '^[A-Z]\b' | sort | uniq

which outputs a list of files only and their state (added, modified, deleted):

A   sites/api/branding/__init__.py
M   sites/api/branding/wtv/mod.py
...
scc
  • 10,342
  • 10
  • 51
  • 65
11

A summary of answers with example output

This is using a local repository with five simple commits.

‣ git log --name-only
commit ed080bc88b7bf0c5125e093a26549f3755f7ae74 (HEAD -> master)
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:46:04 2019 -0700

    mv file4 to file5

file5

commit 5c4e8cfbe3554fe3d7d99b5ae4ba381fa1cdb328
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:36:32 2019 -0700

    foo file1

    really important to foo before the bar

file1

commit 1b6413400b5a6a96d062a7c13109e6325e081c85
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:34:37 2019 -0700

    foobar file2, rm file3

file2
file3

commit e0dd02ce23977c782987a206236da5ab784543cc
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:33:05 2019 -0700

    Add file4

file4

commit b58e85692f711d402bae4ca606d3d2262bb76cf1
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:32:41 2019 -0700

    Added files

file1
file2
file3


‣ git log --name-status
commit ed080bc88b7bf0c5125e093a26549f3755f7ae74 (HEAD -> master)
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:46:04 2019 -0700

    mv file4 to file5

R100    file4   file5

commit 5c4e8cfbe3554fe3d7d99b5ae4ba381fa1cdb328
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:36:32 2019 -0700

    foo file1

    really important to foo before the bar

M       file1

commit 1b6413400b5a6a96d062a7c13109e6325e081c85
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:34:37 2019 -0700

    foobar file2, rm file3

M       file2
D       file3

commit e0dd02ce23977c782987a206236da5ab784543cc
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:33:05 2019 -0700

    Add file4

A       file4

commit b58e85692f711d402bae4ca606d3d2262bb76cf1
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:32:41 2019 -0700

    Added files

A       file1
A       file2
A       file3


‣ git log --stat
commit ed080bc88b7bf0c5125e093a26549f3755f7ae74 (HEAD -> master)
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:46:04 2019 -0700

    mv file4 to file5

 file4 => file5 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)

commit 5c4e8cfbe3554fe3d7d99b5ae4ba381fa1cdb328
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:36:32 2019 -0700

    foo file1

    really important to foo before the bar

 file1 | 3 +++
 1 file changed, 3 insertions(+)

commit 1b6413400b5a6a96d062a7c13109e6325e081c85
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:34:37 2019 -0700

    foobar file2, rm file3

 file2 | 1 +
 file3 | 0
 2 files changed, 1 insertion(+)

commit e0dd02ce23977c782987a206236da5ab784543cc
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:33:05 2019 -0700

    Add file4

 file4 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)

commit b58e85692f711d402bae4ca606d3d2262bb76cf1
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:32:41 2019 -0700

    Added files

 file1 | 0
 file2 | 0
 file3 | 0
 3 files changed, 0 insertions(+), 0 deletions(-)


‣ git log --name-only --oneline
ed080bc (HEAD -> master) mv file4 to file5
file5
5c4e8cf foo file1
file1
1b64134 foobar file2, rm file3
file2
file3
e0dd02c Add file4
file4
b58e856 Added files
file1
file2
file3


‣ git log --pretty=oneline --graph --name-status
* ed080bc88b7bf0c5125e093a26549f3755f7ae74 (HEAD -> master) mv file4 to file5
| R100  file4   file5
* 5c4e8cfbe3554fe3d7d99b5ae4ba381fa1cdb328 foo file1
| M     file1
* 1b6413400b5a6a96d062a7c13109e6325e081c85 foobar file2, rm file3
| M     file2
| D     file3
* e0dd02ce23977c782987a206236da5ab784543cc Add file4
| A     file4
* b58e85692f711d402bae4ca606d3d2262bb76cf1 Added files
  A     file1
  A     file2
  A     file3


‣ git diff-tree HEAD
ed080bc88b7bf0c5125e093a26549f3755f7ae74
:100644 000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 D  file4
:000000 100644 0000000000000000000000000000000000000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 A  file5


‣ git log --stat --pretty=short --graph
* commit ed080bc88b7bf0c5125e093a26549f3755f7ae74 (HEAD -> master)
| Author: My Name <user@email.com>
| 
|     mv file4 to file5
| 
|  file4 => file5 | 0
|  1 file changed, 0 insertions(+), 0 deletions(-)
| 
* commit 5c4e8cfbe3554fe3d7d99b5ae4ba381fa1cdb328
| Author: My Name <user@email.com>
| 
|     foo file1
| 
|  file1 | 3 +++
|  1 file changed, 3 insertions(+)
| 
* commit 1b6413400b5a6a96d062a7c13109e6325e081c85
| Author: My Name <user@email.com>
| 
|     foobar file2, rm file3
| 
|  file2 | 1 +
|  file3 | 0
|  2 files changed, 1 insertion(+)
| 
* commit e0dd02ce23977c782987a206236da5ab784543cc
| Author: My Name <user@email.com>
| 
|     Add file4
| 
|  file4 | 0
|  1 file changed, 0 insertions(+), 0 deletions(-)
| 
* commit b58e85692f711d402bae4ca606d3d2262bb76cf1
  Author: My Name <user@email.com>

      Added files

   file1 | 0
   file2 | 0
   file3 | 0
   3 files changed, 0 insertions(+), 0 deletions(-)


‣ git log --name-only --pretty=format:
file5

file1

file2
file3

file4

file1
file2
file3


‣ git log --name-status --pretty=format:
R100    file4   file5

M       file1

M       file2
D       file3

A       file4

A       file1
A       file2
A       file3


‣ git diff --stat 'HEAD^!'
 file4 => file5 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)


‣ git show
commit ed080bc88b7bf0c5125e093a26549f3755f7ae74 (HEAD -> master)
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:46:04 2019 -0700

    mv file4 to file5

diff --git a/file4 b/file5
similarity index 100%
rename from file4
rename to file5


Credits to @CB-Bailey @Peter-Suwara @Gaurav @Omer-Dagan @xsor @Hazok @nrz @ptc

JamesThomasMoon
  • 6,169
  • 7
  • 37
  • 63
9

git diff --stat HEAD^! shows changed files and added/removed line counts for the last commit (HEAD).

It seems to me that there isn't any single command to get concise output consisting only of filenames and added and removed line counts for several commits at once, so I created my own Bash script for that:

#!/bin/bash
for ((i=0; i<=$1; i++))
do
    sha1=`git log -1 --skip=$i --pretty=format:%H`
    echo "HEAD~$i $sha1"
    git diff --stat HEAD~$(($i+1)) HEAD~$i
done

It is to be called, for example, ./changed_files 99 to get the changes in a concise form from HEAD to HEAD~99. It can be piped, for example, to less.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
nrz
  • 10,435
  • 4
  • 39
  • 71
  • Can't you do `git diff --stat HEAD..master` to show the difference between HEAD and master, or didn't this exist when you posted your answer back in 2012? – Ferrybig Aug 11 '17 at 09:14
  • 1
    @Ferrybig OP's question is about how **"to get a list of changed files in each commit"**, not about the **diff** between `HEAD` and `master`. Those are two different things. – nrz Aug 11 '17 at 18:13
7

I find the following is the ideal display for listing what files changed per commit in a concise format:

git log --pretty=oneline --graph --name-status
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Peter Suwara
  • 781
  • 10
  • 16
  • 1
    Thanks, exactly what i was looking for. I would alsoe suggest using pretty format like 'git log --pretty="format:%n %cn %s %cr" --graph --name-status' https://hansrobo.github.io/cheatsheets/git-log-format – velocity Oct 13 '21 at 21:13
5

I am using:

git diff-tree -v --name-status -r <commit-id>

And it shows very similar output like svn log -v

singleX
  • 375
  • 4
  • 13
2

Another useful command would be git diff-tree <hash> where hash can be also a hash range (denoted by <old>..<new> notation). An output example:

$ git diff-tree  HEAD
:040000 040000 8e09a be406 M myfile

The fields are:

source mode, destination mode, source hash, destination hash, status, and filename

Statuses are the ones you would expect: D (deleted), A (added), M (modified), etc. See the man page for full description

Omer Dagan
  • 14,868
  • 16
  • 44
  • 60
  • I tried this, but it only gave the M status for files in the root of the repo. So for files in a dir it would only give ":xxxx yyy zzz aaa M dirname" – Marco van de Voort Oct 23 '21 at 12:24
2

I generally use these to get the logs:

$ git log --name-status --author='<Name of author>' --grep="<text from Commit message>"

$ git log --name-status --grep="<text from Commit message>"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gaurav
  • 21
  • 1
  • 1
    I didn't know about these options, but this post would be more useful if it explained that it filters the log. For a moment there, I thought it was a way to change the way authors are listed in the output. – Stein May 07 '19 at 16:27