¿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
Lo que el estado te dice es que estás detrás del árbitro llamado, origin/masterque 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.
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.
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)
"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
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:
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.
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 fetch
luego ejecute ungit status
nuevamente.fuente
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:
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:
Espero que esto ayude a alguien.
fuente
"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 push
a su control remoto ( http://git-scm.com/book/en/v2/Git-Internals-Git-References#Remotes ).Desde la raíz de su proyecto, ejecute:
Compare la ID de confirmación mostrada con:
Deberían ser lo mismo, y es por eso que Git dice que
master
está actualizadoorigin/master
.Cuando corres
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
fuente
origin/master
se actualiza la referencia también mediante una búsqueda, así como un impulso?Vamos a ver un repositorio git de muestra para verificar si
your branch (master)
estáup to date
conorigin/master
.Verifique que el maestro local esté rastreando origen / maestro:
Más información sobre la sucursal maestra local:
Verifique si origin / master está en el mismo commit:
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.
fuente
probar con
git add .
antesgit commit
fuente
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.
fuente
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
fuente