0

I have the following problem - I wanted to delete some commits from my git repository history (yes, I know it's a bad habit, but I know what I'm doing). I made it using rebase (I got the instructions from there: https://ncona.com/2011/07/how-to-delete-a-commit-in-git-local-and-remote/) and the commits were removed from my remote branch, but there are still in the history (on a DETACHED_HEAD). How can I get rid of them so that they could disappear completely? Thank you for any help!

10
  • 2
    Commits on a “detached HEAD” are only reachable by that exact certain HEAD. Once something else gets checked out, which would move the HEAD elsewhere, there’s no reference left and the commits will be practically invisible and eligible for garbage collection. Commented Sep 11, 2018 at 10:03
  • 3
    You can checkout a real branch and leave the detached HEAD state. These commits will stay in the repo for a long time invisibly. In case you want them back, you can still find them by git reflog. Commented Sep 11, 2018 at 10:03
  • @ElpieKay thank you, but I want to remove them completely. I don't want to find them... Commented Sep 11, 2018 at 10:07
  • Run git prune? Commented Sep 11, 2018 at 10:08
  • 1
    @user2905035 See stackoverflow.com/questions/11271263/…. But, unless the commits contain very big files, I don't think it's a good idea to completely remove them at once. Commented Sep 11, 2018 at 10:12

1 Answer 1

1

… the commits were removed from my remote branch, but there are still in the history (on a DETACHED_HEAD). How can I get rid of them so that they could disappear completely?

The normal way of doing is to let them die by themselves. The garbage collector will eventually get rid of everything that is no longer in use. You may also manually run it with git gc.

"DETACHED HEAD" simply means that you're currently checking out any commit that is not linked to a branch name (or you checked it out using the commit SHA sum, not the branch name), implying that if you add/commit stuff from this state, the operation will occur but won't be linked to anything by default, and no branch name will be automatically updated at this stage.

If however you have a good reason to make them disappear (accidentally committed a password in human-readable form, boss bashing messages or porn pictures stored in the wrong folder), you first need to check if your commits are no longer reachable, neither from an official reference such as a tag or a branch name, nor from any other commit remaining steady, nor from any entry in the different reflogs.

So you need to clean all this out to be sure that your commit will be scavenged.

You can take a look to this entry to know what options to pass to git gc in order to enjoin it to make everything expire right now, but don't rush into it until you have completely understood what they do.

Unfortunately, you can act only on your local repository. You may use some facilities such as "push -f" to rewrite history on your remote repository if you have the right to do so. However, for janitorial operations such as gc, you'll need a direct access to the git server then operate from there.

Sign up to request clarification or add additional context in comments.

1 Comment

To add a bit more: as you say, the key here is reachability, but for those who don't have a clear idea of what it means for a commit to be "reachable" I recommend working through the web site Think Like (a) Git.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.