Question

J'écris un script qui nécessite de vérifier si un engagement particulier est un engagement de fusion / retour, et je me demande s'il y a une astuce Git pour cela.

Ce que j'ai trouvé jusqu'à présent (et je ne veux certainement pas dépendre du message de validation ici), c'est de vérifier HASH^2 Et voyez si je n'obtiens pas d'erreur, y a-t-il une meilleure façon?

Était-ce utile?

La solution

Déterminer si quelque chose est une fusion est facile. Tout cela s'engage avec plus d'un parent. Pour vérifier cela, vous pouvez faire, par exemple

$ git cat-file -p $commit_id

S'il y a plus d'une ligne «parent» dans la sortie, vous avez trouvé une fusion.

Pour le retour, ce n'est pas aussi facile. Généralement, les engagements normaux qui appliquent le différentiel d'un engagement précédent en inverse, supprimant efficacement les changements introduits. Il n'y a pas de spécial autrement.

Si un retour a été créé avec git revert $commit, alors Git génère généralement un message de validation indiquant le retour et ce qu'il a remis. Cependant, il est tout à fait possible de faire des reportages par d'autres moyens, ou de simplement changer le message de validation d'un engagement généré par git revert.

À la recherche de ceux générés par le message, REVERT COMMISS peut déjà être une heuristique assez bonne pour ce que vous essayez de réaliser. Sinon, vous devez réellement regarder d'autres engins, en comparant leurs diffs les uns aux autres, en regardant l'un est le fonctionnement inverse exact d'un autre. Mais même ce n'est pas une bonne solution. Souvent, assez de rendement sont légèrement différents de l'inverse de l'engagement qu'ils reviennent, par exemple pour accueillir des changements de code qui se sont produits entre le commit et le retour.

Autres conseils

L'instruction suivante se déversera seulement les hachages parents. Moins de filtrage nécessaire ...

git show --no-patch --format="%P" <commit hash>

La réponse en utilisant git cat-file utilise un git "plomberie" Commande, qui est généralement meilleure pour la construction de scripts car le format de sortie ne devrait pas changer. Ceux qui utilisent git show et git rev-parse peut avoir besoin de changer avec le temps car ils utilisent porcelaine Commandes.

La fonction bash que j'utilise depuis longtemps git rev-list:

gitismerge () {
    local sha="$1"
    msha=$(git rev-list -1 --merges ${sha}~1..${sha})
    [ -z "$msha" ] && return 1
    return 0
}

La liste des commandes en porcelaine / plomberie se trouve dans les documents pour le niveau supérieur git commande.

Ce code utilise git-rev-list avec un spécifique gitrévisions requête ${sha}~1..${sha} D'une manière qui imprime le deuxième parent d'un SHA s'il existe, ou rien s'il n'est pas présent, qui est la définition exacte d'un engagement de fusion.

Spécifiquement, SHA~1..SHA moyens Incluez des engins accessibles à partir de Sha mais excluez ceux qui sont accessibles SHA ~ 1, qui est le premier parent de SHA.

Les résultats sont stockés dans $ MSHA et testés pour le vide en utilisant Bash [ -z "$msha" ] Échec (Retour 1) Si vide ou passant (Retour 0) si non vide.

Une façon de tester un engagement de fusion:

$ test -z $(git rev-parse --verify $commit^2 2> /dev/null) || echo MERGE COMMIT

Quant aux commits de retour de Git, je suis d'accord avec @rafl que l'approche la plus réaliste consiste à rechercher la plaque de réintégration du message de retour dans le message de validation; Si quelqu'un le modifiait, la détection serait très impliquée.

Moyen facile de tester pour fusionner Commit:

git show --summary HEAD | grep -q ^Merge:

Cela reviendra 0 pour les engins de fusion, 1 pour les engagements non-mégés. Remplacez la tête par votre engagement souhaité à tester.

Exemple d'utilisation:

if git show --summary some-branch | grep -q ^Merge: ; then
    echo "some-branch is a merge"
fi

Encore une autre façon de trouver les parents d'un engagement:

git show -s --pretty=%p <commit>

Utilisation %P pour le hachage complet. Cela imprime combien de parents HEAD a:

git show -s --pretty=%p HEAD | wc -w
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top