¿Qué hace exactamente la "u"? "Git push -u origin master" vs "git push origin master"

335

Aparentemente soy terrible al usar git, a pesar de mis mejores intentos de entenderlo.

De kernel.org para git push:

-u

--set-upstream

Para cada rama que esté actualizada o que se haya enviado correctamente, agregue una referencia ascendente (seguimiento), utilizada por git-pull (1) sin argumentos y otros comandos. Para obtener más información, consulte branch.<name>.mergeen git-config (1).

Aquí viene branch.<name>.mergede git config:

branch.<name>.merge

Define, junto con branch.<name>.remote, la rama ascendente para la rama dada. Le dice a git fetch / git pull qué rama fusionar y también puede afectar a git push (ver push.default). Cuando está en la rama <name>, le dice a git fetch que la especificación de referencia predeterminada se marque para fusionarse en FETCH_HEAD. El valor se maneja como la parte remota de una especificación de referencia y debe coincidir con una referencia que se obtiene del control remoto proporcionado por "branch.<name>.remote". La información de fusión es utilizada por git pull (que al principio llama a git fetch) para buscar la rama predeterminada para la fusión. Sin esta opción, los valores predeterminados de git pull para fusionar la primera refspec obtenida. Especifique múltiples valores para obtener una fusión de pulpo. Si desea configurar git pull para que se fusione con <name>otra rama en el repositorio local, puede apuntarbranch.<name>.mergea la rama deseada, y use la configuración especial. (un punto) para branch.<name>.remote.

Configuré con éxito un repositorio remoto con github, y empujé con éxito mi primer compromiso con:

git push -u origin master

Luego, sin saberlo, empujé con éxito mi segundo commit a mi repositorio remoto usando:

git commit -m '[...]'

Sin embargo, pensando erróneamente que tendría que empujar de nuevo a originpartir master, me encontré:

# note: no -u
git push origin master

¿Qué hizo eso? No parecía tener ningún efecto en absoluto. ¿"Deshacer" git push -u origin master?

Cierre Vaquero
fuente
45
I'm apparently terrible at using git, despite my best attempts to understand it.- Nunca tuve a alguien que me recreara tan bien.
dgo

Respuestas:

336

La clave es "argumento sin argumento". Cuando haces una git pulldesde una rama, sin especificar una fuente remota o rama, git mira la branch.<name>.mergeconfiguración para saber de dónde sacarla. git push -uestablece esta información para la rama que está presionando.

Para ver la diferencia, usemos una nueva rama vacía:

$ git checkout -b test

Primero, empujamos sin -u:

$ git push origin test
$ git pull
You asked me to pull without telling me which branch you
want to merge with, and 'branch.test.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) for details.

If you often merge with the same branch, you may want to
use something like the following in your configuration file:

    [branch "test"]
    remote = <nickname>
    merge = <remote-ref>

    [remote "<nickname>"]
    url = <url>
    fetch = <refspec>

See git-config(1) for details.

Ahora si agregamos -u:

$ git push -u origin test
Branch test set up to track remote branch test from origin.
Everything up-to-date
$ git pull
Already up-to-date.

Tenga en cuenta que la información de seguimiento se ha configurado para que git pullfuncione como se espera sin especificar el control remoto o la sucursal.

Actualización: consejos de bonificación:

  • Como Mark menciona en un comentario, además de git pullesta configuración también afecta el comportamiento predeterminado de git push. Si tiene la costumbre de usar -upara capturar la rama remota que desea rastrear, le recomiendo configurar su push.defaultvalor de configuración en upstream.
  • git push -u <remote> HEADempujará la rama actual a una rama del mismo nombre <remote>(y también configurará el seguimiento para que pueda hacerlo git pushdespués de eso).
dahlbyk
fuente
44
git push <remote> <branch>hace que las cosas no sean ambiguas . Si deja el control remoto o la rama, git vuelve a las configuraciones de configuración de la rama, que están configuradas para usted git push -u.
dahlbyk
2
@dahlbyk He seguido adelante y te marqué como la respuesta, pero ese comentario me confunde un poco. En su respuesta, demostró que git estaba confundido después git push origin test(que no tiene -u). Luego demostró que eso git push -u origin test elimina la ambigüedad. ¿Hay algún error tipográfico o solo estoy volviendo a ser denso?
ClosureCowboy
1
Creo que estamos hablando uno al lado del otro. :) Cuando digo git push <remote> <branch>que no es ambiguo, me refiero a lo relativo a lo git pushque se basa en la configuración de la rama. Del mismo modo, git pull <remote> <branch>es inequívoco y se git pullbasa en la configuración de la rama. Una vez que ha empujado con -utanto git pushy git pullfuncionará como se espera.
dahlbyk
10
@dahlbyk: Su respuesta está muy bien, pero en sus comentarios anteriores se repiten un error común acerca git push- a menos que establezca push.defaulta sí mismo, git pushsólo utiliza la configuración derivada ascendente para decidir qué distancia para empujar a, no la rama remota de actualización.
Mark Longair
1
La mejor práctica para git es git push origin mastery lo mismo para el otro lado de IE. git pull origin master.. Entonces, si suponemos un cambio de rama, entonces puede git push origin branch_namey lo mismo para el otro lado IE. git pull origin branch_name
Arpit Vaishnav
87
git push -u origin master

… es lo mismo que:

git push origin master ; git branch --set-upstream master origin/master

Haga la última declaración, si olvida el -u!

O podrías forzarlo:

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

Si deja que el comando lo haga por usted, seleccionará sus errores, como si escribió una rama inexistente o no lo hizo git remote add; aunque eso podría ser lo que quieres. :)

sabgenton
fuente
1
Por cierto masteres solo un ejemplo :)
sabgenton
Ok, el segundo bit ahora se deprecia en las versiones más nuevas para: git branch master -u origin/masterdetalles @ stackoverflow.com/a/2286030/790359
sabgenton
2
Si olvida usar la -uopción, escriba git push -uinmediatamente estará bien.
zeekvfu
1
Las versiones más recientes de git indican que --setup-upstreamquedarán en desuso: The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to
Bill Hoag el
--set-upstream está en desuso, ahora funciona:git branch --set-upstream-to=origin/master master
Alberto Perez
43

En términos más simples:

Técnicamente, el -uindicador agrega una referencia de seguimiento al servidor ascendente al que está presionando.

Lo importante aquí es que esto le permite hacer una git pullsin proporcionar más argumentos. Por ejemplo, una vez que haces un git push -u origin master, puedes llamar más tarde git pully git sabrá que realmente quisiste decir git pull origin master.

De lo contrario, tendría que escribir todo el comando.

Adépòjù Olúwáségun
fuente
1
Entonces, si configuro la -ubandera en orgin mastercada próximo tirón, me referiré a ella. ¿Y si quiero cambiar el git pullcomportamiento que debo ejecutar git push -u origin some_other_branchy git pullahora me referiré some_other_branch? ¡Gracias!
Toma Tomov
1
¿podemos usar también "git push" en lugar de "git push origin master"?
cegprakash
Sí, puedes @cegprakash. Sin embargo, inicialmente git push -u origin master
habrías
-11

Todos los comandos necesarios de git bash para empujar y tirar en Github:

git status 
git pull
git add filefullpath

git commit -m "comments for checkin file" 
git push origin branch/master
git remote -v 
git log -2 

Si desea editar un archivo, entonces:

edit filename.* 

Para ver todas las ramas y sus commits:

git show-branch
Kamta Mishra
fuente
44
Creo que respondiste fuera del alcance de la pregunta.
Adépòjù Olúwáségun