Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to have all "git diff" commands use the "Python diff", in all git projects?

When including the line

*.py diff=python

in a local .gitattributes file, git diff produces nice labels for the different diff hunks of Python files (with the name of the function where the changes are, etc.).

Is is possible to ask git to use this diff mode for all Python files across all git projects? I tried to set a global ~/.gitattributes, but it is not used by local git repositories. Is there a more convenient method than initializing each new git project with a ln -s ~/.gitattributes?

like image 553
Eric O Lebigot Avatar asked May 07 '10 12:05

Eric O Lebigot


People also ask

Where do I put Gitattributes?

These path-specific settings are called Git attributes and are set either in a . gitattributes file in one of your directories (normally the root of your project) or in the . git/info/attributes file if you don't want the attributes file committed with your project.

What is a .gitattributes file?

A gitattributes file is a simple text file that gives attributes to pathnames. Each line in gitattributes file is of form: pattern attr1 attr2 ... That is, a pattern followed by an attributes list, separated by whitespaces. Leading and trailing whitespaces are ignored.


2 Answers

Quoting from gitattributes(5):

Attributes that should affect all repositories for a single user should be placed in a file specified by the core.attributesfile configuration option (see git-config(1)). Its default value is $XDG_CONFIG_HOME/git/attributes. If $XDG_CONFIG_HOME is either not set or empty, $HOME/.config/git/attributes is used instead. Attributes for all users on a system should be placed in the $(prefix)/etc/gitattributes file.

TL;DR: echo '*.py diff=python' >> "${XDG_CONFIG_HOME:-$HOME/.config}"/git/attributes


Update, 7 years later

Ok, it's not necessary to configure diff=python for *.py files — it's the default since long ago.

But the general point remains: anything you can set up in local (per-repository) .gitattributes, you can also make global (per-machine).

There're many good examples in man 5 gitattributes itself, so please go RTFM.

Let's do just one custom setup: --word-diff for all Markdown files (kudos to @RayLuo for suggesting this in comments).

First, we add an external diff driver:

git config --global diff.stackoverflow-word-diff.command ~/.local/bin/stackoverflow-word-diff

The API is such that we must make a standalone wrapper executable.

cat > ~/.local/bin/stackoverflow-word-diff << 'EOF'
#!/bin/bash -eu

#-- uncomment for debug:
#echo >&2 "$(basename $0) args: $@"; set -x

FILENAME="$1"
OLDFILE="$2"
OLDHASH="$3"
OLDMODE="$4"
NEWFILE="$5"
NEWHASH="$6"
NEWMODE="$7"

git diff --no-ext-diff --word-diff "$OLDFILE" "$NEWFILE" || exit 0

#-- from https://stackoverflow.com/a/18948381/531179
#-- see `man 1 git` /EXTERNAL_DIFF, or https://www.git-scm.com/docs/git
EOF
chmod +x ~/.local/bin/stackoverflow-word-diff

Finally, we tie that in to *.md, *.markdown via global gitattributes:

mkdir -vp "${XDG_CONFIG_HOME:-$HOME/.config}"/git

{ echo '*.md diff=stackoverflow-word-diff'; \
  echo '*.markdown diff=stackoverflow-word-diff; \
} \
    >> "${XDG_CONFIG_HOME:-$HOME/.config}"/git/attributes

And that's all folks! Test it.

like image 68
ulidtko Avatar answered Oct 14 '22 19:10

ulidtko


To tell git to use ~/.gitattributes you need to put this in ~/.gitconfig:

[core]
  attributesfile = ~/.gitattributes
like image 3
sickill Avatar answered Oct 14 '22 20:10

sickill