J'ai un script qui exécute rsync
avec un répertoire de travail Git comme destination. Je veux que le script ait un comportement différent selon que le répertoire de travail est propre (aucune modification à valider) ou non. Par exemple, si la sortie de git status
est comme ci-dessous, je veux que le script se termine:
git status
Already up-to-date.
# On branch master
nothing to commit (working directory clean)
Everything up-to-date
Si le répertoire n'est pas propre, j'aimerais qu'il exécute quelques commandes supplémentaires.
Comment puis-je vérifier la sortie comme ci-dessus dans un script Shell?
Analyser la sortie de git status
est une mauvaise idée car la sortie est destinée à être lisible par l'homme, pas lisible par la machine. Il n'y a aucune garantie que la sortie restera la même dans les futures versions de Git ou dans des environnements configurés différemment.
commentaire UVV est sur la bonne voie, mais malheureusement le code retour de git status
ne change pas en cas de modifications non validées. Il fournit cependant les --porcelain
, qui provoque la sortie de git status --porcelain
à formater dans un format facile à analyser pour les scripts, et resteront stables dans toutes les versions de Git et quelle que soit la configuration de l'utilisateur.
Nous pouvons utiliser une sortie vide de git status --porcelain
comme indicateur qu'aucune modification ne doit être validée:
if [ -z "$(git status --porcelain)" ]; then
# Working directory clean
else
# Uncommitted changes
fi
Si nous ne nous soucions pas des fichiers non suivis dans le répertoire de travail, nous pouvons utiliser le --untracked-files=no
option pour ignorer ceux-ci:
if [ -z "$(git status --untracked-files=no --porcelain)" ]; then
# Working directory clean excluding untracked files
else
# Uncommitted changes in tracked files
fi
Pour rendre cela plus robuste contre des conditions qui réellement provoquent git status
pour échouer sans sortie vers stdout
, nous pouvons affiner la vérification pour:
if output=$(git status --porcelain) && [ -z "$output" ]; then
# Working directory clean
else
# Uncommitted changes
fi
Il convient également de noter que, bien que git status
ne donne pas de code de sortie significatif lorsque le répertoire de travail est impur, git diff
fournit le --exit-code
, ce qui le rend similaire à l'utilitaire diff , c'est-à-dire qu'il quitte avec le statut 1
quand il y avait des différences et 0
quand aucun n'a été trouvé.
À l'aide de cela, nous pouvons vérifier les modifications non planifiées avec:
git diff --exit-code
et des changements échelonnés mais non validés avec:
git diff --cached --exit-code
Bien que git diff
peut signaler des fichiers non suivis dans des sous-modules via des arguments appropriés pour --ignore-submodules
, malheureusement, il semble qu'il n'y ait aucun moyen de le signaler sur les fichiers non suivis dans le répertoire de travail réel. Si les fichiers non suivis du répertoire de travail sont pertinents, git status --porcelain
est probablement le meilleur choix.
Utilisation:
git diff-index --quiet HEAD
Le code retour reflète l'état du répertoire de travail (0 = propre, 1 = sale). Les fichiers non suivis sont ignorés.
Extension mineure à celle d'André excellente réponse .
C'est une façon d'évaluer les résultats et d'éviter également un piège si vous êtes dans un script qui a précédemment publié set -e .
Les fichiers non suivis sont ignorés.
set +e
git diff-index --quiet HEAD
if [ $? == 1 ] ; then
set -e
GIT_MODS="dirty"
else
set -e
GIT_MODS="clean"
fi
J'ai fait ce genre de test
TEST=$(git status --porcelain|wc -l)
if [ 0 -eq $TEST ]; then
echo "No changes"
else
echo "Changes"
fi
#!/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