I committed sensitive data to a single file on my main
branch. I never pushed it. I can change HEAD to point to the previous commit with git reset HEAD^
, but the commit is still hanging around as git reflog
shows.
How can I use the reflog hash/ID, to COMPLETELY remove/delete that commit?
CodePudding user response:
You can't.1 There is no Git command that removes commits by hash ID or reflog entry.
You can however rest assured that if you use:
git push origin somebranch
and the set of commits reachable by traversing somebranch
's tip commit on backwards does not reach any of the reflog-entry-only commits, git push
won't send those commits (the unwanted ones). It will send only the commits listed by git rev-list somebranch
, minus any commits that the receiving Git already has in the repository to which you're pushing. So the fact that you still have the commits is not important.
The other things you can do—useful for the paranoid, a group in which I count myself sometimes—include:
Clone your clone. The resulting clone won't have the commits, so you can now safely run, in that clone:
git remote add github ssh://[email protected]/myname/myrepo.git git push github origin/somebranch:somebranch
to send the commits from your new clone's
origin/somebranch
(cloned from your old clone'ssomebranch
) to your GitHub repository over atgithub
(assuming your final target repository here is on GitHub; use other names and URLs as appropriate).Use
git reflog expire --expire-unreachable=all
2 orgit reflog delete --rewrite --updateref
to delete specific, or all unreachable, entries from some (specified) reflog or, with--all
, all reflogs. Note, however, that this does not delete the commit.Once the reflog entries are deleted, run
git gc --prune=now
. Be sure nothing else is active in the repository while this runs. If you have packed objects in a.keep
-kept file, though, this won't get rid of them (but also note that.keep
is something you would have had to manually create, so you probably do not have keep-files).
To verify that the commits are really gone, use git show <hash-id>
or git cat-file -t <hash-id>
for each hash ID. Note that you will need to save the hash IDs somewhere, since there won't be any in-Git references to them (that's what allows git gc
to remove them).
1If—this is a strong-ish condition but it may be met in your case—the commit has never been packed, you may be able to use rm .git/objects/xx/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
where the xx
s are the hash ID, split up into first-two and remaining hexadecimal characters. That's not a Git command and you have to be very careful with this; it's a good idea to copy or otherwise back up the repository first. The reflog entries will still exist: they'll just become useless in that Git will barf up an error if you try to use them.
2This all
should logically be now
, and I believe now
works, but it's what's listed in the documentation.
CodePudding user response:
To remove a specific reflog entry, you can use:
git reflog delete HEAD@{X} # set X to the entry number listed in reflog
This is documented here. For removing all reflog history, or history older than a certain date, see this question and answer.
Note, this removes the reflog entry only. For more information about completely removing the commit, see torek's answer.