2010-04-29 7 views
7

Pour vérifier que mon analyse scientifique est reproductible, je souhaite vérifier par programme s'il existe des modifications de la base de code qui ne sont pas enregistrées et, dans le cas contraire, imprimer quel commit est utilisé.Impression par programmation d'une révision git et vérification des modifications non validées

Par exemple, s'il y a des changements non engagés, il doit générer

Warning: uncommitted changes made. This output may not be reproducible. 

Sinon, produire

Current commit: d27ec73cf2f1df89cbccd41494f579e066bad6fe 

Idéalement, il devrait utiliser "plomberie", pas "porcelaine".

Répondre

1

Ceci utilise la porcelaine, mais git diff --exit-code se termine avec 1 s'il y a des différences par rapport aux fichiers existants, et 0 s'il n'y a aucune différence avec les fichiers existants. Il ne vérifie pas les fichiers non suivis, malheureusement.

This answer Comment récupérer le hachage pour le commit actuel dans Git? préconise git rev-parse --verify HEAD pour imprimer la validation en cours.

8

Les bits de plomberie Git dont vous avez besoin sont diff-index, rev-parse --verify et peut-être rev-parse --show-cdup avec ls-files --others.

Le programme shell suivant utilise les commandes de plomberie Git, possède une gestion réglable non-ignoré/ignoré et fait attention à tous les cas d'erreur possibles.

#!/bin/sh 

# warn-unclean: print a warning if the working tree and index are not clean 

# For utmost strictness, set check_untracked=yes and check_ignored=yes. 
# When both are 'yes', verify that working tree and index are identical to HEAD. 
# When only check_untracked is yes, extra ignored files are allowed. 
# When neither is yes, extra untracked files and ignored files are allowed. 

check_untracked=yes 
check_ignored=yes 

warn() { 
    echo 'Warning: '"$*" \ 
     'This output may not be reproducible.' 
} 

# Compare HEAD to index and/or working tree versions of tracked files 
git diff-index --quiet HEAD 
case $? in 
    0) 
     if test "$check_untracked" != yes; then 
      clean=yes 
     else 
      # Still need to check for untracked files 

      or_ignored='' 
      exclude=--exclude-standard 
      if test "$check_ignored" = yes; then 
       or_ignored=' or ignored' 
       exclude='' 
      fi 

      (
       # Move to top level of working tree 
       if up="$(git rev-parse --show-cdup)"; then 
        test -n "$up" && cd "$up" 
       else 
        echo 'error running "git rev-parse --show-cdup"' 
        exit 129 
       fi 

       # Check for untracked files 
       git ls-files --others $exclude --error-unmatch . >/dev/null 2>&1 
       case $? in 
        0) # some untracked/ignored file is present 
         warn 'some untracked'"$or_ignored"' file is present.' 
         exit 1 
        ;; 
        1) # no untracked files 
         exit 0 
        ;; 
        *) 
         echo 'error running "git diff-index"!' 
         exit 129 
        ;; 
       esac 

      ) 
      case $? in 
       0) clean=yes ;; 
       1) clean=no ;; 
       *) exit $? ;; 
      esac 
     fi 

     test "$clean" = yes && 
     if c="$(git rev-parse --verify HEAD)"; then 
      echo 'Current commit: '"$c" 
     else 
      echo 'error running "git rev-parse --verify"!' 
     fi 
    ;; 
    1) 
     warn 'some tracked file has an uncommitted change.' 
    ;; 
    *) 
     echo 'error running "git diff-index"!' 
     exit 129 
    ;; 
esac 

Vous pouvez saupoudrer dans certains autres exit s si vous voulez son code de sortie ait un sens dans tous les cas.

Si vous ne vous inquiétez pas pour toute la gestion des erreurs ou la manipulation untracked/ignoré, alors quelque chose à court pourrait suffire:

if git diff-index --quiet; then 
    printf 'Current commit: %s\n' "$(git rev-parse --verify HEAD) 
else 
    echo 'Warning: …' 
fi 

Vous pouvez également vérifier les fichiers trassez (qui pourrait être modifié pour ignoré, etc.) de façon concise, sans traitement des erreurs:

git ls-files --others --exclude-standard --error-unmatch \ 
    "./$(git rev-parse --show-cdup)" >/dev/null 2>&1 
Questions connexes