Ctrl + Z no Git
É muito comum começarmos a desenvolver e fazer testes e termos que desfazer estas alterações. De que forma será que conseguimos desfazê-las com o Git? Será que ele possui alguma espécie de atalho "Ctrl + Z"?
Por se tratar de um único arquivo, a alteração em uma linha poderia ser desfeita com "Ctrl + Z", mas imaginemos um projeto grande, em que fazemos várias alterações, e só então entendemos que não está como queremos.
git checkout -- nomeDoArquivo
No Git Bash, usaremos git status, o que nos traz algumas informações. É identificado que houve modificações no arquivo, que ainda não foram commitadas. Para isso, precisaríamos chamar o git add, no entanto, é indicado que, se quiséssemos descartar as alterações, poderemos chamar git checkout --, seguido do que queremos desfazer.
O git checkout, portanto, serve para navegarmos em estados do repositório, seja por meio de branches ou desfazendo modificações no arquivo.
git reset HEAD nomeDoArquivo
Usado quando queremos desfazer uma alteração que já foi marcada para ser commitada.
Utilizar "git reset HEAD" seguido do nome do arquivo a ser desmarcado como algo que precisa passar pelo commit.
Sendo assim, basta utilizarmos git checkout -- index.html, o que fará com que não tenhamos mais nada a ser commitado, uma vez que a alteração foi desfeita com sucesso.
git revert hashDoCommit
Utilizado para desfazer um commit já realizado!
O hash do commit é obtido através de "git log" executado previamente.
Sua utilização fará com que o commit informado seja desfeito, criando outro. Ao ser rodado, portanto, ele irá gerar um commit cuja mensagem pode ser alterada, usaremos ":x" para salvarmos e sairmos da tela.
Salvando alterações para commitar depois!
E se quisermos guardar uma parte de uma alteração para depois, como faremos? Alguma modificação no código, para voltarmos a trabalhar nela depois, sem que precisemos commitá-la ou desfazê-la?
Há o conceito de Stash (git stash), no qual conseguimos salvar todas as alterações em um local temporário, sem necessidade de se gerar um commit para isto.
Se, após git stash executarmos git stash list, teremos uma lista de tudo que estiver salvo nestas condições.
Para trazer os dados armazenados pelo git stash ao diretório de trabalho. Há duas opções:
- Executar "git stash list", e em seguida passar o número da stash em "git stash apply 0", faz com que as modificações sejam aplicadas, porém continuarão na stash. Para a remoção, usar "git stash drop".
- Caso queira fazer ambas as ações ao mesmo tempo (pegar a última alteração adicionada à stash, e já removê-la de lá), utilizar "git stash pop", que realiza o merge com as modificações que já existem e aplica aquelas que já estavam salvas.
Viajando no tempo...
Ao utilizar o comando "git log --oneline", temos os hashs com os sete primeiros caracteres, o suficiente para identificá-los de forma única.
É possível utilizar git checkout códigoHash , e a mensagem exibida indicará que estamos em um estado de cabeça (HEAD) desanexado (detached) do controle de versões.
Isto é, não estamos mais em nenhum branch, e sim em um commit específico! E, se voltarmos à master, tudo que commitarmos aqui será ignorado.
Se quisermos manter os commits feitos a partir deste ponto, será necessário criar uma nova branch.
Portando, poderemos utilizar git checkout -b novo-branch, por exemplo, de forma a não estarmos mais desassociados da linha de desenvolvimento.
A descrição do comando git checkout --help, em uma tradução livre é: "Atualizar os arquivos na working tree para ficarem na versão especificada. [...]". Basicamente, podemos deixar o nosso código no estado do último commit de uma branch, de um commit específico, ou mesmo tags (que veremos adiante).