En supposant que le référentiel distant dispose d'une copie de l'application développer (votre description initiale le décrit dans un dépôt local, mais il semble qu'il existe également dans le dépôt distant), vous devriez être en mesure de réaliser ce que je pense que vous voulez, mais l'approche est un peu différente de ce que vous avez envisagé.
L'histoire de Git est basée sur un DAG de commits. Les branches (et les "refs" en général) ne sont que des étiquettes transitoires qui pointent vers des commits spécifiques dans le DAG des commits qui grandit continuellement. En tant que telle, la relation entre les branches peut varier dans le temps, mais pas la relation entre les commits.
---o---1 foo
\
2---3---o bar
\
4
\
5---6 baz
On dirait que baz
est basé sur (une ancienne version de) bar
? Mais que se passe-t-il si nous supprimons bar
?
---o---1 foo
\
2---3
\
4
\
5---6 baz
Maintenant, ça ressemble à baz
est basé sur foo
. Mais l'ascendance de baz
n'a pas changé. Nous avons juste supprimé une étiquette (et le commit qui en résulte). Et si nous ajoutons une nouvelle étiquette à 4
?
---o---1 foo
\
2---3
\
4 quux
\
5---6 baz
Maintenant, ça ressemble à baz
est basé sur quux
. Pourtant, l'ascendance n'a pas changé, seules les étiquettes ont changé.
Si, toutefois, nous demandions "est-ce que le commit 6
un descendant de commit 3
?" (en supposant que 3
y 6
sont des noms de commit SHA-1 complets), alors la réponse serait "oui", que les bar
y quux
Les étiquettes sont présentes ou non.
Ainsi, vous pourriez poser des questions comme "est-ce que le commit poussé est un descendant de la pointe actuelle du développer mais vous ne pouvez pas demander de manière fiable "quelle est la branche parente du commit poussé ?
Une question fiable qui semble se rapprocher de ce que vous voulez est la suivante :
Pour tous les ancêtres du commit poussé (à l'exception de la pointe actuelle de développer et ses ancêtres), qui ont la pointe actuelle de développer en tant que parent :
- existe-t-il au moins un tel engagement ?
- Est-ce que tous ces commits sont des commits monoparentaux ?
Ce qui pourrait être mis en œuvre comme :
pushedrev=...
basename=develop
if ! baserev="$(git rev-parse --verify refs/heads/"$basename" 2>/dev/null)"; then
echo "'$basename' is missing, call for help!"
exit 1
fi
parents_of_children_of_base="$(
git rev-list --pretty=tformat:%P "$pushedrev" --not "$baserev" |
grep -F "$baserev"
)"
case ",$parents_of_children_of_base" in
,) echo "must descend from tip of '$basename'"
exit 1 ;;
,*\ *) echo "must not merge tip of '$basename' (rebase instead)"
exit 1 ;;
,*) exit 0 ;;
esac
Cela couvrira une partie de ce que vous voulez restreindre, mais peut-être pas tout.
À titre de référence, voici un exemple d'historique étendu :
A master
\
\ o-----J
\ / \
\ | o---K---L
\ |/
C--------------D develop
\ |\
F---G---H | F'--G'--H'
| |\
| | o---o---o---N
\ \ \ \
\ \ o---o---P
\ \
R---S
Le code ci-dessus pourrait être utilisé pour rejeter H
y S
tout en acceptant H'
, J
, K
o N
mais il accepterait également L
y P
(ils impliquent des fusions, mais ils ne fusionnent pas l'extrémité des développer ).
Rejeter également L
y P
vous pouvez changer la question et demander
Pour tous les ancêtres du commit poussé (à l'exception de la pointe actuelle de développer et ses ancêtres) :
- Y a-t-il des engagés avec deux parents ?
- Si ce n'est pas le cas, est-ce qu'au moins un de ces commit a le tip actuel de développer son (seul) parent ?
pushedrev=...
basename=develop
if ! baserev="$(git rev-parse --verify refs/heads/"$basename" 2>/dev/null)"; then
echo "'$basename' is missing, call for help!"
exit 1
fi
parents_of_commits_beyond_base="$(
git rev-list --pretty=tformat:%P "$pushedrev" --not "$baserev" |
grep -v '^commit '
)"
case "$parents_of_commits_beyond_base" in
*\ *) echo "must not push merge commits (rebase instead)"
exit 1 ;;
*"$baserev"*) exit 0 ;;
*) echo "must descend from tip of '$basename'"
exit 1 ;;
esac
0 votes
Cette question devrait être reformulée pour trouver le parent d'un parent.