Marcos R. Guevara
Marcos R. Guevara

Reputation: 6398

How to remove file from Git history?

Some time ago I added info(files) that must be private. Removing from the project is not problem, but I also need to remove it from git history.

I use Git and Github (private account).

Note: On this thread something similar is shown, but here is an old file that was added to a feature branch, that branch merged to a development branch and finally merged to master, since this, a lot of changes was done. So it's not the same and what is needed is to change the history, and hide that files for privacy.

Upvotes: 589

Views: 416134

Answers (13)

Petro Franko
Petro Franko

Reputation: 6814

I have found this answer and it helped:

git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch path_to_file' HEAD

Upvotes: 582

Harkály Gergő
Harkály Gergő

Reputation: 841

  1. First install BFG Repo-Cleaner, for example if you use Ubuntu 22.04 or similar:

sudo snap install bfg-repo-cleaner

  1. Then clone your GitHub repository as a mirror, like this:

git clone --mirror [email protected]:YOU/REPO.git

  1. Navigate into folder:

cd REPO

  1. Now you can delete file from Git history, for example:

bfg --delete-files config.php

  1. Now push back changes to GitHub:

git push or git push --force

Upvotes: 0

suhailvs
suhailvs

Reputation: 21740

Remove the file and rewrite total history with new commit hashs:

there are two ways:

  1. Using git-filter-branch:
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch <path to the file or directory>' --prune-empty --tag-name-filter cat -- --all
  1. Using git-filter-repo:
pip3 install git-filter-repo
git filter-repo --path <path to the file or directory> --invert-paths

  • now force push the repo: git push origin --force --all
  • tell your collaborators to rebase git pull --rebase.

Upvotes: 88

LoneDev
LoneDev

Reputation: 1

This command will delete any zip file in your history.

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch *.zip" --prune-empty --tag-name-filter cat -- --all

Replace zip with your files format.

Upvotes: 0

user1844086
user1844086

Reputation:

I had the same "you must be a on a branch" message. I went to the top of the repo in the git UI, and just below the repo name I found a pull down where I could change the branch from default to main. This fixed the issue for me. HTH. enter image description here

Upvotes: 0

Michael Robateau Jr.
Michael Robateau Jr.

Reputation: 55

Add the file pattern to your .gitignore. Example:

*.env

Then remove the cached file information using this command(zsh):

bash -c 'git rm --cached *.env'

Upvotes: -3

Panagiss
Panagiss

Reputation: 3740

Remove file(s)

bfg --delete-files YOUR-FILE-WITH-SENSITIVE-DATA

Replace all text listed in passwords.txt wherever it can be found in your repository's history, run:

bfg --replace-text passwords.txt

After that you need topush your changes to GitHub/GitLab/BitBucket

git push --force

More about the BFG tool here

Furthermore, since this technique it will rewrite your repository's history, which changes the SHAs for existing commits, you should alter and any dependent commits. So merge and close all open PRs!

Upvotes: 5

Tibor Tak&#225;cs
Tibor Tak&#225;cs

Reputation: 4828

git-filter-repo

git recommends using the third-party add-on git-filter-repo (when git filter-branch command is executed). There is a long list of reasons why git-filter-repo is better than any other alternatives, my experience is that it is very simple and very fast.

This command removes the file from all commits in all branches:

git filter-repo --invert-paths --path <path to the file or directory>

Multiple paths can be specified by using multiple --path parameters. You can find detailed documentation here: https://www.mankier.com/1/git-filter-repo

Upvotes: 306

CodeWizard
CodeWizard

Reputation: 142552

  • First of all, add it to your .gitignore file and don't forget to commit the file :-)

  • You can use this site: http://gitignore.io to generate the .gitignore for you and add the required path to your binary files/folder(s)

  • Once you added the file to .gitignore you can remove the "old" binary file with BFG.


How to remove big files from the repository

You can use git filter-branch or BFG. https://rtyley.github.io/bfg-repo-cleaner/

BFG Repo-Cleaner

an alternative to git-filter-branch.

The BFG is a simpler, faster alternative to git-filter-branch for cleansing bad data out of your Git repository history:

*** Removing Crazy Big Files***

  • Removing Passwords, Credentials & other Private data

Examples (from the official site)

In all these examples bfg is an alias for java -jar bfg.jar.

# Delete all files named 'id_rsa' or 'id_dsa' :
bfg --delete-files id_{dsa,rsa}  my-repo.git

enter image description here

Upvotes: 18

Mohamed Fayek Saber
Mohamed Fayek Saber

Reputation: 81

The following commands should be applied one by one in each project in order to remove the history for a specific file, but you have to take backup from the project at the beginning, because the file will be deleted

  • git filter-branch --index-filter "git rm --cached --ignore-unmatch ProjectFolderName/src/main/resources/application-prod.properties" HEAD

  • git push origin --force --all

  • git update-ref -d refs/original/refs/heads/master

..........................................................................

  • git filter-branch --index-filter "git rm --cached --ignore-unmatch ProjectFolderName/src/main/resources/application.properties" HEAD

  • git push origin --force --all

  • git update-ref -d refs/original/refs/heads/master

Upvotes: 2

hspandher
hspandher

Reputation: 16753

If you have recently committed that file, or if that file has changed in one or two commits, then I'd suggest you use rebase and cherrypick to remove that particular commit.

Otherwise, you'd have to rewrite the entire history.

git filter-branch --tree-filter 'rm -f <path_to_file>' HEAD

When you are satisfied with the changes and have duly ensured that everything seems fine, you need to update all remote branches -

git push origin --force --all

Note:- It's a complex operation, and you must be aware of what you are doing. First try doing it on a demo repository to see how it works. You also need to let other developers know about it, such that they don't make any change in the mean time.

Upvotes: 186

vancy-pants
vancy-pants

Reputation: 1358

I read this GitHub article, which led me to the following command (similar to the accepted answer, but a bit more robust):

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

Upvotes: 56

c1au61o_HH
c1au61o_HH

Reputation: 897

Using the bfg repo-cleaner package is another viable alternative to git-filter-branch. Apparently, it is also faster...

Upvotes: 11

Related Questions