Aggiorna i rami Git dal master


676

Sono nuovo di Git, e ora sono in questa situazione:

  • Ho quattro rami (master, b1, b2 e b3).
  • Dopo aver lavorato su b1-b3, mi sono reso conto che ho qualcosa da cambiare su Branch Master che dovrebbe essere in tutti gli altri rami.
  • Ho cambiato quello di cui avevo bisogno mastere ... ecco il mio problema:

Come posso aggiornare tutti gli altri rami con il mastercodice filiale?



59
Ancora un altro semplice compito reso difficile da Git. Gli sviluppatori Git dovrebbero usare Stack Overflow come feedback nel loro loop SDLC. 300.000 persone dovrebbero indicare che qualcosa è seriamente sbagliato nel flusso di lavoro di Git. Devono assumere un esperto di UX perché chiaramente non possono farlo da soli.
jww

Risposte:


621

Hai due opzioni:

Il primo è un'unione, ma questo crea un ulteriore commit per l'unione.

Dai un'occhiata a ciascun ramo:

git checkout b1

Quindi unisci:

git merge origin/master

Quindi premere:

git push origin b1

In alternativa, puoi fare un rebase:

git fetch
git rebase origin/master

15
Ho una preoccupazione per questo approccio. Quando eseguo git log --graph, il grafico mostra che il master è effettivamente unito al ramo dell'argomento. Questo causerà qualche problema a lungo termine? Ho pensato che la migliore pratica sia sempre ricollegare il ramo dell'argomento al master. Per favore, commenta.
Patrick,

2
Cerca questo problema se stai andando con il flusso di lavoro di unione: randyfay.com/node/89
Hampus Ahlgren,

22
Stai fondendo master in b1. Perché tu got push origin master... non ha senso. Non stai cambiando il ramo principale. Penso che sia un errore con 119 voto positivo: /
Yves Lange

22
Non utilizzare il metodo di unione, utilizzando git rebase masterè la risposta corretta
Weston Ganger

6
Per quelli di noi che leggono in seguito - la preoccupazione di @Kursion per il refuso è stata affrontata dalla modifica dell'autore. Inoltre, la seconda risposta più votata più alta qui sotto dice sostanzialmente la stessa cosa di questa risposta, ma con un diagramma della struttura del ramo e un avvertimento sul perché non vorresti riformulare.
Beyondeteal

496

Hai sostanzialmente due opzioni:

  1. Ti unisci. In realtà è abbastanza semplice e un'operazione perfettamente locale:

    git checkout b1
    git merge master
    # repeat for b2 and b3
    

    Questo lascia la storia esattamente come è successo: hai biforcato dal maestro, hai apportato modifiche a tutti i rami e infine hai incorporato i cambiamenti dal maestro in tutti e tre i rami.

    gitè in grado di gestire questa situazione davvero bene, è progettato per le fusioni che avvengono in tutte le direzioni, allo stesso tempo. Puoi fidarti di essere in grado di riunire correttamente tutti i thread. Semplicemente non importa se il ramo b1si fonde mastero si masterfonde b1, il commit di unione sembra lo stesso per git. L'unica differenza è, quale ramo finisce per puntare a questo commit di unione.

  2. Ti rebase. Le persone con un SVN o un background simile lo trovano più intuitivo. I comandi sono analoghi al caso merge:

    git checkout b1
    git rebase master
    # repeat for b2 and b3
    

    Alla gente piace questo approccio perché mantiene una storia lineare in tutti i settori. Tuttavia, questa storia lineare è una bugia e dovresti essere consapevole che lo è. Considera questo grafico di commit:

    A --- B --- C --- D <-- master
     \
      \-- E --- F --- G <-- b1
    

    La fusione risulta nella vera storia:

    A --- B --- C --- D <-- master
     \                 \
      \-- E --- F --- G +-- H <-- b1
    

    Il rebase, tuttavia, ti dà questa storia:

    A --- B --- C --- D <-- master
                       \
                        \-- E' --- F' --- G' <-- b1
    

    Il punto è che gli impegni E', F'e G'mai realmente esistiti, e probabilmente non sono mai stati testati. Non possono nemmeno compilare. In realtà è abbastanza facile creare commit senza senso tramite un rebase, specialmente quando i cambiamenti mastersono importanti per lo sviluppo in b1.

    La conseguenza di questo può essere, che non è possibile distinguere quale delle tre commit E, Fe Gin realtà ha introdotto una regressione, diminuendo il valore di git bisect.

    Non sto dicendo che non dovresti usare git rebase. Ha i suoi usi. Ma ogni volta che lo usi, devi essere consapevole del fatto che stai mentendo sulla storia. E dovresti almeno compilare test i nuovi commit.


Mi è stato la fusione un altro ramo fonte (non master) e misure supplementari da aggiungere a questa bella risposta è stata di aggiornare sul mio repo locale prima fusione (per avere l'ultimo codice a livello locale): git checkout <source branch> git pull. Quindi proseguendo con quanto sopra: git checkout b1...
Rod,

3
Come utente SVN di lunga data, preferisco l'opzione di unione al rebase: utilizzando qualsiasi controllo di versione è molto, molto importante tenere un registro accurato delle modifiche apportate e del perché. Posso vedere l'appello del rebase per semplificare la storia apparente, ma dovresti quindi tornare indietro e aggiungere ai commenti di commit di E ', F', G '- e preferibilmente avere il rebase aggiunto automaticamente a quei commenti. Altrimenti se il processo build / test / test-deploy si interrompe su G ', devi capire perché le modifiche sono state apportate senza informazioni complete.
WillC,

13
La storia è una bugia
piratemurray il

Grazie uso "git merge any-branch-name" per unire il codice di un ramo a un altro ramo. A livello locale posso testare il codice del ramo 1 mentre sono sul ramo 2
Priti

1
@blamb I conflitti di unione si verificano con entrambi git mergee git rebase. Non si possono evitare quelli. git rebaseha il vantaggio di permetterti di nascondere diverse fasi di rebasing (cioè di riassegnare lo stesso ramo su più commit diversi in sequenza per ridurre la quantità di conflitti in ogni fase). Tuttavia, il semplice fatto che un rebase stia mentendo sulla storia rende molto più facile sbagliare in un tale rebase a più livelli ... Ecco perché preferisco sempre l'unione, anche quando ciò significa che devo ingombrare la storia con diversi commit di unione .
cmaster - reintegra monica il

238

git rebase masterè il modo corretto di farlo. La fusione significherebbe la creazione di un commit per l'unione, mentre la rifasatura no.


52
Che dire di quando hai già spinto verso l'origine, se rinnovi riscrivi la cronologia del commit e questo entrerà in conflitto con il tuo ramo remoto. Penso che rebase dovrebbe essere usato solo su pull o quando non hai spinto verso un ramo remoto.
Matt Smith,

6
Se sei l'unico che lavora sul ramo remoto, puoi eseguire git push - forza funzione di origine per aggiornare il tuo ramo remoto con un ramo locale riformulato. stackoverflow.com/questions/8939977/...
stormwild

7
rebase e unisci entrambe le opere, rebase è la cosa migliore per le filiali private, perché fornisce un grafico cronologico più pulito. questa risposta è la migliore
Junchen Liu

5
È necessario essere più chiari sul compromesso tra chiarezza (ottimo per utente singolo o piccolo team) o verità disordinata (per rami di codice multi-contributore - necessari per la manutenibilità (nella mia esperienza - YMMV)).
WillC,


53

Se hai lavorato su un ramo on-e-off, o sono successe molte cose in altri rami mentre hai lavorato su qualcosa, è meglio convertire il tuo ramo in master. Ciò mantiene in ordine la storia e rende le cose molto più facili da seguire.

git checkout master
git pull
git checkout local_branch_name
git rebase master
git push --force # force required if you've already pushed

Appunti:

  • Non modificare i rami su cui hai collaborato con altri.
  • Dovresti rifare il riferimento al ramo in cui ti unirai, che potrebbe non essere sempre padrone.

C'è un capitolo sulla riformulazione su http://git-scm.com/book/ch3-6.html e un sacco di altre risorse sul web.


Grazie per la semplice soluzione
altro ragazzo alto il

18

@cmaster ha fatto la risposta più elaborata. In breve:

git checkout master #
git pull # update local master from remote master
git checkout <your_branch>
git merge master # solve merge conflicts if you have`

Non è necessario riscrivere la cronologia delle filiali invece di mantenerli nello stato effettivo per riferimenti futuri. Mentre si fonde con master, crea un ulteriore commit ma è economico. Impegni non costa.


13

Per aggiornare altri rami come (backup) con la copia del ramo principale. Puoi seguire in entrambi i modi (rebase o unione) ...

  1. Esegui rebase (non verrà eseguito alcun commit aggiuntivo nel ramo di backup).
  2. Unisci i rami (verrà eseguito automaticamente un ulteriore commit nel ramo di backup).

    Nota: Rebase non è altro che stabilire una nuova base (una nuova copia)

git checkout backup
git merge master
git push

(Ripetere l'operazione per altri rami, ad esempio backup2 e così via, ecc.)

git checkout backup
git rebase master
git push

(Ripetere l'operazione per altri rami, ad esempio backup2 e così via, ecc.)



1

Esistono due opzioni per questo problema.

1) git rebase

2) git merge

Solo diff con sopra entrambi in caso di unione, avrà un impegno extra nella cronologia

1) git checkout branch (b1, b2, b3)

2) git rebase origin / master (In caso di conflitti risolti localmente facendo git rebase --continua)

3) git push

In alternativa, l'opzione git merge è di moda simile

1) git checkout "your_branch" (b1, b2, b3)

2) git merge master

3) git push


1

per aggiornare il tuo ramo dal master:

  git checkout master
  git pull
  git checkout your_branch
  git merge master
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.