¿Por qué llamar a git branch --unset-upstream para arreglar?

161

Soy más novato cuando se trata de operaciones avanzadas en git. Mantengo mi blog usando el marco de blogs Octopress . Aunque Octopress no se ha desarrollado desde 2011, cumple con mi propósito y, por lo tanto, no he pensado en cambiar nada hasta ahora.

FYI, mi blog está alojado en las páginas de Github.

Hoy, mientras trabajaba en una nueva publicación, git statusmostró el siguiente mensaje:

On branch source
Your branch is based on 'origin/master', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)

El mismo mensaje se repite para todos los comandos posteriores como git add ., git commit -m 'message'y git push origin source.

  • ¿Qué significa el mensaje?
  • ¿Hay algo roto?
  • En caso afirmativo, ¿qué?
  • ¿Necesito arreglarlo?

Si es posible, indíqueme un artículo en pdf / web donde pueda leer sobre esto y comprenderlo para el futuro.

Más detalles:

bash-3.2$ git branch -a
* source
  remotes/octopress/2.1
  remotes/octopress/HEAD -> octopress/master
  remotes/octopress/gh-pages
  remotes/octopress/linklog
  remotes/octopress/master
  remotes/octopress/refactor_with_tests
  remotes/octopress/rubygemcli
  remotes/octopress/site
  remotes/origin/source

Avíseme si necesita más información. Gracias.

Jatin Ganhotra
fuente

Respuestas:

197

TL; versión DR: la rama de seguimiento remoto origin/mastersolía existir, pero ahora no, por lo que la rama localsource está rastreando algo que no existe, lo que es sospechoso en el mejor de los casos, lo que significa que una función Git diferente no puede hacer nada por usted, y Git te está advirtiendo al respecto. Te has llevado bien sin que la función de "seguimiento ascendente" funcione según lo previsto, por lo que depende de ti cambiar algo.

Para otra versión de la configuración aguas arriba, vea ¿Por qué tengo que "git push --set-upstream origin <branch>"?


Esta advertencia es algo nuevo en Git, que aparece primero en Git 1.8.5. Las notas de la versión contienen solo una pequeña viñeta al respecto:

  • "git branch -v -v" (y "git status") no distinguió entre una rama que no está basada en ninguna otra rama, una rama que está sincronizada con su rama ascendente y una rama que está configurada con un flujo ascendente rama que ya no existe.

Para describir lo que significa, primero debe saber sobre "controles remotos", "ramas de seguimiento remoto" y cómo Git maneja el "seguimiento de un flujo ascendente". ( Las ramas de seguimiento remoto son un término terriblemente defectuoso. En su lugar, comencé a usar nombres de seguimiento remoto , lo que creo que es una ligera mejora. Sin embargo, a continuación, usaré "rama de seguimiento remoto" para mantener la coherencia con la documentación de Git. )

Cada "control remoto" es simplemente un nombre, como origino octopressen este caso. Su propósito es registrar cosas como la URL completa de los lugares desde los cuales usted git fetcho las git pullactualizaciones. Cuando usa 1 Git va a ese control remoto (usando la URL guardada) y trae el conjunto apropiado de actualizaciones. También registra las actualizaciones, utilizando "ramas de seguimiento remoto".git fetch remote,

Una "rama de seguimiento remoto" (o nombre de seguimiento remoto) es simplemente una grabación del nombre de una rama como se vio por última vez en algún "control remoto". Cada control remoto es en sí mismo un repositorio Git, por lo que tiene ramas. Las ramas en el "origen" remoto se registran en su repositorio local en remotes/origin/. El texto dice que mostró que hay una rama llamada sourceen originy ramas nombradas 2.1, linklogy así sucesivamente en octopress.

(Una rama "normal" o "local", por supuesto, es solo un nombre de rama que ha creado en su propio repositorio).

Por último, puede configurar una sucursal (local) para "rastrear" una "sucursal de seguimiento remoto". Una vez que la sucursal local Lestá configurada para rastrear la sucursal de seguimiento remoto R, Git llamará a Rsu "flujo ascendente" y le dirá si está "adelante" y / o "detrás" del flujo ascendente (en términos de confirmaciones). Es normal (incluso recomendable) que la rama local y las ramas de seguimiento remoto usen el mismo nombre (excepto la parte de prefijo remoto), como sourcey origin/source, pero eso no es realmente necesario.

Y en este caso, eso no está sucediendo. Tiene una sucursal local que sourcerastrea una sucursal de rastreo remoto origin/master.

Se supone que no debes conocer la mecánica exacta de cómo Git configura una sucursal local para rastrear una remota, pero son relevantes a continuación, así que te mostraré cómo funciona esto. Empezamos con el nombre de la sucursal local source. Hay dos entradas de configuración que usan este nombre, deletreadas branch.source.remotey branch.source.merge. A partir del resultado que mostró, está claro que ambos están configurados, por lo que verá lo siguiente si ejecuta los comandos dados:

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

Poner estos juntos, 2 esto le dice a Git que su rama de sourceun seguimiento de su "rama remota de seguimiento", origin/master.

Pero ahora mire la salida de git branch -a, que muestra todos los nombres de sucursales de seguimiento local y remoto en su repositorio. Los nombres de seguimiento remoto se enumeran en remotes/... y no hayremotes/origin/master . Presumiblemente hubo, en un momento, pero se ha ido ahora.

Git te dice que puedes eliminar la información de seguimiento con --unset-upstream. Esto eliminará ambos branch.source.originy branch.source.merge, y detendrá la advertencia.

Sin embargo, parece bastante probable que lo que desea es cambiar del seguimiento origin/mastera otro: probablemente origin/source, pero tal vez uno de los octopress/nombres.

Puede hacer esto con git branch --set-upstream-to, 3 por ejemplo:

$ git branch --set-upstream-to=origin/source

(suponiendo que todavía esté en la "fuente" de la rama, y ​​ese origin/sourcees el flujo ascendente que desea, no hay forma de que le diga cuál, si es que hay alguna, realmente quiere).

(Consulte también ¿Cómo hacer que una rama Git existente rastree una rama remota? )

Creo que la forma en que llegaste aquí es que cuando hiciste una git clone, la cosa de la que clonaste tenía una rama master. También tenía una rama master, que estaba configurada para rastrear origin/master(esta es una configuración normal y estándar para git). Esto significaba que tenías branch.master.remotey estabas branch.master.merge, a originy refs/heads/master. Pero luego su origincontrol remoto cambió su nombre de mastera source. Para que coincida, creo que también cambiaste tu nombre local de mastera source. Esto cambió los nombres de su configuración, de branch.master.remoteay branch.source.remotede branch.master.mergea branch.source.merge... pero dejó los valores anteriores , por branch.source.mergelo que ahora estaba equivocado.

Fue en este punto que se rompió el enlace "ascendente", pero en las versiones de Git anteriores a 1.8.5, Git nunca notó la configuración rota. Ahora que tiene 1.8.5, está señalando esto.


Eso cubre la mayoría de las preguntas, pero no la pregunta "¿Necesito arreglarlo?". Es probable que haya estado trabajando alrededor de la ruptura durante años, haciendo (p . Ej .). Si sigue haciendo eso, seguirá solucionando el problema, por lo tanto, no, no necesita solucionarlo. Si lo desea, puede usar para eliminar el flujo ascendente y detener las quejas, y no tener la sucursal local marcada como que tiene ningún flujo ascendente.git pull remote branchgit pull origin source--unset-upstreamsource

El punto de tener un flujo ascendente es hacer que varias operaciones sean más convenientes. Por ejemplo, git fetchseguido de git merge"generalmente hará lo correcto" si el flujo ascendente está configurado correctamente, y git statusluego git fetchle dirá si su repositorio coincide con el flujo ascendente, para esa rama.

Si desea la comodidad, vuelva a configurar el flujo ascendente.


1git pull utiliza git fetch, y a partir de Git 1.8.4, esto (¡finalmente!) También actualiza la información de la "rama de seguimiento remoto". En versiones anteriores de Git, las actualizaciones no se registraban en ramas de seguimiento remoto con git pull, solo con git fetch. Dado que su Git debe ser al menos la versión 1.8.5, esto no es un problema para usted.

2 Bueno, esto más una línea de configuración que estoy ignorando deliberadamente que se encuentra debajo remote.origin.fetch. Git tiene que mapear el nombre de "fusión" para descubrir que el nombre local completo de la rama remota es refs/remotes/origin/master. El mapeo casi siempre funciona igual que esto, sin embargo, por lo que es previsible que masterva a origin/master.

3 O con git config. Si solo desea establecer el flujo ascendente en origin/sourcela única parte que tiene que cambiar es branch.source.merge, y git config branch.source.merge refs/heads/source lo haría. Pero --set-upstream-todice lo que quiere que se haga, en lugar de obligarlo a hacerlo usted mismo manualmente, así que esa es una "mejor manera".

torek
fuente
3
+1 para "Si lo desea, puede usar --unset-upstream para marcar la rama local como que no tiene ningún upstream".
BeatriceThalo
157

La respuesta de torek es probablemente perfecta, pero solo quería que el registro mencionara otro caso que sea diferente al descrito en la pregunta original, pero puede aparecer el mismo error (ya que puede ayudar a otros con un problema similar):

He creado un repositorio vacío (nuevo) usando git init --bareuno de mis servidores. Luego lo he git clonellevado a un espacio de trabajo local en mi PC.

Después de confirmar una única versión en el repositorio local, recibí ese error después de llamar git status.

Siguiendo la respuesta de torek, entiendo que lo que sucedió es que la primera confirmación en el repositorio del directorio de trabajo local creó la rama "maestra". Pero en el repositorio remoto (en el servidor) nunca había nada, por lo que ni siquiera había una rama "maestra" (remotos / origen / maestro).

Después de ejecutar git push origin masterdesde el repositorio local, el repositorio remoto finalmente tenía una rama maestra. Esto detuvo la aparición del error.

Para concluir, se puede obtener un error de este tipo para un nuevo repositorio remoto nuevo con cero confirmaciones ya que no tiene una rama, incluido "maestro".

ElazarR
fuente
66
Este es actualmente el resultado nr 1 para este mensaje de error On branch source Your branch is based on 'origin/master', but the upstream is gone. (use "git branch --unset-upstream" to fixup)y, aunque es subjetivo, es más probable que sea causado por la clonación de un repositorio vacío tan bueno para tener una respuesta alternativa aquí.
Bella
2
Creo que es por eso que siempre es una buena idea inicializar su nuevo repositorio con el archivo README.md, incluso si es un archivo vacío
Ahmed Hussein
8

Esto podría resolver tu problema.

después de hacer cambios, puede confirmarlo y luego

git remote add origin https://(address of your repo) it can be https or ssh
then
git push -u origin master

Espero que funcione para ti.

Gracias

Ajay Kotnala
fuente
1
De hecho, esto ayudaría: el motivo se detalla en mi respuesta (en resumen, esto crea la rama maestra que falta en el repositorio remoto).
ElazarR
7

Para mí, se .git/refs/origin/masterhabía corrompido.

Hice lo siguiente, lo que me solucionó el problema.

rm .git/refs/remotes/origin/master
git fetch
git branch --set-upstream-to=origin/master
smremde
fuente
0

En realidad, torek ya te dijo cómo usar las herramientas mucho mejor de lo que yo podría hacerlo. Sin embargo, en este caso, creo que es importante señalar algo peculiar si sigue las pautas en http://octopress.org/docs/deploying/github/ . Es decir, tendrá múltiples repositorios de github en su configuración. En primer lugar, el que tiene todo el código fuente de su sitio web en decir el directorio $WEBSITE, y luego el que tiene solo los archivos generados estáticos que residen $WEBSITE/_deploy. Lo divertido de la configuración es que hay un .gitignorearchivo en el $WEBSITEdirectorio para que esta configuración realmente funcione.

Suficiente introducción. En este caso, el error también podría provenir del repositorio en _deploy.

cd _deploy

git branch -a
* master
remotes/origin/master
remotes/origin/source

En .git/configque necesitará normalmente encontrar algo como esto:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = [email protected]:yourname/yourname.github.io.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master

Pero en su caso, el maestro de sucursal no tiene un control remoto.

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = [email protected]:yourname/yourname.github.io.git
    fetch = +refs/heads/*:refs/remotes/origin/*

Que puedes resolver por:

cd _deploy
git branch --set-upstream-to=origin/master

Entonces, todo es como torek le dijo, pero podría ser importante señalar que esto muy bien podría referirse al _deploydirectorio en lugar de a la raíz de su sitio web.

PD: Puede valer la pena usar un shell como zshcon un gitcomplemento para no ser mordido por esto en el futuro. Mostrará de inmediato que se _deploytrata de un repositorio diferente.

Anne van Rossum
fuente
0

Tuve esta pregunta dos veces, y siempre fue causada por la corrupción del archivo git cache en mi sucursal local. Lo arreglé escribiendo el hash de confirmación faltante en ese archivo. Obtuve el hash de confirmación correcto del servidor y ejecuté el siguiente comando localmente:

cat .git/refs/remotes/origin/feature/mybranch \
echo 1edf9668426de67ab764af138a98342787dc87fe \
>> .git/refs/remotes/origin/feature/mybranch
usuario1106400
fuente
0

Problema: su rama se basa en 'origen / maestro', pero el flujo ascendente se ha ido.

Solución: git branch --unset-upstream

reecha soni
fuente
3
Bienvenido a stackoverflow. La pregunta no es sobre cómo se puede solucionar el error, quiere saber por qué se produce este error y si debe hacer algo al respecto. Por favor, aborde esto en su respuesta.
cronoik 01 de
0

elimine su sucursal local siguiendo el comando

git branch -d branch_name

también podrías hacer

git branch -D branch_name 

que básicamente fuerzan una eliminación (incluso si el local no se fusionó con la fuente)

Pravin
fuente