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
35cd2f4 2023-11-27 | Revert "Oops, we didn't want this commit" (HEAD -> master) [Alexander Shvets]
fe3e5fc 2023-11-27 | Oops, we didn't want this commit [Alexander Shvets]
43c6fc8 2023-11-27 | Added HTML header (tag: v1) [Alexander Shvets]
91051af 2023-11-27 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets]
e26eae7 2023-11-27 | Added h1 tag [Alexander Shvets]
b01c348 2023-11-27 | 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
35cd2f4 2023-11-27 | Revert "Oops, we didn't want this commit" (HEAD -> master, tag: oops) [Alexander Shvets]
fe3e5fc 2023-11-27 | Oops, we didn't want this commit [Alexander Shvets]
43c6fc8 2023-11-27 | Added HTML header (tag: v1) [Alexander Shvets]
91051af 2023-11-27 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets]
e26eae7 2023-11-27 | Added h1 tag [Alexander Shvets]
b01c348 2023-11-27 | 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 43c6fc8 Added HTML header
$ git log
43c6fc8 2023-11-27 | Added HTML header (HEAD -> master, tag: v1) [Alexander Shvets]
91051af 2023-11-27 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets]
e26eae7 2023-11-27 | Added h1 tag [Alexander Shvets]
b01c348 2023-11-27 | Initial commit [Alexander Shvets]
Nosso branch master
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
43c6fc8 2023-11-27 | Added HTML header (HEAD -> master, tag: v1) [Alexander Shvets]
35cd2f4 2023-11-27 | Revert "Oops, we didn't want this commit" (tag: oops) [Alexander Shvets]
91051af 2023-11-27 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets]
fe3e5fc 2023-11-27 | Oops, we didn't want this commit [Alexander Shvets]
e26eae7 2023-11-27 | Added h1 tag [Alexander Shvets]
b01c348 2023-11-27 | Initial commit [Alexander Shvets]
Podemos ver que os commits errados não foram embora. Eles não estão listados mais no branch master
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.