'Git origen tirón MyBranch' deja MyBranch local N compromete por delante de origen. ¿Por qué?

StackOverflow https://stackoverflow.com/questions/1741143

  •  20-09-2019
  •  | 
  •  

Pregunta

Me acabo de observar algo extraño en git pull, lo que no entiendo.

El viernes, trabajé en una sucursal local. vamos a llamarlo mybranch. Antes de salir de la oficina empujé con el origen (que es mi github repo):. git push origin mybranch

Ayer en casa, pulled MyBranch a mi ordenador portátil, hecho un poco más de codificación, y luego empujó mis cambios de nuevo en GitHub (origen).

Ahora estoy en el trabajo de nuevo, y trató de tirar de los cambios de ayer a mi máquina de trabajo (que no cambia nada en la repo locales de mi lugar de trabajo durante el fin de semana):

git pull origin mybranch

que provocó un avance rápido se funden, lo cual está bien. Entonces hice un git status, y dijo:

# On branch mybranch
# Your branch is ahead of 'origin/mybranch' by 6 commits.
#
nothing to commit (working directory clean)

¿Eh? ¿Cómo puede ser 6 comete delante cuando ni siquiera toco el fin de semana, y apenas sacado de origen? Así que me encontré con un git diff origin/mybranch y los diferenciales eran exactamente los 6 cambios que acaba de sacar del mando a distancia.

Sólo podía "arreglar" esto git fetch origin ejecutando:

From git@github.com:me/project
af8be00..88b0738  mybranch -> origin/mybranch

Al parecer, mi repo local fue faltan algunos objetos de referencia, pero ¿cómo puede ser eso? Es decir, un tirón hace una ya buscar, y yo no trabajar en nada, excepto que la rama, por lo que un git fetch origin y git fetch origin mybranch deben tener el mismo resultado?

¿Debo utilizar siempre git pull origin en lugar de git pull origin branchname?

Estoy confundido.

¿Fue útil?

Solución

git pull llama git fetch con los parámetros adecuados antes de la fusión de las cabezas de forma explícita exageradas (o en su defecto la rama remoto configurado para la fusión) en la rama actual.

La sintaxis: git fetch <repository> <ref> donde <ref> es sólo un nombre de la sucursal sin colon es un 'un solo disparo' ir que no hace buscar a un estándar de todas las ramas de orugas de la distancia especificada pero en cambio obtiene sólo la rama llamada en FETCH_HEAD .

Actualización: para las versiones Git desde 1.8.4, si hay una rama de seguimiento a distancia que rastrea el árbitro que pedirá a buscar entonces la rama de seguimiento se actualizará por fetch. Este cambio se ha hecho específicamente para evitar la confusión que el comportamiento anterior causado.

Al realizar git pull <repository> <ref>, FETCH_HEAD se actualiza el anterior, entonces se combinó en su HEAD desprotegido, pero se actualizará ninguna de las ramas de seguimiento estándar para el repositorio remoto (Git <1.8.4). Esto significa que a nivel local que ve como si estuviera delante de la rama de distancia, mientras que, de hecho, que está al día con él.

Personalmente siempre hacer git fetch seguido por git merge <remote>/<branch> porque me permite ver las advertencias acerca de las actualizaciones forzadas antes de que se fusionan, y puedo obtener una vista previa de lo que estoy en la fusión. Si usara git pull un poco más que yo, lo haría git pull una llanura sin parámetros mayor parte del tiempo, basándose en branch.<branch>.remote y branch.<branch>.merge a 'hacer lo correcto'.

Otros consejos

Lo que hace rendimientos git remote -v show cuando se trata de origen?

Si origen apunta a github, el estado deben estar al día, y no delante de cualquier cesión temporal remoto. Por lo menos, con el Git1.6.5 estoy usando para una prueba rápida.

De todos modos, para evitar esto, definir explícitamente el repositorio remoto de rama principal:

$ git config branch.master.remote yourGitHubRepo.git

A continuación, una git pull origin master, seguido de un git status debe devolver un estado limpio (sin por delante).
¿Por qué? porque el maestro origen conseguir fetch (incluido en el maestro de origen git pull) no acaba de actualizar FETCH_HEAD (como Charles Bailey explica en su respuesta), pero sería también actualizar la "rama master a distancia" dentro de su repositorio Git local.
En ese caso, su maestro local no parecería ser más "delante" del maestro remoto.


Puedo probar esto, con un git1.6.5:

En primer lugar se crea un workrepo:

PS D:\git\tests> cd pullahead
PS D:\git\tests\pullahead> git init workrepo
Initialized empty Git repository in D:/git/tests/pullahead/workrepo/.git/
PS D:\git\tests\pullahead> cd workrepo
PS D:\git\tests\pullahead\workrepo> echo firstContent > afile.txt
PS D:\git\tests\pullahead\workrepo> git add -A 
PS D:\git\tests\pullahead\workrepo> git commit -m "first commit"

I simular un repo GitHub mediante la creación de un acuerdo de recompra desnudo (uno que puede recibir empuje desde cualquier lugar)

PS D:\git\tests\pullahead\workrepo> cd ..
PS D:\git\tests\pullahead> git clone --bare workrepo github

agrego un modif a mi repo de trabajo, que empujo a repo github (añadido como un mando a distancia)

PS D:\git\tests\pullahead> cd workrepo
PS D:\git\tests\pullahead\workrepo> echo aModif >> afile.txt
PS D:\git\tests\pullahead\workrepo> git ci -a -m "a modif to send to github"
PS D:\git\tests\pullahead\workrepo> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo> git push github

creo una cesión temporal casa, clonado de GitHub, en la que hago un par de modificaciones, empujó a GitHub:

PS D:\git\tests\pullahead\workrepo> cd ..
PS D:\git\tests\pullahead> git clone github homerepo
PS D:\git\tests\pullahead> cd homerepo
PS D:\git\tests\pullahead\homerepo> type afile.txt
firstContent
aModif

PS D:\git\tests\pullahead\homerepo> echo aHomeModif1  >> afile.txt
PS D:\git\tests\pullahead\homerepo> git ci -a -m "a first home modif"
PS D:\git\tests\pullahead\homerepo> echo aHomeModif2  >> afile.txt
PS D:\git\tests\pullahead\homerepo> git ci -a -m "a second home modif"
PS D:\git\tests\pullahead\homerepo> git push github

entonces clon workrepo para un primer experimento

PS D:\git\tests\pullahead\workrepo4> cd ..
PS D:\git\tests\pullahead> git clone workrepo workrepo2
Initialized empty Git repository in D:/git/tests/pullahead/workrepo2/.git/
PS D:\git\tests\pullahead> cd workrepo2
PS D:\git\tests\pullahead\workrepo2> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo2> git pull github master
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From d:/git/tests/pullahead/github
 * branch            master     -> FETCH_HEAD
Updating c2763f2..75ad279
Fast forward
 afile.txt |  Bin 46 -> 98 bytes
 1 files changed, 0 insertions(+), 0 deletions(-)

En ese repo, git status hace mención geing principal por delante de 'origin':

PS D:\git\tests\pullahead\workrepo5> git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
nothing to commit (working directory clean)

Pero eso es sólo origin no se github:

PS D:\git\tests\pullahead\workrepo2> git remote -v show
github  d:/git/tests/pullahead/github (fetch)
github  d:/git/tests/pullahead/github (push)
origin  D:/git/tests/pullahead/workrepo (fetch)
origin  D:/git/tests/pullahead/workrepo (push)

Pero si repito la secuencia en un acuerdo de recompra que tiene un origen a github (o no tiene origen en absoluto, sólo un mando a distancia 'github' definido), el estado es limpio:

PS D:\git\tests\pullahead\workrepo2> cd ..
PS D:\git\tests\pullahead> git clone workrepo workrepo4
PS D:\git\tests\pullahead> cd workrepo4
PS D:\git\tests\pullahead\workrepo4> git remote rm origin
PS D:\git\tests\pullahead\workrepo4> git remote add github d:/git/tests/pullahead/github
PS D:\git\tests\pullahead\workrepo4> git pull github master
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From d:/git/tests/pullahead/github
 * branch            master     -> FETCH_HEAD
Updating c2763f2..75ad279
Fast forward
 afile.txt |  Bin 46 -> 98 bytes
 1 files changed, 0 insertions(+), 0 deletions(-)
PS D:\git\tests\pullahead\workrepo4> git status
# On branch master
nothing to commit (working directory clean)

Si sólo había origin que señala en el github, status sería limpia para git1.6.5.
Puede ser con una advertencia 'por delante' de git antes, pero de todos modos, un git config branch.master.remote yourGitHubRepo.git definido de forma explícita debe ser capaz de cuidar de que, incluso con las primeras versiones de Git.

¿Tiene usted cuidado de añadir todos los de su mando a distancia (excepto origin que viene con su clon original) usando git remote add NAME URL? He visto este error cuando acaban de ser añadidos a la git config.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top