2012-07-19 8 views
28

Ho iniziato a utilizzare git rebase di recente e non sono sicuro al 100% che lo stia facendo bene. Per il gusto della domanda, ci sono due rami in origine, master e next, che era ramificato da master.Nozioni di base su git

Dallo scorso sincronizzazione tra i due, master aveva 2 commit e next 6:

$ git log --oneline origin/next..origin/master 
59b5552 master commit #2 
485a811 master commit #1 

$ git log --oneline origin/master..origin/next 
4ebf401 next commit #6 
e9b6586 next commit #5 
197ada0 next commit #4 
4a2c3c6 next commit #3 
040a055 next commit #2 
84537bf next commit #1 

Quando ho checkout next ed eseguire git rebase -i origin/master, ottengo il seguente:

$ git status 
# On branch next 
# Your branch and 'origin/next' have diverged, 
# and have 8 and 6 different commits each, respectively. 

E finalmente dopo aver fatto git pull --rebase, i due commit da master sono in next:

$ git log --oneline origin/next..next 
8741d09 master commit #2 
485a811 master commit #1 

Domande:

  1. È questo approccio corretto?
  2. Perché ci sono altri commit 8 and 6 finché non viene eseguito pull --rebase?
  3. È possibile semplificare il flusso?

molto obbligato :)

+1

Ciao David, volevi dire 'git tirare --rebase' invece di' git rebase --pull'? – MikeSep

+0

@MikeSep sei corretto, corretto, grazie. –

risposta

39

Partiamo dall'inizio. Ecco un diagramma del vostro stato originario:

 
A-B-C (master, origin/master) 
\ 
    D-E-F-G-H-I (next, origin/next) 

Quando hai estratto next e Ribasato next su origin/master, ha creato 6 nuovi commit dopo i due che sono già sul origin/master. Questi nuovi commit hanno "master commit # 2" (C nel mio diagramma) come loro antenato, non il loro antenato originale dove origin/master e origin/next divergevano (A nel mio diagramma), quindi i loro hash saranno diversi. Credo che questo sia il motivo per cui vedrai che next ha 8 commit diversi da origin/next: il 2 da origin/master e il 6 "rehashed" commessi che erano su origin/next.

Dopo git checkout next ; git rebase -i origin/master, si dovrebbe avere questo:

 
A-B-C (master, origin/master) 
\ \ 
    \ D'-E'-F'-G'-H'-I' (next) 
    \ 
    D-E-F-G-H-I (origin/next) 

Si può vedere che next ha 8 commit che non sono sulla origin/next, e origin/next ha 6 commit che non sono sulla next. Concesso che questo è solo secondo gli hash SHA-1 dei commit. Il contenuto effettivo dovrebbe corrispondere molto da vicino se si git diff origin/next next - il diff dovrebbe solo mostrare le modifiche da B e C (come indicato nello schema).

Quando si esegue git pull --rebase mentre ancora sul next, essa recupera i cambiamenti dalla sorgente (il telecomando origin/next) e rebases il ramo corrente (next) su quella remota. Ciò causa le modifiche che si trovavano nello next ma in in origin/next per apparire dopo origin/next nel nuovo ramo next.Dovrebbe apparire così:

 
A-B-C (master, origin/master) 
\ 
    D-E-F-G-H-I (origin/next) 
      \ 
       B'-C' (next) 

Se questo è ciò che si desiderava per il grafico della cronologia, allora ci sei riuscito.

Tuttavia, ho il sospetto si voleva davvero cose da cercare, come il diagramma di mezzo, soprattutto se next è un ramo di caratteristica in cui si sta lavorando al prossimo pezzo del progetto e master è per il codice stabile e piccole correzioni di bug. Se è così, allora dovresti aver fatto git push invece di git pull --rebase per far sì che il telecomando rifletta la tua versione della cronologia invece del contrario.

+0

Presumo che 'git rebase --pull' sia molto simile a' git pull --rebase'.Fa un recupero e poi un 'git rebase @ {u}' Bene, questa è una bugia, ma è un modo semplice per pensarci. Ma il punto è che il tuo ramo locale viene resettato su @ {u} e poi tutti i commit locali sul tuo vecchio ramo prima che il reset venga riprodotto in cima a quello che ha upstream. Ciò consente una spinta fastforward banale a monte. –

+0

Supponendo che 'git rebase --pull' fosse un refuso e avrebbe dovuto essere' git pull --rebase', allora penso che riordina 'next' in' D'-E'-F'-G'-H'- I'-B'-C''. Suona bene? In tal caso, modificherò la mia risposta di conseguenza. – MikeSep

+1

Dopo 'git pull --rebase' otterrai A-D-E-F-G-H-I-B'-C '. La g-p-r costringerà sempre il tuo ramo locale (successivo) a contenere tutti i commit su @ {u} (origine/successiva) e quindi tutto ciò che è unico al prossimo verrà riprodotto (probabilmente raccolto in alto) in cima. Congratulazioni per essere abbastanza intelligente da non tentare di creare D "-E" -F "-G" -H "-I" –

0

Iniziare con i passaggi molto semplici per ribasare il ramo con il master; Nome;

git-rebase 

sinossi;

git rebase [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>] 
     [<upstream>] [<branch>] 
git rebase [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>] 
     --root [<branch>] 
git rebase --continue | --skip | --abort | --edit-todo 

Descrizione; assumere i seguenti storia esiste e il ramo corrente è "campione":

A---B---C sample 
     /
    D---E---F---G master 

Da questo punto, il risultato di uno dei seguenti comandi:

git rebase master 
git rebase master sample 

sarebbe:

A'--B'--C' sample 
       /
    D---E---F---G master 

NOTA: Quest'ultima forma è solo una mano breve di git checkout sample seguita da git rebase master. Quando il rebase termina il campione rimarrà il ramo estratto.

Se il ramo upstream contiene già una modifica effettuata (ad esempio, poiché è stata inviata una patch che è stata applicata a monte), tale commit verrà saltato. Ad esempio, l'esecuzione 'git rebase master` sul seguente storia (in cui A' e A introdurre la stessa serie di cambiamenti, ma hanno diverse informazioni committer):

A---B---C sample 
     /
    D---E---A'---F master 

si tradurrà in:

B'---C' sample 
      /
D---E---A'---F master 

Tutte queste erano la comprensione schematica del processo di rebase. Una volta risolti i conflitti rilevati dopo aver digitato git rebase master , risolvere i conflitti e digitare git add -u per aggiungere i codici modificati al repository. quindi eseguire il comando git rebase --continue e continuare a risolvere i conflitti e ripetere il comando;

git add -u 

e

git rebase --continue 

fino conflitti essere trovati. Finalmente il comando finale sarà,

git push --force origin sample(your branch name) 
+0

per riferimenti esterni, seguire https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html –