Comportamiento predeterminado de "git push" sin una rama especificada


1366

Utilizo el siguiente comando para empujar a mi rama remota:

git push origin sandbox

Si yo digo

git push origin

¿Eso empuja los cambios en mis otras ramas también, o solo actualiza mi rama actual? Tengo tres ramas: master, productiony sandbox.

La git pushdocumentación no es muy clara al respecto, por lo que me gustaría aclarar esto para siempre.

¿Qué ramas y controles remotos git pushactualizan exactamente los siguientes comandos?

git push 
git push origin

origin arriba es un control remoto.

Entiendo que git push [remote] [branch]solo empujará esa rama al control remoto.


Con respecto a la configuración de las herramientas diff en general, y el nuevo script git difftool, he agregado una nueva respuesta en esta otra pregunta SO: stackoverflow.com/questions/255202/…
VonC

67
Hice una publicación en el blog sobre el comportamiento sorprendente de git push, que podría ser de interés
Mark Longair

1
@Mark: en otro trabajo, empujando solo la rama actual a su seguimiento aguas arriba. Agradable.
VonC


help.github.com/articles/pushing-to-a-remote poniendo este enlace aquí para ayuda inmediata a los principiantes como yo
MycrofD

Respuestas:


1591

Puede controlar el comportamiento predeterminado configurando push.default en su configuración de git. De la documentación de git-config (1) :

push.default

Define la acción que debe llevar a cabo git push si no se proporciona ninguna especificación de referencia en la línea de comando, no se configura ninguna especificación en el control remoto y ninguna de las opciones dadas en la línea de comando implica ninguna especificación de referencia. Los valores posibles son:

  • nothing: no empujes nada

  • matching: empuje todas las ramas coincidentes

    Todas las ramas que tienen el mismo nombre en ambos extremos se consideran coincidentes.

    Esto solía ser el valor predeterminado, pero no desde Git 2.0 ( simplees el nuevo valor predeterminado).

  • upstream: empuja la rama actual a su rama ascendente ( trackinges un sinónimo desaprobado para ascendente)

  • current: empuja la rama actual a una rama del mismo nombre

  • simple: (nuevo en Git 1.7.11) como ascendente, pero se niega a presionar si el nombre de la rama ascendente es diferente del local

    Esta es la opción más segura y es adecuada para principiantes.

    Este modo se ha convertido en el predeterminado en Git 2.0.

Los modos simple, actual y ascendente son para aquellos que desean expulsar una sola rama después de terminar el trabajo, incluso cuando las otras ramas aún no están listas para ser expulsadas

Ejemplos de línea de comando:

Para ver la configuración actual:

git config --global push.default

Para establecer una nueva configuración:

git config --global push.default current

11
Probablemente valga la pena señalar que esto es nuevo en v1.6.3: kernel.org/pub/software/scm/git/docs/RelNotes-1.6.3.txt
CB Bailey

8
Este "push.default" es lo mejor para trabajar con repositorios múltiples. Póngalo en "tracking" y estará todo bien. Combinado con la ramificación, configurada en sentido ascendente, estos hacen que empujar y tirar sea más conveniente.
jpswain

13
"tracking" es el sinónimo obsoleto de "upstream": kernel.org/pub/software/scm/git/docs/git-config.html
LuckyMalaka

22
Vale la pena señalar que a partir de Git 1.7.11, hay un nuevo simplemodo. Este modo está destinado a convertirse en el predeterminado en el futuro. simplefunciona como upstream, pero como currentrequiere que los nombres de las ramas sean iguales en ambos extremos.
Kai

99
Vale la pena señalar que a partir de Git 2.0, el simplecomportamiento ahora es el predeterminado.
do0g

209

Puede configurar el comportamiento predeterminado para su git con push.default

git config push.default current

o si tiene muchos repositorios y quiere lo mismo para todos, entonces

git config --global push.default current

La corriente en esta configuración significa que, de forma predeterminada, solo empujará la rama actual cuando haga git push

Otras opciones son:

  • nada: no empujes nada
  • coincidencia: empuje todas las ramas coincidentes (predeterminado)
  • tracking: empuja la rama actual a lo que sea tracking
  • current: empuja la rama actual

ACTUALIZACIÓN - NUEVA MANERA DE HACER ESTO

A partir de Git 1.7.11 haga lo siguiente:

git config --global push.default simple

Esta es una nueva configuración introducida que funciona de la misma manera que la actual, y se establecerá por defecto en git desde v 2.0 según los rumores.


29
Sí, leí la respuesta a la que se refiere, pero esa respuesta solo dice qué hacer y no cómo hacerlo. Entonces agregué mi respuesta para que toda la información necesaria para configurarla esté en la misma página.
Christoffer

3
OKAY; es mejor sugerir una edición a dicha publicación, porque nadie verá su respuesta, ya que no es probable que obtenga tantos votos
CharlesB

¿Cómo podría uno acercarse a la rama actual? git pull origin?
Francois

200

git push originempujará todos los cambios en las ramas locales que tienen ramas remotas coincidentes en originAs forgit push

Funciona como git push <remote>, donde <remote>está el control remoto de la rama actual (u origen, si no hay ningún control remoto configurado para la rama actual).

De la sección de ejemplos de la git-pushpágina del manual


2
Sí, eso lo deja claro. Probablemente estoy ejecutando una versión anterior de git (1.6.1.1 Mac OS X) que no tiene estos ejemplos en la página del manual.
PlagueHammer

Probablemente estoy ejecutando 1.6.3.1. Sin embargo, lo encontré en el sitio que vinculé.
baudtack

2
Entonces, en mi caso, donde todas las ramas locales tienen el mismo "origen" remoto, "git push" sería exactamente lo mismo que "git push origin", que empujaría solo las ramas locales que tienen una rama correspondiente en el control remoto.
PlagueHammer

@Debajit ¡Correcto! Gran pregunta por cierto. Siempre supuse que git push solo empujaría la rama actual. ¡Aparentemente no! Muy bueno saberlo.
baudtack

55
Esta pregunta es antigua pero para cualquiera nuevo, @docgnome tiene razón. Simplemente ejecutando 'git push origin' empujará todas las ramas en lugar de solo la rama actual. Utilice 'git push -f -v -n origin development' para forzar la inserción de una rama llamada desarrollo. Use la bandera -n para simular el resultado de git push para que pueda ver de antemano qué ramas se verán afectadas. Si se ve bien, ejecute 'git push -f -v origin development'. Esto podría ser útil stackoverflow.com/questions/3741136/git-push-f-vs
Dylan Valade

54

Acabo de enviar mi código a una rama y lo envié a github, así:

git branch SimonLowMemoryExperiments
git checkout SimonLowMemoryExperiments
git add .
git commit -a -m "Lots of experimentation with identifying the memory problems"
git push origin SimonLowMemoryExperiments

3
Puede condensar el commit a `git commit -am" ... "`
James Harrington

17
¿Esta respuesta tiene algo que ver con la pregunta? :?
Asim KT

26

Aquí hay una información muy útil y útil sobre Git Push : Git Push: Just the Tip

El uso más común de git push es enviar los cambios locales a su repositorio público ascendente. Suponiendo que el flujo ascendente es un remoto llamado "origen" (el nombre remoto predeterminado si su repositorio es un clon) y la rama a actualizar desde / se llama "maestro" (el nombre de rama predeterminado), esto se hace con:git push origin master

git push origin empujará los cambios de todas las ramas locales a las ramas correspondientes del origen remoto.

git push origin master empujará los cambios de la rama maestra local a la rama maestra remota.

git push origin master:staging empujará los cambios desde la rama maestra local a la rama de preparación remota si existe.


git push origin branch_namepor alguna razón, empuje no solo la branch_namerama, sino también otras ramas locales (git versión 1.9.1).
mrgloom

git push origin master:staginges una joya escondida increíble!
Shakeel

19

(Marzo de 2012)
Cuidado: la " matching" política predeterminada puede cambiar pronto
(a veces después de git1.7.10 +)
:

Consulte " Discuta: ¿qué debe hacer" git push "cuando no dice qué presionar? "

En la configuración actual (es decir push.default=matching), git pushsin argumento empujará todas las ramas que existen localmente y remotamente con el mismo nombre .
Esto suele ser apropiado cuando un desarrollador ingresa a su propio repositorio público, pero puede ser confuso, si no peligroso, al usar un repositorio compartido.

La propuesta es cambiar el valor predeterminado a ' upstream' , es decir, empujar solo la rama actual, y empujarlo a la rama desde la que extraería git.
Otro candidato es ' current'; esto empuja solo la rama actual a la rama remota del mismo nombre.

Lo que se ha discutido hasta ahora se puede ver en este hilo:

http://thread.gmane.org/gmane.comp.version-control.git/192547/focus=192694

Las discusiones relevantes anteriores incluyen:

Para unirse a la discusión, envíe sus mensajes a: git@vger.kernel.org


18

Acabo de poner esto en mi sección de alias .gitconfig y me encanta cómo funciona:

pub = "!f() { git push -u ${1:-origin} `git symbolic-ref HEAD`; }; f"

Empujará la rama actual al origen con git pubu otro repositorio con git pub repo-name. Sabroso.


44
Eso es bueno, pero desafortunadamente se supone que la rama tiene el mismo nombre en el otro repositorio. Intenta en su git push -u --repo="origin" $1;lugar. Funciona bastante bien, excepto que si empuja a otro repositorio, el nombre de la rama será el nombre utilizado por el otro repositorio, no el que está empujando
Casebash

¡Hey gracias! Me hace querer hacer una versión más completa que verifique el estado del seguimiento antes de presionar. Pero me quedaré con el mío por ahora, ya que rara vez tengo diferentes nombres de ramas entre repositorios.
Mat Schaffer


8

Un git push intentará empujar todas las ramas locales al servidor remoto, esto es probablemente lo que no desea. Tengo un par de comodidades configuradas para lidiar con esto:

Alias ​​"gpull" y "gpush" apropiadamente:

En mi ~ / .bash_profile

get_git_branch() {
  echo `git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'`
}
alias gpull='git pull origin `get_git_branch`'
alias gpush='git push origin `get_git_branch`'

Por lo tanto, ejecutar "gpush" o "gpull" empujará solo mi rama "actualmente en".


3
Si siempre desea el comportamiento de gpush, también puede establecer remote.origin.push = HEAD (por ejemplo, "git config remote.origin.push HEAD"), como se menciona en la sección de ejemplos de la página de manual de git-push.
Trevor Robinson

55
Esto no es necesario si nos fijamos en la publicación anterior de "Brian L".
jpswain

1
Lo es, ya que no hay equv. for pull pull.default
SamGoody

8

Puede cambiar ese comportamiento predeterminado en su .gitconfig, por ejemplo:

[push]
  default = current

Para verificar la configuración actual, ejecute:

git config --global --get push.default

3

En lugar de usar alias, prefiero crear scripts git-XXX para poder controlarlos más fácilmente (todos nuestros desarrolladores tienen un cierto directorio controlado por fuente en su camino para este tipo de cosas).

Este script (llamado git-setpush) establecerá el valor de configuración para el remote.origin.pushvalor en algo que solo empujará la rama actual:

#!/bin/bash -eu

CURRENT_BRANCH=$(git branch | grep '^\*' | cut -d" " -f2)
NEW_PUSH_REF=HEAD:refs/for/$CURRENT_BRANCH

echo "setting remote.origin.push to $NEW_PUSH_REF"
git config remote.origin.push $NEW_PUSH_REF

tenga en cuenta que, como estamos usando Gerrit, establece el objetivo refs/for/XXXpara empujar a una rama de revisión. También asume que el origen es su nombre remoto.

Invocarlo después de verificar una sucursal con

git checkout your-branch
git setpush

Obviamente, podría adaptarse para hacer el pago, pero me gustan los scripts para hacer una cosa y hacerlo bien


Una gran idea para configurar remote.origin.push para el uso de gerrit. Mis ramas de características locales feature/fix_fubarapuntan a ramas ascendentes más genéricas como mastero develop, por lo que esto apuntaría a la secuencia ascendente incorrecta. ¿Cómo se ve su flujo local para repos controlados por gerrit?
spazm

Si solo tiene una rama "objetivo" en gerrit, intente simplemente git config remote.origin.push HEAD:refs/for/master.
fracz

2

He agregado las siguientes funciones en mi archivo .bashrc para automatizar estas tareas. Hace git push / git pull + nombre de la rama actual.

function gpush()
{
  if [[ "x$1" == "x-h" ]]; then
    cat <<EOF
Usage: gpush
git: for current branch: push changes to remote branch;
EOF
  else
    set -x
    local bname=`git rev-parse --abbrev-ref --symbolic-full-name @{u} | sed -e "s#/# #"`
    git push ${bname}
    set +x
  fi
}

function gpull()
{
  if [[ "x$1" == "x-h" ]]; then
    cat <<EOF
Usage: gpull
git: for current branch: pull changes from
EOF
  else
    set -x
    local bname=`git rev-parse --abbrev-ref --symbolic-full-name @{u} | sed -e "s#/# #"`
    git pull ${bname}
    set +x
  fi
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.