La clé d'un «script» fiable de Git est d'utiliser les commandes de «plomberie».
Les développeurs prennent soin lors du changement des commandes de plomberie pour s'assurer qu'ils fournissent des interfaces très stables (c'est-à-dire qu'une combinaison donnée d'état du référentiel, stdin, options de ligne de commande, arguments, etc. produira la même sortie dans toutes les versions de Git où la commande / existe). De nouvelles variations de sortie dans les commandes de plomberie peuvent être introduites via de nouvelles options, mais cela ne peut pas poser de problèmes pour les programmes qui ont déjà été écrits sur des versions plus anciennes (ils n'utiliseraient pas les nouvelles options, car elles n'existaient pas (ou du moins étaient non utilisé) au moment de l’écriture du script).
Malheureusement, les commandes Git «quotidiennes» sont les commandes «porcelaine», donc la plupart des utilisateurs de Git peuvent ne pas être familiers avec les commandes de plomberie. La distinction entre la porcelaine et la commande de plomberie est faite dans la page de manuel principale de git (voir les sous-sections intitulées Commandes de haut niveau (porcelaine) et Commandes de bas niveau (plomberie) .
Pour en savoir plus sur les modifications non validées, vous aurez probablement besoin de git diff-index
(comparer l'index (et peut-être des morceaux d'arbre de travail suivis) à d'autres arborescents (par exemple HEAD
)), peut-être git diff-files
(comparer l'arbre de travail à l'index), et éventuellement git ls-files
(lister les fichiers; par exemple, lister les non suivis) , fichiers non ignorés).
(Notez que dans les commandes ci-dessous, HEAD --
est utilisé à la place de HEAD
car sinon la commande échoue s'il y a un fichier nommé HEAD
.)
Pour vérifier si un référentiel a des modifications par étapes (pas encore validées), utilisez ceci:
git diff-index --quiet --cached HEAD --
- S'il sort avec
0
alors il n'y a pas de différences (cela 1
signifie qu'il y a des différences).
Pour vérifier si une arborescence de travail comporte des modifications pouvant être mises en scène:
git diff-files --quiet
- Le code de sortie est le même que pour
git diff-index
( 0
== pas de différences; 1
== différences).
Pour vérifier si la combinaison de l'index et des fichiers suivis dans l'arborescence de travail a des changements par rapport à HEAD
:
git diff-index --quiet HEAD --
- C'est comme une combinaison des deux précédents. Une différence principale est qu'il signalera toujours «aucune différence» si vous avez un changement par étapes que vous avez «annulé» dans l'arborescence de travail (retourné au contenu qui s'y trouve
HEAD
). Dans cette même situation, les deux commandes distinctes renverraient toutes les deux des rapports de «différences présentes».
Vous avez également mentionné les fichiers non suivis. Vous pourriez signifier «non suivi et non ignoré», ou simplement «non suivi» (y compris les fichiers ignorés). Quoi qu'il en soit, git ls-files
est l'outil pour le travail:
Pour «non suivi» (comprendra les fichiers ignorés, le cas échéant):
git ls-files --others
Pour «non suivi et non ignoré»:
git ls-files --exclude-standard --others
Ma première pensée est de simplement vérifier si ces commandes ont une sortie:
test -z "$(git ls-files --others)"
- S'il
0
se termine avec alors il n'y a pas de fichiers non suivis. S'il 1
se termine avec alors il y a des fichiers non suivis.
Il y a une petite chance que cela se traduise par des sorties anormales de git ls-files
dans «aucun fichier non suivi» (les deux entraînent des sorties non nulles de la commande ci-dessus). Une version un peu plus robuste pourrait ressembler à ceci:
u="$(git ls-files --others)" && test -z "$u"
- L'idée est la même que la commande précédente, mais elle permet à des erreurs inattendues de
git ls-files
se propager. Dans ce cas, une sortie non nulle pourrait signifier «il y a des fichiers non suivis» ou cela pourrait signifier qu'une erreur s'est produite. Si vous souhaitez que les résultats "erreur" soient combinés avec le résultat "pas de fichiers non suivis" à la place, utilisez test -n "$u"
(où sortie de 0
signifie "certains fichiers non suivis" et non nul signifie erreur ou "pas de fichiers non suivis").
Une autre idée consiste à utiliser --error-unmatch
pour provoquer une sortie non nulle lorsqu'il n'y a pas de fichiers non suivis. Cela risque également de confondre «aucun fichier non suivi» (sortie 1
) avec «une erreur s'est produite» (sortie non nulle, mais probablement 128
). Mais la vérification des codes de sortie 0
vs. 1
vs non-zéro est probablement assez robuste:
git ls-files --others --error-unmatch . >/dev/null 2>&1; ec=$?
if test "$ec" = 0; then
echo some untracked files
elif test "$ec" = 1; then
echo no untracked files
else
echo error from ls-files
fi
N'importe lequel des git ls-files
exemples ci-dessus peut être --exclude-standard
utilisé si vous souhaitez considérer uniquement les fichiers non suivis et non ignorés.