How to get a list of all files that changed between two Git commits?

Git

Git Problem Overview


Due to bureaucracy, I need to get a list of all changed files in my repository for a report (I started with existing source code).

What should I run to get this list?

Git Solutions


Solution 1 - Git

For files changed between a given SHA and your current commit:

git diff --name-only <starting SHA> HEAD

or if you want to include changed-but-not-yet-committed files:

git diff --name-only <starting SHA>

More generally, the following syntax will always tell you which files changed between two commits (specified by their SHAs or other names):

git diff --name-only <commit1> <commit2>

Using --name-status instead of --name-only will show what happened to the files as well as the names.

Solution 2 - Git

To find the names of all files modified since your last commit:

git diff --name-only

Or (for a bit more information, including untracked files):

git status

Solution 3 - Git

  • To list all unstaged tracked changed files:

      git diff --name-only
    
  • To list all staged tracked changed files:

      git diff --name-only --staged
    
  • To list all staged and unstaged tracked changed files:

      { git diff --name-only ; git diff --name-only --staged ; } | sort | uniq
    
  • To list all untracked files (the ones listed by git status, so not including any ignored files):

      git ls-files --other --exclude-standard
    

If you're using this in a shell script, and you want to programmatically check if these commands returned anything, you'll be interested in git diff's --exit-code option.

Solution 4 - Git

When I have added/modified/deleted many files (since the last commit), I like to look at those modifications in chronological order.

For that I use:

  • To list all non-staged files:

      git ls-files --other --modified --exclude-standard
    
  • To get the last modified date for each file:

      while read filename; do  echo -n "$(stat -c%y -- $filename 2> /dev/null) "; echo $filename;  done
    

Although ruvim suggests in the comments:

xargs -0 stat -c '%y %n' -- 
  • To sort them from oldest to more recent:

      sort
    

An alias makes it easier to use:

alias gstlast='git ls-files --other --modified --exclude-standard|while read filename; do  echo -n "$(stat -c%y -- $filename 2> /dev/null) "; echo $filename;  done|sort'

Or (shorter and more efficient, thanks to ruvim)

alias gstlast='git ls-files --other --modified --exclude-standard|xargs -0 stat -c '%y %n' --|sort'

For example:

username@hostname:~> gstlast
2015-01-20 11:40:05.000000000 +0000 .cpl/params/libelf
2015-01-21 09:02:58.435823000 +0000 .cpl/params/glib
2015-01-21 09:07:32.744336000 +0000 .cpl/params/libsecret
2015-01-21 09:10:01.294778000 +0000 .cpl/_deps
2015-01-21 09:17:42.846372000 +0000 .cpl/params/npth
2015-01-21 12:12:19.002718000 +0000 sbin/git-rcd

I now can review my modifications, from oldest to more recent.

Solution 5 - Git

I need a list of files that had changed content between two commits (only added, A, or modified, M), so I used:

git diff --name-only --diff-filter=AM <from_commit_hash> <to_commit_hash>

Here are the different --diff-filter options from the git diff documentation (see also man git diff):

> --diff-filter=[(A|C|D|M|R|T|U|X|B)…​[*]] > > Select only files that are Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type (i.e. regular file, symlink, submodule, …​) changed (T), are Unmerged (U), are Unknown (X), or have had their pairing Broken (B). Any combination of the filter characters (including none) can be used. When * (All-or-none) is added to the combination, all paths are selected if there is any file that matches other criteria in the comparison; if there is no file that matches other criteria, nothing is selected. > > Also, these upper-case letters can be downcased to exclude. E.g. --diff-filter=ad excludes added and deleted paths. > > Note that not all diffs can feature all types. For instance, diffs from the index to the working tree can never have Added entries (because the set of paths included in the diff is limited by what is in the index). Similarly, copied and renamed entries cannot appear if detection for those types is disabled.

If you want to list the status as well (e.g. A / M), change --name-only to --name-status:

git diff --name-status --diff-filter=AM <from_commit_hash> <to_commit_hash>

Solution 6 - Git

With git show you can get a similar result. For look the commit (like it looks on git log view) with the list of files included in, use:

git show --name-only [commit-id_A]^..[commit-id_B]

Where [commit-id_A] is the initial commit and [commit-id_B] is the last commit than you want to show.

Special attention with ^ symbol. If you don't put that, the commit-id_A information will not deploy.

Solution 7 - Git

The list of unstaged modified can be obtained using git status and the grep command like below. Something like git status -s | grep M:

root@user-ubuntu:~/project-repo-directory# git status -s | grep '^ M'
 M src/.../file1.js
 M src/.../file2.js
 M src/.../file3.js
 ....

Solution 8 - Git

If you want to check the changed files you need to take care of many small things like which will be best to use , like if you want to check which of the files changed just type

git status -- it will show the files with changes

then if you want to know what changes are to be made it can be checked in ways ,

git diff -- will show all the changes in all files

it is good only when only one file is modified

and if you want to check particular file then use

git diff

Solution 9 - Git

Simpiest way to get list of modified files and save it to some text file is:

git diff --name-only HEAD^ > modified_files.txt

Solution 10 - Git

Some filters that are working for me in GitHub Actions depending on type (pull_request or merge to master) are:

git --no-pager diff --name-only --diff-filter=ACMRT ${{github.event.pull_request.base.sha}} ${{ github.event.pull_request.head.sha }}
git --no-pager diff --name-only --diff-filter=ACMRT ${{github.event.pull_request.base.sha}} ${{github.sha}}
git log -m -1 --name-only --pretty="format:" ${{ github.sha }}

Try these and see which one suits your needs.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChen KinnrotView Question on Stackoverflow
Solution 1 - GitAmberView Answer on Stackoverflow
Solution 2 - GitTim BellisView Answer on Stackoverflow
Solution 3 - GitFlimmView Answer on Stackoverflow
Solution 4 - GitVonCView Answer on Stackoverflow
Solution 5 - GitFodderView Answer on Stackoverflow
Solution 6 - GitTomasMolinaView Answer on Stackoverflow
Solution 7 - GitSuperNovaView Answer on Stackoverflow
Solution 8 - GitSaurabh PalView Answer on Stackoverflow
Solution 9 - GitADV-ITView Answer on Stackoverflow
Solution 10 - GitGeorge Ts.View Answer on Stackoverflow