¿Por qué necesito empujar explícitamente una nueva sucursal?

180

Soy nuevo gity estoy practicando. Creé una sucursal local pero vi que cuando lo hice, git pushmi sucursal no estaba cargada en el repositorio. Tenía que hacer realidad: git push -u origin --all.
¿Por qué es esto? ¿No es una rama un nuevo cambio que se va a impulsar de forma predeterminada? ¿Por qué necesito ejecutar el segundo comando?

Cratilo
fuente
15
Tenga en cuenta que esto es configurable (ajuste push.default, ver man git-config). Si lo hace git config --add push.default current, git pushcreará automáticamente la rama en el repositorio remoto si es necesario. Por qué este no es el valor predeterminado se explica en las respuestas.
sleske
@sleske estoy de acuerdo. Para las otras políticas ' current' y ' upstream', consulte mi respuesta anterior stackoverflow.com/a/13751847/6309 .
VonC
¿Por qué no aceptar una respuesta?
laike9m

Respuestas:

224

La razón real es que, en un nuevo repositorio (git init), no hay rama (no master, ninguna rama, cero ramas)

Entonces, cuando está presionando por primera vez a un repositorio ascendente vacío (generalmente uno desnudo ), ese repositorio ascendente no tiene una rama del mismo nombre.

Y:

En ambos casos, dado que el repositorio vacío ascendente no tiene rama:

  • todavía no hay una rama nombrada coincidente
  • no hay ninguna rama ascendente (¡con o sin el mismo nombre! Seguimiento o no)

Eso significa que su primer impulso local no tiene idea:

  • donde empujar
  • qué empujar (ya que no puede encontrar ninguna rama ascendente que se registre como una rama de seguimiento remota y / o que tenga el mismo nombre)

Entonces necesita al menos hacer un:

git push origin master

Pero si solo haces eso, tú:

  • creará una masterrama ascendente en el ascendente (ahora repositorio no vacío): bueno.
  • no registrará que la rama local ' master' necesita ser empujada a upstream ( origin) ' master' (rama ascendente): mal.

Es por eso que se recomienda, para el primer impulso, hacer un:

git push -u origin master

Que registrará origin/mastercomo una rama de seguimiento remoto , y permitirá a la próxima empuje para empujar de forma automática mastera origin/master.

git checkout master
git push

Y eso también funcionará con las políticas de empuje ' current' o ' upstream'.
En cada caso, después de la inicial git push -u origin master, un simple git push será suficiente para continuar empujando master a la rama aguas arriba derecha.

VonC
fuente
2
Después de este punto, ¿el próximo git pushtambién espera que la rama ya exista?
Cratylus
2
Si. Impulsará cualquier actualización a esa rama al repositorio ascendente.
RyPeck
@Cratylus sí, debido a la nueva política de inserción predeterminada ' simple': empuje a cualquier rama ascendente registrada, si esa rama ascendente tiene el mismo nombre que la local. Un simple git pushserá suficiente.
VonC
1
@ButtleButkus Gracias. He restaurado el enlace.
VonC
3
Para el caso más general del interrogador de una nueva rama 'new_branch', usaría git push --set-upstream origin new_brancho git push -u origin new_branchpara abreviar. El -allque utilizó el interrogador omitió nombrar una nueva rama específica al incluir todas las ramas. Esto está cubierto por + Klas Mellbourn en su respuesta.
Paul Masri-Stone
106

No, mira abajo

Encuentro esta 'característica' bastante molesta ya que no estoy tratando de lanzar cohetes a la luna, solo empujo mi maldita rama. ¡Probablemente también lo hagas o no estarías aquí!

Aquí está la solución: si desea que empuje implícitamente la rama actual, independientemente de si esa rama existe en el origen, simplemente emita este comando una vez y nunca más tendrá que volver a hacerlo:

git config --global push.default current

Entonces, si haces ramas como esta:

git checkout -b my-new-branch

y luego hacer algunos commits y luego hacer un

git push -u

para llevarlos al origen (estar en esa rama) y creará dicha rama para ti si no existe.

Tenga en cuenta que el bit -u se asegura de que estén vinculados si fuera a extraerlo de dicha rama. Si no tiene planes de tirar de la rama más tarde (o si está de acuerdo con otro revestimiento si lo hace) -u no es necesario.

John Culviner
fuente
3
Cuando hago esto, si hago un git pull, inmediatamente después, las dos ramas no están vinculadas. :(
Alisso
Esta es la única respuesta que solucionó mi problema.
Raymond Chenon
2
Para vincularlos, usegit push -u
Ben Creasy
¡Gracias! Esta respuesta debe ser aceptada como la solución rápida y 'sucia'. Estoy bastante seguro de que es lo más cercano a la intención de OP.
youngrrrr
3
> No estoy tratando de lanzar cohetes a la luna. -- SI.
VCavallo
39

Salida de git pushal empujar una nueva rama

> git checkout -b new_branch
Switched to a new branch 'new_branch'
> git push
fatal: The current branch new_branch has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin new_branch

Un simple git pushsupone que ya existe una rama remota que la rama local actual está rastreando. Si no existe tal rama remota, y desea crearla, debe especificar eso utilizando el indicador -u(forma corta de --set-upstream).

¿Por qué esto es así? Supongo que los implementadores sintieron que crear una rama en el control remoto es una acción tan importante que debería ser difícil hacerlo por error. git pushes algo que haces todo el tiempo.

"¿No es una rama un nuevo cambio que se va a impulsar de forma predeterminada?" Yo diría que "un cambio" en Git es un compromiso. Una rama es un puntero a una confirmación. Para mí tiene más sentido pensar en un empuje como algo que empuja los compromisos a los otros repositorios. Las confirmaciones que se envían están determinadas por la rama en la que se encuentra y la relación de seguimiento de esa rama con las ramas en el control remoto.

Puede leer más sobre el seguimiento de ramas en el capítulo Ramas remotas del libro Pro Git .

Klas Mellbourn
fuente
No fatalrecibí un mensaje pero ya había hecho una confirmación en la rama. ¿Importa esto?
Cratylus
@Cratylus no, no importa. El commit está seguro en su repositorio, y lo git push -u origincopió al repositorio remoto.
Klas Mellbourn
No, me refiero al hecho de que no recibí un fatalmensaje como el que mencionas en la respuesta. ¿Esta diferencia depende del hecho de que le haya enviado algo a la sucursal?
Cratylus
@Cratylus No sé por qué no recibiste el fatalmensaje. Supongo que la diferencia depende exactamente de qué implementación de git está utilizando. Mi salida es de 1.8.1.msysgit.1 ejecutándose en Windows 8.
Klas Mellbourn
Tengo la misma versión pero en Vista
Cratylus
4

No pude encontrar una justificación de los desarrolladores originales tan rápido, pero puedo darle una suposición educada basada en algunos años de experiencia en Git.

No, no todas las sucursales son algo que desea impulsar al mundo exterior. Podría representar un experimento privado.

Además, ¿a dónde deben git pushenviar todas las sucursales? Git puede funcionar con múltiples controles remotos y es posible que desee tener diferentes conjuntos de ramas en cada uno. Por ejemplo, un proyecto central del repositorio de GitHub puede tener sucursales de lanzamiento; una bifurcación de GitHub puede tener ramas temáticas para su revisión; y un servidor Git local puede tener ramas que contengan configuración local. Si git pushempujaría todas las ramas al control remoto que rastrea la rama actual, este tipo de esquema sería fácil de arruinar.

Fred Foo
fuente
1). It might represent a private experimentOk, pero ¿cuál es el gran problema? La rama "principal" en la que todos están trabajando, masteres decir, no se ve afectada. A menos que quieras mantener oculto el código fuente 2) git push, without a remote, pushes to the current branch's remoteTe perdí aquí :(
Cratylus
@Cratylus: 1) en un proyecto con docenas de desarrolladores que se ramifican ad lib, obtendrá repositorios muy desordenados. Trabajo en tales proyectos, y no me gustaría tener git fetchcientos de ramas a medias trabajando cada vez. 2) Me refiero al git pushcomportamiento predeterminado de. Le informa al control remoto que la rama actual está rastreando, si la hay.
Fred Foo
3

HEAD es la abreviatura de la rama actual, por lo que git push -u origin HEAD funciona. Ahora para evitar este tipeo cada vez que uso un alias:

git config --global alias.pp 'push -u origin HEAD'

Después de esto, cada vez que quiero empujar una rama creada a través de git -b branch, puedo empujarla usando:

git pp

Espero que esto ahorre tiempo para alguien!

Aurimas Rekštys
fuente
2

En el primer cheque

Paso 1: git remote -v
// si se encuentra git initialize, luego elimine u omita el paso 2

Paso 2: git remote rm origin
// Luego configura tu dirección de correo electrónico globalmente git

Paso 3: git config --global user.email "[email protected]"

Paso 4: git initial

Paso 5: git commit -m "Initial Project"
// Si ya agrega el repositorio del proyecto, omita el paso 6

Paso 6: git remote add origin %repo link from bitbucket.org%

Paso 7: git push -u origin master

MD Milton
fuente
1

Acabo de experimentar una mayor permutación de este problema.

Tenía una sucursal nombrada feat/XYZ-1234-some-descriptionporque estaba trabajando en el problema 123 de Jira. Durante el trabajo, creé un nuevo problema de Jira para rastrear un trabajo más pequeño, y cuando llegué a empujar decidí empujar a un nombre de sucursal con este nuevo número de problema en:

git push -u origin feat/XYZ-5678-a-different-description # failed

Esto me dio el error que se discute en este hilo SO. Pero como estaba tratando de pasar a un nombre de sucursal diferente de mi sucursal actual, mi problema era diferente al descrito aquí. Terminé cambiando el nombre de mi sucursal local antes de poder impulsarla:

git branch -m feat/XYZ-1234-some-description feat/XYZ-5678-a-different-description
git push -u origin feat/XYZ-5678-a-different-description # now works

Después de un poco más de lectura alrededor me di cuenta de que podría haber establecido una srcen el git push, ya sea para el nombre de la rama actual, o simplemente HEADen su caso:

git push -u origin feat/XYZ-1234-some-description:feat/XYZ-5678-a-different-description # also works
Mark Birbeck
fuente
-1

Si habilita para impulsar nuevos cambios desde su nueva sucursal la primera vez. Y debajo del error:

*git push -f
fatal: The current branch Coding_Preparation has no upstream branch.

Para empujar la rama actual y configurar el control remoto como ascendente, use

git push -u origin new_branch_name


** Successful Result:** 
 git push -u origin Coding_Preparation
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 599 bytes | 599.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'Coding_Preparation' on GitHub by visiting: ...
 * [new branch]      Coding_Preparation -> Coding_Preparation
Branch 'Coding_Preparation' set up to track remote branch 'Coding_Preparation' from 'origin'.
Mukesh Kumar
fuente