Erklären Sie, welche Gitignore-Regel meine Datei ignoriert

310

Gibt es eine Möglichkeit zu erkennen, warum eine Datei von git ignoriert wird (dh welche Regel in einer .gitignoreDatei bewirkt, dass die Datei ignoriert wird)?

Stellen Sie sich vor, ich habe dieses (oder ein viel komplexeres Szenario mit Hunderten von Ordnern und Dutzenden von .gitignoreDateien:

/
-.gitignore
-folder/
    -.gitignore
    -subfolder/
              -.gitignore
              -file.txt

Wenn ich git add folder/subfolder/file.txtgit starte, kann ich mich darüber beschweren, dass es ignoriert wird:

The following paths are ignored by one of your .gitignore files:
folder/subfolder/file.txt
Use -f if you really want to add them.

Gibt es eine Möglichkeit zu wissen, welche der möglichen .gitignoreeine Regel haben, um diese Datei zu ignorieren und auch die Regel anzuzeigen? Mögen:

The following paths are ignored by your folder/.gitignore file (line 12: *.txt)
folder/subfolder/file.txt
Use -f if you really want to add them.

Oder nur:

$ git why-is-ignored folder/subfolder/file.txt
folder/.gitignore:12:*.txt
Carlos Campderrós
quelle
4
Hinweis: git check-ignorewird bald (git1.8.5 / 1.9) eine --no-indexOption haben. Siehe meine Antwort unten
VonC
Hinweis: GIT_TRACE_EXCLUDE=1 git statuswird in Kürze eine zusätzliche Möglichkeit zum Debuggen von .gitignoreRegeln sein. Siehe meine bearbeitete Antwort unten
VonC
Relevanter Blogbeitrag: danielcompton.net/2016/04/21/… .
krlmlr

Antworten:

643
git check-ignore -v filename

Weitere Informationen finden Sie in der Manpage .

Die ursprüngliche Antwort folgt:

git bietet derzeit so etwas nicht an. Nachdem ich Ihre Frage gesehen hatte, googelte ich und stellte fest, dass diese Funktion bereits 2009 angefordert und teilweise implementiert wurde . Nachdem ich den Thread gelesen hatte, wurde mir klar, dass es nicht zu viel Arbeit sein würde, ihn richtig zu machen. Deshalb habe ich mit der Arbeit an einem Patch begonnen und hoffe, dass er in den nächsten ein oder zwei Tagen fertig sein wird. Ich werde diese Antwort aktualisieren, wenn sie fertig ist.

UPDATE: Wow, das war viel schwieriger als ich erwartet hatte. Die Innereien von git's Ausschlussbehandlung sind ziemlich kryptisch. Wie auch immer, hier ist eine fast abgeschlossene Reihe von Commits, die für die heutige vorgelagerte masterNiederlassung gelten. Die Testsuite ist zu 99% vollständig, aber ich habe die Bearbeitung der --stdinOption noch nicht abgeschlossen. Hoffentlich schaffe ich das dieses Wochenende und sende meine Patches dann an die Git-Mailingliste.

In der Zwischenzeit würde ich es auf jeden Fall begrüßen, von jedem zu testen, der dazu in der Lage ist - klonen Sie einfach von meiner gitGabel , überprüfen Sie den check-ignoreZweig und kompilieren Sie ihn wie gewohnt.

UPDATE 2: Fertig! Die neueste Version ist wie oben beschrieben auf Github und ich habe die Patch-Serie zur Peer-Review an die Git-Mailingliste gesendet . Mal sehen, was sie denken ...

UPDATE 3: Nach einigen weiteren Monaten des Hackens / Patch-Reviews / Diskutierens / Wartens freue ich mich, sagen zu können, dass diese Funktion jetzt den masterZweig von git erreicht hat und in der nächsten Version (1.8.2, voraussichtlich 8.) verfügbar sein wird März 2013). Hier ist die check-ignoreHandbuchseite . Puh, das war viel mehr Arbeit als ich erwartet hatte!

UPDATE 4: Wenn Sie an der vollständigen Geschichte über die Entwicklung dieser Antwort und die Implementierung der Funktion interessiert sind, lesen Sie Episode 32 des GitMinutes-Podcasts .

Adam Spires
quelle
2
Ich benutze 1.8.2 und git check-ignoremache nichts.
Zakdances
3
@yourfriendzak Ist ohne Zweifel git check-ignorevorhanden und arbeitet in 1.8.2. Wenn das Verhalten nicht Ihren Erwartungen entspricht, empfehle ich Ihnen, die Handbuchseite (erneut) zu lesen. Wenn dies immer noch nicht der Fall ist, senden Sie bitte einen ordnungsgemäßen Fehlerbericht auf der Git-Mailingliste. Nur zu sagen, dass es nichts tut, ist nicht sehr hilfreich. Ich gehe davon aus, dass Sie es wahrscheinlich in einer nicht ignorierten Datei ausgeführt haben und fälschlicherweise eine Ausgabe erwarten (obwohl ich --show-unmatchedden --verboseAusgabemodus wahrscheinlich in Zukunft unterstützen werde).
Adam Spires
1
@AdamSpiers du hast recht. Ich hätte angeben sollen, dass beim Ausführen des Befehls nichts gedruckt wird. Keine Fehlermeldung, keine Erfolgsmeldung, keine Infos. Nur die nächste leere Eingabeaufforderung wird angezeigt. Kann ich also zu Recht davon ausgehen, dass "keine Ausgabe" unter bestimmten Umständen ein erwartetes Verhalten ist?
Zakdances
1
@AdamSpiers vielen Dank dafür! Nach drei Tagen der Untersuchung haben Sie mir gerade geholfen, die Ursache für einen fehlerhaften Build aufgrund einer global ignorierten Datei in .gitignore_global zu finden! Ich wusste nicht einmal, dass das eine Sache ist!
BenBtg
3
Es ist nicht alltäglich, dass ein Stack Overflow-Entwickler so viele Änderungen vornimmt, um eine Entwicklerfunktion zu implementieren. Wow und Respekt.
user3613932
18

Update Git 2.8 (März 2016):

GIT_TRACE_EXCLUDE=1 git status

Siehe " Eine Möglichkeit zum Überprüfen der .gitignoreDatei "

Dies ist komplementär zu dem git check-ignore -vunten beschriebenen.


Ursprüngliche Antwort: September 2013 (Git 1.8.2, dann 1.8.5+):

git check-ignoreverbessert sich wieder in git 1.8.5 / 1.9 (Q4 2013) :

" git check-ignore" folgt der gleichen Regel wie " git add" und " git status", da der Ignorier- / Ausschlussmechanismus keine Wirkung auf bereits verfolgte Pfade hat.
Mit der --no-indexOption " " kann diagnostiziert werden, welche Pfade, die ignoriert werden sollten, fälschlicherweise zum Index hinzugefügt wurden .

Siehe Commit 8231fa6 von https://github.com/flashydave :

check-ignorezeigt derzeit, wie .gitignoreRegeln nicht verfolgte Pfade behandeln würden. Verfolgte Pfade erzeugen keine nützliche Ausgabe.
Dies verhindert das Debuggen, warum ein Pfad unerwartet verfolgt wurde, es sei denn, dieser Pfad wird zuerst mit aus dem Index entfernt git rm --cached <path>.

Die Option --no-indexweist den Befehl an, die Prüfung für den Pfad im Index zu umgehen, und ermöglicht daher auch die Prüfung von verfolgten Pfaden.

Obwohl dieses Verhalten von den Merkmalen abweicht git addund git statussein Anwendungsfall wahrscheinlich keine Verwirrung beim Benutzer hervorruft.

Testskripte werden erweitert, um diese Option mit den Standard-Ignorierungen zu vergleichen und ein korrektes Verhalten sicherzustellen.


--no-index::

Schauen Sie nicht in den Index, wenn Sie die Prüfungen durchführen.
Dies kann verwendet werden:

  • zu debuggen, warum ein Pfad von z. B. verfolgt wurde git add .und von den Regeln nicht ignoriert wurde, wie vom Benutzer oder erwartet
  • beim Entwickeln von Mustern einschließlich Negation, um einem zuvor hinzugefügten Pfad zu entsprechen git add -f.
VonC
quelle
4

Ich kann auf der Manpage nichts finden, aber hier ist ein schnelles und schmutziges Skript, das Ihre Datei in jedem übergeordneten Verzeichnis überprüft, um festzustellen, ob sie hinzugefügt werden kann. Führen Sie es in dem Verzeichnis aus, das die Problemdatei enthält:

test-add.sh STOP_DIR FILENAME

Dabei STOP_DIRbefindet sich das Verzeichnis der obersten Ebene des Git-Projekts und FILENAMEder Name der Problemdatei (ohne Pfad). Es erstellt eine leere Datei mit demselben Namen auf jeder Hierarchieebene (falls nicht vorhanden) und versucht git add -nzu prüfen, ob sie hinzugefügt werden kann (sie bereinigt nach sich selbst). Es gibt so etwas aus wie:

FAILED:    /dir/1/2/3
SUCCEEDED: /dir/1/2

Das Skript:

#!/usr/bin/env bash
TOP=$1
FILE=$2
DIR=`pwd`
while : ; do
  TMPFILE=1
  F=$DIR/$FILE
  if [ ! -f $F ]; then
    touch $F
    TMPFILE=0
  fi
  git add -n $F >/dev/null 2>&1
  if [ $? = 0 ]; then
    echo "SUCCEEDED: $DIR"
  else
    echo "FAILED:    $DIR"
  fi
  if [ $TMPFILE = 0 ]; then
    rm $F
  fi
  DIR=${DIR%/*}
  if [ "$DIR" \< "$TOP" ]; then
    break
  fi
done 
Edoloughlin
quelle
1

Um die Hauptantwort der Verwendung hinzuzufügen git check-ignore -v filename(danke übrigens), stellte ich fest, dass meine .gitignore-Datei alles blockierte, weil nach einem Platzhalter eine neue Zeile stand, also hatte ich:

* .sublime-project

als Beispiel. Ich habe gerade die Newline entfernt und voila! Es wurde behoben.

rekordboy
quelle