Mesclar um Branch em Master no Git
- Pré-requisitos
- Preparando para mesclar no Git
-
Merge a Branch Into Master com o método
merge
no Git -
Mesclar uma ramificação no mestre com o método
rebase
- Conclusão
Um dos recursos mais poderosos do git é a criação de ramificações e a operação de mesclagem. O Git permite que os usuários criem um novo branch e os mesclem no código de desenvolvimento. Esse recurso melhora o fluxo de trabalho do processo de desenvolvimento para vários projetos, incentivando tarefas mais específicas, menores e granulares.
Neste artigo tutorial, discutiremos diferentes abordagens para mesclar o branch do recurso git com o master.
A principal vantagem do git é seu sistema de ramificação. É nesses ramos que repousa toda a magia do GIT! O branch master carregará todas as modificações feitas. Portanto, o objetivo não é fazer as modificações diretamente neste branch, mas fazê-las em outros branches e, após vários testes, integrá-los no branch master.
Em nosso tutorial para simplificar, vamos considerar que existem dois ramos, o ramo master
e o ramo de recurso conhecido como feature-1
. O branch principal é o branch master que contém o código de produção, e o segundo branch é onde as modificações serão executadas ou novos recursos serão implementados. No final, se um recurso ou bug for aprovado, ele será mesclado com o master.
Vamos começar a demonstração da fusão de duas ramificações com um exemplo real. Para começar, exigimos o seguinte.
Pré-requisitos
Crie um Repositório no GitHub
Um repositório inicial pode ser criado conforme apresentado no Github
Em seguida, adicione dois arquivos no branch Master usando o botão Add file
na página do repositório. Os nomes dos arquivos são os seguintes.
file1.txt
file2.txt
Neste exemplo, o conteúdo de texto a seguir é adicionado a file1.txt
e file 2.txt
, respectivamente.
$ cat file1.txt
This is dummy text line 1
This is dummy text line 2
$ cat file2.txt
This is dummy test in 2nd file
Repositório de clones
Em seguida, clone seu repositório recém-criado do GitHub em seu sistema para criar uma cópia local do código. O URL do clone pode ser recuperado a partir do botão Código
conforme abaixo.
Use o seguinte comando para clonar.
$ git clone git@github.com:project/demorepo.git
Depois de clonado com sucesso, use o seguinte comando para exibir e verificar o conteúdo dos arquivos master branch:
$ cat file1.txt
This is dummy text line 1
This is dummy text line 2
$ cat file2.txt
This is dummy test in 2nd file
Criar Ramificação de Característica
$ git branch feature-1
Este comando cria um novo branch e não cria um novo commit no git.
Ramificação de recurso de checkout
Anteriormente, criamos um novo branch usando git branch feature-1
. Mas, o branch ativo é o branch master
. Para ativar o novo branch, use este comando no terminal:
$ git checkout feature-1
Switched to branch 'feature-1'
O comando acima mudará o branch ativo de master
para feature-1
. Agora, este ramo está pronto para desenvolvimento individual.
Modificar arquivos no ramo de recurso
Vamos adicionar alguns commits ou adicionar novas linhas no branch feature-1
. Neste caso, file2.txt
será modificado localmente e posteriormente incorporado de volta ao branch master.
Para mudanças até agora, nosso diagrama de confirmação será semelhante a abaixo. Ambos A e E representam estados de ramificação master
e feature-1
. Atualmente, o commit A
e E
são os mesmos, pois nenhum arquivo é alterado durante o checkout.
A ← master
\
E ← feature-1
Agora, file1.txt
é atualizado com o novo texto. Use este comando para atualizar o conteúdo.
$ echo "file update in feature branch" > file1.txt
Agora, file2.txt
tem o conteúdo abaixo.
$ cat file2.txt
This is dummy test in 2nd file
A diferença entre o conteúdo antigo e o novo em file1.txt
pode ser verificada usando o comando abaixo.
$ git diff
diff --git a/file1.txt b/file1.txt
index 11d66d4..48c9378 100644
--- a/file1.txt
+++ b/file1.txt
@@ -1,2 +1 @@
-This is dummy text line 1
-This is dummy text line 2
+file update in feature branch
Agora, prepare este arquivo e crie um commit local por meio do comando abaixo.
$ git add file1.txt
$ git commit -am "update file via feature-1"
[feature-1 22b60b8] update file via feature-1
1 file changed, 1 insertion(+), 2 d
Um instantâneo atual da árvore de commits terá a aparência abaixo. Aqui, F
é um novo commit criado na etapa anterior.
A ← master
\
E --- F ← feature-1
Para demonstrar um exemplo do mundo real, o master
remoto também é alterado simultaneamente por outros desenvolvedores, e essas mudanças são enviadas como commit C
e commit D
para master.
A --- B --- C --- D ← master
\
E --- F ← feature-1
Abaixo está o conteúdo atualizado de file1.txt
no repositório Github no branch master. Observe que a linha 2 foi atualizada e as linhas 3 e 4 foram criadas recentemente.
Isso também pode ser validado localmente, visualizando seu histórico de ramificações no shell de comando em tempo real usando o comando abaixo.
$ git fetch
$ git log --all --decorate --oneline --graph
Preparando para mesclar no Git
Com o Git, temos duas possibilidades de mesclar nossas alterações de branch de recursos com o branch master
remoto:
-
O método
merge
Gitmerge
é um comando que envia mudanças para outro branch. Ele permite aos desenvolvedores pegar suas linhas independentes de código do branch de recursos e integrá-los em um único branch no master por meio da ferramenta git merge. -
O método
rebase
Gitrebase
é outro comando usado essencialmente para o mesmo propósito, exceto que o faz de forma muito diferente.
Vamos entender as duas maneiras em detalhes:
Merge a Branch Into Master com o método merge
no Git
O merge
visa consolidar os branches feature
e master
ao commit que mantém o conteúdo de todos os branches envolvidos. O Git consegue isso, o que é conhecido como merge commit
. Isso também significa que merge
manipula vários ramos.
Quando os ramos divergem, ou seja, um não é ancestral do outro. O Git pode realizar a fusão fazendo um novo commit adicional que possui múltiplos pais. Na ilustração a seguir, se você tiver um commit D
e um commit F
em diferentes branches e misturar os branches (via git merge
), o resultado é um commit G
cujos pais são B
e E
.
A --- B --- C --- D ---
\ \
\ G ← master
E --- F --------- /
No diagrama acima, G
é um commit recém-criado e criado inteiramente pelo git. Este commit tem dois pais! e eles têm um pedido:
- O primeiro pai é
D
, que eramaster
anteriormente. - O segundo pai é
F
, que erafeature-1
anteriormente.
Esse tipo de confirmação é chamado de confirmação de mesclagem.
Agora volte para o nosso exemplo de repositório e mescle o branch feature-1
recém-criado para master
Primeiro, verifique o branch master.
$ git checkout master
Agora, puxe as alterações do mestre remoto para o master
local.
$ git pull origin master
From github.com:repo/demorepo
* branch master -> FETCH_HEAD
Updating 17cc6b4..a802b6b
Fast-forward
file1.txt | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
Depois, use o comando abaixo para mesclar a ramificação do recurso, ou seja, feature-1
, para a ramificação atualmente ativa.
$ git merge feature-1
O branch feature-1
será totalmente mesclado com o branch master
se esta etapa for concluída com sucesso. No entanto, se o git não puder resolver esses conflitos de mesclagem automaticamente, ele falhará com um erro de conflitos de mesclagem.
Este é um cenário muito típico; isso pode acontecer quando duas ramificações modificam a mesma parte do arquivo e o git não consegue resolver qual parte usar. É exatamente o que acontece com nosso exemplo. Este caso é mostrado abaixo via git.
Auto-merging file1.txt
CONFLICT (content): Merge conflict in file1.txt
Automatic merge failed; fix conflicts and then commit the result.
Sempre que o git encontra um conflito, ele adiciona <<<<<<<
& =======
para destacar a seção que causou o conflito e que precisa ser resolvido manualmente.
Uma vez decidido qual parte manter na versão master final do arquivo, um indivíduo deve remover o código irrelevante (incluindo indicadores de conflito). Eventualmente, envie as alterações para o branch remoto conforme abaixo.
$ git add .
$ git commit -am "resolving the mergeconflict"
[master 1acce69] resolving the mergeconflict
$ git push
Desta forma, o branch feature-1
é mesclado com sucesso ao master
remoto.
A seguir, verificaremos o histórico de ramificações novamente com o comando abaixo.
git log --all --decorate --oneline --graph
Podemos verificar se git merge
criou um Merge Commit
com commit-id como 1acce69
para fundir o branch feature-1
com origin/master
.
Mesclar uma ramificação no mestre com o método rebase
Mais uma vez, considere a situação em que nossas ramificações de recurso e mestre estão fora de sincronia e precisam ser mescladas. Vamos também relembrar a ilustração que mostra essa situação anteriormente.
A --- B --- C --- D ← master
\
E --- F ← feature-1
Como uma forma alternativa de mesclar, você pode mesclar o branch feature-1
no branch master
com a opção de rebase. O rebase
unifica os branches envolvidos simplesmente colocando os commits do branch feature na frente do branch master.
Isso será feito por meio dos comandos abaixo,
git checkout master
git pull
git checkout feature-1
git rebase master
Podemos ter a ilustração abaixo após executar o rebase.
A --- B --- C --- D----(operation rebase)----- E--------F ← master
Pela ilustração acima, é visível que algo bom que o rebase
faz é produzir um histórico de commits linear, mais limpo e mais fácil de ler. Ao mesclar, ele também não gera aquele estranho merge commit
adicional.
A desvantagem dessa abordagem é que o rebase altera toda a estrutura dos branches envolvidos, incluindo a reescrita do histórico de commit desses branches. Como rebase
não cria um merge commit
, você não obtém a rastreabilidade de quando dois ramos se fundiram, pois o rebase gera um ramo linear no final do processo.
Conclusão
Ambos os comandos são muito úteis; no entanto, em diferentes situações, cada lado tem vantagens conforme abaixo.
Git rebase
- Simplifique uma história complexa.
- Evite mesclar ruído de commit em repositórios com ramos ocupados.
- Arriscado se não for usado corretamente, pois não preserva a história.
Git merge
- Simples de usar.
- Como um commit extra de mesclagem é criado toda vez, faz com que o histórico de commits pareça confuso e sujo.
- Preserva a história completa e a ordem cronológica.