Mesclar ramo de desenvolvimento com mestre

764

Eu tenho dois ramos, a saber, mastere developmentem um repositório do GitHub. Estou fazendo todo o meu desenvolvimento no ramo de desenvolvimento, como mostrado.

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

Agora eu quero mesclar todas as alterações no developmentramo no master. Minha abordagem atual é:

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

Informe-me se o procedimento que estou seguindo está correto.

Pawan
fonte
7
git pull -udefine o rastreamento upstream para a ramificação (ou todas as ramificações, se pressionar mais de uma). Uma vez definido, o rastreamento persiste. Não há razão para usá-lo continuamente.
David Culp

Respostas:

1166

Geralmente, gosto de mesclar mastero developmentprimeiro para que, se houver algum conflito, eu possa resolver no developmentpróprio ramo e meus masterrestos mortais estejam limpos.

(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)

Não há muita diferença nas duas abordagens, mas às vezes notei que ainda não quero mesclar a ramificação masterdepois de mesclá-las ou que ainda há mais trabalho a ser feito antes que elas possam ser mescladas , então eu tendem a deixar masterintocadas até o material final.

EDIT: Dos comentários

Se você quiser acompanhar quem fez a mesclagem e quando, poderá usar o --no-ffsinalizador durante a mesclagem para fazer isso. Geralmente, isso é útil apenas ao mesclar developmentna master(última etapa), pois pode ser necessário mesclar masterna development(primeira etapa) várias vezes no seu fluxo de trabalho, e criar um nó de confirmação para elas pode não ser muito útil.

git merge --no-ff development
Sailesh
fonte
71
Há uma pequena desvantagem nessa abordagem: a mesclagem real a ser dominada provavelmente é uma mesclagem de avanço rápido e, portanto, não cria nenhum nó de consolidação. Isso não é problema com o código real na ramificação, mas torna difícil descobrir mais tarde, quem fez a mesclagem real para dominar e em que momento. É necessário um explícito --no-ffpara mesclar para dominar para corrigir isso.
Michas
11
Sim, é exatamente isso que --no-ffserve. :)
michas
19
Isso é git merge --no-ff developmentapenas para corrigir o uso do @ elect.
Jewbix.cube 01/03
2
@sailesh, atualize sua resposta para incluir o sinalizador de mesclagem git, se você concorda com os comentários?
Usuário da Web
2
@ Marte, a mesclagem substituirá um arquivo se a alteração antiga estiver em ascendência direta do commit. Por exemplo, A->B->Cseja mestre e A->X->Yé seu ramo de desenvolvimento. Se você alterar parte de um arquivo no Xqual pode ter tido conflitos com uma alteração A, ele não será um conflito, porque Aé um ancestral de X. Em relação às alterações perdidas, consulte stackoverflow.com/questions/7147680/… para recuperar as alterações.
Sailesh
103

Pessoalmente, minha abordagem é semelhante à sua, com mais alguns ramos e algumas abalos de commits quando eles voltam ao domínio.

Um dos meus colegas de trabalho não gosta muito de mudar de ramificação e permanece no ramo de desenvolvimento com algo semelhante ao seguinte, todos executados no ramo de desenvolvimento.

git fetch origin master

git merge master

git push origin development:master

A primeira linha garante que ele tenha quaisquer confirmações upstream que foram feitas para dominar desde a última vez em que atualizou seu repositório local.

O segundo puxa essas mudanças (se houver) do mestre para o desenvolvimento

O terceiro empurra o ramo de desenvolvimento (agora totalmente mesclado com o mestre) até a origem / mestre.

Eu posso estar com o seu fluxo de trabalho básico um pouco errado, mas essa é a essência principal.

David Culp
fonte
Obrigado! Isso para mim faz mais sentido intuitivo.
Jamie Nicholl-Shelley
2
Sim - nos 6 anos ou mais desde que escrevi isso, eu também o adotei - embora com rebasea atualização do devramo em vez de merge.
David Culp
32

Explicação de baixo para aqueles que vieram aqui sem nenhum conhecimento de ramos.

A lógica básica de desenvolvimento de ramificação principal é: Você trabalha apenas em outras ramificações e usa apenas mestre para mesclar outras ramificações.

Você começa a criar uma nova ramificação desta maneira:

1) Clone o repositório no seu diretório local (ou crie um novo repositório):

$ cd /var/www
$ git clone [email protected]:user_name/repository_name.git

2) Crie uma nova ramificação. Ele conterá os arquivos mais recentes do seu repositório de ramificação principal

$ git branch new_branch

3) Altere sua ramificação atual do git para new_branch

$ git checkout new_branch

4) Faça codificação, confirma, como sempre ...

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

5) Quando o trabalho for concluído neste ramo, mesclar com o ramo "mestre":

$ 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”)

Atualização: eu recomendo usar o GitKraken para isso para ver a árvore visual das alterações e ver melhor toda a lógica e confirmações.

Gediminas
fonte
Gostei da sua abordagem de não trabalhar no mestre. mas hoje quando eu estava jogando com o gitflow, criei um releaseramo nosso do develop. Em seguida, adicionou um arquivo de nota de versão e confirmado. Em seguida, termine o lançamento, que será mesclado novamente aos dois master/develop. mas minha ramificação principal só tinha notas de lançamento recém-adicionadas. nenhum outro arquivo durante as confirmações de desenvolvimento anteriores foram atualizados nele.
Amit Shah #
se você trabalha em outra ramificação que não seja mestre, certifique-se de confirmar e enviar alterações nessa ramificação. Você pode ver como os arquivos se parecem na interface gráfica do github.com ou bitbucket.com e tentar clicar em Mesclar lá, no site. Ele deve atualizar tudo, desde sua ramificação até o mestre. Se o mestre tiver arquivos mais recentes, deve haver um conflito e você receberá a mensagem de erro. Não tenho certeza eu respondi bom o suficiente, por favor me dê mensagem se não :)
Gediminas
Estou usando o sourcetree como repositório da GUI e do github. Eu tentei 2 vezes com o teste de lançamento. o mestre nunca é atualizado com a ramificação de desenvolvimento mais recente.
Amit Shah #
tente usar no site do github.com ao vivo os arquivos da sua filial em que você está trabalhando. Eles são empurrados? Se sim, tente clicar no mesmo ramo - Mesclar e você verá o que acontece. Na minha experiência pessoal com sourcetree é muito ruim - eu não era capaz de entender completamente o que está acontecendo em meus galhos também
Gediminas
Obrigado @Gediminas pela explicação detalhada. Eu estava confuso em palavras-chave git antes de ler a sua resposta .. :)
Dinesh Suthar
21

Seria ótimo se você pudesse usar o fluxo de trabalho do Git Flow . Pode mesclar desenvolver ramificações em master facilmente.

O que você quer fazer é seguir as instruções do git-flow mencionadas aqui:

PASSOS:

  • configurar o projeto git-flow
  • criar filiais e mesclar tudo para desenvolver
  • execute o comando git flow release start <version_number>
  • depois forneça uma mensagem significativa para a liberação
  • execute o comando git flow release finish <version_number>
  • ele mesclará tudo no mestre e mudará o ramo para mestre .
  • execute o comando git pushpara publicar as alterações no mestre remoto .

Para mais informações, visite a página - http://danielkummer.github.io/git-flow-cheatsheet/

Harsha
fonte
1
A solução se alguém 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
Rizwan Siddiquee
fonte
9

Sim, isso está correto, mas parece um fluxo de trabalho muito básico, no qual você apenas armazena as alterações antes que elas estejam prontas para a integração. Você deve olhar para fluxos de trabalho mais avançados que o git suporta. Você pode gostar da abordagem de ramificação de tópicos , que permite trabalhar em vários recursos em paralelo, ou a abordagem de graduação que amplia um pouco o fluxo de trabalho atual.

Sergiu Dumitriu
fonte
6

Se você estiver no Mac ou Ubuntu, vá para a pasta de trabalho da filial. No terminal

suponha que harisdev é o nome da filial.

git checkout master

se houver arquivos não rastreados ou não confirmados, você receberá um erro e precisará confirmar ou excluir todos os arquivos não rastreados ou não confirmados.

git merge harisdev 

git push origin master

Um último comando para excluir a ramificação.

$ git branch -d harisdev
Haris Np
fonte
O que aqui é específico para Mac ou Ubuntu?
Talonx
Desculpa. Nenhuma das outras respostas mencionou que os comandos devem ser dados no Terminal e o comando para excluir a ramificação. Na verdade, eu só queria adicionar o comando para excluir a ramificação para que o desenvolvedor não mexa com a mesma ramificação no futuro. Eu estou usando Mac, então eu mencionei isso. Sua pergunta é válida e nenhum desses comandos é específico para Mac ou Ubuntu.
Haris Np
Obrigado por esclarecer.
Talonx
5

Passo 1

Crie e alterne para uma nova ramificação "dev", na qual seus arquivos git locais estão sincronizados com o controle remoto, mas a ramificação "dev" ainda não existe.

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

Faça as alterações no ramo "dev" (atual, se você seguir a etapa 1), confirme e envie-as para o 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.

etapa 3

Mesclar seu ramo "dev" no "mestre".

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.
kataras
fonte
4

É assim que eu costumo fazer. Primeiro, verifique se você está pronto para mesclar suas alterações no mestre.

  1. Verifique se o desenvolvimento está atualizado com as alterações mais recentes do servidor remoto com um git fetch
  2. Depois que a busca estiver concluída git checkout master.
  3. Certifique-se de que a ramificação principal tenha as atualizações mais recentes executando git pull
  4. Após a conclusão dos preparativos, você pode iniciar a mesclagem com git merge development
  5. Empurre as alterações com git push -u origin mastere pronto.

Você pode descobrir mais sobre a fusão do git no artigo.

Nesha Zoric
fonte
3

1) No desenvolvimento da filial, verifique o status do git usando o seguinte comando:

git status

Não deve haver código não confirmado. Se estiver, envie seu código no ramo Desenvolvimento:

git add *

git commit -m "My initial commit message"

git push origin Development

2) Na ramificação Desenvolvimento, execute os seguintes dois comandos:

git branch -f master HEAD

git push -f origin master

Ele enviará o código da ramificação de Desenvolvimento para a ramificação principal.

Himanshu Mahajan
fonte
Isso impulsiona todo o desenvolvimento comprometido a dominar também, ou simplesmente adiciona um novo commit único ao master?
rola
1
como isso realmente funciona? especificamente "git branch master" quando você está desenvolvendo parece loucura. como você pode criar um novo ramo chamado mestre, se já existe um ramo chamado mestre? Os documentos dizem que -f faz isso: Redefina <branchname> para <startpoint>. O que isto significa?
John Little
Essa força não está empurrando o mestre local para o mestre remoto? Parece uma péssima idéia se você estiver trabalhando em equipe.
28418 Nick
-fnão é recomendado.
precisa saber é o seguinte
2

Baseado em @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)

O primeiro comando garantirá que você tenha todas as confirmações upstream feitas no mestre remoto, com a resposta Sailesh que não aconteceria.

O segundo fará uma mesclagem e criará conflitos que você poderá resolver.

Depois de fazer isso, você pode finalmente fazer o checkout do master para mudar para o master.

Em seguida, você mescla a ramificação de desenvolvimento no mestre local. O sinalizador no-ff criará um nó de confirmação no mestre para que toda a mesclagem seja rastreável.

Depois disso, você pode confirmar e empurrar sua mesclagem.

Este procedimento garantirá que haja uma consolidação de mesclagem do desenvolvimento para dominar o que as pessoas podem ver; se elas forem olhar para o ramo de desenvolvimento, poderão ver o comprometimento individual que você fez nesse ramo durante o desenvolvimento.

Opcionalmente, você pode alterar seu commit de mesclagem antes de enviá-lo, se desejar adicionar um resumo do que foi feito no ramo de desenvolvimento.

EDIT: minha resposta original sugeriu um git merge masterque não fez nada, é melhor fazer git merge FETCH_HEADdepois de buscar a origem / mestre

Cisco
fonte
2

Depois de fazer o checkout do ramo de desenvolvimento, você ...

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

 git checkout master 
 git merge dev
 git push origin master 
Tiago Medici
fonte
1

Se você estiver usando o gerrit, os seguintes comandos funcionarão perfeitamente.

git checkout master
git merge --no-ff development

Você pode salvar com a mensagem de confirmação padrão. Verifique se o ID de alteração foi gerado. Você pode usar o seguinte comando para garantir.

git commit --amend

Em seguida, pressione com o seguinte comando.

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

Você pode encontrar uma mensagem de erro como a abaixo.

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

Para resolver isso, o administrador do projeto gerrit deve criar outra referência no gerrit chamada 'refs / for / refs / heads / master' ou 'refs / for / refs / heads / *' (que abrangerá todas as ramificações no futuro). Em seguida, conceda a permissão 'Push Merge Commit' a essa referência e a permissão 'Submit', se necessário, para enviar o GCR.

Agora, tente o comando push acima novamente e ele deve funcionar.

Créditos:

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

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

Sankaran Srinivasan
fonte
1

Eu acho que a solução mais fácil seria

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

Isso também preserva o histórico de todos os ramos em uso

Vishal
fonte
-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
Ankit Kumar Rajpoot
fonte
1
Forçar pressão quando você vê esse erro quase nunca é a coisa correta a ser executada, a menos que você tenha certeza de que sabe por que sua filial local está ausente confirmada pela filial remota. Em geral, é muito melhor voltar ao passo 3 e pullnovamente. Além disso, não está claro qual valor essa resposta agrega em comparação com as respostas existentes.
Kyle Strand