Reputation: 433
Let's say i have done 5 commits in my git project.
At Commit 4 i accidentally added my credentials.json file and pushed to repo.
At Commit 5 i removed the file and did a commit and pushed this change to repo.
Currently the file is not showing in latest commit. But if a user checks commit history, he can go to commit 4 and check the contents of my file.
How can i permanently remove the file from commit history so that it looks like the file was never added to the repo.
Note:-
i have already tried below command:-
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch Credentials.json" \
--prune-empty --tag-name-filter cat -- --all
It does not throw any error but the file is not removed from History.
Actually the file is inside /src folder. But the strange thing is that when i give the below command (including the full path):-
git filter-branch --force --index-filter "git rm --cached --ignore-unmatch ~full-path/src/Credentials.json" --prune-empty --tag-name-filter cat -- --all
I get error as:- ~full-path/src/Credentials.json is outside repository.
Is it because i have already removed my file in commit 5?
What can i do in this scenario?
Is creating a new repo from scratch the only option?
Upvotes: 15
Views: 23017
Reputation: 27568
WARN: Always make a backup of the original repo before you start following operations.
No need to create a new repo. git filter-branch
works.
Don't use full path in git filter-branch
, use the relative path src/Credentials.json
.
git filter-branch --force --index-filter "git rm --cached --ignore-unmatch src/Credentials.json" --prune-empty --tag-name-filter cat -- --all
BTW, bfg
is much easier to use for a newbie. (bfg
accepts filename without path.)
bfg --delete-files Credentials.json
References
Upvotes: 17
Reputation: 91
@Simba's answer works, but you will also need to force-push afterwards with git push origin --force --all
So (1)
git filter-branch --force --index-filter "git rm -rf --cached --ignore-unmatch <relative_path_to_file>" --prune-empty --tag-name-filter cat -- --all
Then (2)
git push origin --force --all
Upvotes: 9
Reputation: 23779
Assuming no one had cloned the repository, you can use git rebase -i
to rewrite the history and remove the file.
Use git rebase -i <commit-hash-of-commit-3>
. This will open an editor with the list of commits starting at commit-4. You can choose to delete a commit (by deleting the line and saving the file), to edit it, etc.
Select 'edit' for commit-4. Save the file. You'll be back at the shell with the files added to the git 'index' but not yet committed.
Now you can git rm credentials.json
to remove the file and git commit --amend
to modify the commit. (updated)
Finally git rebase --continue
to finish. You'll be back at the shell and the file will no longer be part of the repository.
If you had added a commit later on that depends on the Credentials.json file, you may get an error during the 'continue' phase. Git then stops at the problematic commit and you can again use git commands (reset/add) to modify the commit and continue.
Upvotes: 8
Reputation: 3177
I would recommend reading GitHubs help page:
In short:
You can use BFG Repo-Cleaner
bfg --delete-files Credentials.json my-repo.git
You can use git filter-branch
:
git filter-branch --force --index-filter "git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA" --prune-empty --tag-name-filter cat -- --all
(where path is e.g. src/Credentials.json
, This may help you too)
It's worth noting, that if anyone has already a copy of the repo, you have to delete it there too! (or you force re-clone/pull the repo)
Upvotes: 1