Search code examples
gitbfg-repo-cleaner

If credentials are removed from a repo by amending the commit that added them, and subsequent commits are reapplied, is the reflog still tainted?


I've used BFG Repo-Cleaner a couple times to remove credentials that were added dozens/hundreds of commits in the past, and that tool works well, but for smaller-scale situations like the following, I'm wondering if that is necessary.

Suppose there's a local repo to which someone accidentally committed database credentials, and they didn't notice they had done so until a few commits later. If git reset --hard [COMMIT_ID] is used to rewind history to the commit that added the credentials, and then that commit is amended to not have the credentials, and then the subsequent commits are reapplied, will the credentials still be in the reflog somewhere? If so, is there a risk they could be pushed to the remote?

Similarly, if the credentials were added in the most recent commit and this mistake was noticed immediately, is it sufficient to remove the credentials from the file[s] and just run git commit -a --amend? Or will the reflog be tainted in that case, too?

If the reflog is tainted in either scenario, would running something like git reflog expire --expire=now --all && git gc --prune=now --aggressive remove the credentials?

(Those specific commands came from BFG's documentation; they should be run after the tool has done its work on the repo.)


Solution

  • Yes, there are kept in the reflog.

    The reflog can be thought of as a log of all refs. When you create a commit, it is added to the reflog. When you amend a commit, you create a new commit added to the reflog. When you remove all references from a commit/amend it, it will not be removed from tge reflog as it just contains the references so you can recover from them. After all, it is a safety mechanism for the user (to recover lost commits etc) and not something shared.

    The reflog is not pushed. Only the referenced commits are.

    When you push, you just push the commits of certain branches/tags. Unreferenced commits are not pushed.

    Yes, git reflog expire --expire=now --all && git gc --prune=now --aggressive deletes the reflog and unreferenced commits but you don't need it in your case as those are not pushed.