Making git diff --stat show full file path

37,758

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)/{}"
Share:
37,758
Badri
Author by

Badri

Updated on May 05, 2021

Comments

  • Badri
    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 get git diff to always show full path

  • cmcginty
    cmcginty over 11 years
    git diff --numstat is the same as diff-tree
  • jakub.g
    jakub.g about 10 years
    Note 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
    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
    Rudie about 9 years
    Is there any way to globalize this? Typing it every time is crazy.
  • Rudie
    Rudie about 9 years
    Is there any way to globalize --stat=$COLUMNS,$COLUMNS? Typing it every time is crazy.
  • torek
    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
    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
    torek about 9 years
    You'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
    user151841 about 8 years
    @Rudie add export COLUMNS to your ~/.bashrc, and in your ~/.gitconfig under [alias], add smart-diff = ! "gitsmartdiff() { git diff $2 --stat=$COLUMNS,$COLUMNS; }; gitsmartdiff"
  • Rudie
    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
    user151841 about 8 years
    @Rudie Well, after the pull or merge is complete, you can diff between the previous and the new hashes.
  • Rudie
    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
    GCallie over 6 years
    According 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
    cmbuckley over 6 years
    All 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
    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
    sage about 3 years
    I found that just using --relative helped me immensely. (I already use the --stat width options.
  • CervEd
    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
    CervEd almost 3 years
    There's also a corresponding option for git diff-tree but there are other options you need to specify like git diff-tree --name-only -r --no-commit-id HEAD. See my answer stackoverflow.com/a/67330880/1507124 for more info
  • bfontaine
    bfontaine about 2 years
    git diff-tree doesn’t support --no-index like git diff does :/
  • torek
    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 to git 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 and git write-tree).