345 votes

Comment puis-je déterminer par programme s'il y a des modifications non validées ?

Dans un Makefile, j'aimerais effectuer certaines actions s'il y a des changements non validés (soit dans l'arbre de travail, soit dans l'index). Quelle est la manière la plus propre et la plus efficace de le faire ? Une commande qui se termine avec une valeur de retour de zéro dans un cas et de non-zéro dans l'autre me conviendrait.

Je peux courir git status et faire passer la sortie par grep mais je pense qu'il doit y avoir un meilleur moyen.

6 votes

8voto

CervEd Points 146

L'arbre de travail est "propre" si

git ls-files --deleted --modified --others --exclude-standard

ne renvoie rien.

Explication

  • --deleted vérifier les fichiers supprimés dans l'arbre de travail
  • --modified vérifier les fichiers modifiés dans l'arbre de travail
  • --others vérifier les fichiers ajoutés dans l'arbre de travail
  • --exclude-standard ignorer selon l'habituel .gitignore , .git/info/exclude ... règles

Cette sortie est vide si l'arbre de travail est propre.

8voto

stk Points 123

J'ai créé des alias git très pratiques pour lister les fichiers unstaged et staged :

git config --global alias.unstaged 'diff --name-only'
git config --global alias.staged 'diff --name-only --cached'

Alors vous pouvez facilement faire des choses comme :

[[ -n "$(git unstaged)" ]] && echo unstaged files || echo NO unstaged files
[[ -n "$(git staged)" ]] && echo staged files || echo NO staged files

Vous pouvez le rendre plus lisible en créant un script quelque part sur votre site web. PATH appelé git-has :

#!/bin/bash
[[ $(git "$@" | wc -c) -ne 0 ]]

Maintenant, les exemples ci-dessus peuvent être simplifiés :

git has unstaged && echo unstaged files || echo NO unstaged files
git has staged && echo staged files || echo NO staged files

Pour être complet, voici des alias similaires pour les fichiers non suivis et ignorés :

git config --global alias.untracked 'ls-files --exclude-standard --others'
git config --global alias.ignored 'ls-files --exclude-standard --others --ignored'

6voto

Pablo Points 421

Avec python et le paquet GitPython :

import git
git.Repo(path).is_dirty(untracked_files=True)

Renvoie à True si le référentiel n'est pas propre

0 votes

Cela a permis d'éviter certains des problèmes d'"horodatage" mentionnés dans d'autres commentaires

2 votes

Notez que GitPython utilise également le CLI de git. Si vous mettez LOGLEVEL=DEBUG vous verrez toutes les commandes Popen qu'il utilise pour exécuter git diff

1 votes

En supposant que le paquet soit bien testé, il est plus fiable de laisser les responsables du paquet assurer le bon fonctionnement des fonctions si/quand Git change. La documentation de GitPython indique qu'il peut y avoir des fuites de ressources et cela me préoccupe.

4voto

sanmai Points 3990

Comme indiqué dans une autre réponse, une commande aussi simple que celle-ci est suffisante :

git diff-index --quiet HEAD --

Si vous omettez les deux derniers tirets, la commande échouera si vous avez un fichier nommé HEAD .

Exemple :

#!/bin/bash
set -e
echo -n "Checking if there are uncommited changes... "
trap 'echo -e "\033[0;31mFAILED\033[0m"' ERR
git diff-index --quiet HEAD --
trap - ERR
echo -e "\033[0;32mAll set!\033[0m"

# continue as planned...

Attention : cette commande ignore les fichiers non suivis.

2 votes

Comme indiqué dans les commentaires de cette réponse, cette méthode ne détecte pas les fichiers nouvellement ajoutés.

0 votes

Non, il détecte les fichiers nouvellement ajoutés à l'index. Je viens de vérifier.

0 votes

Voir la question. Les fichiers non suivis ne sont pas changements . git add y git clean à la rescousse

-3voto

codyc4321 Points 2288

Voici le meilleur moyen, le plus propre.

function git_dirty {
    text=$(git status)
    changed_text="Changes to be committed"
    untracked_files="Untracked files"

    dirty=false

    if [[ ${text} = *"$changed_text"* ]];then
        dirty=true
    fi

    if [[ ${text} = *"$untracked_files"* ]];then
        dirty=true
    fi

    echo $dirty
}

4 votes

Non, ce n'est pas le meilleur. git status est une commande "porcelaine". N'utilisez pas les commandes porcelaine dans les scripts car elles peuvent changer entre les versions de git. Utilisez plutôt des commandes 'plumbing'.

3 votes

Je pense que si vous le mettez à jour pour utiliser git status --porcelain (qui est conçu dans ce but - un format stable que vous pouvez analyser dans un script), éventuellement aussi avec -z (null-separated au lieu de newline ?) vous pourriez faire quelque chose d'utile avec cette idée. @codyc4321 voir stackoverflow.com/questions/6976473/ pour plus de détails

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X