Making git diff --stat show full file path
Solution 1
By default git diff
truncates its output to fit into a 80-column terminal.
You can override this by specifying values using the --stat
option:
--stat[=<width>[,<name-width>[,<count>]]]
Generate a diffstat. You can override the default output width for
80-column terminal by --stat=<width>. The width of the filename
part can be controlled by giving another width to it separated by a
comma. By giving a third parameter <count>, you can limit the
output to the first <count> lines, followed by ... if there are
more.
These parameters can also be set individually with
--stat-width=<width>, --stat-name-width=<name-width> and
--stat-count=<count>.
For example, by setting the output value to a very large number:
git diff --stat=10000
Note that produces the path relative to the root of the git repository.
(For scripting you might want to use git diff-tree
directly since it's more of a "plumbing" command, although I suspect you'll be fine either way. Note that you need the same extra text with --stat
when using git diff-tree
. The essential difference between using the git diff
"porcelain" front end, and the git diff-tree
plumbing command, is that git diff
looks up your configured settings for options like diff.renames
to decide whether to do rename detection. Well, that, plus the front end git diff
will do the equivalent of git diff-index
if you're comparing a commit with the index, for instance. In other words, git diff
reads your config and invokes the right plumbing automatically.)
Solution 2
For script processing, it might be better to use one of the following:
# list just the file names
git diff --name-only
path/to/modified/file
path/to/renamed/file
# list the names and change statuses:
git diff --name-status
M path/to/modified/file
R100 path/to/existing/file path/to/renamed/file
# list a diffstat-like output (+ed lines, -ed lines, file name):
git diff --numstat
1 0 path/to/modified/file
0 0 path/to/{existing => renamed}/file
These each become more handy for robust script processing when combined with the -z
option, which uses NUL
as the field terminators.
Solution 3
For Bash users, you can use the $COLUMNS
variable to automatically fill the available terminal width:
git diff --stat=$COLUMNS
Very long path names might still be truncated; in this case, you can reduce the width of the +++/--- part using --stat-graph-width
, for example this limits it to 1/5 of the terminal width:
git show --stat=$COLUMNS --stat-graph-width=$(($COLUMNS/5))
For a more generic solution, you could use the output of tput cols
to determine the terminal width.
Solution 4
There’s an option --name-only
: git diff --name-only
. The option is also supported by other git commands like show
and stash
.
Paths don’t get shortened with the option.
Solution 5
A simple solution I found was to do this: (only works on *nix, sorry no osx)
git diff --stat=$COLUMNS --relative | head -n -1 | cut -c 2- | xargs -d '\n' -P4 printf "$(pwd)/%s\n"
This version works for both, but it doesn't look great on osx.
git diff --stat=$COLUMNS --relative | sed -e '$ d' | cut -c 2- | xargs -n4 -I{} echo "$(pwd)/{}"
Badri
Updated on May 05, 2021Comments
-
Badri almost 3 years
On doing
git diff --stat
some files are listed with full path from repository base but some files are listed as:.../short/path/to/filename.
That is the path starts with
...
and only short path is shown.I would like
git diff
to list full file path for all files for it to be easily processed by a script. Is there some way I can getgit diff
to always show full path -
cmcginty over 11 yearsgit diff --numstat is the same as diff-tree
-
jakub.g about 10 yearsNote that to limit the width of the last part (+++/---) you can use a separate
--stat-graph-width=...
switch. Note also that setting high--stat-graph-width=
and--stat-name-width=
is not enough, you must also set--stat-width=
big enough to cover the two. -
torek about 10 years@jakub.g: good point. Based on a bit of digging in the git source, this went in with git 1.7.10.
-
Rudie about 9 yearsIs there any way to globalize this? Typing it every time is crazy.
-
Rudie about 9 yearsIs there any way to globalize
--stat=$COLUMNS,$COLUMNS
? Typing it every time is crazy. -
torek about 9 years@Rudie: alas, no: there's a configuration variable
diff.statGraphWidth
you can use to set the--stat-graph-width
value, but the others default to your terminal width. (So, alternative answer: "yes, just make your terminal window 1000 columns wide" :-) ) -
Rudie about 9 years@torek I tried to make a git alias or bash script to
git diff --stat=$COLUMNS,$COLUMNS ...
but they both don't know$COLUMNS
=( Works perfectly directly on commandline, but I'm not typing all that! =) -
torek about 9 yearsYou'd have to set
COLUMNS
in your environment. An alias or script could then use${COLUMNS+--stat=$COLUMNS...}
to check whether it's set and if so, pass it on (or explicitly test it for nonzero length first, or whatever). -
user151841 about 8 years@Rudie add
export COLUMNS
to your~/.bashrc
, and in your~/.gitconfig
under[alias]
, addsmart-diff = ! "gitsmartdiff() { git diff $2 --stat=$COLUMNS,$COLUMNS; }; gitsmartdiff"
-
Rudie about 8 years@user151841 That changes only
diff
. I want it to work for merges and pulls etc too. (Can't even manually do it there.) I don't think GIT supports it. -
user151841 about 8 years@Rudie Well, after the pull or merge is complete, you can diff between the previous and the new hashes.
-
Rudie almost 8 years@user151841 Sure, but merging already gives a stat summary. Without parameters/config. It'd be great if all 'stat summaries' used the same config.
-
GCallie over 6 yearsAccording to my tests you do not receive the full path of the resource using these commands. For now I only see relative paths for deleted files. I don't know if this is only the case for these files.
-
cmbuckley over 6 yearsAll outpu will return paths relative to
git rev-parse --show-toplevel
. The original problem was referring to truncated paths, which is a problem in diffstats, particularly for long filenames or a low value for--stat-name-width
. The commands above will not truncate the paths, but will show the "full" path as requested, albeit still relative to the repository root. -
user151841 about 5 years@Rudie I created an aliases that seems to do what you want. Check my answer here: stackoverflow.com/a/55796232/151841
-
sage about 3 yearsI found that just using
--relative
helped me immensely. (I already use the--stat
width options. -
CervEd almost 3 years
git diff-tree
is more suited for scripting. But don't use--stat
, there are better options. See my answer stackoverflow.com/a/67330880/1507124 -
CervEd almost 3 yearsThere's also a corresponding option for
git diff-tree
but there are other options you need to specify likegit diff-tree --name-only -r --no-commit-id HEAD
. See my answer stackoverflow.com/a/67330880/1507124 for more info -
bfontaine about 2 years
git diff-tree
doesn’t support--no-index
likegit diff
does :/ -
torek about 2 years@bfontaine: Yes:
git diff-tree
always compares two existing tree objects inside the repository. That is, it cannot look outside the repository at all, nor can it look at the index, so--no-index
is not available here. It's a bit of a problem since there's no--porcelain
option togit diff
though! The workaround, if you really need one, is to create a tree object from some directory in the file system (using a temporary index andgit write-tree
).