Wie kann ich überprüfen, ob ich nicht festgeschriebene Änderungen in meinem Git-Repository habe:
- Dem Index hinzugefügte, aber nicht festgeschriebene Änderungen
- Nicht verfolgte Dateien
aus einem Skript?
git-status
scheint mit git Version 1.6.4.2 immer Null zurückzugeben.
diff
das Vorhandensein oder Fehlen von Unterschieden anstelle der erfolgreichen Ausführung des Befehls angeben müssen, müssen Sie--exit-code
oder verwenden--quiet
. Git-Befehle stimmen im Allgemeinen sehr gut mit der Rückgabe eines Exit-Codes von Null oder Nicht-Null überein, um den Erfolg des Befehls anzuzeigen.Antworten:
Großartiges Timing! Ich habe vor ein paar Tagen einen Blog-Beitrag darüber geschrieben, als ich herausfand, wie ich meiner Eingabeaufforderung Informationen zum Git-Status hinzufügen kann.
Folgendes mache ich:
Für schmutzigen Status:
Für nicht verfolgte Dateien (Beachten Sie das
--porcelain
Flag, mitgit status
dem Sie eine schöne analysierbare Ausgabe erhalten):Obwohl dies
git diff --shortstat
bequemer ist, können Sie auchgit status --porcelain
schmutzige Dateien abrufen:Hinweis:
2>/dev/null
Hiermit werden die Fehlermeldungen herausgefiltert, sodass Sie diese Befehle für Nicht-Git-Verzeichnisse verwenden können. (Sie werden einfach0
für die Anzahl der Dateien zurückkehren.)Bearbeiten :
Hier sind die Beiträge:
Hinzufügen von Git-Statusinformationen zu Ihrer Terminal-Eingabeaufforderung
Verbesserte Git-fähige Shell-Eingabeaufforderung
quelle
__git_ps1
. Es werden Zweigstellennamen angezeigt, einschließlich einer Sonderbehandlung, wenn Sie gerade eine Neugründung, eine Am-Apply, eine Zusammenführung oder eine Halbierung durchführen.GIT_PS1_SHOWDIRTYSTATE
Außerdem können Sie die Umgebungsvariable so einstellen , dass ein Sternchen für nicht bereitgestellte Änderungen und ein Plus für bereitgestellte Änderungen angezeigt wird. (Ich denke, Sie können es auch dazu bringen, nicht verfolgte Dateien anzuzeigen und Ihnen einegit-describe
Ausgabe zu geben)git diff --shortstat
Gibt ein falsches Negativ aus, wenn sich bereits Änderungen im Index befinden.git status --porcelain
ist vorzuziehen, dagit diff --shortstat
neu erstellte leere Dateien nicht abgefangen werden. Sie können es in jedem sauberen Arbeitsbaum versuchen:touch foo && git diff --shortstat
Der Schlüssel zum zuverlässigen "Scripting" von Git liegt in der Verwendung der "Plumbing" -Befehle.
Die Entwickler achten beim Ändern der Installationsbefehle darauf, dass sie sehr stabile Schnittstellen bereitstellen (dh eine bestimmte Kombination aus Repository-Status, Standard, Befehlszeilenoptionen, Argumenten usw. erzeugt in allen Git-Versionen dieselbe Ausgabe, in denen der Befehl / Option existiert). Neue Ausgabevarianten in Installationsbefehlen können über neue Optionen eingeführt werden, dies kann jedoch keine Probleme für Programme mit sich bringen, die bereits für ältere Versionen geschrieben wurden (sie würden die neuen Optionen nicht verwenden, da sie nicht vorhanden waren (oder zumindest waren) nicht verwendet) zum Zeitpunkt der Erstellung des Skripts).
Leider sind die "alltäglichen" Git-Befehle die "Porzellan" -Befehle, so dass die meisten Git-Benutzer möglicherweise nicht mit den Installationsbefehlen vertraut sind. Die Unterscheidung zwischen Porzellan und Sanitärbefehl wird in der Haupt- Git-Manpage vorgenommen (siehe Unterabschnitte mit dem Titel Befehle auf hoher Ebene (Porzellan) und Befehle auf niedriger Ebene (Sanitär) .
Um sich über nicht genehmigte Änderungen zu informieren, müssen Sie wahrscheinlich
git diff-index
(Index (und möglicherweise verfolgte Teile des Arbeitsbaums) mit einem anderen Baum vergleichen (z. B.HEAD
)), möglicherweisegit diff-files
(Arbeitsbaum mit Index vergleichen) und möglicherweisegit ls-files
( Listendateien ; z. B. Liste nicht verfolgt) , nicht signierte Dateien).(Beachten Sie, dass in den folgenden Befehlen
HEAD --
anstelle von verwendet wird,HEAD
da sonst der Befehl fehlschlägt, wenn eine Datei mit dem Namen vorhanden istHEAD
.)Verwenden Sie Folgendes, um zu überprüfen, ob ein Repository Änderungen vorgenommen hat (noch nicht festgeschrieben):
0
wird, gab es keine Unterschiede (1
bedeutet, dass es Unterschiede gab).So überprüfen Sie, ob ein Arbeitsbaum Änderungen enthält, die bereitgestellt werden könnten:
git diff-index
(0
== keine Unterschiede;1
== Unterschiede).So überprüfen Sie, ob sich die Kombination aus Index und nachverfolgten Dateien im Arbeitsbaum in Bezug auf Folgendes geändert hat
HEAD
:HEAD
). In derselben Situation würden die beiden separaten Befehle Berichte über "vorhandene Unterschiede" zurückgeben.Sie haben auch nicht verfolgte Dateien erwähnt. Sie meinen möglicherweise "nicht verfolgt und nicht signiert", oder Sie meinen einfach "nicht verfolgt" (einschließlich ignorierter Dateien). In jedem Fall
git ls-files
ist das Werkzeug für den Job:Für "nicht verfolgt" (enthält ignorierte Dateien, falls vorhanden):
Für "nicht verfolgt und nicht signiert":
Mein erster Gedanke ist, nur zu überprüfen, ob diese Befehle ausgegeben wurden:
0
wird, gibt es keine nicht verfolgten Dateien. Wenn es mit beendet1
wird, gibt es nicht verfolgte Dateien.Es besteht eine geringe Wahrscheinlichkeit, dass dadurch abnormale Exits
git ls-files
in Berichte "Keine nicht verfolgten Dateien" übersetzt werden (beide führen zu Exits ungleich Null des obigen Befehls). Eine etwas robustere Version könnte folgendermaßen aussehen:git ls-files
Ausbreitung unerwarteter Fehler . In diesem Fall kann ein Exit ungleich Null bedeuten, dass nicht verfolgte Dateien vorhanden sind, oder dass ein Fehler aufgetreten ist. Wenn Sie stattdessen die Ergebnisse "Fehler" mit dem Ergebnis "Keine nicht verfolgten Dateien" kombinieren möchten, verwenden Sietest -n "$u"
(wobei exit von0
"einige nicht verfolgte Dateien" bedeutet und ungleich Null Fehler oder "keine nicht verfolgten Dateien" bedeutet).Eine andere Idee besteht darin
--error-unmatch
, einen Exit ungleich Null zu verursachen, wenn keine nicht verfolgten Dateien vorhanden sind. Dies birgt auch das Risiko, dass "keine nicht verfolgten Dateien" (Beenden1
) mit "Ein Fehler ist aufgetreten" (Beenden ungleich Null, aber wahrscheinlich128
) zusammengeführt werden. Die Überprüfung auf Exit-Codes von0
vs.1
vs. ungleich Null ist jedoch wahrscheinlich ziemlich robust:Jedes der oben genannten
git ls-files
Beispiele kann verwendet werden,--exclude-standard
wenn Sie nur nicht verfolgte und nicht signierte Dateien berücksichtigen möchten.quelle
git ls-files --others
gibt lokale untracked Dateien, während diegit status --porcelain
der akzeptierte Antwort alle die untracked Dateien gibt , die unter dem git - Repository sind. Ich bin nicht das, was das Originalplakat wollte, aber der Unterschied zwischen beiden ist interessant.--error-unmatch
. Versuchen Sie es (z. B.)git ls-files --other --error-unmatch --exclude-standard .
(beachten Sie die nachfolgende Periode, die sich auf die cwd bezieht; führen Sie diese aus dem Verzeichnis der obersten Ebene des Arbeitsbaums aus).git update-index -q --refresh
vor dem tundiff-index
, um einige „Fehlalarme“ zu vermeiden, die durch nicht übereinstimmende stat (2) -Informationen verursacht werden.git update-index
Notwendigkeit gebissen ! Dies ist wichtig, wenn etwas die Dateien berührt, ohne Änderungen vorzunehmen.--porcelain
Lösung listet alle nicht verfolgten Dateien auf, die im gesamten Git-Repository gefunden wurden (abzüglich der von Git ignorierten Dateien), selbst wenn Sie sich in einem der Unterverzeichnisse befinden.Angenommen, Sie sind auf Git 1.7.0 oder höher ...
Nachdem ich alle Antworten auf dieser Seite gelesen und einige Experimente durchgeführt habe, denke ich, dass die Methode, die die richtige Kombination aus Korrektheit und Kürze trifft, folgende ist:
Während Git eine Menge Nuancen zwischen dem zulässt, was verfolgt, ignoriert, nicht verfolgt, aber nicht signiert usw. ist, glaube ich, dass der typische Anwendungsfall für die Automatisierung von Build-Skripten besteht, bei denen Sie alles stoppen möchten, wenn Ihre Kaufabwicklung nicht sauber ist.
In diesem Fall ist es sinnvoll zu simulieren, was der Programmierer tun würde:
git status
Geben Sie die Ausgabe ein und sehen Sie sie sich an. Wir möchten uns jedoch nicht darauf verlassen, dass bestimmte Wörter--porcelain
angezeigt werden. Daher verwenden wir den in 1.7.0 eingeführten Modus. Wenn diese Option aktiviert ist, führt ein sauberes Verzeichnis zu keiner Ausgabe.Dann prüfen wir
test -n
, ob eine Ausgabe vorhanden war oder nicht.Dieser Befehl gibt 1 zurück, wenn das Arbeitsverzeichnis sauber ist, und 0, wenn Änderungen festgeschrieben werden müssen. Sie können das
-n
in a ändern ,-z
wenn Sie das Gegenteil wollen. Dies ist nützlich, um dies mit einem Befehl in einem Skript zu verketten. Beispielsweise:Dies besagt effektiv: "Entweder müssen keine Änderungen vorgenommen werden oder es wird ein Alarm ausgelöst." Je nach dem Skript, das Sie schreiben, ist dieser Einzeiler möglicherweise einer if-Anweisung vorzuziehen.
quelle
test -n "$(git diff origin/$branch)"
, um zu verhindern, dass lokale Commits in einer Bereitstellung zulässig sindEine Implementierung aus VonCs Antwort:
quelle
Ich habe ein paar dieser Antworten durchgesehen ... (und hatte verschiedene Probleme mit * nix und Windows, was eine Anforderung war, die ich hatte) ... fand, dass das Folgende gut funktioniert hat ...
So überprüfen Sie den Exit-Code in * nix
So überprüfen Sie den Exit-Code im Fenster $
Der von https://github.com/sindresorhus/pure/issues/115 Dank @paulirish an diesem Beitrag für die gemeinsame Nutzung
quelle
Warum nicht
git status
mit einem Skript einkapseln, das:Auf diese Weise können Sie diesen erweiterten Status in Ihrem Skript verwenden.
Wie 0xfe in seiner hervorragenden Antwort erwähnt ,
git status --porcelain
ist es für jede skriptbasierte Lösung von entscheidender Bedeutungquelle
Eine DIY-Möglichkeit, die aktualisiert wurde, um dem Vorschlag von 0xfe zu folgen
Wie von Chris Johnsen bemerkt , funktioniert dies nur auf Git 1.7.0 oder neuer.
quelle
--porcelain
Flagge hinzugefügt wurde? Funktioniert nicht mit 1.6.4.2.git status --short
dann.git status --porcelain
undgit status --short
wurden beide in 1.7.0 eingeführt.--porcelain
Es wurde speziell eingeführt, umgit status --short
das Format in Zukunft ändern zu können. Esgit status --short
würde also das gleiche Problem auftreten wiegit status
(die Ausgabe kann sich jederzeit ändern, da es sich nicht um einen Installationsbefehl handelt).Ich brauchte ziemlich oft einen einfachen Weg, um einen Build fehlzuschlagen, wenn am Ende der Ausführung modifizierte oder nicht verfolgte Dateien vorhanden sind, die nicht ignoriert werden.
Dies ist sehr wichtig, um zu vermeiden, dass Builds Reste produzieren.
Bisher sieht der beste Befehl, den ich letztendlich verwendet habe, so aus:
Es mag etwas komplex aussehen und ich würde mich freuen, wenn jemand eine kurzgeschlossene Variante findet, die das gewünschte Verhalten beibehält:
quelle
@ eduard-wirch Antwort war ziemlich vollständig, aber da ich beide gleichzeitig überprüfen wollte, ist hier meine endgültige Variante.
Wenn die Ausführung nicht mit set -e oder einem gleichwertigen Element ausgeführt wird, können wir stattdessen eine ausführen
u="$(git ls-files --others)" || exit 1
(oder zurückkehren, wenn dies für eine verwendete Funktion funktioniert).Untracked_files wird also nur gesetzt, wenn der Befehl ordnungsgemäß erfolgreich ist.
Danach können wir nach beiden Eigenschaften suchen und eine Variable (oder was auch immer) festlegen.
quelle
Dies ist eine Shell-freundlichere Variante, um herauszufinden, ob nicht verfolgte Dateien im Repository vorhanden sind:
Dies führt nicht zu einem zweiten Prozess
grep
und erfordert keine Überprüfung, ob Sie sich in einem Git-Repository befinden oder nicht. Das ist praktisch für Shell-Eingabeaufforderungen usw.quelle
Sie können auch tun
. Am Ende wird das Wort "-dirty" angehängt, wenn ein schmutziger Arbeitsbaum erkannt wird. Nach
git-describe(1)
:. Vorsichtsmaßnahme: Nicht verfolgte Dateien gelten nicht als "schmutzig", da sie sich, wie in der Manpage angegeben, nur um den Arbeitsbaum kümmern.
quelle
Es kann eine bessere Kombination von Antworten aus diesem Thread sein .. aber das funktioniert für mich ... für
.gitconfig
‚s[alias]
Abschnitt ...quelle
Der einfachste automatische Test, den ich verwende, um einen verschmutzten Zustand zu erkennen = alle Änderungen, einschließlich nicht verfolgter Dateien :
HINWEIS:
add --all
diff-index
bemerkt nicht verfolgte Dateien nicht.git reset
nach dem Testen des Fehlercodes, um alles wieder zu entfernen.quelle
Hier ist der beste und sauberste Weg. Die ausgewählte Antwort hat aus irgendeinem Grund bei mir nicht funktioniert. Sie hat keine Änderungen erfasst, bei denen es sich um neue Dateien handelt, die nicht festgeschrieben wurden.
quelle