¿Cuál es la diferencia entre 'git pull' y 'git fetch'?

11919

¿Cuáles son las diferencias entre git pully git fetch?

pupeno
fuente
364
Encontré este artículo bien escrito sobre git fetch y git pull que vale la pena leer: longair.net/blog/2009/04/16/git-fetch-and-merge
Marcos Oliveira
51
Nuestro enfoque alternativo se ha convertido git fetch; git reset --hard origin/masteren parte de nuestro flujo de trabajo. Elimina los cambios locales, lo mantiene actualizado con master PERO se asegura de que no solo realice nuevos cambios en la parte superior de los cambios actuales y haga un desastre. Lo hemos usado por un tiempo y básicamente se siente mucho más seguro en la práctica. ¡Solo asegúrese de agregar / confirmar / ocultar cualquier trabajo en progreso primero!
Michael Durrant
26
Asegúrate de saber cómo usar git stash correctamente. Si está preguntando sobre 'pull' y 'fetch', entonces tal vez 'stash' también necesite explicarse ...
Henry Heleine
36
Mucha gente que viene de Mercurial sigue usando "git pull", pensando que es equivalente a "hg pull". Que no lo es. El equivalente de Git a "hg pull" es "git fetch".
Serge Shultz
8
El comando git fetch obtiene el código actualizado con la rama y también obtendrá nuevas ramas agregadas en su local, el comando git pull busca solo el código actualizado de la rama actual solamente
Kartik Patel

Respuestas:

9920

En los términos más simples, git pull¿a git fetchseguido de a git merge.

Puede hacer una git fetchen cualquier momento para actualizar sus sucursales de seguimiento remoto en refs/remotes/<remote>/.

Esta operación nunca cambia ninguna de sus sucursales locales refs/heads, y es segura sin cambiar su copia de trabajo. Incluso he oído hablar de personas que se ejecutan git fetchperiódicamente en un trabajo cron en segundo plano (aunque no recomendaría hacer esto).

A git pulles lo que haría para actualizar una sucursal local con su versión remota, al tiempo que actualiza sus otras sucursales de seguimiento remoto.

Documentación de git - git pull :

En su modo predeterminado, git pulles una forma abreviada de git fetchseguido por git merge FETCH_HEAD.

Greg Hewgill
fuente
326
"Un" git pull "es lo que harías para actualizar tu repositorio" <- ¿la actualización del repositorio ya no se realiza por fetch? ¿no quiere decir que actualiza sus sucursales locales con las sucursales remotas? Para fusionar: fusiona las ramas remotas con sus copias locales de esas ramas, ¿o qué combina exactamente aquí?
Albert
194
@ Albert: Sí, está extrañamente redactado. git pullsiempre se fusionará con la rama actual . Así que selecciona qué rama desea extraer a partir , y se tira de ella en la rama actual. La rama from puede ser local o remota; incluso puede ser una rama remota que no está registrada git remote(lo que significa que pasa una URL en la git pulllínea de comando).
intuido
129129
@espertus: No. Empujar nunca se fusiona automáticamente. Se espera que el usuario tire, resolviendo cualquier conflicto de fusión localmente, luego empuje hacia el control remoto.
Greg Hewgill
33
Si estoy en /home/alice/y hago git fetch /home/bob, ¿qué parámetros debo pasar al siguiente git merge?
ripper234
106
Nota para las personas que aprenden Git: en pullrealidad no puede ser emulado por un fetchplus a merge. Acabo de obtener un cambio donde solo cambia un puntero de rama remoto, y se mergeniega a hacer nada. pull, por otro lado, avanza rápidamente mi rama de seguimiento.
Roman Starkov
2173
  • Cuando lo usas pull, Git intenta hacer automáticamente tu trabajo por ti. Es sensible al contexto , por lo que Git fusionará cualquier confirmación extraída en la rama en la que está trabajando actualmente. pull Combina automáticamente las confirmaciones sin permitirle que las revise primero . Si no administra de cerca sus sucursales, puede encontrarse con conflictos frecuentes.

  • Cuando usted fetch, Git recopila cualquier confirmación de la rama de destino que no existe en su rama actual y la almacena en su repositorio local . Sin embargo, no los fusiona con su rama actual . Esto es particularmente útil si necesita mantener actualizado su repositorio, pero está trabajando en algo que podría romperse si actualiza sus archivos. Para integrar los commits en su rama maestra, usted usa merge.

Mouna Cheikhna
fuente
34
De acuerdo, gran comentario. Es por eso que odio git pull. ¿Cuándo tendría sentido dejar que una herramienta de revisión haga ediciones de código por usted? ¿Y no es eso lo que está haciendo la fusión de dos archivos? ¿Qué pasa si esas dos ediciones están físicamente separadas en el archivo, pero LÓGICAMENTE en desacuerdo?
Lee Dixon
126
@elexhobby abreviado, git fetchsolo actualiza su .git/directorio (AKA: repositorio local) y nada fuera .git/(AKA: árbol de trabajo). No cambia sus sucursales locales, y tampoco toca master. Sin remotes/origin/masterembargo, toca (ver git branch -avv). Si tienes más controles remotos, inténtalo git remote update. Esto es git fetchpara todos los controles remotos en un solo comando.
Tino
24
@Tino el tuyo es realmente el punto más importante. Es posible que la gente no sepa que las ramas "remotas" en realidad se almacenan como un montón de hashes .git/refs/remotes/origin/.
Chris
13
Cuando busca, Git recopila cualquier confirmación de la rama de destino que no existe en su rama actual y la almacena en su repositorio local : ¿cómo veo lo que se trajo del control remoto y cómo lo combino en mis ramas locales?
ア レ ッ ク ス
13
@Tino Lo que todavía no entiendo es ... ¿cuál es el punto? ¿Por qué usar fetch si solo se actualiza .git? ¿Cuál es el beneficio previsto y qué se supone que debo hacer después de eso?
BadHorsie
1210

Es importante contrastar la filosofía de diseño de git con la filosofía de una herramienta de control de fuente más tradicional como SVN.

Subversion fue diseñado y construido con un modelo cliente / servidor. Hay un único repositorio que es el servidor, y varios clientes pueden obtener el código del servidor, trabajar en él y luego volver a enviarlo al servidor. Se supone que el cliente siempre puede contactar al servidor cuando necesita realizar una operación.

Git fue diseñado para admitir un modelo más distribuido sin necesidad de un repositorio central (aunque ciertamente puede usar uno si lo desea). También git fue diseñado para que el cliente y el "servidor" no necesiten estar en línea al mismo tiempo. Git fue diseñado para que las personas en un enlace poco confiable pudieran intercambiar código por correo electrónico, incluso. Es posible trabajar completamente desconectado y grabar un CD para intercambiar código a través de git.

Para admitir este modelo, git mantiene un repositorio local con su código y también un repositorio local adicional que refleja el estado del repositorio remoto. Al mantener una copia del repositorio remoto localmente, git puede descubrir los cambios necesarios incluso cuando no se puede acceder al repositorio remoto. Más adelante, cuando necesite enviar los cambios a otra persona, git puede transferirlos como un conjunto de cambios desde un punto en el tiempo conocido por el repositorio remoto.

  • git fetch es el comando que dice "actualizar mi copia local del repositorio remoto".

  • git pull dice "llevar los cambios en el repositorio remoto a donde guardo mi propio código".

Normalmente lo git pullhace haciendo un git fetchpara actualizar la copia local del repositorio remoto y luego fusionando los cambios en su propio repositorio de código y posiblemente su copia de trabajo.

La conclusión es tener en cuenta que a menudo hay al menos tres copias de un proyecto en su estación de trabajo. Una copia es su propio repositorio con su propio historial de confirmación. La segunda copia es su copia de trabajo donde está editando y construyendo. La tercera copia es su copia local "en caché" de un repositorio remoto.

MikeD
fuente
75
Técnicamente, los repositorios locales y remotos son realmente uno y el mismo. En Git, un repositorio es un DAG de commits que apuntan a sus padres. Las ramas son, técnicamente, nada más que nombres significativos de commits. La única diferencia entre las ramas locales y remotas es que las remotas tienen el prefijo remoteName/ Git desde cero, es una muy buena lectura. Una vez que entiendes cómo funciona Git, y es realmente simple , todo tiene sentido.
Emil Lundberg
13
Muchas gracias por la explicación. Realmente no entendía hasta ahora que Git fue diseñado, por lo que no era necesario tener un repositorio central. Todos siempre dicen "DVCS" cuando describen Git, pero como un programador relativamente nuevo, eso no significa nada para mí. Nunca he visto un CVCS, y tampoco he trabajado con un repositorio remoto central al colaborar con otros (es decir, Github), así que hasta ahora todavía no he entendido qué hizo a Git especial.
Brian Peterson
77
Entonces, en base a esto, ¿por qué NO es una buena idea obtener un trabajo cronológico? Siempre es una buena idea mantener una copia del control remoto con el que está trabajando en su máquina local. De hecho, tengo ganas de escribir un script que verifique si he actualizado mi control remoto en las últimas 24 horas y lo vinculo con un enlace udev para conexión a internet.
Brian Peterson
24
Una de las razones por las que NO es una buena idea tener un trabajo cron: a menudo, cuando trabajo en un boleto nuevo o en actualizaciones de una sucursal, me gusta ver los cambios que se obtienen. Si los cambios no llegan durante una recuperación, tendré más confianza para preguntarle a mi compañero programador "¿Oye, presionaste?". También tengo una idea de cuánto 'abandono' en el repositorio desde la última vez que busqué. Esto también ayuda a darme una idea de la cantidad y la velocidad de los cambios que se realizan actualmente en este repositorio.
Michael Durrant
55
@Nabheet Thing es que Git está orientado al contenido. Almacena datos solo una vez y los señala varias veces. Es por eso que en Git, incluso las confirmaciones múltiples sobre un original no afectan mucho el tamaño del repositorio, ya que la mayoría de los objetos son iguales.
cst1992
890

Aquí está la imagen de Oliver Steele de cómo encaja todo :

ingrese la descripción de la imagen aquí

Si hay suficiente interés, supongo que podría actualizar la imagen para agregar git cloney git merge...

Aplazamiento de pago
fuente
156
¡Una imagen actualizada con git cloney git mergesería muy útil!
MEMark
20
Sí, agregue git merge: debe mostrar claramente que mergellamar por separado NO es lo mismo que llamar pullporque se pullestá fusionando solo desde remoto e ignora sus confirmaciones locales en su rama local que está rastreando la rama remota desde la que se extrae.
JustAMartin
12
¡Una imagen vale mas que mil palabras! ¿La imagen actualizada con flujo de datos de clonación y fusión está lista en alguna parte? ¿Algún otro flujo de datos además de lo que ya está en el diagrama?
shikhanshu
10
@Contango, por favor agregue clon y fusione. Sería útil para los novatos como yo.
alquila el
11
Hay dos diagramas que muestran clonar y fusionar en otras respuestas (a continuación) por th3sly y thedarkpassenger.
intotecho
488

Un caso de uso git fetches que lo siguiente le indicará cualquier cambio en la rama remota desde su última extracción ... para que pueda verificar antes de realizar una extracción real, lo que podría cambiar los archivos en su rama actual y copia de trabajo.

git fetch
git diff ...origin

Consulte: https://git-scm.com/docs/git-diff con respecto a la sintaxis de doble y triple punto en el comando diff

mepster
fuente
99
¿por qué no git diff ..origin?
Erik Kaplun
3
git diff origin y git diff ..origin parecen funcionar pero no es raro ... cosas
Marc
19
@Compustretch No se suponía que hubiera un espacio. git diff ...origines equivalente a git diff $(git-merge-base HEAD origin) origin(vea la git diff [--options] <commit>...<commit> [--] [<path>…]sección de kernel.org/pub/software/scm/git/docs/git-diff.html#_description ), que es diferente de git diff origin; git diff ...origines conceptualmente los cambios realizados origindesde que la rama actual se bifurcó origin, mientras que git diff origintambién incluye el reverso de los cambios realizados en la rama actual desde que se bifurcó origin.
Max Nanasy
2
ninguno de los comandos ... funcionó para mí (en Windows), pero git diff origin/masterfunciona, como se menciona a continuación
Brian Burns
lo mismo aquí usando git 2.0.0 en OSX. Ninguno de estos comandos funcionó. ¿Han sido desaprobados?
K.-Michael Aye
373

Me costó un poco entender cuál era la diferencia, pero esta es una explicación simple. masteren tu localhost hay una rama.

Cuando clonas un repositorio, obtienes todo el repositorio para tu host local. Esto significa que en ese momento tiene un puntero de origen / maestro HEADy un maestro apuntando al mismo HEAD.

cuando empiezas a trabajar y haces commits avanzas el puntero maestro a HEAD+ tus commits. Pero el puntero de origen / maestro todavía apunta a lo que era cuando clonó.

Entonces la diferencia será:

  • Si lo hace git fetch, solo obtendrá todos los cambios en el repositorio remoto ( GitHub ) y moverá el puntero de origen / maestro a HEAD. Mientras tanto, su maestro de sucursal local seguirá señalando hacia dónde tiene.
  • Si hace un git pull, básicamente buscará (como se explicó anteriormente) y combinará cualquier cambio nuevo en su rama maestra y moverá el puntero a HEAD.
Gerardo
fuente
14
origin / master es una rama local que es una COPIA de master on origin. Cuando busca, actualiza local: / origin / master. Una vez que realmente entiendes que todo en git es una sucursal, esto tiene mucho sentido y es una forma muy poderosa de mantener diferentes conjuntos de cambios, hacer sucursales locales rápidas, fusionar y rebase, y generalmente obtener mucho valor de la ramificación barata modelo.
cam8001
3
Aún confuso. Pensé git fetchque, literalmente, debía descargar los cambios en el repositorio remoto en su repositorio local, pero NO confirmarlos, es decir, aún deben agregarse / confirmarse en su repositorio local.
krb686
3
fetch solo extrae de remoto / origen (github) a su origen local. Pero no se fusiona con sus archivos de trabajo reales. si haces un tirón, se buscará y se fusionará con tus archivos de trabajo actuales
Gerardo
223

A veces, una representación visual ayuda.

ingrese la descripción de la imagen aquí

thedarkpassenger
fuente
18
Creo que la imagen muestra que también afecta al repositorio local. Es decir, Git pull es una combinación de afectar el repositorio local y la copia de trabajo. En este momento parece que solo afecta la copia de trabajo.
nonopolaridad
10
@ 太極 者 無極 而 生 De acuerdo: esta imagen es bastante engañosa, porque hace que parezca que se git pullestá omitiendo la búsqueda, que por supuesto es inexacta.
forresthopkinsa
99
¿Cuál es la diferencia entre un 'Repositorio local' y una 'Copia de trabajo'? ¿No son ambos locales en la computadora?
theITvideos
1
¿Cuál es el uso de git fetch entonces? ¿Cómo ver qué diferencia hay en el repositorio local y la copia de trabajo?
Vikash
2
@theITvideos No, no lo es. Un repositorio local es donde va su código (desde el repositorio de trabajo) cuando se compromete. (Va al repositorio remoto cuando presiona).
Vikash
219

Brevemente

git fetches similar pullpero no se fusiona. es decir, obtiene actualizaciones remotas ( refsy objects) pero su local permanece igual (es decir, origin/masterse actualiza pero masterpermanece igual).

git pull se despliega desde un control remoto y se fusiona instantáneamente.

Más

git clone clona un repositorio.

git rebaseguarda cosas de su rama actual que no está en la rama aguas arriba en un área temporal. Su rama ahora es la misma que antes de comenzar sus cambios. Por lo tanto, git pull -rebasedesplegará los cambios remotos, rebobinará su sucursal local, reproducirá sus cambios en la parte superior de su sucursal actual, uno por uno, hasta que esté actualizado.

Además, git branch -ale mostrará exactamente lo que está sucediendo con todas sus sucursales, locales y remotas.

Esta publicación de blog fue útil:

La diferencia entre git pull, git fetch y git clone (y git rebase) - Mike Pearce

y cubiertas git pull, git fetch, git cloney git rebase.

====

ACTUALIZAR

Pensé en actualizar esto para mostrar cómo usarías esto en la práctica.

  1. Actualice su repositorio local desde el control remoto (pero no combine):

    git fetch 
    
  2. Después de descargar las actualizaciones, veamos las diferencias:

    git diff master origin/master 
    
  3. Si está satisfecho con esas actualizaciones, combine:

    git pull
    

Notas:

En el paso 2: para obtener más información sobre las diferencias entre locales y remotos, consulte: ¿Cómo comparar una rama git local con su rama remota?

En el paso 3: Probablemente sea más preciso (por ejemplo, en un repositorio que cambia rápidamente) hacer un git rebase originaquí. Vea el comentario de @Justin Ohms en otra respuesta.

Ver también: http://longair.net/blog/2009/04/16/git-fetch-and-merge/

Snowcrash
fuente
1
Me parece que si alguien solo quiere que el código local refleje "la sugerencia", debería usarlo git clone. Pongo el consejo entre comillas, ya que supongo que significaría lo que sea maestro y lo que alguien "descargaría como zip" de github.com
Chris K
3
¿Qué pasa si no estás satisfecho con los cambios después de obtener Git Fetch? que hacer despues
Kugutsumen
Su párrafo sobre rebase fue justo lo que estaba buscando. Toda la idea de reducir todo a cero, actualizar desde el control remoto y luego volver a reproducir los cambios además de las confirmaciones anteriores que ocurrieron mientras trabajaba. Explicación perfecta suponiendo que sea correcta. ;)
coblr
178
git-pull: recupera y combina con otro repositorio o una rama local
SINOPSIS

git pull ...
DESCRIPCIÓN

Ejecuta git-fetch con los parámetros dados y llama a git-merge para fusionar el 
cabeza (s) recuperada en la rama actual. Con --rebase, llama a git-rebase
en lugar de git-merge.

Tenga en cuenta que puede usar. (directorio actual) como <repository> para extraer
del repositorio local: esto es útil al fusionar sucursales locales 
en la rama actual.

También tenga en cuenta que las opciones destinadas a git-pull en sí y git-merge subyacente 
debe darse antes de las opciones destinadas a git-fetch.

Tirarías si quisieras fusionar las historias, buscarías si solo 'quieres el codez' ya que alguna persona ha estado etiquetando algunos artículos por aquí.

Vinko Vrsalovic
fuente
55
Muy interesante, pero realmente no puedo ver un caso de uso en el que quieras "solo el código". ¿Y qué sucede con tu código cuando buscas? ¿Se borra? ¿Qué sucede con los cambios remotos? ¿Cómo entra en su repositorio sin borrar su código si no se fusiona?
e-satis
11
@ e-satis: la rama remota también se almacena localmente en su máquina. Entonces, cuando lo hace git fetch, recupera los cambios del repositorio y actualiza su sucursal remota local. No afecta a su sucursal local que rastrea la sucursal remota local, por lo que no afecta a su copia de trabajo. Ahora, cuando haga una merge, fusionará los cambios recuperados con su sucursal local.
jeffreyveon
Un caso de uso simple para el comando fetch: realice operaciones que consuman mucho tiempo involucrando los commits recientes de otras personas, como una fusión o una revisión de código, accediendo solo a su repositorio local actualizado sin requisitos de conectividad de red, porque anteriormente utilizó fetch para descargar todo lo que necesita rápidamente (por ejemplo, mientras visita a otro desarrollador y se conecta a la red de otro repositorio). El comando pull descargaría los mismos commits, pero la fusión que realiza puede ser indeseable.
Lorenzo Gatti
163

Puede buscar desde un repositorio remoto, ver las diferencias y luego extraer o fusionar.

Este es un ejemplo para un repositorio remoto llamado originy una rama llamada masterseguimiento de la rama remota origin/master:

git checkout master                                                  
git fetch                                        
git diff origin/master
git rebase origin master
Antonio Bardazzi
fuente
35
Probablemente desee omitir la extracción y simplemente hacer un "origen de rebase git" como último paso, ya que ya obtuvo los cambios. La razón es que alguien podría haber empujado los cambios en el tiempo transcurrido desde que realizó la recuperación y estos no habrían estado en recuperación en los que realizó la revisión de diferencias.
Justin Ohms
158

La respuesta corta y fácil es que git pullsimplemente es git fetchseguida por git merge.

Es muy importante tener en cuenta que git pullse fusionará automáticamente, le guste o no . Esto podría, por supuesto, dar lugar a conflictos de fusión. Digamos que su control remoto es originy su rama es master. Si git diff origin/masterantes de tirar, debe tener una idea de posibles conflictos de fusión y podría preparar su sucursal local en consecuencia.

Además de tirar y empujar, implican algunos flujos de trabajogit rebase , como este, que parafraseo del artículo vinculado:

git pull origin master
git checkout foo-branch
git rebase master
git push origin foo-branch

Si te encuentras en una situación así, puedes sentirte tentado a hacerlo git pull --rebase. A menos que realmente sepas lo que estás haciendo, te aconsejaría que no. Esta advertencia es de la manpágina para la git-pullversión 2.3.5:

Este es un modo de operación potencialmente peligroso. Reescribe el historial, que no es un buen augurio cuando ya publicaste ese historial. No use esta opción a menos que haya leído git-rebase (1) cuidadosamente.

jfmercer
fuente
2
@JustinOhms Si git pull --rebaseno es lo correcto en la situación dada, ¿es correcto si se hace en dos pasos? Si es lo correcto, ¿cuál es el beneficio adicional de hacerlo en dos pasos?
Kaz
@Kaz: porque el rebase no es automático. Obtener los cambios primero le permite realizar la llamada de juicio. No soluciona el problema con el historial de rebase que ya ha empujado. Le permitirá ver si es seguro modificar los cambios que aún no ha presionado.
Justin Ohms
2
@JustinOhms ¿Cómo decidiría si es seguro cambiar los cambios? Simplemente intentaría git rebase y retrocedería si hacía un desastre, en cuyo caso también podría hacer git pull --rebase. Pero tal vez tienes otra manera?
Kaz
3
@KaZ gitk le permite ver la estructura de la rama visualmente. Le mostrará la posición de su jefe local, controles remotos y las estructuras de sus ramas en relación con lo que ha obtenido. De esta manera, puede asegurarse de no volver a crear cambios recuperados que se basan en un antepasado anterior a lo que ya ha enviado a su (s) control (es) remoto (s).
Justin Ohms
Úselo rebasecuando trabaje en una sucursal local que aún no se haya enviado. Si está trabajando en una rama que existe en el control remoto, rebasepuede ocasionar algunos problemas desagradables, por lo que debe preferir una regular merge.
Justus Romijn
151

OK , aquí hay información sobre , git pully git fetchpara que pueda comprender las diferencias reales ... en pocas palabras, fetch obtiene los datos más recientes, pero no los cambios en el código y no va a alterar su código de sucursal local actual, pero tire get el código cambia y se fusiona con su sucursal local, siga leyendo para obtener más detalles sobre cada uno:

git fetch

Descargará todas las referencias y objetos y cualquier rama nueva a su repositorio local ...

Obtenga ramas y / o etiquetas (colectivamente, "referencias") de uno o más repositorios, junto con los objetos necesarios para completar sus historias. Las ramas de seguimiento remoto se actualizan (consulte la descripción a continuación para conocer las formas de controlar este comportamiento).

Por defecto, también se recupera cualquier etiqueta que apunta a las historias que se están recuperando; el efecto es buscar etiquetas que apuntan a las ramas que le interesan. Este comportamiento predeterminado se puede cambiar usando las opciones --tags o --no-tags o configurando remote..tagOpt. Al usar una especificación de referencia que busca etiquetas explícitamente, también puede buscar etiquetas que no apuntan a las ramas que le interesan.

git fetch puede buscar desde un único repositorio con nombre o URL, o desde varios repositorios a la vez si se proporciona y hay un control remoto. entrada en el archivo de configuración. (Ver git-config 1 ).

Cuando no se especifica ningún control remoto, de manera predeterminada se usará el control remoto de origen, a menos que haya una rama ascendente configurada para la rama actual.

Los nombres de las referencias que se obtienen, junto con los nombres de los objetos a los que apuntan, se escriben en .git / FETCH_HEAD. Esta información puede ser utilizada por scripts u otros comandos git, como git-pull.


git pull

Aplicará los cambios de la sucursal remota a la actual en local ...

Incorpora cambios desde un repositorio remoto en la rama actual. En su modo predeterminado, git pull es la abreviatura de git fetch seguido de git merge FETCH_HEAD.

Más precisamente, git pull ejecuta git fetch con los parámetros dados y llama a git merge para fusionar las cabezas de rama recuperadas en la rama actual. Con --rebase, ejecuta git rebase en lugar de git merge.

debe ser el nombre de un repositorio remoto como se pasa a git-fetch 1 . puede nombrar una referencia remota arbitraria (por ejemplo, el nombre de una etiqueta) o incluso una colección de referencias con las correspondientes ramas de seguimiento remoto (por ejemplo, refs / heads / : refs / remotes / origin / ), pero generalmente es el nombre de una rama en el repositorio remoto.

Los valores predeterminados para y se leen desde la configuración "remota" y "fusionar" para la rama actual establecida por git-branch --track.


También creo el siguiente visual para mostrarle cómo git fetchy git pulltrabajar juntos ...

git pull y git fetch

Alireza
fuente
10
Si le gusta la imagen, eche un vistazo a la hoja de trucos de git, que es el mismo tipo de cosas para todos los comandos de git ... ndpsoftware.com/git-cheatsheet.html
Tom
3
¿La clonación también afecta el repositorio local (copiando todo el historial de forma remota)?
Tom Loredo
135

ingrese la descripción de la imagen aquí

Esta representación gráfica interactiva es muy útil para comprender git: http://ndpsoftware.com/git-cheatsheet.html

git fetchsimplemente "descarga" los cambios desde el remoto a su repositorio local. git pulldescarga los cambios y los combina en su sucursal actual. "En su modo predeterminado, git pulles la abreviatura de git fetchseguido por git merge FETCH_HEAD".

th3sly
fuente
18
Gente, haga clic en el enlace para interactuar con las diferentes columnas. Esta hoja de trucos es el mejor recurso que he visto para comprender completamente las diferencias entre cada comando.
M. Luisa Carrión
Esta respuesta debe ir a la cima
Tessaracter
126

Prima:

Al hablar de pull & fetch en las respuestas anteriores, me gustaría compartir un truco interesante,

git pull --rebase

Este comando anterior es el comando más útil en mi vida git que ahorró mucho tiempo.

Antes de enviar sus nuevos commits al servidor, pruebe este comando y sincronizará automáticamente los últimos cambios del servidor (con fetch + merge) y colocará su commit en la parte superior en git log. No necesita preocuparse por la extracción / fusión manual.

Encuentre detalles en: http://gitolite.com/git-pull--rebase

Sazzad Hissain Khan
fuente
44
Un buen consejo, aunque vale la pena mencionar a los nuevos usuarios de git que rebase modifica los hashes de confirmación (me pareció sorprendente viniendo de la subversión).
AlexMA
1
¿Puedes explicar cuál es la diferencia entre git pully git pull --rebase?
shaijut
2
Vea la clara advertencia sobre este método en una respuesta anterior: stackoverflow.com/a/6011169/241244
118

Me gusta tener una representación visual de la situación para comprender estas cosas. Tal vez a otros desarrolladores también les gustaría verlo, así que aquí está mi adición. No estoy totalmente seguro de que todo sea correcto, así que comente si encuentra algún error.

                                         LOCAL SYSTEM
                  . =====================================================    
================= . =================  ===================  =============
REMOTE REPOSITORY . REMOTE REPOSITORY  LOCAL REPOSITORY     WORKING COPY
(ORIGIN)          . (CACHED)           
for example,      . mirror of the      
a github repo.    . remote repo
Can also be       .
multiple repo's   .
                  .
                  .
FETCH  *------------------>*
Your local cache of the remote is updated with the origin (or multiple
external sources, that is git's distributed nature)
                  .
PULL   *-------------------------------------------------------->*
changes are merged directly into your local copy. when conflicts occur, 
you are asked for decisions.
                  .
COMMIT            .                             *<---------------*
When coming from, for example, subversion, you might think that a commit
will update the origin. In git, a commit is only done to your local repo.
                  .
PUSH   *<---------------------------------------*
Synchronizes your changes back into the origin.

Algunas de las principales ventajas de tener un espejo del control remoto son:

  • Rendimiento (desplácese por todas las confirmaciones y mensajes sin intentar exprimirlo a través de la red)
  • Comentarios sobre el estado de su repositorio local (por ejemplo, uso el SourceTree de Atlassian, que me dará una bombilla que indica si estoy comprometido adelante o atrás en comparación con el origen. Esta información se puede actualizar con un GIT FETCH).
Justus Romijn
fuente
¿No git pullse realiza también una fusión, es decir, ir hasta la copia de trabajo?
Kamiel Wanrooij
Buen punto, sí, pondrá todos los cambios en su copia de trabajo, y luego puede confirmarlo usted mismo en el repositorio local. Actualizaré lo visual.
Justus Romijn
@JustusRomijn ¿Un pull no actualiza también el repositorio local? ¿No debería haber un asterisco entre el origen y los asteriscos de la copia de trabajo?
user764754
2
@ user764754 Cuando tira, su copia de trabajo obtiene los cambios (también puede haber algunos conflictos que deba resolver). Todavía tiene que confirmarlo en su repositorio local.
Justus Romijn
@JustusRomijn: Gracias por la ilustración. Sería genial si pudieras hacer que el diagrama sea más completo al ilustrar los efectos de operaciones como reinicio, selección de cereza en los estados del repositorio.
jith912
106

He luchado con esto también. De hecho, llegué aquí con una búsqueda en Google de exactamente la misma pregunta. Al leer todas estas respuestas, finalmente pinté una imagen en mi cabeza y decidí intentar descifrar esto mirando el estado de los 2 repositorios y 1 caja de arena y las acciones realizadas a lo largo del tiempo mientras miraba la versión de ellas. Así que aquí está lo que se me ocurrió. Por favor corrígeme si me equivoqué en alguna parte.

Los tres repositorios con una búsqueda:

---------------------     -----------------------     -----------------------
- Remote Repo       -     - Remote Repo         -     - Remote Repo         -
-                   -     - gets pushed         -     -                     -
- @ R01             -     - @ R02               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Repo        -     - Local Repo          -     - Local Repo          -
- pull              -     -                     -     - fetch               -
- @ R01             -     - @ R01               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Sandbox     -     - Local Sandbox       -     - Local Sandbox       -
- Checkout          -     - new work done       -     -                     -
- @ R01             -     - @ R01+              -     - @R01+               -
---------------------     -----------------------     -----------------------

Los tres repos con un tirón

---------------------     -----------------------     -----------------------
- Remote Repo       -     - Remote Repo         -     - Remote Repo         -
-                   -     - gets pushed         -     -                     -
- @ R01             -     - @ R02               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Repo        -     - Local Repo          -     - Local Repo          -
- pull              -     -                     -     - pull                -
- @ R01             -     - @ R01               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Sandbox     -     - Local Sandbox       -     - Local Sandbox       -
- Checkout          -     - new work done       -     - merged with R02     -
- @ R01             -     - @ R01+              -     - @R02+               -
---------------------     -----------------------     -----------------------

Esto me ayudó a entender por qué una búsqueda es muy importante.

pn1 amigo
fuente
No es tan difícil de leer: los cuadros representan el estado de un repositorio, que en cada fila cambia de tiempo de izquierda a derecha después de la operación informada en la fila 2 del cuadro. Las etiquetas R0n son etiquetas en git, y una etiqueta con un + todavía es material no confirmado. Sanbox se usa para su carpeta de trabajo, que es diferente de la carpeta de repositorio, donde se almacenan las cosas comprometidas.
user1708042
96

La diferencia entre GIT Fetch y GIT Pull se puede explicar con el siguiente escenario: (¡Teniendo en cuenta que las imágenes hablan más que las palabras! He proporcionado una representación gráfica)

Tomemos un ejemplo de que está trabajando en un proyecto con los miembros de su equipo. Por lo tanto, será una Rama principal del proyecto y todos los contribuyentes deben bifurcarlo a su propio repositorio local y luego trabajar en esta rama local para modificar / Agregar módulos y luego regresar a la rama principal.

Así, estado inicial de las dos ramas cuando se bifurcó el principal proyecto en su repositorio local será como esto: ( A, By Cson módulos ya se ha completado del proyecto)

ingrese la descripción de la imagen aquí

Ahora, que ha empezado a trabajar en el nuevo módulo (supongamos D) y cuando haya completado el Dmódulo que desea empujar a la rama principal, pero mientras tanto lo que pasa es que uno de sus compañeros de equipo ha desarrollado un nuevo módulo E, Fy modificado C.
Entonces, ahora lo que sucedió es que su repositorio local carece del progreso original del proyecto y, por lo tanto, empujar sus cambios a la rama principal puede provocar conflictos y puede causar un Dmal funcionamiento de su Módulo .

ingrese la descripción de la imagen aquí

Para evitar tales problemas y trabajar en paralelo con el progreso original del proyecto, hay dos maneras:

1. Git Fetch: esto descargará todos los cambios que se han realizado en el proyecto de sucursal principal / origen que no están presentes en su sucursal local. Y esperará a que el comando Git Merge aplique los cambios que se han obtenido en su Repositorio o rama.

ingrese la descripción de la imagen aquí

Así que ahora puede monitorear cuidadosamente los archivos antes de fusionarlos en su repositorio. Y también puede modificar Dsi es necesario debido a Modificado C.

ingrese la descripción de la imagen aquí

2. Git Pull: esto actualizará su rama local con la rama principal / de origen, es decir, en realidad lo que hace es una combinación de Git Fetch y Git fusionan una tras otra. Pero esto puede causar conflictos, por lo que se recomienda usar Git Pull con una copia limpia.

ingrese la descripción de la imagen aquí

Aman Tiwari
fuente
1
si pudieras cambiar 'Main Branch' a 'Remote Repo', sería una gran respuesta.
Qibiron que
87

Simplemente decimos:

git pull == git fetch + git merge

Si ejecuta git pull, no necesita fusionar los datos a local. Si ejecuta git fetch, significa que debe ejecutar git mergepara obtener el código más reciente en su máquina local. De lo contrario, el código de máquina local no se cambiaría sin combinar.

Entonces, en Git Gui, cuando obtienes, tienes que fusionar los datos. Fetch en sí no hará los cambios de código en su local. Puede verificar eso cuando actualice el código obteniendo una vez buscar y ver; El código no cambiará. Luego te unes ... Verás el código cambiado.

Selvamani
fuente
3
Prefiero decir git pull == git fetch + git merge:)
melvynkim
2
Perogit pull --rebase = git fetch + git rebase
Tino
83

git fetchextrae el código del servidor remoto a sus ramas de seguimiento en su repositorio local. Si el mando a distancia se llama origin(el valor predeterminado), entonces estas ramas estará dentro de origin/, por ejemplo origin/master, origin/mybranch-123,, etc. Estos no son sus ramas actuales, que son locales copias de esas ramas del servidor.

git pullhace un git fetchpero luego también combina el código de la rama de seguimiento en su versión local actual de esa rama. Si aún no está listo para esos cambios, solo git fetchprimero.

Michael Durrant
fuente
78

git fetchrecuperará ramas remotas para que pueda git diffo git mergeellos con la rama actual. git pullejecutará fetch en el brach remoto seguido por la rama actual y luego combinará el resultado. Puede usar git fetchpara ver si hay actualizaciones para la sucursal remota sin necesidad de fusionarlas con su sucursal local.

ntanase
fuente
73

Git Fetch

Descarga los cambios en su sucursal local desde el origen a través de la búsqueda. Fetch le pide al repositorio remoto todas las confirmaciones que otros han realizado pero que usted no tiene en su repositorio local. Fetch descarga estos commits y los agrega al repositorio local.

Git Merge

Puede aplicar los cambios descargados a través de fetch utilizando el comando merge. Merge tomará los commits recuperados de fetch e intentará agregarlos a su sucursal local. La fusión mantendrá el historial de confirmación de sus cambios locales para que cuando comparta su sucursal con push, Git sepa cómo otros pueden fusionar sus cambios.

Git Pull

Fetch y merge se ejecutan juntos con la frecuencia suficiente para crear un comando que combine los dos, pull. Pull realiza una búsqueda y luego una combinación para agregar los commits descargados a su sucursal local.

Pinkesh Sharma
fuente
51

La única diferencia entre git pully git fetches que:

git pull tira de una rama remota y la fusiona.

git fetch solo se obtiene de la rama remota pero no se fusiona

es decir, git pull = git fetch + git merge ...

Rohitashv Singhal
fuente
1
Y tampoco ayuda si git cree que estás atrasado por los commits y puedes "avanzar rápidamente", lo que al final terminé todo rm -rfy comencé de nuevo. Estúpido Git, ¿solo déjame ponerme al día para que pueda volver a trabajar?
Chris K
47

En términos simples, si estaba a punto de subirse a un avión sin conexión a Internet ... antes de partir, podría hacerlo git fetch origin <master>. Obtendría todos los cambios en su computadora, pero lo mantendría separado de su espacio de trabajo / desarrollo local.

En el avión, puede realizar cambios en su espacio de trabajo local y luego fusionarlo con lo que ha obtenido y resolver posibles conflictos de fusión, todo sin una conexión a Internet. Y a menos que alguien haya realizado nuevos cambios conflictivos en el repositorio remoto, una vez que llegue al destino, lo haría git push origin <branch>e iría a buscar su café.


De este increíble tutorial de Atlassian :

El git fetchcomando descarga confirmaciones, archivos y referencias de un repositorio remoto en su repositorio local.

Buscar es lo que haces cuando quieres ver en lo que todos los demás han estado trabajando. Es similar a la actualización de SVN, ya que le permite ver cómo ha progresado el historial central, pero no le obliga a fusionar los cambios en su repositorio. Git aísla el contenido obtenido como contenido local existente , no tiene absolutamente ningún efecto en su trabajo de desarrollo local . El contenido recuperado se debe extraer explícitamente con el git checkoutcomando Esto hace que la búsqueda sea una forma segura de revisar las confirmaciones antes de integrarlas con su repositorio local.

Cuando la descarga de contenido desde un repositorio remoto, git pully git fetchcomandos están disponibles para realizar la tarea. Puede considerar git fetchla versión 'segura' de los dos comandos. Descargará el contenido remoto, pero no actualizará el estado de trabajo de su repositorio local, dejando intacto su trabajo actual. git pulles la alternativa más agresiva, descargará el contenido remoto para la rama local activa e inmediatamente se ejecutará git mergepara crear una confirmación de fusión para el nuevo contenido remoto. Si tiene cambios pendientes en progreso, esto provocará conflictos y dará inicio al flujo de resolución de conflictos de fusión.


Con git pull:

  • No tienes ningún aislamiento.
  • Afecta su desarrollo local.
  • No necesita ser desprotegido explícitamente. Porque implícitamente hace a git merge.
  • Básicamente NO es seguro. Es agresivo
  • A diferencia de git fetchdonde solo afecta a usted .git/refs/remotes, git pull afectará tanto a usted .git/refs/remotes como a .git/refs/heads/

Hmmm ... así que si no estoy actualizando la copia de trabajo git fetch, ¿dónde estoy haciendo los cambios? ¿Dónde almacena Git fetch los nuevos commits?

Gran pregunta Lo pone en algún lugar aislado de su copia de trabajo. Pero de nuevo, ¿dónde? Vamos a averiguar.

En su directorio de proyecto (es decir, donde realiza sus gitcomandos) haga:

  1. ls. Esto mostrará los archivos y directorios. Nada genial, lo sé.

  2. Ahora hazlo ls -a. Esto mostrará los archivos de puntos , es decir, archivos que comienzan con .A continuación, será capaz de ver un directorio llamado: .git.

  3. Hacer cd .git. Obviamente, esto cambiará su directorio.
  4. Ahora viene la parte divertida; hacer ls. Verá una lista de directorios. Estamos buscando refs. Hacer cd refs.
  5. Es interesante ver qué hay dentro de todos los directorios, pero centrémonos en dos de ellos. headsy remotes. Use cdpara verificar dentro de ellos también.
  6. Todo lo git fetch que haga actualizará los elementos en el /.git/refs/remotesdirectorio. No actualizará nada en el /.git/refs/headsdirectorio.
  7. Cualquiera git pull hará primero git fetch, actualizará los elementos en el /.git/refs/remotesdirectorio, luego se fusionará con su local y luego cambiará la cabecera dentro del /.git/refs/headsdirectorio.

También se puede encontrar una muy buena respuesta relacionada en ¿Dónde se ubica 'git fetch'? .

Además, busque "notación de barra" en la publicación de convenciones de nomenclatura de rama de Git . Le ayuda a comprender mejor cómo Git coloca las cosas en diferentes directorios.


Para ver la diferencia real

Solo haz:

git fetch origin master
git checkout master

Si se actualizó el maestro remoto, recibirá un mensaje como este:

Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Si no lo hiciste fetchy lo hiciste git checkout master, tu git local no sabría que hay 2 commits agregados. Y solo diría:

Already on 'master'
Your branch is up to date with 'origin/master'.

Pero eso está desactualizado e incorrecto. Es porque git te dará comentarios únicamente en función de lo que sabe. Es ajeno a las nuevas confirmaciones que aún no ha eliminado ...


¿Hay alguna forma de ver los nuevos cambios realizados en forma remota mientras se trabaja en la sucursal localmente?

Algunos IDE (por ejemplo, Xcode) son súper inteligentes y utilizan el resultado de git fetchay pueden anotar las líneas de código que se han cambiado en la rama remota de su rama de trabajo actual. Si esa línea ha sido modificada por los cambios locales y la rama remota, entonces esa línea se anota con rojo. Esto no es un conflicto de fusión. Es un posible conflicto de fusión. Es un aviso que puede usar para resolver el futuro conflicto de fusión antes de hacerlo git pulldesde la rama remota.

ingrese la descripción de la imagen aquí


Consejo divertido:

Si buscó una rama remota, por ejemplo:

git fetch origin feature/123

Entonces esto iría a su directorio de controles remotos. Todavía no está disponible para su directorio local. Sin embargo, simplifica su pago a esa rama remota por DWIM (haga lo que quiero decir):

git checkout feature/123

ya no necesitas hacer:

git checkout -b feature/123 origin/feature/123

Para más información sobre eso, lea aquí

Miel
fuente
1
Me gusta esta respuesta
Kid_Learning_C
44

Git permite aplicar confirmaciones cronológicamente más antiguas después de confirmaciones más nuevas. Debido a esto, el acto de transferir confirmaciones entre repositorios se divide en dos pasos:

  1. Copiar nuevas confirmaciones de la rama remota para copiar esta rama remota dentro del repositorio local.

    (operación de repositorio a repositorio) master@remote >> remote/origin/master@local

  2. Integrando nuevos compromisos a la sucursal local

    (operación dentro del repositorio) remote/origin/master@local >> master@local

Hay dos formas de realizar el paso 2. Puede:

  1. Bifurque la rama local después del último ancestro común y agregue nuevas confirmaciones paralelas a las confirmaciones que son exclusivas del repositorio local, finalizadas fusionando la confirmación y cerrando la bifurcación.
  2. Inserte nuevos commits después del último antecesor común y vuelva a aplicar commits únicos al repositorio local.

En gitterminología, el paso 1 es git fetch, el paso 2 es git mergeogit rebase

git pulles git fetchygit merge

Pawel Furmaniak
fuente
37

Git obtiene la rama de la última versión del control remoto al local usando dos comandos:

  1. git fetch: Git obtendrá la última versión de remota a local, pero no se fusionará automáticamente.      git fetch origin master git log -p master..origin/master git merge origin/master

         Los comandos anteriores significan que descargue la última versión de la rama principal desde el origen desde la rama maestra remota a la original. Y luego compara la rama maestra local y la rama maestra de origen. Finalmente, fusionarse.

  2. git pull: Git obtendrá la última versión del control remoto y se fusionará con el local.

        git pull origin master

         El comando anterior es el equivalente a git fetchy git merge. En la práctica, git fetchquizás sea más seguro porque antes de la fusión podemos ver los cambios y decidir si fusionamos.

Marcus Thornton
fuente
37

¿Cuál es la diferencia entre git pully git fetch?

Para comprender esto, primero debe comprender que su git local mantiene no solo su repositorio local, sino que también mantiene una copia local del repositorio remoto.

git fetchactualiza su copia local del repositorio remoto. Por ejemplo, si su repositorio remoto es GitHub, es posible que desee recuperar los cambios realizados en el repositorio remoto en su copia local del repositorio remoto. Esto le permitirá realizar operaciones como comparar o fusionar.

git pullpor otro lado, traerá los cambios en el repositorio remoto donde guarda su propio código. Por lo general, git pullva a hacer una git fetchprimera para llevar la copia local del repositorio remoto hasta la fecha, y luego se fusionará los cambios en su propio repositorio de código y, posiblemente, su copia de trabajo.

Donal
fuente
35

git pull == (git fetch + git merge)

git fetch no cambia a las sucursales locales.

Si ya tiene un repositorio local con una configuración remota para el proyecto deseado, puede tomar todas las ramas y etiquetas para el control remoto existente usando git fetch. ... Fetch no realiza ningún cambio en las ramas locales, por lo que deberá fusionar una rama remota con una rama local emparejada para incorporar los cambios de recuperación nuevos. de github

Iggy
fuente
34

Tratando de ser claro y simple.

El comando git pull es en realidad un shortcutfor git fetch seguido por el comando git merge o el comando git rebase según su configuración. Puede configurar su repositorio Git para que git pull sea ​​una búsqueda seguida de una nueva versión.

Montells
fuente
33

Una representación gráfica simple para principiantes,

ingrese la descripción de la imagen aquí

aquí,

git pull  

buscará el código del repositorio y lo volverá a crear con su local ... en git pull existe la posibilidad de que se creen nuevas confirmaciones.

pero en ,

git fetch

buscará el código del repositorio y necesitamos volver a crearlo manualmente usando git rebase

por ejemplo: voy a buscar del servidor maestro y volverlo a crear en mi maestro local.

1) git pull (el rebase se realizará automáticamente):

git pull origin master

aquí el origen es tu maestro de repositorio remoto es tu sucursal

2) git fetch (necesita rebase de forma manual):

git fetch origin master

buscará los cambios del servidor desde el origen. y estará en tu local hasta que lo rebastes por tu cuenta. Necesitamos solucionar los conflictos manualmente al verificar los códigos.

git rebase origin/master

esto cambiará el código a local. antes de eso, asegúrese de estar en la rama correcta.

Mohideen bin Mohammed
fuente
Buen gráfico, pero es posible que desee explicar por qué usa "rebase" cuando el gráfico dice "fusionar".
Guntram Blohm apoya a Monica el
2
La combinación representará otra confirmación de rama y producirá una nueva confirmación que contiene confirmaciones como referencia. pero rebase replicará confirmaciones de otra rama, no creará nuevas confirmaciones en lugar de replicar
Mohideen bin Mohammed
33

En realidad, Git mantiene una copia de su propio código y el repositorio remoto.

El comando git fetchactualiza su copia local al obtener datos del repositorio remoto. La razón por la que necesitamos esto es porque alguien más podría haber realizado algunos cambios en el código y usted desea mantenerse actualizado.

El comando git pulltrae los cambios en el repositorio remoto a donde guarda su propio código. Normalmente, git pullhace esto haciendo una 'búsqueda de git' primero para actualizar la copia local del repositorio remoto, y luego combina los cambios en su propio repositorio de código y posiblemente su copia de trabajo.

Pokemon
fuente