2010-04-29 15 views
7

Para garantizar que mi análisis científico sea reproducible, me gustaría verificar mediante programación si hay modificaciones en el código base que no están registradas, y si no, imprimir qué compromiso se está utilizando.Impresión git programáticamente y comprobación de cambios no confirmados

Por ejemplo, si hay cambios no confirmados, que debe ser la salida

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

lo demás, producen

Current commit: d27ec73cf2f1df89cbccd41494f579e066bad6fe 

Idealmente, debería utilizar "cañerías", no "porcelana".

Respuesta

1

Esto usa porcelana, pero git diff --exit-code sale con 1 si hay diferencias con los archivos existentes, y 0 si no hay diferencias con los archivos existentes. No comprueba si hay archivos sin seguir, desafortunadamente.

This answer ¿Cómo recuperar el hash para la confirmación actual en Git? aboga por git rev-parse --verify HEAD para imprimir el compromiso actual.

8

Los bits de Git de fontanería que necesita son diff-index, rev-parse --verify y tal vez rev-parse --show-cdup con ls-files --others.

El siguiente programa de shell utiliza esos comandos de plomería de Git, tiene un manejo ajustable sin seguimiento/ignorado, y es bastante cuidadoso con todos los posibles casos de error.

#!/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 

Es posible que en algunos espolvorear más exit s si desea que su código de salida sea significativa en todos los casos.

Si no se preocupan por todo el manejo de errores o la manipulación sin seguimiento/ignorado, entonces algo corto puede ser suficiente:

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

También puede comprobar los archivos sin seguimiento (que podría ser ajustado para ignorado etc) de manera breve, sin manejo de errores:

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