¿Cómo se consigue que git siempre extraiga de una rama específica?

485

No soy un maestro de git, pero he estado trabajando con él durante algún tiempo, con varios proyectos diferentes. En cada proyecto, siempre git clone [repository]y desde ese punto, siempre puedo git pull, siempre que no tenga cambios sobresalientes, por supuesto.

Recientemente, tuve que volver a una rama anterior, y lo hice con git checkout 4f82a29. Cuando volví a estar listo para tirar, descubrí que tenía que volver a establecer mi rama en master. Ahora, no puedo tirar usando una escalera, git pullsino que tengo que especificar git pull origin master, lo que es molesto, y me indica que no entiendo completamente lo que está sucediendo.

¿Qué ha cambiado que no me permite hacer una escalera git pullsin especificar el origen maestro y cómo puedo volver a cambiarlo?

ACTUALIZAR:

-bash-3.1$ cat config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[branch "master"]
[remote "origin"]
    url = [email protected]:user/project.git
    fetch = refs/heads/*:refs/remotes/origin/*

ACTUALIZACIÓN 2: Para ser claros, entiendo que mi método original puede haber sido incorrecto, pero necesito arreglar este repositorio para que pueda simplemente usarlo git pullnuevamente. Actualmente, git pull da como resultado:

-bash-3.1$ git pull
You asked me to pull without telling me which branch you
want to merge with, and 'branch.master.merge' in
your configuration file does not tell me either.  Please
name which branch you want to merge on the command line and
try again (e.g. 'git pull  ').
See git-pull(1) for details on the refspec.

If you often merge with the same branch, you may want to
configure the following variables in your configuration
file:

    branch.master.remote = 
    branch.master.merge = 
    remote..url = 
    remote..fetch = 

See git-config(1) for details.

Puedo decir git pullqué rama fusionar, y funciona correctamente, pero git pullno funciona como lo hizo originalmente antes de mi git checkout.

David Smith
fuente
¿Cómo se ve tu .git / config? ¿Qué hiciste después de revisar esa confirmación?
Ryan Graham
¿Hiciste commits encima de 4f82a29?
Pat Notz
Pat, no hice ningún commit encima. Esto está en un servidor, y necesitábamos volver a una versión estable para ocultar un error que habíamos creado. Este sistema no es para fines de desarrollo, por lo que simplemente quería retroceder, esperar mientras reparamos el error y luego volver a la versión principal.
David Smith
2
Ryan, he actualizado para incluir .git / config. Después del pago, no hice nada. Esta computadora es un servidor, no para desarrollo.
David Smith el

Respuestas:

731

A continuación [branch "master"], intente agregar lo siguiente al archivo de configuración de Git del repositorio ( .git/config):

[branch "master"]
    remote = origin
    merge = refs/heads/master

Esto le dice a Git 2 cosas:

  1. Cuando estás en la rama maestra, el control remoto predeterminado es el origen.
  2. Cuando se usa git pullen la rama maestra, sin control remoto ni rama especificada, use el control remoto predeterminado (origen) y combine los cambios desde la rama maestra remota.

Sin embargo, no estoy seguro de por qué esta configuración se habría eliminado de su configuración. Es posible que tenga que seguir las sugerencias que otras personas también han publicado, pero esto puede funcionar (o al menos ayudar).

Si no desea editar el archivo de configuración a mano, puede usar la herramienta de línea de comandos en su lugar:

$ git config branch.master.remote origin
$ git config branch.master.merge refs/heads/master
mipadi
fuente
2
Esto también funcionó para mí, había revisado un proyecto de github. Estoy ejecutando OS X 10.4
Sam Barnum
Gracias muy mucho - me pasó esto en un solo proyecto desarrollador con un repositorio "servidor" y dos ordenadores (que he utilizado para empujar / tirar con frecuencia sin problemas antes del fallo), no sé por qué, pero el arreglo funcionó ¡multa!
chesterbr
1
¿Qué quieres decir con Under [branch "master"]
ianj
3
@ianj: en el archivo de configuración de Git (desde la raíz del repositorio .git/config).
mipadi
1
@ianj: Desde la línea de comando, siempre puedes hacerlo en su $ git config branch.master.remote origin ; git config branch.master.merge refs/heads/masterlugar.
mipadi
139

Si lo prefiere, puede configurar estas opciones a través de la línea de comando (en lugar de editar el archivo de configuración) de la siguiente manera:

  $ git config branch.master.remote origin
  $ git config branch.master.merge refs/heads/master

O, si eres como yo y quieres que este sea el valor predeterminado en todos tus proyectos, incluidos aquellos en los que podrías trabajar en el futuro, agrégalo como una configuración global:

  $ git config --global branch.master.remote origin
  $ git config --global branch.master.merge refs/heads/master
Cabeza
fuente
12
+1 por conocer la palabra mágica "refs / heads / master". Yo no tenía problemas para averiguar cómo establecer la variable, pero no tenía absolutamente ninguna idea de lo que lo puso a , y las páginas de manual no fueron de mucha ayuda. Finalmente encontré el lugar correcto en los documentos después de encontrar esta respuesta. Para los curiosos: la palabra mágica se refiere a una ruta de archivo .giten la que git parece mantener el código hash de masters commit actual.
mokus
84
git branch --set-upstream master origin/master

Esto agregará la siguiente información a su configarchivo:

[branch "master"]
    remote = origin
    merge = refs/heads/master

Si es branch.autosetuprebase = alwaysasí, también agregará:

    rebase = true
cmcginty
fuente
1
Creo que esta es la forma más fácil de hacer que git se comporte como se le pidió, especialmente si hay más ramas, no solo remotas (incluso si tiene que hacer esto para cada rama, es una vez por rama)
s3v3n
2
Acabo de intentar esto, y recibo el error fatal: Not a valid object name: 'origin/master'.a pesar de que origines un control remoto válido y masterexiste, como de costumbre, en ambos repositorios.
Ken Williams
2
Ken, primero debes hacer "git fetch origin" para obtener los nombres de las ramas remotas.
Eric Lee
14
Git más nuevo quiere que uses git branch --set-upstream-to=origin/master master.
orbeckst
52

Me resulta difícil recordar el exacto git configo los git branchargumentos como en las respuestas de mipadi y Casey, así que uso estos 2 comandos para agregar la referencia ascendente:

git pull origin master
git push -u origin master

Esto agregará la misma información a su .git / config, pero me resulta más fácil de recordar.

Luke Sampson
fuente
1
Estoy de acuerdo. Esta debería ser la mejor respuesta más simple.
linbianxiaocao
2
Su respuesta debe incluir por qué funciona y consultar la sección en los documentos que explica por qué.
vfclists
24

Git pull combina dos acciones: obtener nuevas confirmaciones del repositorio remoto en las ramas rastreadas y luego fusionarlas en su rama actual .

Cuando revisó una confirmación particular, no tiene una rama actual, solo tiene HEAD apuntando a la última confirmación que realizó. Entonces git pullno tiene todos sus parámetros especificados. Por eso no funcionó.

Según su información actualizada, lo que intenta hacer es revertir su repositorio remoto. Si conoce la confirmación que introdujo el error, la forma más fácil de manejar esto es con la git revertque registra una nueva confirmación que deshace la confirmación de error especificada:

$ git checkout master
$ git reflog            #to find the SHA1 of buggy commit, say  b12345
$ git revert b12345
$ git pull
$ git push

Dado que es su servidor lo que desea cambiar, supondré que no necesita reescribir el historial para ocultar la confirmación de errores.

Si el error se introdujo en una confirmación de fusión, este procedimiento no funcionará. Consulte Cómo revertir una fusión defectuosa .

Pablo
fuente
Me está dando una buena educación aquí, lo cual agradezco, pero es posible que no esté describiendo mi situación muy bien, por lo que no es una coincidencia exacta para mi flujo de trabajo. Probablemente publicaré otra pregunta para abordar eso. ¡Gracias, Paul! +1 para usted, señor.
David Smith el
Acabo de leer mal tu situación. Me alegra que hayas obtenido la respuesta que necesitabas.
Paul
12

También hay una manera de configurar Git para que siempre extraiga y empuje la rama remota equivalente a la rama actualmente desprotegida en la copia de trabajo. Se llama una rama de seguimiento que git ready recomienda configurar de forma predeterminada .

Para el siguiente repositorio sobre el directorio de trabajo actual:

git config branch.autosetupmerge true

Para todos los repositorios de Git, que no están configurados de otra manera:

git config --global branch.autosetupmerge true

Tipo de magia, en mi humilde opinión, pero esto podría ayudar en los casos en que la rama específica es siempre la rama actual .

Cuando haya branch.autosetupmergeestablecido truey finalizado la compra de una sucursal por primera vez, Git le informará sobre el seguimiento de la sucursal remota correspondiente:

(master)$ git checkout gh-pages
Branch gh-pages set up to track remote branch gh-pages from origin.
Switched to a new branch 'gh-pages'

Git empujará a esa rama correspondiente automáticamente:

(gh-pages)$ git push
Counting objects: 8, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 1003 bytes, done.
Total 6 (delta 2), reused 0 (delta 0)
To [email protected]:bigben87/webbit.git
   1bf578c..268fb60  gh-pages -> gh-pages
Bengt
fuente
10

Como no quería editar mi archivo de configuración de git, seguí la información en la publicación de @ mipadi y usé:

$ git pull origin master

fuente
13
El punto era hacer esto automáticamente en lugar de especificarlo.
Eric
4

Su pregunta inmediata sobre cómo hacer que sea un maestro, debe hacer lo que dice. Especifique la refspec para extraer en su configuración de sucursal.

[branch "master"]
    merge = refs/heads/master
Ryan Graham
fuente
¿No debería ser eso "árbitros / jefes / maestro"? Según git-pull (1), este es el nombre de la sucursal en el sitio remoto que se fusiona de manera predeterminada.
Adam Monsen
Si, estas en lo correcto. El repositorio del que tomé mi ejemplo es un caso especial. Corregido
Ryan Graham
0

Solo quería agregar alguna información que, podemos verificar esta información si git pullse refiere automáticamente a cualquier rama o no.

Si ejecuta el comando, git remote show origin(asumiendo el origen como el nombre corto para remoto), git muestra esta información, ya sea que exista git pullo no una referencia predeterminada .

A continuación se muestra un resultado de muestra (tomado de la documentación de git).

$ git remote show origin
* remote origin
  Fetch URL: https://github.com/schacon/ticgit
  Push  URL: https://github.com/schacon/ticgit
  HEAD branch: master
  Remote branches:
    master                               tracked
    dev-branch                           tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

Tenga en cuenta la parte donde se muestra, rama local configurada para git pull.

En este caso, git pullse referirá agit pull origin master

Inicialmente, si ha clonado el repositorio, utilizando git clone, estas cosas se resuelven automáticamente. Pero si ha agregado un control remoto manualmente usando git remote add, estos faltan en la configuración de git. Si ese es el caso, la parte donde muestra "Rama local configurada para 'git pull':", faltaría en la salida degit remote show origin .

Los siguientes pasos a seguir si no existe una configuración para git pull, ya han sido explicados por otras respuestas.

dr_dev
fuente