Exclure un répertoire de git diff

179

Je me demande comment je peux exclure un répertoire entier de mon diff Git. (Dans ce cas / spec). Je crée un diff pour l'ensemble de notre version logicielle à l'aide de la commande git diff. Cependant, les modifications apportées aux spécifications ne sont pas pertinentes pour cette procédure et ne font que créer des maux de tête. maintenant je sais que je peux faire

git diff previous_release..current_release app/

Cela créerait un diff pour toutes les modifications dans le répertoire de l'application, mais pas par exemple, dans le répertoire lib /. Quelqu'un sait-il comment accomplir cette tâche? Merci!

Edit: Je veux juste être clair, je sais que je peux simplement enchaîner les paramètres de tous mes répertoires à la fin, moins / spec. J'espérais qu'il y avait un moyen d'exclure vraiment un seul répertoire dans la commande.

Mysrt
la source
4
J'ai trouvé cette question incroyable parce que je cherchais à ignorer les sous-modules . Dans ce cas, si vous êtes aussi naïf que moi, cette question peut être plus utile.
brandizzi
C'est étrange que nous n'ayons toujours pas de commutateur Git natif pour faire cela en septembre 2016
Michael Z

Réponses:

138

En supposant que vous utilisez bash et que vous avez activé la fonction de globbing étendu ( shopt -s extglob), vous pouvez gérer cela du côté du shell:

git diff previous_release current_release !(spec)

Vous évite d'avoir à lister toutes les autres choses.

Ou, agnostique de coquille:

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

Vous pouvez résumer cela dans un script shell à une ligne pour vous éviter d'avoir à retaper les arguments.

Cascabel
la source
1
Le globbing PS ne correspond pas aux fichiers cachés, donc si vous êtes obsessionnel, vous voudrez peut-être .!(.|)faire correspondre tout ce qui commence par un en .plus .et ...
Cascabel
Cela ne semble pas fonctionner pour les fichiers neufs ou supprimés dans les branches. J'obtiens des erreurs qui interrompent l'exécution du script, disant qu'il ne peut pas être différent.
Graham Christensen
2
@Graham: Je pense que ce que --je viens d'ajouter devrait résoudre ce problème.
Cascabel
1
Réponse géniale. Je voulais seulement montrer les noms (pas la différence réelle) donc j'ai dû ajouter --name-onlyà la toute fin également.
août
1
Après avoir joué avec, je veux juste ajouter que si vous changez le nom d'un fichier, il générera une erreur, mais tout ce que vous avez à faire est d'ajouter -- path/of/new/fileet il le comprendra :)
août
321

Sur la base de cette réponse, vous pouvez également utiliser:

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

C'est une nouvelle fonctionnalité git qui permet d'exclure certains chemins. Il devrait être plus fiable que divers oneliners shell.

Je poste ceci ici parce que cette question est toujours le hit n ° 1 pour "git diff exclude path".

cdleonard
la source
4
J'adore cette réponse. Si vous ajoutez des options, faites-le avant le double tiret. Ex: git diff previous_release current_release --name-status -- . ':!spec'
liamvictor
Je ne savais pas que je pouvais utiliser des noms de branche pour le current_releaseet previous_release- m'a fait sourire quand j'ai compris.
trueheart78
2
Ce qui a fonctionné pour moi git diff --stat dev -- . ':!/Mopy/Docs/*'. Ce qui n'a pas fonctionné pour moi git diff dev --stat -- . ':!('Mopy/Docs/Wrye Bash General Readme.html'|'Mopy/Docs/Wrye Bash Advanced Readme.html')'et les variations
Mr_and_Mrs_D
Très utile. Voici la syntaxe pour voir si des fichiers sont modifiés, autres que database.yml:git diff --check -- . ':!config/database.yml'
Dan Kohn
17
Peut également exclure plusieurs éléments comme git diff previous_release current_release -- . ':!file_a' ':!file_b'
suit
37

Si vous souhaitez spécifier plus d'un chemin à exclure dans un git diff, vous ajoutez simplement des paramètres d'exclusion supplémentaires à la fin, par exemple pour exclure tout ce qui se trouve dans les répertoires vendor et bin des stats: -

git diff --stat previous_release..current_release -- . ':!vendor' ':!bin'
David Graham
la source
33

Vous pouvez essayer de désactiver l'attribut diff pour tous les fichiers du répertoire lib.
.gitattributes:

lib/* -diff

racl101 ajoute dans les commentaires :

Juste pour ajouter à cela, pour ceux d'entre vous qui souhaitent limiter la git diffsortie de fichiers d'un type spécifique, dans un répertoire spécifique et ses sous-répertoires, comme tout le JavaScript généré par le regroupement de vos .jsfichiers par Webpack , par exemple, vous pouvez ajouter ceci à .gitattributes:

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

Ensuite, vous ne voyez pas tout ce bruit dans votre sortie git diff et cela s'affiche simplement comme suit: Binary files ... differce qui est plus utile.

VonC
la source
cela supprimerait les spécifications de tous mes diffs cependant. Je veux toujours voir mes diffs dans le dossier spec normalement, mais pas quand
j'exécute ce
2
@Mystr: Vous pouvez placer ce .gitattributesfichier dans une branche spéciale faite uniquement pour ce type de diff 'release';) Rebase cette branche spéciale par-dessus current_releaseet faites votre différence à partir de là.
VonC
Cela ne semble pas non plus fonctionner pour les fichiers supprimés entre les branches. Les fichiers supprimés affichent toujours la différence complète.
Graham Christensen
Ça ne marche pas pour moi. Les _ chemins sont-ils spéciaux? _site/* -diff
Marius
@MariusAndreiana Non, '_' n'est pas spécial. Pouvez-vous vérifier quelle règle gitattributes s'applique pour un fichier de ce dossier avec: git-scm.com/docs/git-check-attr
VonC
22

Git diff accepte désormais un format d'exclusion personnalisé: git diff -- ':(exclude)lib/*'

Soyez prudent si vous avez beaucoup de noms de dossiers répétitifs ('/ app', '/ lib', etc.), car cela exclura les fichiers relatifs au répertoire de travail actuel ET au répertoire racine de git.

MaxPRafferty
la source
1
vous manquez un point, ne devrait-il pas plutôt l'être git diff -- . ':(exclude)lib/*'?
Nicolas Dermine
1
@NicolasDermine Non, mais ce que vous avez écrit est équivalent. La partie "comprend" du chemin est également facultative. C'est pourquoi vous pouvez simplement faire git diffpour tout ce qui concerne votre chemin actuel, plutôt que d'exigergit diff -- .
MaxPRafferty
Remarque: sur les machines Windows, utilisez des guillemets doubles, commegit diff -- ":(exclude)lib/*"
cnlevy
Je ne sais pas pourquoi, mais pour moi, cela ne fonctionne qu'avec le point, comme suggéré par @NicolasDermine. J'utilise Cmder sur win10.
Olivvv
3

Par rapport au répertoire racine de git

git diff accepte une exclusion facultative

git diff -- ":(exclude)thingToExclude"

Vous voudrez peut-être ajouter des caractères génériques

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

Cibler des types de fichiers spécifiques

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

Du sucre syntaxique appliqué

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

Ou déposez un petit script pour vos fichiers dot

Tels que .bash_profileou.zshrc

gde() {
    : '
        git diff exclude files or folders
        usage:
        gde fileOrFolderNameToExclude
    '
    git diff -- ":!/\$1/"
}
Jasonleonhard
la source
-6
git diff app lib
Jed Schneider
la source