I accidentally commited something that might be sensetive information in git (only locally) and I wanna remove it from git history in a simple way. Will
git reset --soft HEAD~1
and then unstage the sensetive information and add to gitignore be enough to completely remove it from git history?
No, a soft reset is not enough. Doing this will leave the file in your index (where you stage files to be committed). This means, that git is still tracking the file.
You will want to do a mixed reset, which unstages these files as well. As René pointed out, it is also a good idea to remove the file or add it to your .gitignore
so you don't accidentally commit it again.
This is enough so the sensitive information will not be transmitted to a remote server on git push
.
However, the information is still in your local repository. If you ever "loose" a commit by accidentally resetting too far, git reflog is a very useful tool.
Now to clean all away all commits, that are not reachable through a branch or tag:
git reflog expire --expire=1.minute --all
git prune
git gc
reflog expire
and prune
are destructive operations. I recommend running these commands with the --dry-run
argument first, to see what exactly gets removed.
git reset --soft HEAD~1
resets only the HEAD
to the previous commit while the index and working directory is not touched.
This means that the index and working directory still reflects the state that contains the sensitive information. Just remove these files from the index git reset HEAD <file>...
and commit again.
After you removed the sensitive data files from the index, they will remain in the working directory. Maybe you also want to delete them from the working directory or add them to .gitignore
.
EDIT
Do you mean I should first do git reset --soft HEAD~1 and then git reset HEAD ?
Yes. Normally you stage files git add ..
and then commit them. If you do a git reset --soft HEAD~1
your repository reflects the state just before that commit. You can see this if you do a git status
. So you can modify the index and commit again.
Also, does this remove the data 100% from git history?
No, not completely. If a commit is not referenced anymore git will delete it after 90 days (default value - see git gc
). If you want to delete it immediately, you must ensure that it is not referenced anymore. Therefore you must delete it from any reflog that contains it, e.g. git reflog --delete HEAD@{3}
. Normally it will be contained in the reflog of the HEAD
and your branch. Also ensure that it is not contained in any branch, e.g. if the commit if is A
do a git branch -a --contains A
. The output must be empty.
Then you can garbage collect it using git gc --prune=now
. Check that the commit has been deleted using git log -n1 COMMIT-ID
. It should output fatal: bad object
.
For details on removing files and direcotries from git take a look at my blog https://www.link-intersystems.com/blog/2014/07/17/remove-directories-and-files-permanently-from-git/.
No need for --soft
: git reset HEAD~1
will unstage the current commit files by resetting the index in addition of moving HEAD.
Then a .gitignore
will be enough to ignore that file.
Do you mean I should first do
git reset --soft HEAD~1
and thengit reset HEAD <file>
?
No, you need to remove the all commit to be sure the history won't include your sensitive file.
git reset HEAD~1
echo sensitiveFile >> .gitignore
git add .gitignore
git add -A .
git commit -m "Redo commit, without sensitiveFile"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With