Git é uma excelente ferramenta para o trabalho cooperativo. Ele pode fazer muitas coisas, mas é incapaz de resolver conflitos entre as pessoas. Afinal de contas, o Git é apenas um programa de computador e, enquanto não chega o dia da Strong AI, teremos que resolver os conflitos apenas entre nós, reles seres humanos.
A que tipo de conflito estou me referindo? Não estou falando de nada muito
sério, como o que aconteceu aqui na Europa há 70 anos, mas apenas de
situações que ocorrem quando dois colaboradores estão trabalhando
concomitantemente em um projeto sob controle Git. Cada um faz modificações
e commits do seu lado, partindo do mesmo ponto da história. Um deles é
mais esperto e faz o git push
primeiro. Quando o outro chega para fazer
o seu push, o repositório remoto reclama, dizendo que há novidades e o
obriga a fazer um pull, seguido de um merge. Aí, o outro fica com uma
história assim:
2015-05-09 06:22 Hani Camille Yehia M─┐ Merge branch 'master' of www.cefala.org:blog
2015-05-09 11:16 Rafael Laboissiere │ o Use the correct name for the git-multimail command
2015-05-09 06:20 Hani Camille Yehia o │ Include command to define 'ci' as an alias to 'commit' in article 'o-git-me-manda-noticias'
2015-05-09 06:10 Hani Camille Yehia o─┘ Add Hani's email address to the push notification mailing list
(Abrindo parêntese rapidinho, o que está mostrado acima é uma cópia das linhas do Tig. Trata-se de uma interface totalmente textual para visualizar a história do Git, sem aqueles frufrus todos das interfaces tipo Click-O-Rama. Fecha parêntese.)
Bom, a história ficou feia de com força, por causa daquele commit "Merge
branch etc.". Felizmente, o Git, como nos bons tempos do Stalinismo e do
KGB, é capaz de reescrever a história e evitar que você passe
constrangimento ao fazer o git push
. Normalmente, o fluxo de trabalho
com Git deve ser o seguinte:
$ git pull
$ editor some-file
$ git pull
$ git add some-file
$ git commit -m "Changed some file"
$ git push
Great, thanks for your contribution!
Note que eu coloquei duas vezes git pull
acima. O primeiro, você faz
antes de introduzir as suas modificações. Entretanto, estas modificações
podem durar horas ou dias. É por isto que recomendo o segundo git pull
.
De qualquer maneira, a sequência pull/add/commit/push deve ser feita
rapidamente.
Agora, problemas acontecem quando você deixa de fazer o git pull
na hora
certa. Aí, pode dar nisto:
$ editor some-file
$ git add some-file
$ git commit -m "Changed some file"
$ git push
You, moron, do a git pull first!
$ git pull
Ha! I will force you to do an ugly merge!
$ git push
Quando isto ocorrer, chame o super git rebase
e ele virá ao seu socorro.
Santa rebaseada, Batman!
Logo após o git pull
, lance os comandos seguintes e a história voltará a
ser linear, como se nada tivesse acontecido, não é mesmo, Vladimir?
$ git rebase remotes/origin/master master
$ git push
Uma outra maneira de evitar todo e qualquer problema é o uso sistemático da
opção --rebase
do command git pull
.
P.S.: Por falar em reescrever a história, a Rússia festejou hoje o armistício da Segunda Guerra Mundial, com toda pompa militar de uma ex-URSS. Eles gostam de ser diferentes do resto do mundo, que festejou o armistício ontem, no dia 8 de maio. Muito se falou por aqui na Europa, nestes últimos dias, da tomada do Reichstag em Berlim pelo Exército Vermelho. Aí eu me lembrei daquela famosa foto do hasteamento da bandeira soviética. Notem que a foto, que foi toda preparada pela propaganda soviética, teve que ser retocada antes da publicação, pois aparecia nela um soldado com relógios nos dois pulsos, prova da pilhagem constrangedora de guerra. No bom estilo Git (o retoque, é claro, não a pilhagem!).