Faire “git log” ignorer les changements pour certains chemins

Comment puis-je créer uniquement des commits qui ont changé des fichiers autres que ceux que je spécifie?

Avec git log , je peux filtrer les commits que je vois à ceux qui touchent un ensemble donné de chemins. Ce que je veux, c’est inverser ce filtre pour ne valider que les chemins tactiles autres que ceux spécifiés.

Je peux obtenir ce que je veux avec

 git log --format="%n/%n%H" --name-only | ~/filter-log.pl | git log --stdin --no-walk 

filter-log.pl est:

 #!/usr/bin/perl use ssortingct; use warnings; $/ = "\n/\n"; ; while () { my ($commit, @files) = split /\n/, $_; if (grep { $_ && $_ !~ m[^(/$|.etckeeper$|lvm/(archive|backup)/)] } @files) { print "$commit\n"; } } 

sauf que je veux quelque chose d’un peu plus élégant que ça.

Notez que je ne demande pas comment faire git ignorer les fichiers. Ces fichiers doivent être suivis et validés. C’est juste que, la plupart du temps, je ne suis pas intéressé à les voir.

Question connexe: Comment inverser `git log –grep = ` ou Comment afficher les journaux git qui ne correspondent pas à un modèle C’est la même question à l’exception des messages de validation plutôt que des chemins.

Discussion du forum sur ce sujet à partir de 2008: Re: Exclure les fichiers de git-diff Cela semblait prometteur mais le fil semble avoir séché.

Il est maintenant implémenté (git 1.9 / 2.0, T1 2014) avec l’introduction de pathspec magic :(exclude) et sa forme courte:! dans commit ef79b1f et comm 1649612 , par Nguyễn Thái Ngọc Duy ( pclouds ) .

Vous pouvez maintenant tout enregistrer sauf un contenu de sous-dossier:

 git log -- . ":(exclude)sub" git log -- . ":!sub" 

Ou vous pouvez exclure des éléments spécifiques dans ce sous-dossier

  • un fichier spécifique:

     git log -- . ":(exclude)sub/sub/file" git log -- . ":!sub/sub/file" 
  • tout fichier donné dans le sub :

     git log -- . ":(exclude)sub/*file" git log -- . ":!sub/*file" git log -- . ":(exclude,glob)sub/*/file" 

Vous pouvez rendre cette exclusion insensible!

 git log -- . ":(exclude,icase)SUB" 

Comme Kenny Evitt l’a noté

Si vous utilisez Git dans un shell Bash, utilisez ':!sub' ou ":\!sub" au lieu de cela pour éviter les erreurs de bash: ... event not found


Note: Git 2.13 (Q2 2017) appenda un synonyme ^ à !

Voir commit 859b7f1 , commit 42ebeb9 (08 févr. 2017) par Linus Torvalds ( torvalds ) .
(Fusionné par Junio ​​C Hamano – gitster – dans commit 015fba3 , 27 février 2017)

pathspec magic: ajoutez ‘ ^ ‘ comme alias pour ‘ !

Le choix de ‘ ! «pour un pathspec négatif, vous finissez non seulement par ne pas correspondre à ce que nous faisons pour les révisions, mais c’est également un horrible caractère pour l’expansion du shell car il doit être cité.

Ajoutez donc ‘ ^ ‘ comme alias alternatif pour une entrée pathspec exclue.

tl; dr: shopt -s extglob && git log !(unwanted/glob|another/unwanted/glob) / shopt -s extglob && git log !(unwanted/glob|another/unwanted/glob)

Si vous utilisez Bash, vous devriez pouvoir utiliser la fonctionnalité de globalisation étendue pour obtenir uniquement les fichiers dont vous avez besoin:

 $ cd -- "$(mktemp --directory)" $ git init Initialized empty Git repository in /tmp/tmp.cJm8k38G9y/.git/ $ mkdir aye bee $ echo foo > aye/foo $ git add aye/foo $ git commit -m "First commit" [master (root-commit) 46a028c] First commit 0 files changed create mode 100644 aye/foo $ echo foo > bee/foo $ git add bee/foo $ git commit -m "Second commit" [master 30b3af2] Second commit 1 file changed, 1 insertion(+) create mode 100644 bee/foo $ shopt -s extglob $ git log !(bee) commit ec660acdb38ee288a9e771a2685fe3389bed01dd Author: My Name  Date: Wed Jun 5 10:58:45 2013 +0200 First commit 

Vous pouvez combiner ceci avec globstar pour une action récursive.

Vous pouvez ignorer temporairement les modifications dans un fichier avec:

 git update-index --skip-worktree path/to/file 

En allant plus loin, toutes les modifications apscopes à ces fichiers seront ignorées par git status , git commit -a , etc. Lorsque vous êtes prêt à valider ces fichiers, inversez-le:

 git update-index --no-skip-worktree path/to/file 

et commettre comme d’habitude.