¿Puede un git commit tener más de 2 padres?

48

En esta documentación se menciona

Un objeto commit puede tener cualquier número de padres.

Pero, según tengo entendido, el único caso en el que un commit tendrá más de 1 padre es cuando se ha producido una fusión, y en ese caso solo habrá dos padres. Entonces mi pregunta es, ¿puede un commit tener más de 2 padres? ¿Si es así cuando?

No puedo decir
fuente
11
github.com/torvalds/linux/commit/… - No creo que Github sepa cómo mostrar un diferencial de 27 vías, pero siéntase libre de clonar el repositorio y verlo usted mismo.
user253751

Respuestas:

43

Puede usar git merge para fusionar más de una confirmación en su rama actual. De man git-merge(o git help merge):

git-merge: une dos o más historias de desarrollo juntas

El resultado será un compromiso con más de dos padres cuando hagas eso.

David Hammen
fuente
33
Una fusión de más de una rama (es decir, una confirmación con más de dos padres) se conoce coloquialmente como una "fusión de pulpo". Esa es también la fuente de inspiración para el logotipo y la mascota de GitHub, el gato de ocho patas: originalmente se llamaba Octopuss, pero pasó a llamarse Octocat, más amigable para las empresas.
Jörg W Mittag
44
¿Cuáles son las ventajas de fusionar tres o más ramas en una única confirmación, en lugar de una serie de confirmaciones?
Tor Klingberg
2
@TorKlingberg Cleaner history, pero asegúrese de probar el producto final antes de pasar al repositorio remoto.
Ferrybig
55
@KasunSiyambalapitiya: hay varios ejemplos en un repositorio de github en particular . Una de las muchas combinaciones de pulpo en ese repositorio que involucra a 27 padres .
David Hammen
1
@ JörgWMittag Literalmente, nada de eso es cierto. Fuente: trabajó en GitHub durante cinco años.
gjtorikian
5

Sí, ¿qué tal 100k padres?

Aquí hay un ejemplo de GitHub en vivo con una fusión de 100k commits: https://github.com/cirosantilli/test-octopus-100k Generado con este script .

Trivialidades

A Linus no le gustan los compromisos con más de 60 padres: https://www.destroyallsoftware.com/blog/2017/the-biggest-and-weirdest-commits-in-linux-kernel-git-history

Se tira y está bien, pero claramente hay un equilibrio entre "las combinaciones de pulpo están bien" y "Cristo, eso no es un pulpo, es una fusión de Cthulhu".

Eche un vistazo al formato para el objeto de confirmación Git

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

De ese análisis, podemos ver que la lista de padres es una lista arbitraria de tipo separada por una nueva línea:

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

y entonces se permite un número arbitrario de padres.

Ejemplo mínimo

Guión:

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

Salida:

*-.   2d2a6c2 (HEAD -> master) merge
|\ \  
| | * 2300c18 2
| * | 7e096cb 1
| |/  
* | 50aa125 3
|/  
* a1e94fd root
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
fuente
No estoy seguro de si GitHub simplemente no puede manejar una fusión de esa magnitud o si lo ha dejado como un depósito privado. O si GitHub solo tiene algún problema no relacionado. Pero independientemente, el enlace de fusión 100k es un error 500 para mí.
8bittree
@ 8bittree no puede manejar, el repositorio privado sería 400 :-) github.com/isaacs/github/issues/1344
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
¿Cuál es esta conexión entre la sandalia barbuda que lleva a los defensores de FOSS y Lovecraft que encuentro repetidamente?
Neutrino
3

Puede especificar más de una rama al fusionar.

Por ejemplo:

git merge branch_A branch_B branch_C [...]

Entonces commit tiene más padres.

simhumileco
fuente