Comportamento predefinito di "git push" senza un ramo specificato


1366

Uso il seguente comando per inviare al mio ramo remoto:

git push origin sandbox

Se dico

git push origin

questo provoca cambiamenti anche negli altri miei rami o aggiorna solo il mio ramo attuale? Ho tre rami: master, productione sandbox.

La git pushdocumentazione non è molto chiara al riguardo, quindi vorrei chiarire questo aspetto per sempre.

Quali rami e telecomandi git pushaggiornano esattamente i seguenti comandi?

git push 
git push origin

origin sopra è un telecomando.

Capisco che git push [remote] [branch]spingerà solo quel ramo sul telecomando.


Per quanto riguarda la configurazione di strumenti diff in generale, e la nuova sceneggiatura difftool git, ho aggiunto una nuova risposta a quest'altra domanda SO: stackoverflow.com/questions/255202/...
VonC

67
Ho pubblicato un post sul blog sul comportamento sorprendente di git push, che potrebbe essere di interesse
Mark Longair

1
@Mark: in altri lavori, spingendo solo il ramo corrente al suo tracciato a monte. Bello.
VonC


help.github.com/articles/pushing-to-a-remote mettendo qui questo link per un aiuto immediato ai novizi come me
MycrofD

Risposte:


1591

Puoi controllare il comportamento predefinito impostando push.default nella tua configurazione di git. Dalla documentazione di git-config (1) :

push.default

Definisce l'azione che git push dovrebbe intraprendere se non viene fornito refspec sulla riga di comando, nessun refspec è configurato nel telecomando e nessuna refspec è implicita in nessuna delle opzioni fornite nella riga di comando. I valori possibili sono:

  • nothing: non spingere nulla

  • matching: spingere tutti i rami corrispondenti

    Tutti i rami con lo stesso nome su entrambe le estremità sono considerati corrispondenti.

    Questo era il valore predefinito, ma non da Git 2.0 ( simpleè il nuovo valore predefinito).

  • upstream: spinge il ramo corrente al suo ramo a monte ( trackingè un sinonimo deprecato per a monte)

  • current: sposta il ramo corrente su un ramo con lo stesso nome

  • simple: (nuovo in Git 1.7.11) come upstream, ma rifiuta di spingere se il nome del ramo upstream è diverso da quello locale

    Questa è l'opzione più sicura ed è adatta per i principianti.

    Questa modalità è diventata l'impostazione predefinita in Git 2.0.

Le modalità semplice, corrente e upstream sono per coloro che vogliono espellere un singolo ramo dopo aver terminato il lavoro, anche quando gli altri rami non sono ancora pronti per essere espulsi

Esempi da riga di comando:

Per visualizzare la configurazione corrente:

git config --global push.default

Per impostare una nuova configurazione:

git config --global push.default current

11
Probabilmente vale la pena notare che questo è nuovo in v1.6.3: kernel.org/pub/software/scm/git/docs/RelNotes-1.6.3.txt
CB Bailey

8
Questo "push.default" è la cosa migliore di sempre per lavorare con repository multipli. Impostalo su "tracking" e sei a posto. In combinazione con la diramazione, impostate a monte, rendono più conveniente la spinta e la trazione.
jpswain,

13
"tracking" è il sinonimo deprecato di "upstream": kernel.org/pub/software/scm/git/docs/git-config.html
LuckyMalaka

22
Vale la pena notare che a partire da Git 1.7.11, c'è una nuova simplemodalità. Questa modalità è destinata a diventare l'impostazione predefinita in futuro. simplefunziona come upstream, ma come currentrichiede che i nomi dei rami siano gli stessi su entrambe le estremità.
Kai,

9
Vale la pena notare che a partire da Git 2.0 il simplecomportamento è ora predefinito.
dal

209

È possibile impostare il comportamento predefinito per git con push.default

git config push.default current

o se hai molti repository e vuoi lo stesso per tutti allora

git config --global push.default current

La corrente in questa configurazione significa che per impostazione predefinita spingerai il ramo corrente solo quando esegui git push

Altre opzioni sono:

  • niente: non spingere nulla
  • matching: invia tutti i rami corrispondenti (impostazione predefinita)
  • tracciamento: sposta il ramo corrente su qualsiasi tracciamento
  • corrente: spinge il ramo corrente

AGGIORNAMENTO - NUOVO MODO DI FARLO

A partire da Git 1.7.11, procedi come segue:

git config --global push.default simple

Questa è una nuova impostazione introdotta che funziona allo stesso modo dell'attuale e sarà resa predefinita per git dalla v 2.0 secondo le voci


29
Sì, ho letto la risposta a cui ti riferisci, ma quella risposta dice solo cosa fare e non come farlo. Quindi ho aggiunto la mia risposta in modo che tutte le informazioni necessarie per configurarlo si trovino sulla stessa pagina.
Christoffer,

3
OK; è meglio suggerire una modifica al suddetto post, perché nessuno vedrà la tua risposta, poiché non è probabile che ottenga il maggior numero di voti
CharlesB,

come si potrebbe andare in giro a ramo corrente? git pull origin?
Francois,

200

git push originspingerà tutte le modifiche sui rami locali che hanno rami remoti corrispondenti su originAs forgit push

Funziona come git push <remote>, dove si <remote>trova il telecomando del ramo corrente (o origine, se nessun telecomando è configurato per il ramo corrente).

Dalla sezione Esempi della git-pushpagina man


2
Sì, questo lo rende chiaro. Probabilmente sto usando una versione precedente di git (1.6.1.1 Mac OS X) che non ha questi esempi nella pagina man.
PlagueHammer,

Probabilmente sto correndo 1.6.3.1. L'ho trovato sul sito che ho collegato comunque.
baudtack,

2
Quindi, nel mio caso, in cui tutti i rami locali hanno la stessa "origine" remota, "git push" sarebbe esattamente lo stesso di "git push origin" che spingerebbe solo i rami locali che hanno un ramo corrispondente nel telecomando.
PlagueHammer,

@Debajit Bene! Ottima domanda a proposito. Ho sempre pensato che Git Push avrebbe solo spinto il ramo attuale. Apparentemente no! Molto bene a sapersi.
baudtack

5
Questa domanda è vecchia ma per chiunque sia nuova, @docgnome ha ragione. Basta eseguire 'git push origin' per spingere tutti i rami invece che solo il ramo corrente. Usa 'git push -f -v -n sviluppo origine' per forzare il push di un ramo chiamato sviluppo. Usa il flag -n per simulare il risultato push git in modo da poter vedere in anticipo quali rami saranno interessati. Se sembra buono, esegui 'git push -f -v origin development'. Questo potrebbe essere utile stackoverflow.com/questions/3741136/git-push-f-vs
Dylan Valade,

54

Ho appena trasferito il mio codice in un ramo e l'ho inviato a github, in questo modo:

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
Puoi condensare il commit per `git commit -am" ... "`
James Harrington

17
Questa risposta ha qualcosa a che fare con la domanda ?? :?
Asim KT,

26

Ecco alcune informazioni molto utili e utili su Git Push : Git Push: solo la punta

L'uso più comune di git push è di inviare le modifiche locali al repository pubblico a monte. Supponendo che l'upstream sia un nome remoto "origine" (il nome remoto predefinito se il repository è un clone) e che il ramo da aggiornare a / da sia denominato "master" (il nome ramo predefinito), questo viene fatto con:git push origin master

git push origin spingerà le modifiche da tutti i rami locali ai rami corrispondenti al telecomando di origine.

git push origin master invierà le modifiche dal ramo principale locale al ramo principale remoto.

git push origin master:staging spingerà le modifiche dal ramo principale locale al ramo di gestione temporanea remota se esiste.


git push origin branch_nameper qualche motivo spingere non solo branch_namebranch, ma anche altre mie filiali locali (versione git 1.9.1).
MrGloom,

git push origin master:stagingè una gemma nascosta fantastica!
Shakeel,

19

(Marzo 2012)
Attenzione: la " matching" politica predefinita potrebbe cambiare presto
(a volte dopo git1.7.10 +)
:

Vedi " Per favore, discutete: cosa dovrebbe fare" git push "quando non dite cosa spingere? "

Nell'impostazione corrente (cioè push.default=matching), git pushsenza argomento spingerà tutti i rami che esistono localmente e in remoto con lo stesso nome .
Questo di solito è appropriato quando uno sviluppatore invia al proprio repository pubblico, ma può essere fonte di confusione se non pericoloso quando si utilizza un repository condiviso.

La proposta è di cambiare il valore predefinito in ' upstream' , ovvero spingere solo il ramo corrente e spingerlo verso il ramo da cui trarrebbe estrazione.
Un altro candidato è ' current'; questo spinge solo il ramo corrente sul ramo remoto con lo stesso nome.

Ciò che è stato discusso finora può essere visto in questo thread:

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

Le discussioni pertinenti precedenti includono:

Per partecipare alla discussione, invia i tuoi messaggi a: git@vger.kernel.org


18

Ho appena inserito questo nella mia sezione degli alias .gitconfig e adoro come funziona:

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

Spingerà il ramo corrente all'origine con git pubo un altro repository con git pub repo-name. Gustoso.


4
È carino, ma purtroppo presuppone che il ramo abbia lo stesso nome sull'altro repository. Prova git push -u --repo="origin" $1;invece. Funziona abbastanza bene, tranne se si spinge in un altro repository, il nome del ramo sarà il nome usato dall'altro repository, non quello da cui si sta spingendo
Casebash

Ehi grazie! Mi fa venir voglia di fare una versione più completa che controlla lo stato di tracciamento prima di spingere. Ma rimarrò con il mio per ora poiché raramente ho nomi di rami diversi tra i repository.
Mat Schaffer,

10

È possibile inviare il ramo corrente con il comando

git push origin HEAD

(preso da qui )


8

Un git push proverà a inviare tutti i rami locali al server remoto, questo è probabilmente ciò che non vuoi. Ho un paio di configurazioni di convenienza per affrontare questo:

Alias ​​"gpull" e "gpush" in modo appropriato:

Nel mio ~ / .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`'

Pertanto, l'esecuzione di "gpush" o "gpull" spingerà solo il mio ramo "attualmente attivo".


3
Se vuoi sempre il comportamento di gpush, puoi anche impostare remote.origin.push = HEAD (es. "Git config remote.origin.push HEAD"), come menzionato nella sezione degli esempi della pagina man di git-push.
Trevor Robinson,

5
Questo non è necessario se guardi il post sopra di "Brian L".
jpswain,

1
Lo è, poiché non esiste un equv. per pull pull.default
SamGoody,

8

Puoi modificare quel comportamento predefinito nel tuo .gitconfig, ad esempio:

[push]
  default = current

Per verificare le impostazioni correnti, eseguire:

git config --global --get push.default

3

Piuttosto che usare gli alias, preferisco creare script git-XXX in modo da poterli controllare più facilmente (i nostri sviluppatori hanno tutti una determinata directory controllata dal loro percorso per questo tipo di cose).

Questo script (chiamato git-setpush) imposterà il valore di configurazione per remote.origin.pushvalue su qualcosa che spingerà solo il ramo corrente:

#!/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

nota, mentre stiamo usando Gerrit, imposta l'obiettivo da refs/for/XXXinserire in un ramo di revisione. Presuppone inoltre che l'origine sia il tuo nome remoto.

Richiamalo dopo aver verificato un ramo con

git checkout your-branch
git setpush

Ovviamente potrebbe essere adattato per fare anche il checkout, ma mi piacciono gli script per fare una cosa e farlo bene


ottima idea di impostazione remote.origin.push per l'utilizzo di gerrit. I miei rami di funzionalità locali feature/fix_fubarsono tutti indirizzati a rami a monte più generici come mastero develop, quindi ciò indicherebbe a monte a monte sbagliato. Com'è il tuo flusso locale per i repository controllati da gerrit?
spazm

Se hai solo un ramo "target" su gerrit, prova semplicemente git config remote.origin.push HEAD:refs/for/master.
venerdì

2

Ho aggiunto le seguenti funzioni al mio file .bashrc per automatizzare queste attività. Fa git push / git pull + nome del ramo corrente.

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
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.