Un git commit peut-il avoir plus de 2 parents?

48

Dans cette documentation, il est mentionné

Un objet commit peut avoir un nombre quelconque de parents.

Mais, à ma connaissance, le seul cas où un commit aura plus d'un parent est le moment où une fusion a eu lieu. Dans ce cas, il n'y aura que deux parents. Ma question est donc la suivante: un commit peut-il avoir plus de 2 parents? Si oui, quand?

Je ne peux pas dire
la source
11
github.com/torvalds/linux/commit/… - Je ne pense pas que Github sache comment afficher un diff à 27 voies, mais n'hésitez pas à cloner le référentiel et à l'afficher vous-même.
user253751

Réponses:

43

Vous pouvez utiliser git merge pour fusionner plusieurs validations dans votre branche actuelle. De man git-merge(ou git help merge):

git-merge - Joindre deux ou plusieurs historiques de développement

Le résultat sera un engagement avec plus de deux parents lorsque vous le ferez.

David Hammen
la source
33
Une fusion de plus d'une branche (c'est-à-dire un commit avec plus de deux parents) est couramment appelée "fusion de pieuvre". C'est également la source d'inspiration du logo et de la mascotte de GitHub, le chat à huit pattes: il s'appelait à l'origine Octopuss, mais a été renommé Octocat, plus convivial pour les entreprises.
Jörg W Mittag
4
Quels sont les avantages de la fusion de trois branches ou plus dans un même commit, au lieu d'une série de commits?
Tor Klingberg
2
L'historique de @TorKlingberg Cleaner, mais veillez à tester le produit final avant de le placer sur le répertoire distant.
Ferrybig
5
@ KasunSiyambalapitiya - Il y a de nombreux exemples dans un dépôt particulier de github . Une des nombreuses pieuvres se confond dans cette pension qui implique 27 parents .
David Hammen
1
@ JörgWMittag Littéralement, rien de tout cela n'est vrai. Source: a travaillé chez GitHub pendant cinq ans.
dimanche
5

Oui, que diriez-vous de 100 000 parents?

Voici un exemple GitHub en direct avec une fusion de 100 000 validations: https://github.com/cirosantilli/test-octopus-100k Généré avec ce script .

Trivia

Linus n'aime pas les engagements avec plus de 60 parents: https://www.destroyallsoftware.com/blog/2017/the-biggest-and-weirdest-commits-in-linux-kernel-git-history

C'est tiré, et c'est bien, mais il y a clairement un équilibre entre "les fusions de poulpes vont bien" et "Christ, ce n'est pas une pieuvre, c'est une fusion de Cthulhu".

Regardez le format de l'objet commit Git

https://stackoverflow.com/questions/22968856/what-is-the-file-format-of-a-git-commit-object/37438460#37438460

À partir de cette analyse, nous pouvons voir que la liste de la liste des parents est une liste arbitraire de types séparés par un saut de ligne:

parent {parent_1_sha}
parent {parent_2_sha}
...
parent {parent_N_sha}

et donc un nombre arbitraire de parents est autorisé.

Exemple minimal

Scénario:

#!/usr/bin/env bash
set -eu

mkdir tmp
cd tmp
git init

touch root
git add .
git commit -m root
sha_root="$(git log -1 --format="%H")"

touch 1
git add .
git commit -m 1
sha1="$(git log -1 --format="%H")"

git reset --hard "$sha_root"
touch 2
git add .
git commit -m 2
sha2="$(git log -1 --format="%H")"

git reset --hard "$sha_root"
touch 3
git add .
git commit -m 3
sha3="$(git log -1 --format="%H")"

git merge -m merge "$sha1" "$sha2"

Sortie:

*-.   2d2a6c2 (HEAD -> master) merge
|\ \  
| | * 2300c18 2
| * | 7e096cb 1
| |/  
* | 50aa125 3
|/  
* a1e94fd root
Ciro Santilli 改造 中心 六四 事件
la source
Je ne sais pas si GitHub ne peut tout simplement pas gérer une fusion de cette ampleur ou si vous l'avez laissé en tant que référentiel privé. Ou si GitHub a juste un problème sans rapport. Mais peu importe, le lien de fusion 100k est une erreur 500 pour moi.
8bittree
@ 8bittree il ne peut pas gérer, mettre en pension privée serait 400 :-) github.com/isaacs/github/issues/1344
Ciro Santilli新疆改造中心法轮功六四事件
Quel lien existe-t-il entre les partisans du FOSS portant des sandales à barbe et Lovecraft que j’ai rencontré à plusieurs reprises?
Neutrino
3

Vous pouvez spécifier plusieurs branches lors de la fusion.

Par exemple:

git merge branch_A branch_B branch_C [...]

Puis engage a plus de parents.

Simhumileco
la source