¿Diferencias entre los comandos "git pull" al extraer desde el origen?

82

¿Cuáles son las diferencias entre estos comandos ?:

# 1
git pull
# 2
git pull origin
# 3
git pull origin master
# 4
git pull origin/master
# 5
git pull origin HEAD:master
Ben Gao
fuente
Bueno, incluso después de leer la página del manual, no está claro en todos los casos qué es exactamente lo que sucede. Por ejemplo: ¿Qué significa git pullsin un upstream configurado? (La página del manual sólo se establece el valor predeterminado a ser el de aguas arriba configurado.)
michas
En resumen: 1. fallará sin una configuración para la rama actual y de lo contrario será como 2. con el nombre remoto. 2. utilizará las configuraciones de recuperación predeterminadas para el control remoto dado (y fusionará la primera), mientras que en 3. usted especificará qué buscar y fusionar. 4. no es válido, en mi humilde opinión. 5. (si funciona), pondrá el HEAD remoto en refs / remotes / origin / master y lo fusionará.
andi5
2
Votando para reabrir esta pregunta porque, desafortunadamente, es uno de los resultados de búsqueda de site:stackoverflow.com git Difference "git pull" "git pull origin master".

Respuestas:

81

git pulles un comando de conveniencia, que hace diferentes cosas al mismo tiempo. Básicamente es solo una combinación de git fetch, que se conecta al repositorio remoto y busca nuevas confirmaciones, y git merge(o git rebase) que incorpora las nuevas confirmaciones en su rama local. Debido a los dos comandos diferentes involucrados, el significado de git pullno siempre es obvio.

Puede configurar un upstream para una sucursal local. Después de un clon nuevo, tendrá una rama local "maestra", un "origen" remoto y su rama maestra tiene "origen / maestra" como aguas arriba. Asumo esta configuración a continuación. (Puede ver su configuración ascendente con git branch -vvo mirando .git / config.)

Ahora para sus preguntas:

  1. git pull= git fetch origin+ git merge origin/master(o cualquiera que sea su aguas arriba)
  2. git pull origin= git pull(siempre que el origen sea su control remoto ascendente)
  3. git pull origin master= git fetch origin master+git merge FETCH_HEAD
  4. git pull origin/master : inválido a menos que tenga un control remoto llamado "origen / maestro"
  5. git pull origin HEAD:master: Intenta restablecer directamente su maestro local a lo que sea que HEAD apunte en el origen. (No hagas esto).
michas
fuente
2
¿Por qué está ejecutando git pull origin HEAD:masteruna mala idea?
Ryan Edwards
2
Se supone que el lado derecho es una rama remota. Vea la advertencia en la página del manual. Asegúrese de saber lo que está haciendo si usa esto.
michas
si estuviera en otra rama, git pullsacaría esa rama o maestro
aWebDeveloper
1
@aWebDeveloper: Para completar: git pull origin HEAD:masteresencialmente (fue literalmente hasta que el script se reescribió en C en Git 2.6) pasa la HEAD:masterparte a git fetch, por lo que hace lo que git fetchhace para ese paso; luego se fusiona o reajusta usando el hash de confirmación que git fetchobtuvo el paso. Las especificaciones de referencia son fuente: dest , por lo que HEADse le da al otro Git para traducir. Así que depende del otro Git, pero normalmente el otro Git HEADes un nombre para él master. Si no está solo master, la combinación o rebase usa su fetch-updated master( dest ) (a menos que fetchfalle).
torek
1
Otra cosa a tener en cuenta: nunca lo hagas git pull origin br1 br2. Se ve y se siente como debería git checkout br1; git pull origin; git checkout br2; git pull originhacerlo, ¡pero no es así! En su lugar, en efecto, lo hace:, git fetch origin && git merge origin/br1 origin/br2que fusiona ambos resultados de búsqueda en su rama actual , algo que Git llama fusión de pulpo . Esto nunca es lo que quiere nadie. Probablemente git pulldebería rechazar el comando por completo (cualquiera que realmente lo quiera puede ejecutar primero la búsqueda y luego fusionar).
torek
18

A pulles básicamente a fetch(que obtiene algunas confirmaciones y objetos asociados de un repositorio remoto al suyo) y luego una operación que "aplica" estos en su copia de trabajo. La segunda etapa, de forma predeterminada, se realiza con a, mergepero puede establecer la pull.rebasevariable en truey luego se reajustará en su lugar.

Hay dos preguntas que surgen con el pullcomando. La primera es, ¿qué se busca exactamente? Y el segundo es, ¿cómo aplica estos cambios a mi copia de trabajo? Empecemos por el primero. La forma completa del comando es

git pull [options] [repository] [<refspec>...]

El optionsson banderas que el comportamiento de control (por ejemplo --rebase para hacer pullel trabajo como un fetch+ rebaseincluso si pull.rebasees false).

repository es el nombre (o URL) del control remoto desde el que buscar.

refspecs son una forma sucinta de especificar qué referencias en el control remoto desea obtener y dónde desea colocarlas en su copia de trabajo actual.

Tomemos primero la forma más explícita.

 git pull origin branch1:branch2

Esto básicamente dice, extraiga los cambios en la referencia branch1en el control remoto llamado originy luego combínelos (o vuelva a colocarlos) en la rama local branch2. Si yo, por ejemplo, digo git pull origin master:dev, obtendré una rama local llamada devque apuntará a la misma confirmación que master. Los detalles sobre cómo especificar refspecs están aquí . Puede utilizar a *para indicar varias especificaciones de referencia. Por ejemplo, git pull origin refs/heads/*:refs/heads/*extraerá todas las ramas (almacenadas en heads) en el repositorio local y las fusionará en ramas locales con los mismos nombres.

Ahora, eliminemos los argumentos uno por uno para discutir cómo funciona el predeterminado. Primero, podemos eliminar el destino de nuestra especificación de referencia y simplemente decir git pull origin branch1. Esto primero hará que fetchla ramificación remota branch1a su repositorio local. Estará disponible como referencia temporal llamada FETCH_HEAD. Después de eso, se ejecutará git merge FETCH_HEADlo que fusionará esta rama en su rama activa actual (es decir HEAD). Esto se hace a menudo cuando se encuentra en una sucursal local y desea obtener cambios desde un control remoto a esa sucursal.

Ahora, dejemos el branch1completamente y digamos git pull origin. Ahora, git sabe de dónde buscar ( origin) pero no sabe qué buscar. Tiene algunos valores predeterminados para esto. El escenario más común es cuando su archivo de configuración tiene una branch.<name>.mergeopción (esta es una entrada llamada mergedentro de una sección como [branch "master"]). Si es así, utilizará las especificaciones de referencia allí para la operación.

Si dejamos caer origincompletamente y simplemente decimos git pull, verificará la configuración para ver si hay una branch.<name>.remoteque especifique de qué control remoto extraer. Eso, junto con lo anterior, te dice qué tirar.

Sus puntos 4 y 5 no son casos de uso normales. El primero tiene sentido si tiene un control remoto llamado, lo origin/mastercual es poco probable. origin/mastersuele ser una referencia local que rastrea la masterrama en el control remoto origin. El segundo intentará obtener cambios en HEADel control remoto (la rama predeterminada que suele ser master) y luego fusionarlos en su local master. Si bien esto puede ser algo que desee hacer de forma regular, el comando es bastante poco convencional y no es algo que haya visto que se use a menudo.

Me he saltado algunos detalles, pero estos deberían ser suficientes para mantenerte seguro y cómodo en tu trabajo diario. Para todos los detalles sangrientos, puede consultar la página del manual para git pull.

Noufal Ibrahim
fuente
"Si, por ejemplo, digo git pull origin master: dev, obtendré una rama local llamada dev que apuntará a la misma confirmación que master". Entonces, ¿descargaría una nueva rama llamada dev y apuntaría a master?
user33276346
No, obtendría la rama masterdesde el control remoto, pero se llamaría devlocalmente.
Noufal Ibrahim
git pull origin refs/heads/*:refs/heads/*no funcionó para mí, y lo conseguí no matches found: refs/heads/*:refs/heads/*. También lo intenté git pull origin refs/remotes/origin/*:refs/heads/*, pero tampoco funcionó. No creo que sea posible extraer todas las ramas de forma remota en un comando, y tampoco lo es la fusión / reajuste posterior de todas estas ramas en sus ramas locales posteriores.
Ben Butterworth