Czy git commit może mieć więcej niż 2 rodziców?

48

W tej dokumentacji jest wspomniane

Obiekt zatwierdzenia może mieć dowolną liczbę rodziców.

Ale z mojego zrozumienia, jedynym przypadkiem, w którym zatwierdzenie będzie miało więcej niż jednego rodzica, jest przypadek scalenia, w którym to przypadku będą tylko dwoje rodziców. Więc moje pytanie brzmi: czy zatwierdzenie może mieć więcej niż 2 rodziców? Jeśli tak, to kiedy?

Nie mogę powiedzieć
źródło
11
github.com/torvalds/linux/commit/… - Nie sądzę, aby Github wiedział, jak wyświetlić 27-drożny diff, ale możesz sklonować repozytorium i zobaczyć je sam.
user253751

Odpowiedzi:

43

Możesz użyć git merge do scalenia więcej niż jednego zatwierdzenia w bieżącym oddziale. Od man git-merge(lub git help merge):

git-merge - Połącz dwie lub więcej historii rozwoju razem

Rezultatem będzie zatwierdzenie z więcej niż dwojgiem rodziców, gdy to zrobisz.

David Hammen
źródło
33
Scalenie więcej niż jednej gałęzi (tj. Zatwierdzenie z więcej niż dwoma rodzicami) jest potocznie nazywane „scaleniem ośmiornicy”. Jest to również źródło inspiracji dla logo i maskotki GitHub, ośmiorożego kota: pierwotnie nazywał się Octopuss, ale przemianowano go na bardziej przyjazny dla firmy Octocat.
Jörg W Mittag
4
Jakie są zalety połączenia trzech lub więcej gałęzi w jednym zatwierdzeniu zamiast serii zatwierdzeń?
Tor Klingberg
2
@TorKlingberg Historia czyszczenia, ale koniecznie przetestuj produkt końcowy przed przekazaniem go do zdalnego repozytorium.
Ferrybig
5
@KasunSiyambalapitiya - Istnieje wiele przykładów w jednym konkretnym repozytorium github . Jedna z wielu ośmiornic łączy się w tym repozytorium, które obejmuje 27 rodziców .
David Hammen
1
@ JörgWMittag Dosłownie nic z tego nie jest prawdą. Źródło: pracował w GitHub przez pięć lat.
gjtorikian
5

Tak, a co powiesz na 100 000 rodziców?

Oto przykład GitHub na żywo ze scaleniem 100k zatwierdzeń: https://github.com/cirosantilli/test-octopus-100k Wygenerowany za pomocą tego skryptu .

Drobnostki

Linus nie lubi commits z więcej niż 60 rodzicami: https://www.destroyallsoftware.com/blog/2017/the-biggest-and-weirdest-commits-in-linux-kernel-git-history

Jest wyciągnięty i jest w porządku, ale najwyraźniej istnieje równowaga między „połączeniem ośmiornicy jest w porządku” a „Chrystusem, to nie jest ośmiornica, to połączenie Cthulhu”.

Zobacz format obiektu Git commit

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

Na podstawie tej analizy możemy zobaczyć, że lista listy rodziców jest arbitralną listą rozdzieloną znakiem nowej linii:

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

i dlatego dozwolona jest dowolna liczba rodziców.

Minimalny przykład

Scenariusz:

#!/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"

Wynik:

*-.   2d2a6c2 (HEAD -> master) merge
|\ \  
| | * 2300c18 2
| * | 7e096cb 1
| |/  
* | 50aa125 3
|/  
* a1e94fd root
Ciro Santilli
źródło
Nie jestem pewien, czy GitHub po prostu nie jest w stanie obsłużyć scalenia tej wielkości, czy też zostawiłeś je jako prywatne repozytorium. Lub jeśli GitHub ma jakiś niezwiązany problem. Ale niezależnie od tego link do scalenia 100k jest dla mnie błędem 500.
8bittree
@ 8bittree to nie poradzi, prywatne repo to 400 :-) github.com/isaacs/github/issues/1344
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
Jaki jest związek między brodatymi sandałami noszącymi rzeczników FOSS a Lovecraftem, z którym wielokrotnie się spotykam?
Neutrino
3

Podczas łączenia możesz podać więcej niż jeden oddział.

Na przykład:

git merge branch_A branch_B branch_C [...]

W takim razie commit ma więcej rodziców.

simhumileco
źródło