Good-lookin' diffs. Actually… nah… The best-lookin' diffs. 🎉
Perl Shell
Latest commit 9d20ab0 Jan 20, 2017 @scottchiefbaker scottchiefbaker committed on GitHub Merge pull request #212 from Kmaschta/patch-1
Fix README patch alias

readme.md

diff-so-fancy Circle CI build TravisCI build AppVeyor build

diff-so-fancy builds on the good-lookin' output of git contrib's diff-highlight to upgrade your diffs' appearances.

  • Output will not be in standard patch format, but will be readable.
  • No pesky + or - at line-start, making for easier copy-paste.

Screenshot

git diff vs git diff --color | diff-so-fancy

diff-highlight vs diff-so-fancy

Usage

You can do one-off fanciness:

git diff --color | diff-so-fancy

But, you'll probably want to fancify all your diffs. Set your core.pager to run diff-so-fancy, and pipe the output through your existing pager, or if unset we recommend less --tabs=4 -RFX:

git config --global core.pager "diff-so-fancy | less --tabs=4 -RFX"

However, if you'd prefer to do the fanciness on-demand with git dsf, add an alias to your ~/.gitconfig by running:

git config --global alias.dsf '!f() { [ -z "$GIT_PREFIX" ] || cd "$GIT_PREFIX" '\
'&& git diff --color "$@" | diff-so-fancy  | less --tabs=4 -RFX; }; f'

Install

For convenience, the recommended installation is via NPM. If you'd prefer, you may choose to do a manual installation instead.

npm install -g diff-so-fancy

This will install and link the diff-so-fancy and diff-highlight scripts. You can also upgrade to the latest version with this command.

On Mac, you can install via Homebrew:

brew update
brew install diff-so-fancy

A package is available in Arch linux:

pacman -S diff-so-fancy

Improved colors for the highlighted bits

diff-highlight has default colors that are arguably a little nasty. They'll work fine, but you can try some fancier colors:

git config --global color.diff-highlight.oldNormal "red bold"
git config --global color.diff-highlight.oldHighlight "red bold 52"
git config --global color.diff-highlight.newNormal "green bold"
git config --global color.diff-highlight.newHighlight "green bold 22"

You may also want to configure general diff colors.

Manual install

If you want, you can choose to install manually:

  1. Grab the two scripts (diff-highlight and diff-so-fancy) via either downloading or cloning the repo.
  2. If you download diff-highlight from the official git repo, give it a chmod +x.
  3. Place them in a location that is in your PATH directly or with symlinks.
  4. Place libexec/diff-so-fancy.pl in the same directory as diff-so-fancy. You will end up something like this:
    • ~/bin/diff-highlight
    • ~/bin/diff-so-fancy
    • ~/bin/libexec/diff-so-fancy.pl
  5. Set up the git core.pager config, as described above.

Note: The diff-highlight dependency is an official git-contrib script, duplicated here for convenience. If you prefer less fancy in your diff, you also use diff-highlight on it's own.

options

markEmptyLines

Should the first block of an empty line be colored.

changeHunkIndicators

Simplify git header chunks to a more human readable format.

stripLeadingSymbols

Should the pesky + or - at line-start be removed.

useUnicodeRuler

By default the separator for the file header uses Unicode line drawing characters.
If this is causing output errors on your terminal set this to false to use ASCII characters instead.

By default all the configs are true. You can turn any off by running:

git config --bool --global diff-so-fancy.markEmptyLines false
git config --bool --global diff-so-fancy.changeHunkIndicators false
git config --bool --global diff-so-fancy.stripLeadingSymbols false
git config --bool --global diff-so-fancy.useUnicodeRuler false

To reset them to default (true):

git config --unset --global diff-so-fancy.markEmptyLines
git config --unset --global diff-so-fancy.changeHunkIndicators
git config --unset --global diff-so-fancy.stripLeadingSymbols
git config --unset --global diff-so-fancy.useUnicodeRuler

Pro-tips

Opting-out

Sometimes you will want to bypass diff-so-fancy. Use --no-pager for that:

git --no-pager diff

Raw patches

As a shortcut for a 'normal' diff to save as a patch for emailing or later application, it may be helpful to configure an alias:

[alias]
    patch = !git --no-pager diff --no-color

which can then be used as git patch > changes.patch.

Moving around in the diff

You can pre-seed your less pager with a search pattern, so you can move between files with n/N keys:

[pager]
    diff = diff-so-fancy | less --tabs=4 -RFX --pattern '^(Date|added|deleted|modified): '

History

diff-so-fancy started as a commit in paulirish's dotfiles, which grew into a standalone script. Later, @stevemao brought it into its own repo (here), and gave it the room to mature. It's quickly grown into a widely collaborative project.

Contributing

Pull requests quite welcome, along with any feedback or ideas.

Reporting bugs

If you find a bug using the following command

git diff HEAD..HEAD^

You can use report-bug.sh we provide

./report-bug.sh 'git diff HEAD..HEAD^'

# or

curl https://raw.githubusercontent.com/so-fancy/diff-so-fancy/master/report-bug.sh | bash -s 'git diff HEAD..HEAD^' 'diff.txt'

Grab the output file and attach to the GitHub issue you create. A base64 version is also copied to your clipboard so you can paste to the issue.

Hacking

# fork and clone the diff-so-fancy repo.
git clone https://github.com/so-fancy/diff-so-fancy/ && cd diff-so-fancy

# test a saved diff against your local version
cat test/fixtures/ls-function.diff | ./diff-so-fancy

# setup symlinks to use local copy
npm link
cd ~/projects/catfabulator && git diff

Running tests

You'll need to install bats, the Bash automated testing system. It's also available as brew install bats

git submodule sync
git submodule update --init # pull in the assertion library, bats-assert

# Run the test suite once:
bats test

# Run it on every change with `entr`
brew install entr
ls --color=never diff-so-fancy test/*.bats | entr bats test

When writing assertions, you'll likely want to compare to expected output. To grab that reliably, you can use something like git --no-pager diff | diff-so-fancy > output.txt

You can lint your scripts via shellcheck, our CI bots will also check.

brew install shellcheck
shellcheck diff-so-fancy update-deps.sh

License

MIT