How to use git diff
filters via --diff-filter=
To get a list of all changed files, excluding all deleted (via lower-case d
filter) files, use the --diff-filter=d
, like this:
# 1. see list of changed, but NOT 'd'eleted files since `from_commit_hash` to
# now
git diff --name-only --diff-filter=d from_commit_hash
# 2. specifying a range of commits:
git diff --name-only --diff-filter=d from_commit_hash to_commit_hash
# or (same thing)
git diff --name-only --diff-filter=d from_commit_hash..to_commit_hash
# 3. use the 3-dot syntax to look at just the changes since the common ancestor
# between `from_commit_hash` and `to_commit_hash`
# See: https://mcmap.net/q/11932/-what-are-the-differences-between-double-dot-quot-quot-and-triple-dot-quot-quot-in-git-diff-commit-ranges
git diff --name-only --diff-filter=d from_commit_hash...to_commit_hash
# or (same thing)
git diff --name-only --diff-filter=d \
$(git merge-base from_commit_hash to_commit_hash) to_commit_hash
# 4. looking at all changes in `commit2` which are NOT in `commit1`
git diff --name-only --diff-filter=d ^commit1 commit2
You can confirm this against the full list of changed files by looking at both the file names and their changed statuses with --name-status
:
# 1.
git diff --name-status from_commit_hash
# 2. specifying a range of commits
git diff --name-status from_commit_hash to_commit_hash
# or (same thing)
git diff --name-status from_commit_hash..to_commit_hash
# etc. etc.
Note that I consider --diff-filter=d
to be better than --diff-filter=AM
because the former includes everything except 'd'eleted files, whereas the latter excludes everything (including deleted files) except 'A'dded and 'M'odified files. The former is therefore more-inclusive, excluding only what you really want to exclude, making it better in my opinion.
In --diff-filter=
, CAPITAL filter letters INCLUDE vs lower-case filter letters exclude
Use CAPITAL letters, such as D
, A
, or M
, etc., to include that type of file, and lower-case letters, such as d
, a
, or m
, etc., respectively, to exclude that type of file.
Hence, the following is true:
--diff-filter=AM # INCLUDE only Added and Modified files
# vs
--diff-filter=am # EXCLUDE all added and modified files
From man git diff
(emphasis added):
--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 a
dded and d
eleted paths.
Note that not all diffs can feature all types. For instance, copied and renamed entries cannot appear if detection for those types is disabled.
References
- See the
git diff --diff-filter=
documentation here or with man git diff
.
- See also this particular answer: How to get a list of all files that changed between two Git commits?