Reputation: 2203
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 get git diff
to always show full path
Upvotes: 171
Views: 56575
Reputation: 487983
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.)
Upvotes: 168
Reputation: 4243
git diff
is a porcelain (user friendly) command. For scripting purposes, you probably want to use the corresponding plumbing command git diff-tree
.
You can get git diff-tree
to output the full paths, relative to the git repository, using a combination of the --name-only
, -r
and --no-commit-id
options.
Paths of files changed in the "last" (the HEAD
) commit of the current branch.
git diff-tree --name-only -r --no-commit-id HEAD
Paths of files in the last commit on the main
branch
git diff-tree --name-only -r --no-commit-id main
Paths of files of the last three commits on the main
branch
git diff-tree --name-only -r main main~3
Paths of the files of the last commit under path src/
git diff-tree --name-only -r --no-commit-id main src/
Absolute paths of the files changed in the last commit on the current branch
git diff-tree --name-only -r --no-commit-id --line-prefix=`git rev-parse --show-toplevel`/ HEAD
git diff-tree
compares the blobs of two treeish objects.
A commit is a treeish
object, which points to the objects in the repository root. Directories are also treeish
objects whereas files are blobs
.
Running git diff-tree HEAD
will compare the blobs of HEAD
and HEAD~1
and contain the difference in blobs of the repository root. To see all the changed files that are not in the root, we need to descend into the directory treeish
objects. This is achieved using the -r
(as in recurse) option.
Note that this allows one two compare arbitrary directories in arbitrary commits.
By default, if only one commit object is specified, it's compared to its parent. Ie, running git diff-tree HEAD
is equivalent to git diff-tree HEAD HEAD~1
. If you only specified one commit as the treeish object, the parent commit id is displayed. Using --no-commit-id
gets rid of this.
git-diff-tree
prints a lot of information we don't want (ids, permissions, whether it's an add, delete, modification). We just want the name, so we use --name-only
.
If we wanted absoluted paths, we need to prefix all lines using something like git rev-parse --show-toplevel
. This gets the absolute path of the repository, without the trailing /
. So we add that.
--line-prefix=`git rev-parse --show-toplevel`/
Upvotes: 3
Reputation: 6808
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)/{}"
Upvotes: 3
Reputation: 18046
I created the following git alias:
diffstat = ! "gitdiffstat() { git diff --stat=$(tput cols) ${1:-master} ; }; gitdiffstat"
It reads the column count from the tput cols
command. It defaults to diffing against master
, but you can optionally specify another branch.
$ git diffstat
.gitalias | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Upvotes: 0
Reputation: 601
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.
Upvotes: 8
Reputation: 12981
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.
Upvotes: 21
Reputation: 42458
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.
Upvotes: 38
Reputation: 55864
I found that the behaviour of diff --stat changed somewhere around git 1.7.10 where previously it would shorten file paths to a fixed width by default - it now displays as much as your terminal window will allow. If you are experiencing this problem, make sure you upgrade to 1.8.0 or newer.
Upvotes: -1