Come mantenere un ramo git sincronizzato con master


276

Al momento git mi sta facendo la testa, non riesco a trovare la migliore soluzione per quanto segue.

Esistono due rami, uno chiamato master e l'altro chiamato mobiledevicesupport . Voglio mantenere mobiledevicesupport come un ramo continuo che verrà unito / sincronizzato con il ramo master ogni volta che mobiledevicesupport è stabile. Ciò unirebbe le modifiche da mobiledevicesupport a master ma porterebbe anche tutte le modifiche da master a mobiledevicesupport in modo che il ramo possa continuare a lavorare e le funzionalità migliorate o modificate. Questo deve funzionare con un repository centrale e più sviluppatori.

Per favore, un esempio di flussi di lavoro simili che altre persone usano o semplicemente dimmi se questa idea è stupida e dovrei considerare altre opzioni. Al momento il flusso di lavoro sembra corretto, ma non so come far funzionare Git in questo modo.

Grazie, tutto l'aiuto è molto apprezzato.

Aggiornamento 1: se dovessi unire master in mobiledevicesupport e mobiledevice support in master, ricevo commit replicati su entrambi i rami. Oppure git è abbastanza intelligente da capire che ho portato le ultime modifiche dal ramo A al ramo B e ho aggiunto il commit della fusione C al ramo B. E ho tirato le ultime modifiche dal ramo B al ramo A e ho aggiunto il commit della fusione D al ramo UN?

Stavo per pubblicare un'immagine ma non ho abbastanza reputazione per questo, quindi immagino che la seguente illustrazione dovrà fare. Due rami che corrono continuamente con fusioni che vanno spesso in entrambe le direzioni. La cosa chiave di cui non sono sicuro è come git eseguirà i commit e riempirà uno dei rami con i commit dell'altro ramo al momento delle fusioni o rimarrà pulito. Ho usato rebase prima, ma sembra terminare il ramo e mettere tutti i commit nel master, o ho fatto male. Grazie per l'aiuto finora.

master
A--B--C-----H--I--J--M--N
       \   /    \
mobile  \ /      \
D--E--F--G--------K--L

1
Se tu, come me, cercassi come farlo con il client GitHub : help.github.com/articles/merging-branches
cregox,

1
Questa domanda mi ha salvato la vita per secoli; Grazie per il grande sforzo nel prendere tempo per porre questa meravigliosa domanda @Mr. EZEKIEL
DJphy

Nel caso in cui tu stia lavorando su una forcella, devi seguire help.github.com/articles/syncing-a-fork
koppor

Risposte:


417

si basta

git checkout master
git pull
git checkout mobiledevicesupport
git merge master

per mantenere sincronizzato il supporto per dispositivi mobili con master

poi quando sei pronto a mettere mobiledevicesupport in master, prima unisci in master come sopra, quindi ...

git checkout master
git merge mobiledevicesupport
git push origin master

e questo è tutto.

il presupposto qui è che mobilexxx è un ramo di argomenti con lavoro che non è ancora pronto per entrare nel ramo principale. Quindi si fondono in master solo quando mobiledevicesupport è in una buona posizione


Mi sembra ragionevole, suppongo di non essere sicuro di quanto sporca possa rendere la cronologia del commit, aggiornerò la mia domanda con un esempio di ciò che penso possa accadere.
Mr. EZEKIEL

1
Avrai diversi "merge commit", essenzialmente git che cerca di risolvere le differenze tra i tuoi rami. se sei preoccupato per questo E sei l'unico ad usare il ramo, fai un "master git rebase" invece di un "master git merge" E NON PREMERE GLI IMPEGNI PER LA FILIALE REMOTA. Se lo fai ti ritroverai a fare un sacco di spinte di forza (git push --force) verso origin / mobiledevices support perché perché (probabilmente) invierai sempre una storia di commit che non corrispondono a ciò che il ramo remoto ha. maggiori dettagli qui git-scm.com/book/en/Git-Branching-Rebasing
concept47

Credo che questa sia la risposta corretta, suona esattamente come quello che voglio. Ho aggiunto un'illustrazione sopra per renderlo un po 'più chiaro, ma se ciò che stai dicendo è vero, allora dovrebbe funzionare esattamente come voglio. Grazie.
Mr. EZEKIEL

2
Leggi questo per capire perché questo non è particolarmente un buon consiglio: kentnguyen.com/development/visualized-git-practices-for-team/… . È stato scritto dal manutentore di Git, quindi probabilmente è giusto dire che sa di cosa sta parlando riguardo a questo particolare argomento.
Dan Molding,

2
Questo rende la cronologia del commit disordinata, vedi la mia risposta farlo tramite rebase.
Gob00st

43

Ogni volta che vuoi ottenere le modifiche dal master nel tuo ramo di lavoro, fai un git rebase <remote>/master. Se ci sono conflitti. risolverli.

Quando il tuo ramo di lavoro è pronto, fai nuovamente il rebase e poi fallo git push <remote> HEAD:master. Ciò aggiornerà il ramo master sul telecomando (repository centrale).


3
Quali sono i pro / contro di farlo in questo modo invece che nella risposta accettata?
Hampus Ahlgren,

33
Sane fino a quando non passi 5 ore all'inferno rebase
IcedDante

21
Questo è vero solo se il tuo ramo è su un repository privato. Non rifare mai qualcosa che è stato spinto a monte. Ecco perché: git-scm.com/book/en/v2/…
Kleag

3
Il problema con il rebasing come riscrittura della storia è che gli SHA del commit rinnovato vengono modificati e quindi non è possibile fare affidamento sull'output di (ad es git branch --contains <commit>. ) .
jnns,

13

L'approccio di concept47 è il modo giusto per farlo, ma consiglierei di unirmi all'opzione --no-ff per mantenere chiara la cronologia dei tuoi commit.

git checkout develop
git pull --rebase
git checkout NewFeatureBranch
git merge --no-ff master

9

Sì, sono d'accordo con il tuo approccio. Per unire mobiledevicesupport in master puoi usare

git checkout master
git pull origin master //Get all latest commits of master branch
git merge mobiledevicesupport

Allo stesso modo puoi anche unire il master nel supporto dispositivi mobili.

D. Se la fusione incrociata è un problema o no.

R. Beh, dipende dagli commit fatti nel ramo mobile * e nel ramo principale dall'ultima volta che sono stati sincronizzati. Prendi questo esempio: dopo l'ultima sincronizzazione, a questi rami succedono i seguenti commit

Master branch: A -> B -> C [where A,B,C are commits]
Mobile branch: D -> E

Supponiamo ora che il commit B abbia apportato alcune modifiche al file a.txt e il commit D abbia anche apportato alcune modifiche a a.txt. Diamo un'occhiata all'impatto di ogni operazione di fusione ora,

git checkout master //Switches to master branch
git pull // Get the commits you don't have. May be your fellow workers have made them.
git merge mobiledevicesupport // It will try to add D and E in master branch.

Ora, ci sono due tipi di fusione possibili

  1. Unione rapida in avanti
  2. True merge (Richiede uno sforzo manuale)

Git tenterà innanzitutto di unire FF e se rileva conflitti non è risolvibile con git. Non riesce l'unione e ti chiede di unire. In questo caso, si verificherà un nuovo commit che è responsabile della risoluzione dei conflitti in a.txt.

Quindi la linea di fondo è La fusione incrociata non è un problema e alla fine devi farlo ed è ciò che significa la sincronizzazione. Assicurati di sporcarti le mani unendo i rami prima di fare qualsiasi cosa in produzione.


1
Quindi la fusione incrociata in questo modo non è un problema?
Mr. EZEKIEL

La fusione incrociata è ciò che diciamo sincronizzazione e non è un problema a meno che gli impegni in entrambi i rami non causino conflitti. Si prega di vedere la mia risposta aggiornata.
sachinjain024

3

La risposta accettata tramite git merge porterà a termine il lavoro ma lascia un disordinato commit hisotry, il modo corretto dovrebbe essere 'rebase' tramite i seguenti passaggi (supponendo che tu voglia mantenere il ramo delle tue funzioni in sycn con sviluppo prima di fare il push finale prima di PR ).

1 git fetchdal tuo ramo di funzionalità (assicurati che il ramo di funzionalità su cui stai lavorando sia aggiornato fino ad oggi)

2 git rebase origin/develop

3 in caso di conflitto, risolverli uno per uno

4 utilizzare git rebase --continueuna volta risolti tutti i conflitti

5 git push --force


1
È difficile da leggere e da capire. Aggiorna la tua risposta e utilizza il markdown del codice appropriato per separare i tuoi commenti dai comandi.
not2qubit

2

Stai pensando nella giusta direzione. Unisci il master con mobiledevicesupport continuamente e unisci mobiledevicesupport con master quando mobiledevicesupport è stabile. Ogni sviluppatore avrà il proprio ramo e potrà unirsi ae dal supporto master o da quello mobile a seconda del proprio ruolo.

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.