Git Quebrando Um Commit E Cancelando Algumas AlteraçõEs

10
Git 12/2009 GIT: Quebrando um commit e cancelando algumas alterações Dando seqüência aos posts sobre GIT, aí vai mais uma dica: Como quebrar um commit e cancelar algumas alterações. Cenário: Foi feito o push de um commit contendo várias alterações no código. Porém, após ter sido feito o code review foi detectado que algumas mudanças não seriam mais necessárias, e/ou deveriam ser implementadas de outra forma. Claro que seria possível ir no código fonte e ir apagando todas as alterações que foram feitas. Mas, será que essa “limpeza” sairia às mil maravilhas? Será que o código voltaria a ficar da mesma forma que antes das alterações terem sido feitas? Acho difícil! Elaborei um pequeno exemplo, apenas, para tentar ilustrar o cenário acima. Temos os seguintes commits em nosso Projeto: Por Alberto Leal http://www.albertoleal.eti.br [email protected] twitter.com/albertoleal www.imasters.com.br

Transcript of Git Quebrando Um Commit E Cancelando Algumas AlteraçõEs

Page 1: Git  Quebrando Um Commit E Cancelando Algumas AlteraçõEs

Git12/2009

GIT: Quebrando um commit e cancelando algumas

alterações

Dando seqüência aos posts sobre GIT, aí vai mais uma dica: Como quebrar um commit e cancelar algumas alterações.

Cenário: Foi feito o push de um commit contendo várias alterações no código. Porém, após ter sido feito o code review foi detectado que algumas mudanças não seriam mais necessárias, e/ou deveriam ser implementadas de outra forma. Claro que seria possível ir no código fonte e ir apagando todas as alterações que foram feitas. Mas, será que essa “limpeza” sairia às mil maravilhas? Será que o código voltaria a ficar da mesma forma que antes das alterações terem sido feitas? Acho difícil!

Elaborei um pequeno exemplo, apenas, para tentar ilustrar o cenário acima.

Temos os seguintes commits em nosso Projeto:

Por Alberto Lealhttp://www.albertoleal.eti.br

[email protected]/albertolealwww.imasters.com.br

Page 4: Git  Quebrando Um Commit E Cancelando Algumas AlteraçõEs

Repare que foi criado um branch para resolver um defeito. No nosso caso, foi adicionar um novo campo, País. Mas por algum motivo o registro de idade foi alterado acidentalmente.

No caso acima, é fácil ir ao arquivo e desfazer as alteração incorreta no campo “idade” antes de fazer o rebase/merge, eu sei. Mas, tente imaginar códigos reais, complexos, onde voltar ao código fonte e desfazer as alterações não seria a melhor solução =)

Uma solução para trazer todas as alterações e escolher o que vai ser efetivado para o merge/rebase é trazer o commit de volta para o stage do git para trabalhar nas alterações. Para isso, vamos utilizar o comando git format-patch para recuperar os commits. Em seguida, criaremos um novo branch para trabalharmos nas modificações e finalmente fazer o rebase com o branch master:

Alberto:ProjectX Alberto$ git branch* Defect123 masterAlberto:ProjectX Alberto$ git status# On branch masternothing to commit (working directory clean) Alberto:ProjectX Alberto$ git logcommit ea4f2953c305b0453fd20f27b3043ebf96d541dfAuthor: Alberto Leal <[email protected]>Date: Sat May 23 15:42:16 2009 -0300 Adding new fields commit 656236111360762d92f9efacb05e27b5cd067a04Author: Alberto Leal <[email protected]>Date: Sat May 23 15:41:35 2009 -0300 Some new changes commit 131519b37c1d1415e962d6fd23d4058c93438870Author: Alberto Leal <[email protected]>Date: Sat May 23 15:40:40 2009 -0300 Initial CommitAlberto:ProjectX Alberto$ git format-patch master0001-Some-new-changes.patch0002-Adding-new-fields.patch

Por Alberto Lealhttp://www.albertoleal.eti.br

[email protected]/albertolealwww.imasters.com.br

Page 5: Git  Quebrando Um Commit E Cancelando Algumas AlteraçõEs

Repare que os patches foram gerados a partir do Defect123 em relação ao branch master, ou seja, somente as diferenças entre eles.

Para escolher quais as modificações que vão entrar para então fazer o merge/rebase com o master, é necessário que se crie um novo branch a partir do master - limpo, sem as modificações de Defect123 e use o comando git apply para aplicar os patches no stage. Agora que os patches com os últimos commits já foram gerados, chegou a hora de jogá-los novamente no stage:

Veja que o arquivo config.txt foi alterado. Agora, vamos adicionar as alterações para serem commitadas, mas para isso vamos utilizar o comando git add -p (similar ao add interativo):

Alberto:ProjectX Alberto$ git checkout masterSwitched to branch "master"Alberto:ProjectX Alberto$ git checkout -b Defect123_ChangesSwitched to a new branch "Defect123_Changes"Alberto:ProjectX Alberto$ git apply 0001-Some-new-changes.patchAlberto:ProjectX Alberto$ git apply 0002-Adding-new-fields.patchAlberto:ProjectX Alberto$ git logcommit 131519b37c1d1415e962d6fd23d4058c93438870Author: Alberto Leal &lt;[email protected]&gt;Date: Sat May 23 15:40:40 2009 -0300 Initial CommitAlberto:ProjectX Alberto$ git status# On branch Defect123_Changes# Changed but not updated:# (use "git add &lt;file&gt;..." to update what will be committed)## modified: config.txt## Untracked files:# (use "git add &lt;file&gt;..." to include in what will be committed)## 0001-Some-new-changes.patch# 0002-Adding-new-fields.patchno changes added to commit (use "git add" and/or "git commit -a")

Por Alberto Lealhttp://www.albertoleal.eti.br

[email protected]/albertolealwww.imasters.com.br

Page 6: Git  Quebrando Um Commit E Cancelando Algumas AlteraçõEs

Utilizando o comando acima, podemos quebrar as alterações feitas no arquivo utilizando a opção “s” (split). Após, você informa se deseja adicionar os fragmentos ao stage, utilizando as opções “y”- yes e “n”- no. Todos os fragmentos que você desejar adicionar no stage para comitá-lo, utilize a opção “y”. No pequeno exemplo acima, apenas foi mantido no commit a adição dos novos campos: Telefone e País. A alteração equivocada no campo “idade”foi eliminada do commit. Só nos resta efetivar as alterações commitando as mudanças:

Alberto:ProjectX Alberto$ git add -p config.txtdiff --git a/config.txt b/config.txtindex ac82771..b36405c 100644--- a/config.txt+++ b/config.txt@@ -1,6 +1,8 @@ Nome: Alberto Leal-email: [email protected]: 24+Email: [email protected]+Idade: 2423434 Empresa: IBM+Telefone: 12-1234-5678+País: Brasil Sexo: Masculino Estado civil: solteiroStage this hunk [y/n/a/d/s/?]? sSplit into 2 hunks.@@ -1,4 +1,4 @@ Nome: Alberto Leal-email: [email protected]: 24+Email: [email protected]+Idade: 2423434 Empresa: IBMStage this hunk [y/n/a/d/j/J/?]? n@@ -4,3 +4,5 @@ Empresa: IBM+Telefone: 12-1234-5678+País: Brasil Sexo: Masculino Estado civil: solteiroStage this hunk [y/n/a/d/K/?]? y

Por Alberto Lealhttp://www.albertoleal.eti.br

[email protected]/albertolealwww.imasters.com.br

Page 7: Git  Quebrando Um Commit E Cancelando Algumas AlteraçõEs

Cuidado para não adicionar o arquivo novamente ao stage (git add config.txt). As alterações que você fez já estão lá, prontas para serem commitadass. Se você se esquecer e adicionar o arquivo novamente ao stage, você perderá todas as mudanças que você fez no add interativo. É aconselhável que, logo após o comando git commit, você execute git checkout <file>, como mostrado acima. Desse jeito, você pegará o arquivo que está no repositório atualizado.

Alberto:ProjectX Alberto$ git commit -m 'Cutting branch'Created commit 9e365a2: Cutting branch 1 files changed, 2 insertions(+), 0 deletions(-)Alberto:ProjectX Alberto$ git checkout config.txtAlberto:ProjectX Alberto$ cat config.txtNome: Alberto Lealemail: [email protected]: 24Empresa: IBMTelefone: 12-1234-5678País: BrasilSexo: MasculinoEstado civil: solteiro

Por Alberto Lealhttp://www.albertoleal.eti.br

[email protected]/albertolealwww.imasters.com.br

Page 9: Git  Quebrando Um Commit E Cancelando Algumas AlteraçõEs

Agora, só nos resta fazer o rebase com o branch principal:

Alberto:ProjectX Alberto$ git checkout masterSwitched to branch "master"Alberto:ProjectX Alberto$ git rebase Defect123_ChangesFirst, rewinding head to replay your work on top of it...Fast-forwarded master to Defect123_Changes.

Por Alberto Lealhttp://www.albertoleal.eti.br

[email protected]/albertolealwww.imasters.com.br