15. Removendo um commit de um branch
Metas
- Aprender a deletar os commits mais recentes de um branch.
Revert
é um comando poderoso da seção anterior que te permite cancelar quaisquer commits para um repositório. Apesar disso, tanto os commits originais quanto os cancelados permanecem visíveis no histórico do branch (quando usamos o comando git log
).
Frequentemente depois que um commit é feito percebemos que ele era um erro. Seria legal ter um comando de desfazer que permitisse deletar o commit incorreto imediatamente. Esse comando preveniria a aparição de um commit indesejado no histórico do git log
.
01 O comando reset
Já vimos o comando reset
e o usamos para definir a área de preparação para ser consistente com um determinado commit (usamos o commit HEAD
em nossa lição anterior).
Quando você executa o comando reset
junto com uma referência de commit (ou seja, um branch, hash ou nome de tag), o comando...
- Aponta o ramo atual para o commit especificado.
- Opcionalmente, redefinirá a área de preparação para que ela esteja em conformidade com o commit especificado.
- Opcionalmente, redefina o diretório de trabalho para que ele corresponda ao commit especificado.
02 Cheque nosso histórico
Vamos fazer um rápido scan do nosso histórico de commits.
Execute
git log
Resultado
$ git log
86364a1 2023-11-28 | Revert "Oops, we didn't want this commit" (HEAD -> main) [Alexander Shvets]
6a44bec 2023-11-28 | Oops, we didn't want this commit [Alexander Shvets]
b7614c1 2023-11-28 | Added HTML header (tag: v1) [Alexander Shvets]
46afaff 2023-11-28 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets]
78433de 2023-11-28 | Added h1 tag [Alexander Shvets]
5836970 2023-11-28 | Initial commit [Alexander Shvets]
Nós vemos que os dois últimos commits desse branch são "Oops" and "Revert Oops". Vamos removê-los com o comando reset
.
03 Marque esse branch primeiro
Vamos marcar nosso último commit com tag, para que possamos achá-lo após remover commits.
Execute
git tag oops
Resultado
$ git log
86364a1 2023-11-28 | Revert "Oops, we didn't want this commit" (HEAD -> main, tag: oops) [Alexander Shvets]
6a44bec 2023-11-28 | Oops, we didn't want this commit [Alexander Shvets]
b7614c1 2023-11-28 | Added HTML header (tag: v1) [Alexander Shvets]
46afaff 2023-11-28 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets]
78433de 2023-11-28 | Added h1 tag [Alexander Shvets]
5836970 2023-11-28 | Initial commit [Alexander Shvets]
04 Resete o commit para o oops
anterior
No log de histórico (veja acima), o commit com tag v1
está fazendo commit sobre um commit anterior incorreto. Vamos resetar o branch para aquele ponto. Como o branch tem uma tag, podemos usar o nome da tag no comando reset
(se não possuir uma tag, podemos usar o valor hash).
Execute
git reset --hard v1
git log
Resultado
$ git reset --hard v1
HEAD is now at b7614c1 Added HTML header
$ git log
b7614c1 2023-11-28 | Added HTML header (HEAD -> main, tag: v1) [Alexander Shvets]
46afaff 2023-11-28 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets]
78433de 2023-11-28 | Added h1 tag [Alexander Shvets]
5836970 2023-11-28 | Initial commit [Alexander Shvets]
Nosso branch main
está apontando para o commit v1
e "Revert Oops", e commits "Oops" não mais existem no branch. O parâmetro --hard
aponta que o diretório de trabalho deve ser atualizado para refletir o novo head do branch.
05 Nada é perdido para sempre
O que acontece com os commits errados? Eles ainda estão no repositório. Na verdade, ainda podemos nos referir a eles. No início da lição, criamos a tag oops
para o commit cancelado. Vamos dar uma olhada em all (todos) commits.
Execute
git log --all
Resultado
$ git log --all
b7614c1 2023-11-28 | Added HTML header (HEAD -> main, tag: v1) [Alexander Shvets]
86364a1 2023-11-28 | Revert "Oops, we didn't want this commit" (tag: oops) [Alexander Shvets]
46afaff 2023-11-28 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets]
6a44bec 2023-11-28 | Oops, we didn't want this commit [Alexander Shvets]
78433de 2023-11-28 | Added h1 tag [Alexander Shvets]
5836970 2023-11-28 | Initial commit [Alexander Shvets]
Podemos ver que os commits errados não foram embora. Eles não estão listados mais no branch main
mas ainda permanecem no repositório. Eles ainda estariam no repositório caso não tivéssemos colocado uma tag neles, mas só poderíamos referenciá-los por seus nomes hash. Commits não referenciados continuam no repositório até que um software coletor de lixo é acionado pelo sistema.
06 Perigos de resetar
Resets em branches locais geralmente são inofensivos. As consequências de quaisquer "acidentes" podem ser revertidos usando um commit apropriado.
Apesar disso, outros usuários que compartilham o branch podem ficar confusos se o branch compartilhado fica armazenado em repositórios remotos.