TL; DR: git branch --set-upstream-to origin/solaris
La risposta alla domanda che hai posto, che mi riformulare un po 'come "devo impostare un monte", è: no, non si deve impostare un monte a tutti.
Se non si dispone di upstream per il ramo corrente, tuttavia, Git modifica il suo comportamento su git push
e anche su altri comandi.
La storia push completa qui è lunga e noiosa e risale alla storia precedente alla versione 1.5 di Git. Per accorciarlo molto, è git push
stato implementato male. 1 A partire dalla versione 2.0 di Git, Git ora dispone di una manopola di configurazione push.default
che ora è predefinita simple
. Per diverse versioni di Git prima e dopo la 2.0, ogni volta che correvi git push
, Git emetteva un sacco di rumore nel tentativo di convincerti a impostare push.default
solo per stare git push
zitto.
Non menzioni quale versione di Git stai eseguendo, né se hai configurato push.default
, quindi dobbiamo indovinare. La mia ipotesi è che si sta utilizzando la versione Git 2 punti-qualcosa, e che è stato impostato push.default
per simple
per farlo stare zitto. Proprio quale versione di Git che hai, e che cosa se tutto quello che avete push.default
impostato, non importa, a causa di quella storia lunga e noiosa, ma alla fine, il fatto che stai ricevendo l'ennesima denuncia da Git indica che il Git è configurato per evitare uno degli errori del passato.
Che cos'è un monte?
Un upstream è semplicemente un altro nome di ramo, di solito un ramo di tracciamento remoto, associato a un ramo (normale, locale).
Ogni ramo ha la possibilità di avere un (1) set upstream. Cioè, ogni ramo o ha un upstream o non ha un upstream. Nessun ramo può avere più di un upstream.
L'upstream dovrebbe , ma non deve essere, un ramo valido (sia come localizzazione remota che come locale ). Cioè, se l'attuale ramo B ha U a monte , dovrebbe funzionare. Se non funziona, se si lamenta che U non esiste, la maggior parte di Git si comporta come se l'upstream non fosse impostato. Alcuni comandi, come , mostreranno l'impostazione a monte ma la contrassegneranno come "sparita".origin/B
master
git rev-parse U
git branch -vv
A che serve un monte?
Se push.default
è impostato su simple
o upstream
, l'impostazione upstream farà git push
, utilizzata senza argomenti aggiuntivi, funzionerà.
Questo è tutto, è tutto ciò che fa git push
. Ma questo è abbastanza significativo, poiché git push
è uno dei luoghi in cui un semplice errore di battitura provoca grossi mal di testa.
Se push.default
è impostato su nothing
, matching
o current
, l'impostazione di un upstream non fa nulla per git push
.
(Tutto questo presuppone che la tua versione Git sia almeno 2.0.)
L'upstream colpisce git fetch
Se si esegue git fetch
senza argomenti aggiuntivi, Git scopre da quale telecomando prelevare consultando l'upstream della filiale corrente. Se l'upstream è un ramo di tracciamento remoto, Git recupera da quel telecomando. (Se l'upstream non è impostato o è un ramo locale, Git prova a recuperare origin
.)
Il monte colpisce git merge
e git rebase
troppo
Se si esegue git merge
o git rebase
senza argomenti aggiuntivi, Git utilizza l'upstream del ramo corrente. Quindi accorcia l'uso di questi due comandi.
L'upstream colpisce git pull
Si dovrebbe mai 2 uso git pull
in ogni caso, ma se lo fai, git pull
utilizza l'impostazione a monte per capire quale remota per recuperare da, e poi quale ramo di unione o rebase con. Cioè, git pull
fa la stessa cosa come git fetch
-perché effettivamente eseguito git fetch
-e poi fa la stessa cosa come git merge
o git rebase
, perché in realtà viene eseguito git merge
o git rebase
.
(Di solito dovresti semplicemente fare questi due passaggi manualmente, almeno finché non conosci Git abbastanza bene che quando uno dei due passaggi fallisce, cosa che alla fine riconoscerai cosa è andato storto e sai cosa fare al riguardo.)
L'upstream colpisce git status
Questo potrebbe effettivamente essere il più importante. Una volta che hai un set upstream, git status
puoi segnalare la differenza tra la tua filiale corrente e la sua upstream, in termini di commit.
Se, come nel caso normale, sei sul ramo B
con il suo upstream impostato su , e corri , vedrai immediatamente se hai commit che puoi spingere e / o commit su cui puoi unire o rifare.origin/B
git status
Questo perché git status
esegue:
git rev-list --count @{u}..HEAD
: quanti commit hai e B
che non sono attivi ?origin/B
git rev-list --count HEAD..@{u}
: quanti commit hai e che non sono attivi ?origin/B
B
L'impostazione di un upstream ti dà tutte queste cose.
Come mai master
ha già un set upstream?
Quando cloni per la prima volta da qualche telecomando, usando:
$ git clone git://some.host/path/to/repo.git
o simili, l'ultimo passo Git fa è, essenzialmente, git checkout master
. Questo verifica la tua filiale locale, master
solo che non hai una filiale locale master
.
D'altra parte, si fa avere un ramo remoto il monitoraggio di nome origin/master
, perché hai appena clonato esso.
Git indovina che si deve aver significato: "mi fanno un nuovo locale master
che punta allo stesso commettono come remote-tracking origin/master
, e, mentre ci sei, impostare il monte per master
a origin/master
."
Questo succede per ogni ramo git checkout
che non hai già. Git crea il ramo e lo rende "traccia" (ha come upstream) il ramo di tracciamento remoto corrispondente.
Ma questo non funziona per i nuovi rami, ovvero i rami senza ramo di monitoraggio remoto ancora .
Se si crea una nuova filiale:
$ git checkout -b solaris
c'è, ancora, no origin/solaris
. Il tuo locale solaris
non può tracciare il ramo di tracciamento remoto origin/solaris
perché non esiste.
Quando si preme per la prima volta il nuovo ramo:
$ git push origin solaris
che crea solaris
su origin
, e quindi crea anche origin/solaris
nel proprio repository Git. Ma è troppo tardi: hai già un locale solaris
che non ha monte . 3
Git non dovrebbe semplicemente impostarlo automaticamente come upstream?
Probabilmente. Vedi "implementato male" e la nota 1. È difficile cambiare ora : ci sono milioni di 4 script che usano Git e alcuni potrebbero dipendere dal suo comportamento attuale. La modifica del comportamento richiede una nuova versione principale, nag-ware per forzare l'impostazione di un campo di configurazione e così via. In breve, Git è vittima del suo stesso successo: qualsiasi errore abbia oggi, può essere risolto solo se il cambiamento è per lo più invisibile, chiaramente molto meglio o fatto lentamente nel tempo.
Il fatto è che non lo è oggi, a meno che non si usi --set-upstream
o -u
durante il git push
. Ecco cosa ti dice il messaggio.
Non devi farlo in quel modo. Bene, come abbiamo notato sopra, non devi assolutamente farlo, ma diciamo che vuoi un upstream. È già stato creato ramo solaris
su origin
, attraverso una spinta in precedenza, e come i vostri git branch
spettacoli di uscita, è già avere origin/solaris
nella vostra repository locale.
Semplicemente non lo hai impostato come upstream per solaris
.
Per impostarlo ora, anziché durante la prima pressione, utilizzare git branch --set-upstream-to
. Il --set-upstream-to
comando secondario prende il nome di qualsiasi ramo esistente, ad esempio origin/solaris
, e imposta il ramo corrente a monte di quell'altro ramo.
Questo è tutto - è tutto ciò che fa - ma ha tutte quelle implicazioni annotate sopra. Significa che puoi semplicemente correre git fetch
, quindi guardarti intorno, quindi correre git merge
o git rebase
come appropriato, quindi fare nuovi commit ed eseguire git push
, senza un mucchio di problemi aggiuntivi.
1 Ad essere onesti, all'epoca non era chiaro che l'implementazione iniziale fosse soggetta a errori. Ciò è diventato chiaro solo quando ogni nuovo utente ha commesso gli stessi errori ogni volta. Ora è "meno povero", il che non vuol dire "grande".
2 "Mai" è un po 'forte, ma trovo che i neofiti di Git capiscano le cose molto meglio quando separo i passaggi, specialmente quando posso mostrare loro ciò che git fetch
effettivamente hanno fatto, e possono quindi vedere cosa git merge
o git rebase
faranno dopo.
3 Se esegui il tuo primo git push
come git push -u origin solaris
—ie, se aggiungi il -u
flag — Git imposterà origin/solaris
come upstream per il tuo ramo attuale se (e solo se) il push ha successo. Quindi dovresti fornire -u
alla prima spinta. In effetti, puoi fornirlo su qualsiasi spinta successiva, e imposterà o cambierà l'upstream in quel punto. Ma penso che git branch --set-upstream-to
sia più facile, se hai dimenticato.
4 Misurato dal metodo Austin Powers / Dr Evil di dire semplicemente "un MILLLL-YUN", comunque.