Unire il ramo di sviluppo con il master


764

Ho due rami in particolare mastere developmentin un repository GitHub. Sto facendo tutto il mio sviluppo nel ramo dello sviluppo, come mostrato.

git branch development
git add *
git commit -m "My initial commit message"
git push -u origin development

Ora voglio unire tutte le modifiche sul developmentramo in master. Il mio approccio attuale è:

git checkout master 
git merge development
git push -u origin master 

Per favore fatemi sapere se la procedura che sto seguendo è corretta.


7
git pull -uimposta il tracciamento a monte per il ramo (o tutti i rami se ne spinge più di uno). Una volta impostato, il tracciamento persiste. Non c'è motivo di usarlo continuamente.
David Culp,

Risposte:


1166

In genere mi piace unirmi masteral developmentprimo in modo che se ci sono conflitti, posso risolverlo nel developmentramo stesso e i miei masterresti puliti.

(on branch development)$ git merge master
(resolve any merge conflicts if there are any)
git checkout master
git merge development (there won't be any conflicts now)

Non c'è molta differenza nei due approcci, ma a volte ho notato che non voglio ancora unire il ramo master, dopo averli uniti, o che c'è ancora molto lavoro da fare prima che questi possano essere uniti , quindi tendo a lasciare masterintatto fino all'ultimo materiale.

EDIT: dai commenti

Se vuoi tenere traccia di chi ha fatto l'unione e quando, puoi usare --no-ffflag durante l'unione per farlo. Questo è generalmente utile solo quando si unisce developmental master(ultimo passaggio), perché potrebbe essere necessario fondersi masterin development(prima fase) più volte nel vostro flusso di lavoro, e la creazione di un commit nodo per questi potrebbe non essere molto utile.

git merge --no-ff development

71
C'è un leggero svantaggio su questo approccio: l'unione effettiva al master è molto probabilmente un'unione di avanzamento rapido e quindi non crea alcun nodo di commit. Questo non è un problema con il codice effettivo sul ramo, ma rende difficile scoprire in seguito, chi ha fatto l'unione effettiva da padroneggiare e in quale momento. Per --no-ffrisolvere ciò è necessario un esplicito all'unione da padroneggiare.
Michas,

11
Sì, è esattamente quello che --no-ffserve. :)
michas

19
Questo è git merge --no-ff developmentsolo per correggere l'uso di @eletti.
jewbix.cube

2
@sailesh puoi aggiornare la tua risposta per includere il flag git merge, se sei d'accordo con i commenti?
Utente Web

2
@Mars, la fusione sovrascriverà un file se la vecchia modifica era di origine diretta del commit. Ad esempio, A->B->Csiate padroni ed A->X->Yè il vostro ramo dev. Se si modifica una parte di un file in Xcui potrebbero essersi verificati conflitti con una modifica A, non si tratterà di un conflitto, poiché Aè un antenato di X. Per quanto riguarda le modifiche perse, controlla stackoverflow.com/questions/7147680/… per recuperare eventuali modifiche.
Sailesh,

103

Personalmente, il mio approccio è simile al tuo, con qualche altro ramo e qualche schiacciamento di commit quando tornano al master.

A uno dei miei colleghi non piace dover cambiare molto ramo e rimane sul ramo di sviluppo con qualcosa di simile al seguente tutto eseguito dal ramo di sviluppo.

git fetch origin master

git merge master

git push origin development:master

La prima riga si assicura che abbia tutti gli commit a monte che sono stati fatti da padroneggiare dall'ultima volta che ha aggiornato il suo repository locale.

Il secondo tira quei cambiamenti (se presenti) dal master allo sviluppo

Il terzo spinge il ramo di sviluppo (ora completamente unito al master) fino a origin / master.

Potrei avere un po 'sbagliato il suo flusso di lavoro di base, ma questa è la sostanza principale.


Grazie! Questo per me ha un senso più intuitivo.
Jamie Nicholl-Shelley,

2
Sì, negli ultimi 6 anni da quando ho scritto questo, anch'io l'ho adottato, anche se con rebasel'aggiornamento di devBranch invece di merge.
David Culp,

32

Spiegazione dal basso per coloro che sono venuti qui senza alcuna conoscenza dei rami.

La logica di sviluppo di base dei rami master è: lavori solo su altri rami e usi master solo per unire altri rami.

Inizi a creare un nuovo ramo in questo modo:

1) Clonare il repository nella directory locale (o creare un nuovo repository):

$ cd /var/www
$ git clone git@bitbucket.org:user_name/repository_name.git

2) Crea un nuovo ramo. Conterrà gli ultimi file del repository della diramazione principale

$ git branch new_branch

3) Cambia il tuo ramo git corrente in new_branch

$ git checkout new_branch

4) Codifica, si impegna, come al solito ...

$ git add .
$ git commit -m “Initial commit”
$ git push (pushes commits only to “new_branch”)

5) Al termine del lavoro su questo ramo, unire con il ramo "master":

$ git merge master
$ git checkout master (goes to master branch)
$ git merge development (merges files in localhost. Master shouldn’t have any  commits ahead, otherwise there will be a need for pull and merging code by hands!)
$ git push (pushes all “new_branch” commits to both branches - “master” and “new_branch”)

Aggiornamento: consiglio vivamente di usare GitKraken per questo per vedere l'albero visivo delle modifiche e vedere meglio tutta la logica e gli commit.


Mi è piaciuto il tuo approccio di non lavorare sul maestro. ma oggi, quando stavo giocando con gitflow, ho creato il releasenostro branch of the develop. Quindi aggiunto un file della nota di rilascio e impegnato. Quindi finito il rilascio che si fonde nuovamente con entrambi master/develop. ma il mio ramo principale aveva solo una nota di rilascio appena aggiunta. in esso non sono stati aggiornati altri file durante i precedenti commit di sviluppo.
Amit Shah

se lavori su un ramo diverso da quello principale, assicurati di aver eseguito il commit e di aver inviato le modifiche a quel ramo. Quindi puoi guardare come appaiono i file sull'interfaccia grafica di github.com o bitbucket.com e provare a fare clic su Unisci lì, sul sito Web. Dovrebbe aggiornare tutto dalla tua branche al master. Se master ha file più recenti, dovrebbe essere un conflitto e verrà visualizzato il messaggio di errore. Non sono sicuro di aver risposto abbastanza bene, per favore dammi un messaggio in caso contrario :)
Gediminas

Sto usando sourcetree come repository GUI e github. Ho provato 2 volte con il test di rilascio. il master non si è mai aggiornato con l'ultimo ramo di sviluppo.
Amit Shah

prova ad usare sul sito web live di github.com i file della tua filiale su cui stai lavorando. Sono spinti? Se sì, prova a fare clic sullo stesso ramo: Unisci e vedrai cosa succede. Nella mia esperienza personale con sourcetree è piuttosto male - non sono stato in grado di comprendere appieno anche quello che sta succedendo nei miei rami
Gediminas

Grazie @Gediminas per la spiegazione dettagliata. Ero confuso nelle parole chiave git prima di leggere la tua risposta .. :)
Dinesh Suthar,

21

Sarebbe bello se puoi usare il flusso di lavoro di Git Flow . Può unire facilmente il ramo di sviluppo al master.

Quello che vuoi fare è semplicemente seguire le istruzioni git-flow menzionate qui:

STEPS:

  • imposta il progetto git-flow
  • creare rami e unire tutto per sviluppare
  • eseguire il comando git flow release start <version_number>
  • quindi fornire un messaggio significativo per il rilascio
  • eseguire il comando git flow release finish <version_number>
  • unirà tutto in maestro e cambierà il ramo in master .
  • eseguire il comando git pushper pubblicare le modifiche sul telecomando master .

Per ulteriori informazioni, visitare la pagina - http://danielkummer.github.io/git-flow-cheatsheet/


1
La soluzione se qualcuno usa git flow!
Csaba Toth,

21
1. //pull the latest changes of current development branch if any        
git pull (current development branch)

2. //switch to master branch
git checkout master 

3. //pull all the changes if any
git pull

4. //Now merge development into master    
git merge development

5. //push the master branch
git push origin master

9

Sì, questo è corretto, ma sembra un flusso di lavoro molto semplice, in cui stai solo memorizzando le modifiche prima che siano pronte per l'integrazione. Dovresti esaminare i flussi di lavoro più avanzati supportati da git. Potresti apprezzare l' approccio branch topic , che ti consente di lavorare su più funzionalità in parallelo, o l' approccio di graduazione che estende un po 'il tuo flusso di lavoro corrente.


6

Se sei su Mac o Ubuntu, vai alla cartella di lavoro del ramo. Nel terminale

supponiamo che harisdev sia il nome del ramo.

git checkout master

se sono presenti file non tracciati o non impegnati, verrà visualizzato un errore e sarà necessario eseguire il commit o l'eliminazione di tutti i file non tracciati o non impegnati.

git merge harisdev 

git push origin master

Un ultimo comando per eliminare il ramo.

$ git branch -d harisdev

Cosa è specifico per Mac o Ubuntu?
Talonx,

Scusate. Nessuna delle altre risposte menzionava che i comandi dovevano essere dati nel Terminale e il comando per cancellare il ramo. In realtà volevo solo aggiungere il comando per eliminare il ramo in modo che lo sviluppatore non rovinasse lo stesso ramo in futuro. Sto usando il Mac, quindi l'ho menzionato. La tua domanda è valida e nessuno di questi comandi è specifico per Mac o Ubuntu.
Haris Np,

Grazie per il chiarimento.
Talonx,

5

Passo 1

Crea e passa a un nuovo ramo "dev", dove i tuoi file git locali sono sincronizzati con il telecomando ma il ramo "dev" non esiste ancora.

git branch dev # create
git checkout dev # switch
# No need to git add or git commit, the current
# branch's files will be cloned to the new branch by-default.
git push --set-upstream origin dev # push the "dev" branch to the remote.

Passo 2

Apporta le modifiche al ramo "dev" (il tuo attuale se segui il passaggio 1), esegui il commit e spingile al ramo "dev" remoto.

git add .
git commit -S -m "my first commit to the dev branch" # remove the -S if you're not "secure", secure = when you already setup crypto private and public keys (i.e "verified" green sign in github)
git push -u origin dev # push the changes to the remote, -u origin dev is optional but good to use.

Passaggio 3

Unisci il tuo ramo "dev" nel "master".

git checkout dev # switch to "dev" branch if you're not already.
git merge master # optionally, this command is being used to resolve any conflicts if you pushed any changes to your "master" but "dev" doesn't have that commit.
git checkout master # switch to "master", which is the branch you want to be merged.
git merge --no-ff dev # merge the "dev" branch into the "master" one.

4

È così che di solito lo faccio. Innanzitutto, assicurati di essere pronto a unire le tue modifiche in master.

  1. Controlla se lo sviluppo è aggiornato con le ultime modifiche dal tuo server remoto con a git fetch
  2. Una volta completato il recupero git checkout master .
  3. Assicurarsi che il ramo principale abbia gli ultimi aggiornamenti eseguendo git pull
  4. Una volta completati i preparativi, puoi iniziare l'unione con git merge development
  5. Spingi le modifiche con git push -u origin mastere il gioco è fatto.

Puoi trovare ulteriori informazioni sulla fusione di git nell'articolo.


3

1) Su Branch Branch, controlla lo stato git usando il seguente comando:

git status

Non ci dovrebbero essere codici non impegnati. In tal caso, inserisci il tuo codice nel ramo Sviluppo:

git add *

git commit -m "My initial commit message"

git push origin Development

2) Nel ramo Sviluppo, esegui due comandi seguenti:

git branch -f master HEAD

git push -f origin master

Spingerà il codice del ramo di sviluppo al ramo principale.


Questo spinge anche tutti gli sviluppatori impegnati a padroneggiare o semplicemente aggiungere un nuovo singolo commit in master?
Rotola il

1
come funziona davvero? in particolare "git branch master" quando sei sullo sviluppo sembra una follia. come puoi creare un nuovo ramo chiamato master, se esiste già un ramo chiamato master? i documenti dicono che -f fa questo: reimposta <branchname> su <startpoint>. Cosa significa questo?
John Little,

Questa forza non sta spingendo il master locale sul master remoto? Sembra una cattiva idea se lavori in gruppo.
Nick,

-fnon è raccomandato
DawnSong,

2

Basato su @Sailesh e @DavidCulp:

(on branch development)
$ git fetch origin master
$ git merge FETCH_HEAD
(resolve any merge conflicts if there are any)
$ git checkout master
$ git merge --no-ff development (there won't be any conflicts now)

Il primo comando assicurerà che tutti i commit a monte siano stati fatti su master remoto, con la risposta di Sailesh che non sarebbe avvenuta.

Il secondo eseguirà un'unione e creerà conflitti che è possibile risolvere.

Dopo averlo fatto, puoi finalmente effettuare il checkout del master per passare al master.

Quindi unisci il ramo di sviluppo al master locale. Il flag no-ff creerà un nodo di commit nel master affinché l'intera unione sia tracciabile.

Dopodiché puoi impegnarti e spingere la tua unione.

Questa procedura assicurerà che ci sia un commit di unione dallo sviluppo al master che le persone possono vedere, quindi se guardano al ramo di sviluppo possono vedere i singoli commit che hai fatto a quel ramo durante il suo sviluppo.

Facoltativamente, è possibile modificare il commit di unione prima di inviarlo, se si desidera aggiungere un riepilogo di ciò che è stato fatto nel ramo di sviluppo.

EDIT: la mia risposta originale mi ha suggerito di git merge masternon fare nulla, è meglio farlo git merge FETCH_HEADdopo aver recuperato l'origine / master


2

Dopo aver verificato il ramo di sviluppo ...

 git add .
 git commit -m "first commit"
 git push origin dev
 git merge master

 git checkout master 
 git merge dev
 git push origin master 

1

Se stai usando gerrit, i seguenti comandi funzionano perfettamente.

git checkout master
git merge --no-ff development

È possibile salvare con il messaggio di commit predefinito. Assicurarsi che l'id di modifica sia stato generato. È possibile utilizzare il seguente comando per assicurarsi.

git commit --amend

Quindi premere con il seguente comando.

git push origin HEAD:refs/for/refs/heads/master

È possibile che venga visualizzato un messaggio di errore simile al seguente.

! [remote rejected] HEAD -> refs/for/refs/heads/master (you are not allowed to upload merges)

Per risolvere questo problema, l'amministratore del progetto gerrit deve creare un altro riferimento in gerrit chiamato 'refs / for / refs / heads / master' o 'refs / for / refs / heads / *' (che coprirà tutti i rami in futuro). Quindi concedere l'autorizzazione "Push Merge Commit" a questo riferimento e l'autorizzazione "Invia" se necessario per inviare il GCR.

Ora prova di nuovo il comando push sopra e dovrebbe funzionare.

Crediti:

https://github.com/ReviewAssistant/reviewassistant/wiki/Merging-branches-in-Gerrit

https://stackoverflow.com/a/21199818/3877642


1

Penso che la soluzione più semplice sarebbe

git checkout master
git remote update
git merge origin/Develop -X theirs
git commit -m commit -m "New release"
git push --recurse-submodules=check --progress "origin" refs/heads/Master

Ciò preserva anche la storia di tutti i rami in uso


-4
1. //push the latest changes of current development branch if any        
git push (current development branch)

2. //switch to master branch
git checkout master 

3. //pull all the changes if any from (current development branch)
git pull origin (current development branch)

4. //Now merge development into master    
git merge development

5. //push the master branch
git push origin master

Error
To https://github.com/rajputankit22/todos-posts.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/rajputankit22/todos-posts.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Then Use 
5. //push the master branch forcefully
git push -f origin master

1
Spingere forzatamente quando vedi che l'errore non è quasi mai la cosa giusta da fare, a meno che tu non sia molto sicuro di sapere perché manca la tua filiale locale, commette dalla filiale remota. In generale, è molto meglio tornare al passaggio 3 e pullancora. Inoltre, non è chiaro quale valore aggiunge questa risposta rispetto alle risposte esistenti.
Kyle Strand
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.