Git squash?? WTF?
Autor: Rafael Henrique | Publicado: 2015-03-24T10:16:00-07:00


Galera conforme mencionei no post anterior.. estou contribuindo com o puppetboard&nbsp;(mais informações no post abaixo desse :P). E fiz meu primeiro Pull Request e talz resolvendo uma questão que estava na issue para acrescentar uma nova funcionalidade ao projeto. Porém quando eu fiz meu PR (Pull Request) teve um cara que me disse o seguinte:




** squash

Ai eu pensei como qualquer ótimo conhecedor do Git que porras é essa de squash?&nbsp;o que seria esse squash ai?

O squash é uma prática utilizada para combinar mais de um commit em um commit só, desta forma eliminando "lixos" do projeto. Agora aqui neste post explicarei como raios você faz isso, pois não achei uma documentação simples que explicasse a uma pessoa normal&nbsp;como fazer isso, e após aprender, decidi TENTAR explicar de uma forma simples :D.

O projeto

Primeiro obviamente você precisa ter um repositório git, para isso eu criei um repositório BEEEM simples:

$ mkdir teste$ cd teste$ git init$ echo "Rafael" &gt;&gt; README$ git add README$ git commit -m "Adicionado Rafael"&nbsp;

$ echo "Henrique" &gt;&gt; README$ git add README$ git commit -m "Adicionado Henrique"&nbsp;

$ echo "da" &gt;&gt; README$ git add README$ git commit -m "Adicionado da"&nbsp;

$ echo "Silva" &gt;&gt; README$ git add README$ git commit -m "Adicionado Silva"&nbsp;

$ echo "Correia" &gt;&gt; README$ git add README$ git commit -m "Adicionado Correia"

Feito isso terei o seguinte histórico de commits:


$ git log --oneline4c03027 Adicionado Correiae23576b Adicionado Silva769bda9 Adicionado da2a71622 Adicionado Henrique5ebadcd Adicionado Rafael
O squash

Agora vamos imaginar que eu quero fazer um squash a partir de Henrique, ou seja quero que os commits 2a71622, 769bda9, e23576b e 4c03027 sejam um só, pois todos tratam da adição do sobrenome no arquivo README. Para isso precisarei usar o comando rebase do git no commit que eu desejo, no caso a partir do Henrique (como é a partir do Henrique deveremos pegar 1 commit antes):

$ git rebase -i 5ebadcd
Após executar este comando será aberto um arquivo temporário para podermos fazer as alterações desejadas, o arquivo será similar a este abaixo:

pick 2a71622 Adicionado Henriquepick 769bda9 Adicionado dapick e23576b Adicionado Silvapick 4c03027 Adicionado Correia&nbsp;

# Rebase 5ebadcd..4c03027 onto 5ebadcd## Commands:# &nbsp;p, pick = use commit# &nbsp;r, reword = use commit, but edit the commit message# &nbsp;e, edit = use commit, but stop for amending# &nbsp;s, squash = use commit, but meld into previous commit# &nbsp;f, fixup = like "squash", but discard this commit's log message# &nbsp;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 out
Neste mesmo arquivo já podemos visualizar algumas opções do que fazer com esses commits, para este post utilizaremos somente o squash, mas vale a pena conhecer as outras opções descritas abaixo de commands. Agora altere este arquivo da seguinte maneira:

pick 2a71622 Adicionado Henriquesquash 769bda9 Adicionado dasquash&nbsp;e23576b Adicionado Silvasquash&nbsp;4c03027 Adicionado Correia&nbsp;

# Rebase 5ebadcd..4c03027 onto 5ebadcd## Commands:# &nbsp;p, pick = use commit# &nbsp;r, reword = use commit, but edit the commit message# &nbsp;e, edit = use commit, but stop for amending# &nbsp;s, squash = use commit, but meld into previous commit# &nbsp;f, fixup = like "squash", but discard this commit's log message# &nbsp;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 out
As linhas dos commits 769bda9, e23576b e 4c03027 foram mudadas para squash, portanto serão combinados ao commit que possui a o nome pick, então o commit 2a71622 agora será unido aos 3 commits abaixo dele. É importante comentar que o squash não remove os logs (mensagens dos commits) conforme a descrição do "Commands" já a opção fixup descarta os logs. Feita esta alteração basta salvar o arquivo e sair. Feito isso será apresentado outro arquivo similar a este abaixo:

# This is a combination of 4 commits.# The first commit's message is:Adicionado Henrique# This is the 2nd commit message:Adicionado da# This is the 3rd commit message:Adicionado Silva# This is the 4th commit message:Adicionado Correia# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.## Date: &nbsp; &nbsp; &nbsp;Tue Mar 24 11:08:29 2015 -0300## rebase in progress; onto 5ebadcd# You are currently editing a commit while rebasing branch 'master' on '5ebadcd'.#
&nbsp;Neste arquivo você poderá mudar as mensagens de log (mensagens dos commits) caso desejar, se desejar mude alguma coisa e salve e saia do arquivo. Terminada a edição/salvamento deste arquivo você acabou o squash! Podemos ver no log como ficou a nova estrutura:

$ git log --onelinef4c9d80 Adicionado Henrique5ebadcd Adicionado Rafael&nbsp;
Ou:

$ git logcommit f4c9d80a089ee35fca0eb7c6e5aabcb435fb9bb4Author: Rafael Henrique da Silva Correia Date: &nbsp; Tue Mar 24 11:08:29 2015 -0300&nbsp; &nbsp; Adicionado Henrique&nbsp; &nbsp;&nbsp; &nbsp; Adicionado da&nbsp; &nbsp;&nbsp; &nbsp; Adicionado Silva&nbsp; &nbsp;&nbsp; &nbsp; Adicionado Correia&nbsp;

commit 5ebadcde3eb8c006bd33ee4c62f9cbb359822d6eAuthor: Rafael Henrique da Silva Correia Date: &nbsp; Tue Mar 24 11:08:14 2015 -0300&nbsp; &nbsp; Adicionado Rafael
Conclusão

Esta prática é bem interessante e deixa o repositório do git mais limpo, é MUITO válida principalmente em projetos grandes onde se tem muitos contribuidores (principalmente em projetos open source ;)).