Come fai a fare in modo che Git attiri sempre da un ramo specifico?


485

Non sono un maestro git, ma ci lavoro da qualche tempo, con diversi progetti. In ogni progetto, sempre git clone [repository]e da quel momento, posso sempre git pull, purché non abbia cambiamenti eccezionali, ovviamente.

Di recente, ho dovuto tornare a una succursale precedente e l'ho fatto con git checkout 4f82a29. Quando ero di nuovo pronto a tirare, ho scoperto che dovevo riportare il mio ramo al padrone. Ora, non posso tirare usando una scala git pullma invece, devo specificare git pull origin master, che è fastidioso, e mi indica che non capisco perfettamente cosa sta succedendo.

Cosa è cambiato che non mi consente di fare una scala git pullsenza specificare il master di origine e come posso cambiarlo?

AGGIORNARE:

-bash-3.1$ cat config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[branch "master"]
[remote "origin"]
    url = git@github.com:user/project.git
    fetch = refs/heads/*:refs/remotes/origin/*

AGGIORNAMENTO 2: Per essere chiaro, capisco che il mio metodo originale potrebbe essere stato errato, ma ho bisogno di correggere questo repository in modo da poterlo semplicemente utilizzare di git pullnuovo. Attualmente, git pull risulta in:

-bash-3.1$ git pull
You asked me to pull without telling me which branch you
want to merge with, and 'branch.master.merge' in
your configuration file does not tell me either.  Please
name which branch you want to merge on the command line and
try again (e.g. 'git pull  ').
See git-pull(1) for details on the refspec.

If you often merge with the same branch, you may want to
configure the following variables in your configuration
file:

    branch.master.remote = 
    branch.master.merge = 
    remote..url = 
    remote..fetch = 

See git-config(1) for details.

Posso dire git pullquale ramo unire e funziona correttamente, ma git pullnon funziona come prima in precedenza git checkout.


Che aspetto ha il tuo .git / config? Cosa hai fatto dopo aver verificato quel commit?
Ryan Graham,

Hai fatto commit su 4f82a29?
Pat Notz,

Pat, non ci ho fatto alcun impegno. Questo è su un server e abbiamo dovuto tornare a una versione stabile per nascondere un bug che avevamo creato. Questo sistema non ha scopi di sviluppo, quindi volevo semplicemente tornare indietro, attendere che il bug fosse risolto e quindi tornare alla versione principale.
David Smith,

2
Ryan, ho aggiornato per includere .git / config. Dopo il checkout, non ho fatto nulla. Questo computer è un server, non per lo sviluppo.
David Smith,

Risposte:


731

Sotto [branch "master"], prova ad aggiungere quanto segue al file di configurazione Git del repository ( .git/config):

[branch "master"]
    remote = origin
    merge = refs/heads/master

Questo dice a Git 2 cose:

  1. Quando sei sul ramo principale, il telecomando predefinito è origine.
  2. Quando si utilizza git pullsul ramo principale, senza remoto e ramo specificato, utilizzare il telecomando predefinito (origine) e unire le modifiche dal ramo principale remoto.

Tuttavia, non sono sicuro del motivo per cui questa configurazione sarebbe stata rimossa dalla tua configurazione. Potrebbe essere necessario seguire i suggerimenti pubblicati anche da altre persone, ma questo potrebbe funzionare (o aiutare almeno).

Se non si desidera modificare manualmente il file di configurazione, è possibile utilizzare invece lo strumento da riga di comando:

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

2
Questo ha funzionato anche per me, avevo controllato un progetto da Github. Sto eseguendo OS X 10.4
Sam Barnum

Grazie molto molto - questo è successo a me su un unico progetto di sviluppo con un repository "server" e due computer (che ho usato per spingere / tirare spesso con problemi prima che il problema tecnico), non so perché, ma la correzione ha funzionato bene!
Chester

1
Cosa intendi con Under [branch "master"]
ianj il

3
@ianj: nel file di configurazione Git (dalla radice del repository .git/config).
mipadi,

1
@ianj: dalla riga di comando, puoi sempre fare $ git config branch.master.remote origin ; git config branch.master.merge refs/heads/masterinvece.
mipadi,

139

Se preferisci, puoi impostare queste opzioni tramite la riga di comando (invece di modificare il file di configurazione) in questo modo:

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

Oppure, se sei come me e desideri che questo sia il valore predefinito in tutti i tuoi progetti, compresi quelli su cui potresti lavorare in futuro, quindi aggiungilo come impostazione di configurazione globale:

  $ git config --global branch.master.remote origin
  $ git config --global branch.master.merge refs/heads/master

12
+1 per conoscere la parola magica "refs / heads / master". Non ho avuto problemi a capire come impostare la variabile, ma non aveva assolutamente idea di cosa per impostarlo a , e le pagine man non erano molto aiuto. Alla fine ho trovato il posto giusto nei documenti dopo aver trovato questa risposta. Per i curiosi: la parola magica si riferisce a un percorso di file .gitin cui git sembra mantenere il codice hash del mastercommit corrente.
mokus,

84
git branch --set-upstream master origin/master

Ciò aggiungerà le seguenti informazioni al tuo configfile:

[branch "master"]
    remote = origin
    merge = refs/heads/master

Se hai branch.autosetuprebase = alwaysquindi aggiungerà anche:

    rebase = true

1
Trovo che questo sia il modo più semplice per far sì che git si comporti come richiesto, specialmente se ci sono più rami, non solo remoti (anche se devi farlo per ogni ramo, è una volta per ramo)
s3v3n

2
Ho appena provato questo e ottengo l'errore fatal: Not a valid object name: 'origin/master'.anche se originè un telecomando valido ed masteresiste, come al solito, in entrambi i repository.
Ken Williams,

2
Ken, devi prima fare "git fetch origin" per ottenere i nomi dei rami remoti.
Eric Lee,

14
Il nuovo git vuole che tu usi git branch --set-upstream-to=origin/master master.
orbeckst,

52

Trovo difficile ricordare l'esatto git configo gli git branchargomenti come nelle risposte di mipadi e Casey, quindi uso questi 2 comandi per aggiungere il riferimento a monte:

git pull origin master
git push -u origin master

Questo aggiungerà le stesse informazioni al tuo .git / config, ma trovo più facile da ricordare.


1
Sono d'accordo. Questa dovrebbe essere la migliore risposta più semplice.
linbianxiaocao,

2
La tua risposta dovrebbe includere il motivo per cui funziona e fare riferimento alla sezione della documentazione che spiega il perché.
vfclists,

24

Git pull combina due azioni: recuperare nuovi commit dal repository remoto nei rami tracciati e quindi unirli nel ramo corrente .

Quando hai estratto un determinato commit, non hai un ramo corrente, hai solo HEAD che punta all'ultimo commit che hai fatto. Quindi git pullnon ha tutti i suoi parametri specificati. Ecco perché non ha funzionato.

Sulla base delle informazioni aggiornate, ciò che stai cercando di fare è ripristinare il repository remoto. Se conosci il commit che ha introdotto il bug, il modo più semplice per gestirlo è con git revertcui registra un nuovo commit che annulla il commit con buggy specificato:

$ git checkout master
$ git reflog            #to find the SHA1 of buggy commit, say  b12345
$ git revert b12345
$ git pull
$ git push

Poiché è il tuo server che desideri modificare, suppongo che non sia necessario riscrivere la cronologia per nascondere il commit errato.

Se il bug è stato introdotto in un commit di unione, questa procedura non funzionerà. Vedi Come ripristinare un'unione difettosa .


Mi stai dando un'ottima educazione qui, che apprezzo, ma potrei non descrivere molto bene la mia situazione, quindi questa non è una corrispondenza esatta per il mio flusso di lavoro. Probabilmente posterò un'altra domanda per risolverlo. Grazie comunque, Paul! +1 a te, signore.
David Smith,

Ho appena letto male la tua situazione. Sono contento che tu abbia ottenuto la risposta di cui avevi bisogno.
Paul

12

C'è anche un modo di configurare Git in modo che tira e spinga sempre il ramo remoto equivalente al ramo attualmente estratto nella copia di lavoro. Si chiama ramo di tracciamento che git ready consiglia di impostare di default .

Per il prossimo repository sopra l'attuale directory di lavoro:

git config branch.autosetupmerge true

Per tutti i repository Git, che non sono configurati diversamente:

git config --global branch.autosetupmerge true

Tipo di magia, IMHO ma questo potrebbe aiutare nei casi in cui il ramo specifico è sempre il ramo corrente .

Quando hai branch.autosetupmergeimpostato truee verificato un ramo per la prima volta, Git ti dirà come tracciare il ramo remoto corrispondente:

(master)$ git checkout gh-pages
Branch gh-pages set up to track remote branch gh-pages from origin.
Switched to a new branch 'gh-pages'

Git quindi spingerà automaticamente verso quel ramo corrispondente:

(gh-pages)$ git push
Counting objects: 8, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 1003 bytes, done.
Total 6 (delta 2), reused 0 (delta 0)
To git@github.com:bigben87/webbit.git
   1bf578c..268fb60  gh-pages -> gh-pages

10

Non volendo modificare il mio file di configurazione git ho seguito le informazioni nel post di @ mipadi e ho usato:

$ git pull origin master

13
Il punto era fare questo automaticamente anziché specificarlo.
Eric,

4

La tua domanda immediata su come farlo diventare maestro, devi fare quello che dice. Specificare refspec da cui estrarre nella configurazione del ramo.

[branch "master"]
    merge = refs/heads/master

Non dovrebbe essere "refs / heads / master"? Secondo git-pull (1), questo è il nome del ramo nel sito remoto che viene unito per impostazione predefinita.
Adam Monsen,

Sì, hai ragione. Il repository da cui ho preso il mio esempio è un caso speciale. Corretto.
Ryan Graham,

0

Volevo solo aggiungere alcune informazioni che, possiamo controllare queste informazioni se git pullsi riferiscono automaticamente a qualsiasi ramo o meno.

Se si esegue il comando, git remote show origin(assumendo origine come nome breve per il telecomando), git mostra queste informazioni, indipendentemente dal fatto che esista un riferimento predefinito git pull.

Di seguito è riportato un esempio di output (tratto dalla documentazione di Git).

$ git remote show origin
* remote origin
  Fetch URL: https://github.com/schacon/ticgit
  Push  URL: https://github.com/schacon/ticgit
  HEAD branch: master
  Remote branches:
    master                               tracked
    dev-branch                           tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

Nota la parte in cui mostra, Ramo locale configurato per git pull.

In questo caso, si git pullfarà riferimento agit pull origin master

Inizialmente, se hai clonato il repository, usando git clone, queste cose vengono automaticamente curate. Ma se hai aggiunto manualmente un telecomando usando git remote add, questi mancano nella configurazione di git. In tal caso, la parte in cui mostra "Branch locale configurato per 'git pull':", mancherebbe dall'output di git remote show origin.

I prossimi passi da seguire se non esiste alcuna configurazione per git pull, sono già stati spiegati da altre risposte.

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.