¿Por qué el estado de git muestra que la sucursal está actualizada cuando existen cambios aguas arriba?

226

Los cambios existen aguas arriba en una rama rastreada, pero cuando escribo git status indica que mi rama local está actualizada. ¿Es este nuevo comportamiento, cambié una configuración o algo está mal?

Gracias por la ayuda.

ubuntu@host:/my/repo# git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean


ubuntu@host:/my/repo# git pull
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 11 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (11/11), done.
From bitbucket.org:my/repo
   1234567..abcdefg  master     -> origin/master
Updating 1234567..abcdefg
Fast-forward
 file1        |  1 -
 file2        | 43 +++++++++++++++++++++++++++++++++++++++++++
 file3        | 21 ++++++++++++---------
 file4        | 21 ++++++++++++---------
 4 files changed, 67 insertions(+), 19 deletions(-)
 create mode 100644 file5
GregB
fuente

Respuestas:

274

Lo que el estado te dice es que estás detrás del árbitro llamado, origin/master que es un árbitro local en tu repositorio local . En este caso, esa referencia pasa a rastrear una rama en algún control remoto, llamado origin, pero el estado no le dice nada sobre la rama en el control remoto. Le informa sobre la referencia, que es solo una ID de confirmación almacenada en su sistema de archivos local (en este caso, generalmente está en un archivo llamado .git/refs/remotes/origin/masteren su repositorio local).

git pullhace dos operaciones; primero hace una git fetchactualización de las confirmaciones en el repositorio remoto (que actualiza la origin/masterreferencia en su repositorio local), luego hace ungit merge para fusionar esas confirmaciones en la rama actual.

Hasta que realice el fetchpaso (ya sea solo o por medio git pull), su repositorio local no tiene forma de saber que hay confirmaciones adicionales en sentido ascendente, y git statussolo mira su origin/masterreferencia local .

Cuando git statusdice actualizado, significa "actualizado con la rama que rastrea la rama actual", que en este caso significa "actualizado con el árbitro local llamado origin/master". Eso solo equivale a "estar actualizado con el estado ascendente que se recuperó la última vez que hicimos un fetch" que no es lo mismo que "actualizado con el último estado en vivo del flujo ascendente".

¿Por qué funciona de esta manera? Bueno, el fetchpaso es una operación de red potencialmente lenta y costosa. El diseño de Git (y otros sistemas de control de versiones distribuidos ) es para evitar operaciones de red cuando no es necesario, y es un modelo completamente diferente al típico sistema cliente-servidor al que muchas personas están acostumbradas (aunque como se señala en los comentarios a continuación, el concepto de Git de una "rama de seguimiento remoto" que causa confusión aquí no es compartida por todos los DVCS). Es completamente posible usar Git sin conexión, sin conexión a un servidor centralizado, y la salida degit status refleja esto.

Se supone que crear y cambiar sucursales (y verificar su estado) en Git es liviano, no algo que realiza una operación de red lenta a un sistema centralizado. La suposición al diseñar Git, y la git statussalida, fue que los usuarios entienden esto (demasiadas características de Git solo tienen sentido si ya sabes cómo funciona Git). Con la adopción de Git por parte de muchos usuarios que no están familiarizados con DVCS, esta suposición no siempre es válida.

Jonathan Wakely
fuente
79
Un comentario tardío pero me encontré con la misma situación. Entiendo por qué git no tiene forma de saber acerca de los cambios antes de buscar. Pero entonces no debería decir "actualizado", lo cual simplemente no es cierto. Mejor debería decir "no tengo idea de lo que podría haber sucedido remotamente".
Droidum
31
Tal vez es estrictamente lógico, pero no es en absoluto humano razonable. ¿Por qué no lo diseñarías para HACER una búsqueda y ENTONCES declarar si está actualizado? ¿O cambie el mensaje para decir lo que realmente hizo, por ejemplo, "Su sucursal estaba actualizada con 'origen / maestro' cuando se verificó por última vez en {marca de hora}"? ¿O incluso decir: "Haga una búsqueda para saber si su sucursal está actualizada"?
Colin May
25
¿Por qué molestarse en mostrar el mensaje "Su sucursal está actualizada"? No veo ningún punto en conocer el estado de origen / maestro, y si se supone que representa la rama maestra real en el control remoto de origen, entonces claramente no tiene idea de todos modos.
whiterook6
2
@pastullo, así que crea un alias.
Jonathan Wakely
23
Este es un ejemplo perfecto de la usabilidad horrible de Git. Me encanta su poder y flexibilidad, pero simplemente cambiando el mensaje a algo como "Su sucursal está actualizada con la versión local de 'origin / master'". Sería una gran mejora. La confusión aquí es que el origen / maestro de la rama local (coincidencia de patrón con cualquier control remoto / rama que esté usando) que rastrea una rama remota.
matthewcummings516
35

Esto se debe a que su repositorio local no se ha registrado con los controles remotos ascendentes. Para que esto funcione como espera, utilice y git fetchluego ejecute ungit status nuevamente.

Ryan
fuente
7

Si bien todas estas son respuestas viables, decidí dar mi forma de verificar si el repositorio local está en línea con el control remoto, sin ir a buscarlo o extraerlo. Para ver dónde están mis ramas, simplemente uso:

git remote show origin

Lo que hace es devolver todas las ramas rastreadas actuales y lo más importante: la información si están actualizadas, adelante o detrás de las de origen remoto. Después del comando anterior, este es un ejemplo de lo que se devuelve:

  * remote origin
  Fetch URL: https://github.com/xxxx/xxxx.git
  Push  URL: https://github.com/xxxx/xxxx.git
  HEAD branch: master
  Remote branches:
    master      tracked
    no-payments tracked
  Local branches configured for 'git pull':
    master      merges with remote master
    no-payments merges with remote no-payments
  Local refs configured for 'git push':
    master      pushes to master      (local out of date)
    no-payments pushes to no-payments (local out of date)

Espero que esto ayude a alguien.

Skycube
fuente
0

"origen / maestro" se refiere a la referencia poiting a la confirmación HEAD de la rama "origen / maestro". Una referencia es un alias de nombre humano para un objeto Git, generalmente un objeto de confirmación. La referencia "origen / maestro" solo se actualiza cuando usted git pusha su control remoto ( http://git-scm.com/book/en/v2/Git-Internals-Git-References#Remotes ).

Desde la raíz de su proyecto, ejecute:

cat .git/refs/remotes/origin/master

Compare la ID de confirmación mostrada con:

cat .git/refs/heads/master

Deberían ser lo mismo, y es por eso que Git dice que masterestá actualizado origin/master.

Cuando corres

git fetch origin master

Eso recupera nuevos objetos Git localmente en la carpeta .git / objects. Y Git actualiza .git / FETCH_HEAD para que ahora apunte a la última confirmación de la rama obtenida.

Por lo tanto, para ver las diferencias entre su rama local actual y la rama obtenida desde arriba, puede ejecutar

git diff HEAD FETCH_HEAD
Marek Stanley
fuente
1
No debe colocar elementos en el directorio .git, no funcionará con referencias empaquetadas. Además, el comportamiento de búsqueda que describió es para versiones anteriores de git.
Andrew C
¿no origin/masterse actualiza la referencia también mediante una búsqueda, así como un impulso?
Jonathan Wakely
Correcto. Estaba usando Git 1.8.3 hasta ahora. De hecho, puedo notar que con la versión 2.2.1, FETCH_HEAD también se actualiza durante una recuperación. Además, cuando se trata del mensaje "Su sucursal está actualizada con ..." o "Su sucursal está detrás ... por X commits", solo aparece si su sucursal local rastrea una sucursal remota determinada. Para que master rastree origin / master, se debe ejecutar git branch -u origin / master desde branch master. Si no hay seguimiento, aún necesita ejecutar git diff.
Marek Stanley
Bueno, entonces te sugiero que corrijas la afirmación de que la referencia "origen / maestro" solo se actualiza cuando presionas tu control remoto "
Jonathan Wakely
0

Vamos a ver un repositorio git de muestra para verificar si your branch (master)está up to dateconorigin/master .

Verifique que el maestro local esté rastreando origen / maestro:

$ git branch -vv
* master a357df1eb [origin/master] This is a commit message

Más información sobre la sucursal maestra local:

$ git show --summary
commit a357df1eb941beb5cac3601153f063dae7faf5a8 (HEAD -> master, tag: 2.8.0, origin/master, origin/HEAD)
Author: ...
Date:   Tue Dec 11 14:25:52 2018 +0100

    Another commit message

Verifique si origin / master está en el mismo commit:

$ cat .git/packed-refs | grep origin/master
a357df1eb941beb5cac3601153f063dae7faf5a8 refs/remotes/origin/master

Podemos ver el mismo hash, y es seguro decir que la rama está en consistencia con la remota, al menos en el repositorio actual de git.

campo temático
fuente
0

probar con git add .antesgit commit

Dejan Baric llevo3
fuente
0

Respuesta trivial pero precisa en algunos casos, como la que me trajo aquí. Estaba trabajando en un repositorio que era nuevo para mí y agregué un archivo que el estado no veía como nuevo.

Resulta que el archivo coincide con un patrón en el archivo .gitignore.

Krustyengineer
fuente
0

en este caso use git add e integre todos los archivos pendientes y luego use git commit y luego git push

git add: integra todos los archivos pendientes

git commit - guarda el commit

git push: guardar en el repositorio

Airton Silveira
fuente