Es ist jetzt implementiert (git 1.9 / 2.0, Q1 2014) mit der Einführung pathspec magic :(exclude)und seiner Kurzform:! in commit ef79b1f und commit 1649612 von
Nguyễn Thái Ngọc Duy ( pclouds) . Die Dokumentation finden Sie hier .
Sie können jetzt alles außer dem Inhalt eines Unterordners protokollieren:
git log -- . ":(exclude)sub"
git log -- . ":!sub"
Oder Sie können bestimmte Elemente in diesem Unterordner ausschließen
eine bestimmte Datei:
git log -- . ":(exclude)sub/sub/file"
git log -- . ":!sub/sub/file"
jede gegebene Datei innerhalb sub:
git log -- . ":(exclude)sub/*file"
git log -- . ":!sub/*file"
git log -- . ":(exclude,glob)sub/*/file"
Sie können diesen Ausschlussfall unempfindlich machen!
git log -- . ":(exclude,icase)SUB"
Wie Kenny Evitt bemerkte
Wenn Sie Git in einer Bash-Shell ausführen, verwenden Sie stattdessen ':!sub'oder ":\!sub", um Fehler zu vermeidenbash: ... event not found
Hinweis: Git 2,13 (Q2 2017) ein Synonym hinzufügen wird ^zu!
Siehe Commit 859b7f1 , Commit 42ebeb9 (08. Februar 2017) von Linus Torvalds ( torvalds) .
(Zusammengeführt von Junio C Hamano - gitster- in Commit 015fba3 , 27. Februar 2017)
pathspec magic: füge ' ^' als Alias für ' !' hinzu
Die Wahl von ' !' für eine negative Pfadspezifikation entspricht nicht nur nicht dem, was wir für Revisionen tun, sondern ist auch ein schrecklicher Charakter für die Shell-Erweiterung, da sie zitiert werden muss.
^Fügen Sie daher ' ' als alternativen Alias für einen ausschließenden Pfadspezifikationseintrag hinzu.
Beachten Sie, dass vor Git 2.28 (Q3 2020) die Verwendung einer negativen Pfadspezifikation beim Sammeln von Pfaden, einschließlich nicht verfolgter Pfade im Arbeitsbaum, unterbrochen wurde.
Siehe Commit f1f061e (05. Juni 2020) von Elijah Newren ( newren) .
(Zusammengeführt von Junio C Hamano - gitster- in Commit 64efa11 , 18. Juni 2020)
dir: Fix Behandlung von negierten Pathspecs
Berichtet von: John Millikin
Unterzeichnet von: Elijah Newren
do_match_pathspec()begann das Leben als match_pathspec_depth_1()und für die Richtigkeit sollte nur von gerufen werden match_pathspec_depth(). match_pathspec_depth()wurde später in umbenannt match_pathspec(), daher ist die Invariante, die wir heute erwarten, dass do_match_pathspec()es keine direkten Anrufer außerhalb von gibt match_pathspec().
Leider ging diese Absicht mit der Umbenennung der beiden Funktionen verloren, und zusätzliche Aufrufe do_match_pathspec()wurden in den Commits 75a6315f74 hinzugefügt (" ls-files: Pfadspezifikationsübereinstimmung für Submodule hinzufügen", 2016-10-07, Git v2.11.0-rc0 - Zusammenführung in aufgeführt Batch # 11 ) und 89a1f4aaf7 (" dir: Wenn unsere Pfadspezifikation möglicherweise mit Dateien unter einem Verzeichnis übereinstimmt, greifen Sie darauf zurück", 2019-09-17, Git v2.24.0-rc0).
do_match_pathspec()Hatte natürlich einen wichtigen Vorteil gegenüber match_pathspec()- match_pathspec()würde Flags auf einen von zwei Werten fest codieren , und diese neuen Anrufer mussten einen anderen Wert für Flags übergeben.
Auch wenn der do_match_pathspec()direkte Aufruf falsch war, gab es wahrscheinlich keinen Unterschied in der beobachtbaren fill_diretory()Endausgabe , da der Fehler nur bedeutete, dass er in nicht benötigte Verzeichnisse zurückkehren würde.
Da nachfolgende Überprüfungen der Pfadübereinstimmung einzelner Pfade unter dem Verzeichnis dazu führen würden, dass diese zusätzlichen Pfade herausgefiltert werden, bestand der einzige Unterschied zur Verwendung der falschen Funktion in einer unnötigen Berechnung.
Der zweite dieser schlechten Anrufe do_match_pathspec()betraf - entweder durch direkte Bewegung oder durch Kopieren + Bearbeiten - eine Reihe späterer Refaktoren.
Siehe Commits 777b420347 (" dir: synchronize treat_leading_path()and read_directory_recursive()", 2019-12-19, Git v2.25.0-rc0 - merge ), 8d92fb2927 (" dir: Exponentialalgorithmus durch einen linearen ersetzen", 2020-04-01, Git v2.27.0 -rc0 - Zusammenführung in Stapel 5 aufgelistet ) und 95c11ecc73 ("Fehleranfällige fill_directory()API korrigieren ; nur Übereinstimmungen zurückgeben", 2020-04-01, Git v2.27.0-rc0 - Zusammenführung in Stapel 5 aufgeführt ) .
Die letzte davon führte die Verwendung von do_match_pathspec()für eine einzelne Datei ein und führte somit dazu, dass einzelne Pfade zurückgegeben wurden, die nicht sein sollten.
Das Problem beim Aufrufen do_match_pathspec()statt match_pathspec()ist, dass alle negierten Muster wie '`:! Unerwünschter_Pfad`` ignoriert werden .
Fügen Sie eine neue match_pathspec_with_flags()Funktion hinzu, um die Anforderungen der Angabe spezieller Flags zu erfüllen, während negierte Muster weiterhin korrekt überprüft werden. Fügen Sie oben einen großen Kommentar hinzu do_match_pathspec(), um zu verhindern, dass andere sie missbrauchen, und korrigieren Sie aktuelle Anrufer, do_match_pathspec()um stattdessen entweder match_pathspec()oder zu verwenden match_pathspec_with_flags().
Ein letzter Hinweis ist, dass DO_MATCH_LEADING_PATHSPECbei der Arbeit mit besonders berücksichtigt werden muss DO_MATCH_EXCLUDE.
Der Punkt DO_MATCH_LEADING_PATHSPECist, wenn wir eine Pfadspezifikation wie haben
*/Makefile
und wir überprüfen einen Verzeichnispfad wie
src/module/component
dass wir es als Übereinstimmung betrachten wollen, damit wir in das Verzeichnis zurückkehren, weil es _might_ eine Datei hat, die Makefileirgendwo unten benannt ist.
Wenn wir jedoch ein Ausschlussmuster verwenden, dh wir haben eine Pfadspezifikation wie
:(exclude)*/Makefile
Wir wollen NICHT sagen, dass ein Verzeichnispfad wie
src/module/component
ist eine (negative) Übereinstimmung.
Während sich unter diesem Verzeichnis möglicherweise eine Datei mit dem Namen "Makefile" befindet, können sich auch andere Dateien befinden, und wir können nicht alle Dateien in diesem Verzeichnis vorbeugend ausschließen. Wir müssen einzelne Dateien rekursieren und dann überprüfen.
Passen Sie die DO_MATCH_LEADING_PATHSPECLogik so an, dass sie nur für positive Pfadspezifikationen aktiviert wird.
!f() { git log ... | path/to/filter-log.pl "$@" | git log --stdin --no-walk; foder sogar diesen Pipeline-Teil in das Skript einbinden.