¿Cómo borrar definitivamente un commit en git?

publicado por: Anonymous

Creo un repositorio con dos commits :

~/ttt$ echo 1 > a
~/ttt$ git init
Initialized empty Git repository in /home/jose/ttt/.git/
~/ttt$ git add .
~/ttt$ git commit -m "Primer"
[master (root-commit) fdcbd32] Primer
 1 file changed, 1 insertion(+)
 create mode 100644 a
~/ttt$ git branch inicio
~/ttt$ echo 22 >> a
~/ttt$ git add .
~/ttt$ git commit -m "Segundo"
[master 36cbf1c] Segundo
 1 file changed, 1 insertion(+)

Pero cambio de idea y decido que ya no quiero el segundo commit. Me quedo con el primero solo.

~/ttt$ git checkout inicio
Switched to branch 'inicio'
~/ttt$ git branch -D master
Deleted branch master (was 36cbf1c).
~/ttt$ git checkout master
error: pathspec 'master' did not match any file(s) known to git.

Bien, ya me he cargado ese segundo commit. Su rama master no existe y no puedo acceder a el….
Error. El commit aún está ahí, y se puede llegar con el hash.

~/ttt$ git checkout 36cbf1c
Note: checking out '36cbf1c'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 36cbf1c... Segundo
~/ttt$ cat a
1
22

¿Cómo me lo cargo del todo?
rm -rf .git no es una respuesta válida, quiero conservar el otro commit.

solución

Es un poco brusco borrar la rama master para eliminar un solo commit, pero supongo que era para darle énfasis al ejemplo.

Los commits huérfanos se los lleva el garbage collector eventualmente, en la medida que ya no queden ramas ni tags que lo referencien.

Si quieres gatillar esa limpieza manualmente puedes hacer

git gc --prune=now

Hay un flag que puedes darle que es más radical, y según Linus Torvalds (que además de Linux inventó Git) puede dañar seriamente un repo dependiendo de la profundidad de sus deltas:

git gc --prune=now --aggressive

PD: Encontré el hilo que leí una vez, y menciona

Date: Wed, 5 Dec 2007 22:09:12 -0800 (PST) From: Linus Torvalds
Subject: Re: Git and GCC

Absolutely. git –aggressive is mostly dumb. It’s really only useful
for the case of “I know I have a really bad pack, and I want to
throw away all the bad packing decisions I have done”.

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *