Linux Kamarada

Dica de Git: merge e diff facilitados pela interface gráfica com Meld e Atom

Dica para desenvolvedores que usam Git: já sentiu dificuldade ao fazer um merge? Sabia que é possível resolver conflitos com o auxílio de interfaces gráficas que facilitam bastante o trabalho? Hoje veremos dois aplicativos que podem nos ajudar a resolver conflitos: o editor de texto Atom e a ferramenta de diff e merge Meld.

Fazendo merge e resolvendo conflitos

Antes da dica propriamente dita, para garantir que estamos todos na mesma página, vejamos como normalmente se faz git merge e se resolve conflitos.

Imagine que você e um colega trabalham em um projeto de desenvolvimento e usam um repositório do Git para armazenar o código-fonte. Além do branch principal (master), cada um possui seu próprio branch (por exemplo, antonio e jose). Ao terminar o desenvolvimento de uma funcionalidade, cada um deve fazer merge do seu branch para o branch principal.

Imagine também que vocês trabalharam em paralelo no mesmo arquivo, editando linhas próximas (ou as mesmas linhas), mas seu colega fez merge com o branch master primeiro. Quando você fizer merge do seu branch com o master, o Git acusará um conflito de arquivo:

Um exemplo que aconteceu comigo na vida real, ao trazer atualizações do upstream para um fork:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ git checkout master1
$ git merge upstream1
Auto-merging publish.sh
Auto-merging libs/popper.js/1.16.0/umd/popper.js
...
Auto-merging _layouts/post.html
Auto-merging _layouts/default.html
Auto-merging _includes/sidebar.html
Auto-merging _includes/head.html
CONFLICT (content): Merge conflict in _includes/head.html
Auto-merging _includes/footer.html
CONFLICT (content): Merge conflict in _includes/footer.html
Automatic merge failed; fix conflicts and then commit the result.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ git status
On branch master1
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Changes to be committed:

	modified:   _includes/adsense.html
	modified:   _includes/sidebar.html
...
	new file:   libs/popper.js/1.16.0/umd/popper.min.js.map
	modified:   publish.sh

Unmerged paths:
  (use "git add/rm <file>..." as appropriate to mark resolution)

	both modified:   _includes/footer.html
	both modified:   _includes/head.html
	deleted by us:   _posts/2015-08-25-welcome-to-jekyll.markdown
	both modified:   assets/css/main.css

Em caso de conflito durante o merge, você deve editar manualmente os arquivos conflituosos, comparando as alterações que você e o seu colega fizeram, elaborar a versão final do arquivo e, por fim, executar git commit para concluir o merge.

Resolvendo conflitos com o Atom

Se você ainda não conhece, o Atom é um editor de texto feito pelo GitHub, por desenvolvedores e para desenvolvedores. Possui muitas funcionalidades, é bastante inteligente já em sua configuração padrão, mas pode receber extensões. O Atom faz lembrar o Sublime Text, mas é software livre e gratuito.

Para instalar o Atom no Linux Kamarada ou no openSUSE, baixe e instale o pacote RPM do seu site:

Ao abrir um arquivo conflituoso com o Atom, ele permite facilmente escolher entre uma versão ou outra das linhas, basta clicar no botão Use me referente à versão desejada:

Note que a decisão não precisa ser binária: você pode escolher uma das versões e editá-la para obter um meio termo. O que importa é o conteúdo final do arquivo na hora de salvar.

Resolvendo conflitos com o Meld

O Meld é uma ferramenta gráfica de diff e merge feita para desenvolvedores. Permite comparar arquivos e pastas em duas ou três vias e suporta vários sistemas de controle de versão, dentre eles o Git. Para instalar o Meld no Linux Kamarada ou no openSUSE, execute:

1
# zypper in meld meld-lang

Você pode usar o Meld sozinho, abrindo o aplicativo e selecionando os arquivos ou pastas que deseja comparar, mas não vou entrar em detalhes nesse sentido, porque nosso objetivo aqui é ver como usar o Meld integrado ao Git.

Para resolver conflitos com o Meld, execute o comando git mergetool:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ git mergetool

This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc codecompare emerge vimdiff
Merging:
_includes/footer.html
_includes/head.html
_posts/2015-08-25-welcome-to-jekyll.markdown
assets/css/main.css

Normal merge conflict for '_includes/footer.html':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (meld):

A função do comando git mergetool é iniciar uma ferramenta apropriada para a resolução de conflitos. Ele exibe essa mensagem comprida na primeira utilização porque ainda não configuramos uma ferramenta. Note que ele suporta várias ferramentas, dentre elas o Meld, que é a primeira da lista e é também a que ele sugere usar. Tecle Enter para iniciar o Meld.

O Meld abre o arquivo conflituoso em três vias: à esquerda, a versão anterior do branch atual (nesse exemplo, o branch master1); no meio, a versão mesclada (esse é o resultado que irá no commit do merge); e à direita, a versão do branch que está sendo mesclado (upstream1):

Você pode usar as setas ao lado das linhas para copiar trechos de código de um lado para o outro.

Note que também no Meld as decisões não precisam ser binárias: você pode simplesmente posicionar o cursor na via do meio e começar a digitar. A versão final do arquivo mesclado será tudo que estiver na via do meio, não importando se o conteúdo veio da via da esquerda, da via da direita ou se foi digitado à mão.

Quando terminar de resolver o conflito, clique em Salvar.

Para que o Git sempre use o Meld para resolver conflitos sem perguntar qual ferramenta usar, execute os comandos a seguir:

1
2
$ git config --global merge.tool meld
$ git config --global mergetool.prompt false

Feito isso, aquela mensagem comprida não aparecerá mais ao executar git mergetool: o Git indicará qual arquivo está mesclando e já abrirá o Meld (você não precisará teclar Enter).

Além de resolver conflitos, o Meld pode ser usado para comparar versões de arquivos controladas pelo Git.

Comparando versões de arquivos

Para comparar versões de um mesmo arquivo (por exemplo, qual a diferença entre um arquivo em um branch e esse mesmo arquivo em outro branch, ou o que mudou em um arquivo entre dois commits), você pode usar o comando git diff:

1
2
$ git checkout master1
$ git diff upstream1 -- _includes/footer.html

Nesse exemplo, queremos saber o que mudou no arquivo _includes/footer.html do branch upstream1 (especificado como referência inicial) para o branch atual (master1):

Talvez usando o Meld essa comparação fique mais interessante. Vejamos.

Comparando versões de arquivos com o Meld

Como se fosse uma mistura do git diff com o git mergetool é o comando git difftool:

1
$ git difftool upstream1 -- _includes/footer.html

De forma semelhante, no primeiro uso ele alerta que não foi configurado e pergunta se deseja iniciar o Meld:

1
2
3
4
5
6
7
This message is displayed because 'diff.tool' is not configured.
See 'git difftool --tool-help' or 'git help config' for more details.
'git difftool' will now attempt to use one of the following tools:
meld opendiff kdiff3 tkdiff xxdiff kompare gvimdiff diffuse diffmerge ecmerge p4merge araxis bc codecompare emerge vimdiff

Viewing (1/1): '_includes/footer.html'
Launch 'meld' [Y/n]?

Tecle Enter para iniciar o Meld. Dessa vez, ele faz uma comparação em duas vias: à esquerda, é exibida a versão especificada como referência (nesse caso, a versão do branch upstream1), e à direita, é exibida a versão do branch atual (nesse caso, o branch master1):

Configurar o git difftool para sempre usar o Meld sem perguntar também é parecido:

1
2
$ git config --global diff.tool meld
$ git config --global difftool.prompt false

Referências

Me paga um café?
Se você gostou muito, se foi muito útil pra você, será que vale um café? Se quiser, você pode "me pagar um café" pelo PayPal ou contribuir com o projeto de outras formas.

Comentários

Sobre

O Projeto Linux Kamarada visa divulgar e promover o Linux como um sistema operacional robusto, seguro, versátil e fácil de usar, adequado para o uso diário seja em casa, no trabalho ou no servidor. Os focos do projeto são principalmente distribuição e documentação.

Anúncios

Facebook

Autor