Olá Pessoal, tudo bom?
Há 3 anos atrás construí uma serie de artigos sobre versionamento de Projetos de Software, mas nunca mais mudei esses artigos ou acrescentei coisas novas. Essa é uma nova série, com todas as atualizações que a ferramenta do Bitbucket e do Eclipse sofreram nesses últimos 3 anos. Para ver todos os artigos sobre versionamento acesse esta página. Lá haverá um mapa mental com todos os artigos. Esse artigo mostra como resolver o conflito de um mesmo arquivo que pode ocorrer durante uma operação de commit. Veja na continuação.
Eclipse – Resolvendo conflitos no mesmo arquivo – non-fast-forward
O erro de conflito entre arquivos, mais conhecido como non-fast-forward, é uma ocorrência que acontece diversas vezes durante o versionamento de projetos, principalmente se a equipe tiver um número grande desenvolvedores ou se determinadas classes sofrerem alterações constantemente.
Para mostrar como realizar a solução desse conflito é necessário primeiro fazer uma simulação de conflito. Assim vamos dividir esse artigo em duas partes. A primeira tratará como construir a simulação, que normalmente ocorrerá no dia a dia do versionamento do projeto. A segunda parte mostrará como corrigir o conflito e voltar a normalidade. No caso desse artigo, o conflito está ocorrendo porque temos versões diferentes de commits e também por alterações no mesmo arquivo.
Simulação de conflito no mesmo arquivo
É necessário escolher um arquivo para realizar a simulação. Vamos escolher o arquivo Instituicao para editar via Bitbucket e via Eclipse.
A primeira coisa a ser feita é adicionar um comentário a classe Instituicao via site do BitBucket, simulando dessa forma que alguém fez uma alteração no arquivo e realizou um commit. Para fazer essa edição online, por favor veja esse artigo. No nosso exemplo colocamos o comentário “comentario para testes de conflito no mesmo arquivo – bitbucket”. O arquivo deverá ficar parecido com a Figura 01.
Agora abra no Eclipse a classe Instituicao e realize a adição de mais um comentário. No nosso caso adicionamos o comentário “comentario para testes de conflito no mesmo arquivo – Eclipse”. Veja a classe Instituicao como exemplo na Figura 02
Realize o commit do arquivo Instituicao, adicionando este arquivo como staged changes e com uma mensagem descrevendo o porque do commit, conforme Figura 03. Feito esse processo clique no botão Commit and Push…
A dialog Push Results será exibida, Figura 04, como sempre acontece após um commit, o problema é que agora apareceu um Reject. Como é um pequeno detalhe que diferencia, é muito mais complicado ver se deu erro. No caso aqui deu um erro de non-fast-forward.
Vamos analisar o que aconteceu. Na ferramenta GIT a cada commit é criada uma nova versão dos arquivos para o repositório. Assim, suponha que ambos os repositórios estavam na versão 10.
No momento em que você foi até o repositório remoto e alterou um arquivo, o GIT alterou a versão do repositório para a versão 11, mas seu repositório local ainda permanecia na versão 10. Quando você realizou o commit de um novo arquivo, o seu repositório local passou para a versão 11, mas quando ele comunicou-se com o repositório remoto lá já havia a versão 11, então o GIT, para não perder nenhum arquivo commitado, força o erro non-fast-forward, rejeitando o commit.
Lembrando que não é somente quando você vai até o Bitbucket e altera um arquivo que ocorre esse erro. Se você estiver trabalhando em uma equipe, outras pessoas irão realizar commits e pushes para o repositório remoto, alterando assim a versão dos arquivos do repositório, ocasionando o conflito.
Correção da rejeição do Commit e conflito do arquivo
Nesse momento começamos a correção dessa rejeição, ou seja, vamos deixar o repositório local novamente apto para realizar commits para o repositório remoto. O primeiro passo a ser realizado é fazer a operação de pull, através do Team > Pull. Essa operação faz com que o Eclipse traga os arquivos que estão no repositório remoto e apresente a dialog Pull Result, com todos os commits realizados, conforme Figura 05.
Após fechar a dialog, repare que houveram algumas modificações na apresentação do explorer do projeto, Figura 06. Ao lado do nome do projeto existe a palavra Conflicts indicando que há arquivos com conflitos de informação. Esses arquivos estão indicados no próprio explorer com um simbolo vermelho de dois losangos sobrepostos. Além disso existem, ao lado do branch atual no nome do projeto, as setas para cima com o número 1 e para baixo com o número 1. Elas indicam que existe uma versão mais recente no repositório local (seta pra cima) e uma versão mais recente no repositório remoto.
Clique sobre a classe que está com conflito nesse caso Instituição. O código exibido para a parte com conflito é muito peculiar, conforme mostra a Figura 07.
Apenas para entender a lógica do conflito e apresentação pela ferramenta. O que estiver antes da linha de iguais é o trecho que está contido no arquivo do Eclipse, repositório local. O que estiver após a linha de iguais é o trecho que está contido no arquivo do Bitbucket, repositório remoto. É sempre confuso trabalhar diretamente com essa representação, o Eclipse provê uma ferramenta, chamada Merge Tool, que auxilia, um pouco, nesse processo. Para acessar essa ferramenta, clique sobre o arquivo com conflito e vá em Team > Merge Tool conforme mostra a Figura 08.
O Eclipse irá abrir a ferramenta de compare com as alterações entre o arquivo do repositório local, à esquerda da tela, e do repositório remoto, à direita da tela, conforme Figura 09.
Quando estamos realizando um merge manual, que é o caso aqui, é uma boa prática priorizar a manutenibilidade do código, ou seja, não deixar que o merge realizado gere bugs ou erros de compilação no código. Outra boa prática é conversar com a pessoa que fez o código que está dando conflito e verificar qual o motivo da alteração, principalmente se afeta o código gerado por você. No caso desse nosso merge, vamos apenas adicionar mais essa linha criada, assim teremos ao final as duas linhas de comentários na classe, uma gerada no Bitbucket e outra gerada no Eclipse, conforme mostra a Figura 10.
Salve as alterações realizadas no arquivo local e acesse a view Git Staging. O arquivo que você acabou de salvar, deverá estar na parte Unstaged Changes. Selecione o arquivo e clique no botão “+” (mais) para passar o arquivo para a parte Staged Changes. O Eclipse irá gerar um comentário automático, conforme figura 11. AINDA NÃO COMMITE! Vamos analisar alguns detalhes do Eclipse.
O primeiro detalhe está na própria Figura 11. Ao lado as setas para cima e para baixo, apareceu a palavra Merged. Indicando que a sua operação de merge foi realizada com sucesso. Já na Figura 12, vamos novamente observar o explorer do projeto. Lá no nome do projeto que antes havia a palavra Conflicts agora aparece a palavra Merged. Além disso o símbolo vermelho sumiu dando lugar ao simbolo do asterisco.
Agora clique no botão Commit da View Git Staging, vamos realizar a operação em duas partes, a fim de entender o que irá acontecer no Eclipse. Após o clique o botão Commit, a palavra Merged irá sumir, assim como o asterisco no arquivo, restando apenas uma seta para cima com o número 2, Figura 13. Isso indica que o arquivo foi commitado para o repositório local, ocorrendo o merge entre as versões dos arquivos, pois agora não havia conflitos.
Agora realize a operação de Push, para enviar os arquivos ao repositório remoto. Aparecerá a dialog Push Results com os commits realizados, conforme Figura 14.
finnaly{
A resolução de conflitos entre arquivos commitados, principalmente quanto está dentro de uma equipe de desenvolvimento de software é muito importante. Ao conseguir o domínio sobre a correção de conflitos isso permite trabalhar mais facilmente com a equipe, muitas vezes gerenciando projetos muito grandes.
Duvidas ou sugestões? Deixe seu feedback! Isso ajuda a saber a sua opinião sobre os artigos e melhorá-los para o futuro! Isso é muito importante!
Até um próximo post!
Leave a Reply