it-swarm.com.de

Stellen Sie fest, ob das Git-Arbeitsverzeichnis in einem Skript sauber ist

Ich habe ein Skript, das rsync mit einem Git-Arbeitsverzeichnis als Ziel ausführt. Ich möchte, dass sich das Skript unterschiedlich verhält, je nachdem, ob das Arbeitsverzeichnis sauber ist (keine Änderungen am Commit) oder nicht. Zum Beispiel, wenn die Ausgabe von git status ist wie folgt, ich möchte, dass das Skript beendet wird:

git status
Already up-to-date.
# On branch master
nothing to commit (working directory clean)
Everything up-to-date

Wenn das Verzeichnis nicht sauber ist, möchte ich, dass es weitere Befehle ausführt.

Wie kann ich in einem Shell-Skript nach Ausgaben wie oben suchen?

102
brentwpeterson

Das Analysieren der Ausgabe von git status ist eine schlechte Idee, da die Ausgabe für Menschen lesbar und nicht maschinenlesbar sein soll. Es gibt keine Garantie dafür, dass die Ausgabe in zukünftigen Versionen von Git oder in anders konfigurierten Umgebungen gleich bleibt.

VVs Kommentar ist auf dem richtigen Weg, aber leider ändert sich der Rückkehrcode von git status nicht, wenn nicht festgeschriebene Änderungen vorliegen. Es bietet jedoch die Option --porcelain , mit der die Ausgabe von git status --porcelain in einem einfach zu analysierenden Format für Skripte formatiert wird, = und bleibt in allen Git-Versionen und unabhängig von der Benutzerkonfiguration stabil.

Wir können die leere Ausgabe von git status --porcelain als Indikator dafür verwenden, dass keine Änderungen festgeschrieben werden müssen:

if [ -z "$(git status --porcelain)" ]; then 
  # Working directory clean
else 
  # Uncommitted changes
fi

Wenn uns nicht verfolgte Dateien im Arbeitsverzeichnis egal sind, können wir die Option --untracked-files=no verwenden, um diese zu ignorieren:

if [ -z "$(git status --untracked-files=no --porcelain)" ]; then 
  # Working directory clean excluding untracked files
else 
  # Uncommitted changes in tracked files
fi

Um dies gegenüber Bedingungen robuster zu machen, die dazu führen, dass tatsächlichgit status fehlschlägt, ohne dass eine Ausgabe an stdout erfolgt, können wir die Prüfung verfeinern auf:

if output=$(git status --porcelain) && [ -z "$output" ]; then
  # Working directory clean
else 
  # Uncommitted changes
fi

Es ist auch erwähnenswert, dass git status zwar keinen aussagekräftigen Exit-Code liefert, wenn das Arbeitsverzeichnis unsauber ist, git diff jedoch --exit-code bereitstellt Option, mit der es sich ähnlich wie das Dienstprogramm diff verhält, dh mit dem Status 1 beendet wird, wenn es Unterschiede gab, und 0, wenn keine gefunden wurden.

Auf diese Weise können wir nach nicht bereitgestellten Änderungen suchen mit:

git diff --exit-code

und inszenierte, aber nicht festgeschriebene Änderungen mit:

git diff --cached --exit-code

Obwohl git diff über nicht verfolgte Dateien in Submodulen über entsprechende Argumente an --ignore-submodules berichten kann, scheint es leider keine Möglichkeit zu geben, über nicht verfolgte Dateien in zu berichten das eigentliche Arbeitsverzeichnis. Wenn nicht verfolgte Dateien im Arbeitsverzeichnis relevant sind, ist git status --porcelain wahrscheinlich die beste Wahl.

160
Thomas Nyman

Verwenden:

git diff-index --quiet HEAD

Der Rückkehrcode gibt den Status des Arbeitsverzeichnisses wieder (0 = sauber, 1 = schmutzig). Nicht verfolgte Dateien werden ignoriert.

25
André van Herk

Kleinere Erweiterung auf André's ausgezeichnet Antwort .

Dies ist eine Möglichkeit, die Ergebnisse auszuwerten und eine Gefahr zu vermeiden, wenn Sie sich in einem Skript befinden, das zuvor set -e ausgegeben hat.

Nicht verfolgte Dateien werden ignoriert.

set +e
git diff-index --quiet HEAD

if [ $? == 1 ] ; then
  set -e
  GIT_MODS="dirty"
else
  set -e
  GIT_MODS="clean"
fi
1
orion elenzil

Ich habe diese Art von Test gemacht

TEST=$(git status --porcelain|wc -l)
if [ 0 -eq $TEST ]; then
   echo "No changes"
else
   echo "Changes"
fi 
1
PHZ.fi-Pharazon
#!/bin/bash
echo "First arg: $1"

cd $1

bob="Already up-to-date."
echo $bob

echo $(git pull) > s.txt
cat s.txt
if [ "$(cat s.txt)" == "$bob" ]
then
echo "up"
else
echo "not up"
fi
rm -rf s.txt
0
Robert A