git reset
git reset: reseta o HEAD e a branch atual para um commit diferente.
O git reset é um comando do Git usado principalmente para mover o HEAD e a branch atual de volta para um commit específico — na prática, "rebobinando" o histórico do projeto para um estado anterior. Esse comando é útil quando você precisa desfazer commits feitos na branch atual.
Quando você usa o git reset, é como dizer ao seu repositório Git para esquecer que certas alterações aconteceram e considerar um estado anterior como o estado atual do projeto. Isso é extremamente útil para desfazer alterações, simplificar um histórico complexo ou até combinar vários commits em um só antes de compartilhá-los com outras pessoas.
Historicamente, o git reset era usado para vários fins, inclusive para resetar o diretório de trabalho e a staging area. Até hoje, desenvolvedores veteranos usam o git reset para essas tarefas. Mas, com a chegada do comando git restore no Git 2.23.0, a recomendação atual é usar o git restore para gerenciar o diretório de trabalho e a staging area, deixando o git reset principalmente para mover o HEAD e o ponteiro da branch atual.
Com o git restore, a chance de quebrar algo sem querer é menor, porque ele é mais direcionado e menos destrutivo que o git reset. Mas quem está acostumado com o velho git reset pode levar um tempo até se acostumar com o comando novo. Já se o Git ainda é novidade para você, vale entender a diferença e tentar usar o git restore em vez do git reset quando fizer sentido.
Exemplos
Mova a branch atual um commit para trás e redefina o stage para corresponder a esse commit, sem alterar o diretório de trabalho. As alterações do commit que deixou de fazer parte do histórico da branch passam a aparecer fora do stage.
Um caso de uso comum é dividir um commit feito às pressas em vários commits mais focados ou adicionar apenas parte dele ao stage novamente:
git reset HEAD~1Mova a branch atual três commits para trás sem alterar o stage nem o diretório de trabalho. As alterações desses commits aparecem juntas no stage.
Um caso de uso comum é substituir vários commits locais pequenos ou bagunçados por um único commit limpo:
git reset --soft HEAD~3Mova a branch atual dois commits para trás e redefina o stage e o diretório de trabalho para corresponder a esse commit anterior. Isso descarta as alterações desses commits e qualquer alteração não commitada em arquivos rastreados. Alterações não commitadas podem ser perdidas permanentemente.
Um caso de uso comum é abandonar por completo um experimento local quando você tem certeza de que não precisa dos commits nem das alterações em arquivos rastreados:
git reset --hard HEAD~2Nesses exemplos, HEAD~1 significa "um commit antes do HEAD". O número depois de ~ indica quantos commits o Git deve voltar, então HEAD~3 significa "três commits antes do HEAD". Você também pode indicar o destino com o hash de um commit, uma branch ou outra referência a um commit.
Tenha cuidado ao usar o git reset, principalmente com a opção --hard, porque ele pode descartar alterações de forma permanente. Sempre confira duas vezes se está resetando para o commit certo e considere usar o git stash para guardar no stash as alterações não commitadas antes de resetar, caso ache que pode precisar delas depois.
Repare: o git reset não remove commits de verdade; ele só move o ponteiro da branch. Os commits "removidos" continuam no histórico do repositório (acessíveis pelo hash do commit), mas deixam de ser alcançáveis a partir da branch atual. Ou seja: você pode recuperá-los se precisar, mas eles não aparecem mais no histórico da branch.
.gitignoregit checkoutgit configgit taggit worktree