Comment git ne rien commettre sans erreur?

91

J'essaye d'écrire un script de fabric qui fait un git commit; cependant, s'il n'y a rien à valider, git se termine avec le statut 1. Le script de déploiement considère cela comme un échec et se ferme. Je veux détecter les échecs réels de validation, donc je ne peux pas simplement donner à Fabric une couverture ignorer les git commitéchecs. Comment puis-je autoriser l'ignorance des échecs de validation vide afin que le déploiement puisse continuer, tout en détectant les erreurs causées par l'échec d'une validation réelle?

def commit():
    local("git add -p && git commit")
Kojiro
la source

Réponses:

154

Catch cette condition au préalable en vérifiant le code de sortie de git diff?

Par exemple (en shell):

git add -A
git diff-index --quiet HEAD || git commit -m 'bla'

EDIT: Correction de la git diffcommande selon le commentaire de Holger.

Tobi
la source
64
Notez qu'il git diffs'agit d'une commande "porcelain" qui ne doit pas être utilisée pour les scripts. Ce que vous voulez probablement, c'est git diff-index --quiet HEAD || git commit -m 'bla'. Voir aussi cette réponse .
Holger
1
Pour expliquer les choses plus en détail, le problème avec git diff --quiet --exit-code --cachedest qu'il sera évalué à 1(false) uniquement pour les fichiers modifiés qui n'ont pas été préparés pour la validation (fichiers non ajoutés). Le commentaire voté à la hausse est la meilleure solution pour tenir compte des nouveaux fichiers et des suppressions.
Jorge Bucaran
2
Le commentaire sur git diff-index --quiet HEAD || git commit -m 'bla'devrait être une réponse à cette question.
Rakib le
1
Comme Tobi ne se souciait pas de corriger sa réponse en fonction du commentaire de Holger, j'ai édité sa réponse moi-même.
vog
Notez que git diff-index --quiet HEAD ne teste pas si le référentiel local est à jour avec l'origine.
bortzmeyer
62

Depuis la git commitpage de manuel:

--allow-empty
    Usually recording a commit that has the exact same tree as its
    sole parent commit is a mistake, and the command prevents you
    from making such a commit. This option bypassesthe safety, and
    is primarily for use by foreign SCM interface scripts.
Sven Marnach
la source
41
Cela créerait cependant un commit.
ThiefMaster
6
@ThiefMaster: C'est vrai. Je ne peux pas dire du PO si c'est un problème ou non. Je suppose que si vous utilisez des validations automatiques, vous ne vous souciez pas du fait que votre historique soit propre de toute façon.
Sven Marnach
1
Je préférerais qu'il ne s'engage pas si cela peut être évité. Y-a-t-il un moyen de faire ça?
kojiro
3
Ce n'est pas la réponse à la question
manojlds
7
@manojlds: "Bien sûr, l'OP ne veut pas créer un commit vide." J'ai laissé ma boule de cristal à la maison aujourd'hui, donc je ne savais pas. raté -p, cependant, mais quand même
Sven Marnach
5
with settings(warn_only=True):
  run('git commit ...')

Cela amène le fabric à ignorer l'échec. A l'avantage de ne pas créer de commits vides.

Vous pouvez l'envelopper dans une couche supplémentaire with hide('warnings'):pour supprimer totalement la sortie, sinon vous obtiendrez une note dans la sortie du fabric indiquant que la validation a échoué (mais le fabfile continue de s'exécuter).

Tyler Eaves
la source
3
OP a écrit "Je veux détecter les échecs réels de validation"; ce code masquera tous les échecs de validation.
bfontaine
-2

essayez / attrapez bébé!

from fabric.api import local
from fabric.colors import green


def commit(message='updates'):
    try:
        local('git add .')
        local('git commit -m "' + message + '"')
        local('git push')
        print(green('Committed and pushed to git.', bold=False))
    except:
        print(green('Done committing, likely nothing new to commit.', bold=False))
devpascoe
la source
10
Pour expliquer pourquoi vous avez obtenu un vote négatif: il peut y avoir d'autres erreurs que vous voulez attraper. Vous ne voulez pas simplement supposer qu'en cas d'erreur, il se peut que rien ne doive être commis. - Aussi, mais ce n'est pas lié: n'utilisez jamais un générique except:, utilisez except Exceptionplutôt un autre.
Albert