git pull VS git fetch Vs git rebase

294

Otra pregunta que se dice git pulles como un git fetch+ git merge.

Pero, ¿cuál es la diferencia entre git pullVS git fetch+ git rebase?

Miguel
fuente
2
alguien debería limpiar el enlace ... y estoy sorprendido de cuántos votos obtuvo esa otra pregunta.
xenoterracide
13
@xeno: Creo que es solo un recuento de cuántas personas van "Yo también tuve esta pregunta"
bobobobo
45
Algún día encontraré tiempo para leer realmente la documentación de GIT, pero hasta entonces, agregaré mis votos a este tipo de preguntas
Eran Medan

Respuestas:

336

Debería ser bastante obvio a partir de su pregunta que en realidad solo está preguntando sobre la diferencia entre git mergey git rebase.

Entonces, supongamos que está en el caso común: ha realizado un trabajo en su rama maestra y extrae del origen, que también ha hecho algo de trabajo. Después de la búsqueda, las cosas se ven así:

- o - o - o - H - A - B - C (master)
               \
                P - Q - R (origin/master)

Si se fusiona en este punto (el comportamiento predeterminado de git pull), suponiendo que no haya conflictos, terminará con esto:

- o - o - o - H - A - B - C - X (master)
               \             /
                P - Q - R --- (origin/master)

Si, por otro lado, hiciste el rebase apropiado, terminarías con esto:

- o - o - o - H - P - Q - R - A' - B' - C' (master)
                          |
                          (origin/master)

El contenido de su árbol de trabajo debería terminar igual en ambos casos; acabas de crear una historia diferente antes de eso . El rebase reescribe su historial, haciendo que parezca que se ha comprometido encima de la nueva rama maestra de origen ( R), en lugar de donde se comprometió originalmente ( H). Nunca debe usar el enfoque de rebase si alguien más ya se ha retirado de su rama maestra.

Finalmente, tenga en cuenta que en realidad puede configurar git pulluna rama determinada para usar rebase en lugar de fusionar estableciendo el parámetro config branch.<name>.rebaseen true. También puede hacer esto para un solo tirón usando git pull --rebase.

Cascabel
fuente
39
¿Qué sucede si tuvieras que hacer un rebase después de que alguien ya se haya retirado de tu rama maestra? ¿Eso rompería el repositorio?
Didier A.
12
¿Cómo saber si alguien se retiró de su rama maestra?
Frank
29
Si no está seguro de que alguien no , debe asumir que sí.
Chris Down
44
Estaba pensando que, a menos que también esté presionando cambios en otro lugar que no sea origen / maestro, no veo el problema de que alguien más haya retirado los cambios en cuestión, porque si ya había empujado estos cambios al origen / maestro, no habría nada que rebase en primer lugar. Me parece que la advertencia realmente solo importa en los casos en que tienes algo más complejo que X -> origen / X, pero podría estar equivocado. Si alguien sabe de un escenario que estoy pasando por alto, por favor comparta.
neverfox
1
@SteveChambers No, ese no es el resultado. Las líneas simplemente representan ascendencia de compromiso, es decir, A es el padre de B. No hay ninguna implicación acerca de si Q o B fueron los primeros en el tiempo. Todas estas operaciones se basan en gráficos de compromiso, no en tiempo. Rebase simplemente trasplanta algunos commits, con el resultado que mostré sin importar cuáles sean las marcas de tiempo de commit.
Cascabel
9

TLDR:

git pulles como correr git fetchentonces git merge
git pull --rebasees como git fetchentoncesgit rebase

En respuesta a tu primera declaración,

git pulles como un git fetch+ git merge.

"En su modo predeterminado, git pull es una abreviatura git fetchseguida de git mergeFETCH_HEAD" Más precisamente, se git pullejecuta git fetchcon los parámetros dados y luego llama git mergepara fusionar las cabezas de rama recuperadas en la rama actual "

(Ref: https://git-scm.com/docs/git-pull )


Para su segunda declaración / pregunta:

'Pero, ¿cuál es la diferencia entre git pullVS git fetch+ git rebase'

De nuevo, de la misma fuente:
git pull --rebase

"Con --rebase, ejecuta git rebase en lugar de git merge".


Ahora, si quisieras preguntar

'la diferencia entre mergey rebase'

eso también se responde aquí:
https://git-scm.com/book/en/v2/Git-Branching-Rebasing
(la diferencia entre alterar la forma en que se registra el historial de versiones)

harshvchawla
fuente
2
Me gustaría mencionar que "git pull --rebase" es como "git fetch then git rebase" la mayor parte del tiempo, pero no siempre. En algunas situaciones, "git pull --rebase" hace un poco más. Vea este ejemplo a menudo referenciado aquí: gitolite.com/git-pull--rebase
Daniel K.
1
Muchas gracias por tu respuesta. Realmente entiendo cómo git fetch + git rebasefuncionan los comandos a partir de ahora. No hay más o menos conflicto en nuestro árbol de git a partir de ahora :)
Travis Le