web-dev-qa-db-fra.com

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

Dans cette documentation elle est mentionnée

Un objet commit peut avoir n'importe quel nombre de parents.

Mais d'après ce que je comprends, le seul cas où un commit aura plus d'un parent est lorsqu'une fusion a eu lieu, et 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?

52
Can't Tell

Vous pouvez utiliser git merge pour fusionner plus d'un commit dans votre branche actuelle. De man git-merge (ou git help merge):

git-merge - Joignez deux ou plusieurs histoires de développement ensemble

Le résultat sera un commit avec plus de deux parents lorsque vous faites cela.

47
David Hammen

Oui, que diriez-vous de 100 000 parents?

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

Anecdotes

Linus n'aime pas les commits 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 ça va, mais il y a clairement un équilibre entre "les fusions de poulpe sont bien" et "Christ, ce n'est pas une poulpe, c'est une fusion de Cthulhu".

Jetez un œil au format de l'objet de validation Git

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

À partir de cette analyse, nous pouvons voir que la liste des parents est une liste de type arbitraire séparée par des sauts 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"

Production:

*-.   2d2a6c2 (HEAD -> master) merge
|\ \  
| | * 2300c18 2
| * | 7e096cb 1
| |/  
* | 50aa125 3
|/  
* a1e94fd root

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

Par exemple:

git merge branch_A branch_B branch_C [...]

Ensuite, commit a plus de parents.

3
simhumileco