Mysrt
Mysrt

Reputation: 3373

Exclude a directory from 'git diff'

How can I exclude an entire directory from my Git diff (in this case /spec)?

I'm creating a diff for our entire software release using the git diff command. However, the changes to the spec folder are irrelevant for this procedure, and just create headaches. Now I know I can do

git diff previous_release..current_release app/

This would create a diff for all the changes in the app directory, but not for instance, in the lib/ directory. How can I accomplish this task?

I just want to be clear, I know I can just string the parameters of all of my directories on the end, minus /spec. I was hoping there was a way to truly exclude a single directory in the command.

Upvotes: 302

Views: 129497

Answers (7)

jasonleonhard
jasonleonhard

Reputation: 13887

Relative to the Git root directory

git diff accepts an optional exclude

git diff -- ":(exclude)thingToExclude"

You might want to add some wild cards

git diff -- ":(exclude)*/thingToExclude/*"

Target specific file types

git diff -- ":(exclude)*/$1/*.png"

Some syntactic sugar applied

git diff -- ":!/\$1/"

Or drop a little script for your dotfiles

Such as the $HOME/.bash_profile or $HOME/.zshrc files

gde() {
    : '
        git diff exclude files or folders
        usage:
        gde fileOrFolderNameToExclude
    '
    git diff -- ":!/\$1/"
}

Upvotes: 41

Cascabel
Cascabel

Reputation: 496852

Assuming you use Bash, and you've enabled extended globbing (shopt -s extglob), you could handle that from the shell side:

git diff previous_release current_release !(spec)

Saves you having to list all other things.

Or, shell-agnostic:

git diff previous_release current_release --name-only | grep -v '^spec/' \
    | xargs git diff previous_release current_release --

You could wrap that up in a one-liner shell script to save yourself having to retype the arguments.

Upvotes: 150

cdleonard
cdleonard

Reputation: 7050

Based on this answer, you can also use:

git diff previous_release..current_release -- . ':!spec'

This is a newish Git feature which allows excluding certain paths. It should be more reliable than various shell one-liners.

I'm posting this here because this question is still the #1 hit for "git diff exclude path".

Since Git 2.13 (Q2 2017), you can replace ! with ^. The latter doesn't need quotes. So you can write it as:

git diff previous_release..current_release -- . :^spec

Upvotes: 519

David Graham
David Graham

Reputation: 541

If you want to specify more than one path to exclude in a Git diff, you just add additional exclusion parameters to the end, e.g., to exclude everything in vendor and bin directories from the stats:

git diff --stat previous_release..current_release -- . ':!vendor' ':!bin'

Upvotes: 50

MaxPRafferty
MaxPRafferty

Reputation: 4977

Git diff now accepts a custom exclusion format: git diff -- ':(exclude)lib/*'

Be careful if you have a lot of repetitive folder names ('/app', '/lib', etc.), as this will exclude files relative to the current working directory and the Git root directory.

Upvotes: 31

VonC
VonC

Reputation: 1323753

You can try and unset the diff attribute for any files within the lib directory.
.gitattributes:

lib/* -diff

racl101 adds in the comments:

Just to add to this, for those of you who want to limit the git diff output of files of a specific type, within a specific directory and its subdirectories, like all the JavaScript generated by Webpack's bundling of your .js files, for example, you can add this to .gitattributes:

dist/js/**/*.js -diff

Then you don't see all that noise in your git diff output and it just shows as: Binary files ... differ which is more helpful.

Upvotes: 38

Jed Schneider
Jed Schneider

Reputation: 14671

git diff app lib

Upvotes: -10

Related Questions