Faça Commits como um profissional
Controle de versão já é algo padrão no desenvolvimento de software. Seja utilizando SVN, GIT ou qualquer outra coisa.
O GIT é um dos controles de versões mais utilizados hoje em dia. Ele é bem flexível e nos disponibiliza diversas ferramentas para fazermos um trabalho cada vez melhor.
Quando estamos trabalhando sozinhos em um projeto, a árvore de commits do GIT fica bem organizada, pois estamos produzindo uma coisa de cada vez. Mas quando trabalhamos em um time grande, a história é outra!
A árvore de commits acaba ficando muito bagunçada e quando acontece algum problema, fica impossível identificar onde ele apareceu. A imagem abaixo mostra a árvore de commits de um projeto em que trabalho.

Você consegue identificar qual branch foi mergeado em qual lugar? Talvez sim, se você ficar horas olhando e analisando. Mas você não tem todo esse tempo quando um problema aparece em produção e você precisa descobrir rapidamente o que aconteceu.

Outro problema bem comum de acontecer em times grandes está relacionado ao texto do commit. Quem nunca subiu pra master um commit “wip” ou “subindo”?
Seu histórico de commits se assemelham de alguma forma com essas imagens? Vamos entender então como mudar essa situação.
Eu gosto de pensar que o GIT é uma espécie de documentação do meu projeto. Você escreveria uma documentação de qualquer jeito? Acho que não… Então porque sujar o histórico do projeto dessa forma?
Conversando com outros times dentro da empresa e mostrando o problema que tínhamos, me apresentaram um tal de squash do GIT.
O squash é um modo de alterar o histórico de commits de um branch de tal modo que ele seja unificado em apenas um único commit. O GIT nos da algumas possibilidades de realizar essa ação:
$git commit --amend
O amend permite modificar o último commit, deixando você adicionar, modificar ou remover arquivos.
$git commit rebase -i HEAD~3
O rebase -i é interativo e te permite, no exemplo acima, alterar os últimos 3 commits do seu branch.
Ao usar o rebase, você receberá uma lista de commits (o mais antigo em cima) e também uma lista de opções:
pick f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file
# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented outO script executa suas linhas de baixo para cima, então se formos fazer o squash dos commits, ficaria assim:
edit f7f3f6d changed my name a bit
squash 310154e updated README formatting and added blame
squash a5f4a0d added cat-fileAo final, os dois commits marcados como squash serão “mergeados” ao primeiro e o primeiro será renomeado (em uma nova janela que será aberta).
Só com o squash as coisas já ficam um pouco melhores, pois ao mergear um branch no master, apenas um commit aparecerá no histórico. “Mas só isso não vai deixar minha árvore organizada!!!”. Sim, eu sei…
O grande problema que tínhamos era que sempre que pretendíamos atualizar um branch com o master, era feito um merge. Isso mantém a árvore intacta e por isso ela fica gigante. Quando passamos a fazer o rebase, as coisas mudaram. Veja imagem abaixo

Agora as coisas estão bem mais simples e fáceis de entender, certo?
Algumas dicas que eu dou:
- Não fazer squash no master, apenas nos branchs de desenvolvimento.
- Fazer rebase do master no seu branch é mais simples quando você já fez o squash no seu branch.
- Rebase quando quiser levar algo para o seu branch e merge quando quiser levar seu branch para o master.
Para saber mais, veja a documentação do GIT.
