Perché devo fare `–set-upstream ‘tutto il tempo?

Creo una nuova filiale in Git:

git branch my_branch 

Spingilo:

 git push origin my_branch 

Ora dì che qualcuno ha apportato alcune modifiche sul server e voglio estrarre da origin/my_branch . Lo voglio:

 git pull 

Ma ottengo:

 You asked me to pull without telling me which branch you want to merge with, and 'branch.my_branch.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 (eg 'git pull  '). 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 "my_branch"] remote =  merge =  [remote ""] url =  fetch =  See git-config(1) for details. 

Ho imparato che posso farlo funzionare con:

 git branch --set-upstream my_branch origin/my_branch 

Ma perché devo farlo per ogni ramo che creo? Non è ovvio che se spingo my_branch in origin/my_branch , allora vorrei estrarre origin/my_branch in my_branch ? Come posso rendere questo il comportamento predefinito?

Una scorciatoia, che non dipende dal ricordare la syntax per git branch --set-upstream 1 deve fare:

 git push -u origin my_branch 

… la prima volta che spingi quel ramo. Oppure, per passare al ramo corrente a un ramo con lo stesso nome (utile per un alias):

 git push -u origin HEAD 

Devi solo usare -u una volta, e questo imposta l’associazione tra il tuo ramo e quello origin allo stesso modo del git branch --set-upstream .

Personalmente, penso che sia una buona cosa impostare esplicitamente quell’associazione tra il tuo ramo e uno sul telecomando. È solo un peccato che le regole siano diverse per git push e git pull .


1 Può sembrare sciocco, ma molto spesso dimentico di specificare il ramo attuale, assumendo che sia il default – non lo è, ed i risultati sono più confusi 🙂

Aggiornamento 2012-10-11 : Apparentemente non sono l’unica persona che ha trovato facile sbagliare! Grazie a VonC per aver sottolineato che git 1.8.0 introduce il più ovvio git branch --set-upstream-to , che può essere usato come segue, se sei nel ramo my_branch :

 git branch --set-upstream-to origin/my_branch 

… o con l’opzione breve:

 git branch -u origin/my_branch 

Questo cambiamento e il suo ragionamento sono descritti nelle note di rilascio di git 1.8.0, release candidate 1 :

Si è tentati di dire git branch --set-upstream origin/master , ma questo dice a Git di organizzare l’ origin/master ramo locale per integrarsi con il ramo attualmente estratto, il che è altamente improbabile che cosa intendesse l’utente. L’opzione è deprecata; usa invece la nuova opzione --set-upstream-to (con un breve-e-dolce -u ).

Puoi farlo accadere con meno digitando. Innanzitutto, cambia il modo in cui funziona la tua spinta:

 git config --global push.default current 

Questo origin my_branch parte di origin my_branch , quindi puoi fare:

 git push -u 

Quale creerà il ramo remoto con lo stesso nome e lo seguirà.

Puoi semplicemente

 git checkout -b my-branch origin/whatever 

innanzitutto. Se si imposta branch.autosetupmerge o branch.autosetuprebase (il mio preferito) su always (il valore predefinito è true ), my-branch branch.autosetuprebase automaticamente l’ origin/whatever .

Vedi git help config .

È ansible impostare upstream più semplice in due modi. Innanzitutto quando crei il ramo:

 git branch -u origin/my-branch 

o dopo aver creato un ramo, puoi usare questo comando.

 git push -u origin/my-branch 

Puoi anche diramare, estrarre e impostare upstream in un singolo comando:

 git checkout -b my-branch -t origin/my-branch 

La mia preferenza personale è di farlo in un comando in due passaggi:

 git checkout -b my-branch git push -u origin/my-branch 

Puoi usare:

git config –global branch.autosetupmerge sempre

che collegherà il ramo upstream ogni volta che crei o esegui il checkout di un nuovo ramo.

Vedi https://felipec.wordpress.com/2013/09/01/advanced-git-concepts-the-upstream-tracking-branch/

Questo funziona anche con autosetuprebase, se segui un stream di lavoro più focalizzato su rebase, ma non usarlo a meno che tu non sappia cosa stai facendo, poiché il tuo comportamento di pull predefinito sarà rebase, il che può causare risultati strani.

Questo è il mio uso più comune per The Fuck .

 $ git push fatal: The current branch master has no upstream branch. To push the current branch and set the remote as upstream, use git push --set-upstream origin master $ fuck git push --set-upstream origin master [enter/↑/↓/ctrl+c] Counting objects: 9, done. ... 

Inoltre, è divertente digitare parole parolacce nel tuo terminale.

A proposito, la scorciatoia per spingere il ramo corrente su un telecomando con lo stesso nome:

 $ git push -u origin HEAD 
 git branch --set-upstream-to=origin/master 

Puoi anche dire esplicitamente a git pull quale ramo remoto da estrarre (come menzionato nel messaggio di errore):

git pull

Fai attenzione, tuttavia: se ti trovi su un ramo diverso e fai un tiro esplicito, il refspec che trascini verrà unito al ramo su cui ti trovi!

Per quel che vale, se stai cercando di rintracciare un ramo che esiste già sul telecomando (ad esempio origin / somebranch) ma non lo hai ancora verificato localmente, puoi fare:

 $ git checkout --track origin/somebranch 

Nota: ‘-t’ è la versione abbreviata dell’opzione ‘–track’.

Questo crea la stessa associazione sin da subito.

Uso questo alias Git invece di copiare / incollare il suggerimento da Git ogni volta: https://gist.github.com/ekilah/88a880c84a50b73bd306

Fonte copiata di seguito (aggiungi questo al tuo file ~/.gitconfig ):

 [alias] pushup = "!gitbranchname() { git symbolic-ref --short HEAD; }; gitpushupstream() { git push --set-upstream origin `gitbranchname`; }; gitpushupstream" 

È ansible impostare un alias veramente buono in grado di gestirlo senza la syntax eccessivamente dettagliata.

Ho il seguente alias in ~/.gitconfig :

 po = "!git push -u origin \"$(git rev-parse --abbrev-ref HEAD)\"" 

Dopo aver effettuato un commit su un nuovo ramo, puoi spingere il tuo nuovo ramo semplicemente digitando il comando:

 git po 

Personalmente uso questi alias seguenti in bash

nel file ~ / .gitconfig

 [alias] pushup = "!git push --set-upstream origin $(git symbolic-ref --short HEAD)" 

e nel file ~ / .basehrc o ~ / .zshrc

 alias gpo="git pushup" alias gpof="gpo -f" alias gf="git fetch" alias gp="git pull" 

Per chi cerca un alias che git pull con git pull , questo è quello che uso:

 alias up="git branch | awk '/^\\* / { print \$2 }' | xargs -I {} git branch --set-upstream-to=origin/{} {}" 

Ora ogni volta che ottieni:

 $ git pull There is no tracking information for the current branch. ... 

Corri:

 $ up Branch my_branch set up to track remote branch my_branch from origin. $ git pull 

E tu sei bello andare

Puoi anche fare git push -u origin $(current_branch)

Perché git ha la capacità di spingere / tirare diversi rami verso diversi repository “upstream”. Potresti anche usare repository separati per spingere e tirare – sullo stesso ramo. Questo può creare un stream distribuito a più livelli, posso vedere questo essere utile su un progetto come il kernel di Linux. Git è stato originariamente costruito per essere utilizzato su quel progetto.

Di conseguenza, non fa ipotesi su quale repository il tuo ramo dovrebbe tracciare.

D’altra parte, la maggior parte delle persone non usa git in questo modo, quindi potrebbe essere utile per un’opzione predefinita.

Git è generalmente piuttosto di basso livello e può essere frustrante. Tuttavia ci sono GUI e dovrebbe essere facile scrivere script di aiuto se si vuole ancora usarlo dalla shell.

Ho scoperto nuovamente legit causa di questo problema (solo OS X). Ora tutto ciò che uso quando si diramano sono questi due comandi:

legit publish [] Pubblica il ramo specificato sul telecomando. (alias: pub )

legit unpublish Rimuove il ramo specificato dal remoto. (alias: unp )

SublimeGit viene fornito con il supporto legit per impostazione predefinita, il che rende l’intera routine di branching facile come premere Ctrl-b.

Usiamo il phabricator e non spingiamo usando git. Ho dovuto creare l’alias bash che funziona su Linux / mac

 vim ~/.bash_aliases new_branch() { git checkout -b "$1" git branch --set-upstream-to=origin/master "$1" } 

salvare

 source ~/.bash_aliases new_branch test #instead of git checkout -b test git pull