How to remove a file from the repository history when there are multiple files with the same name?

Platform Notice: Cloud Only - This article only applies to Atlassian products on the cloud platform.

Summary

We can use BFG to remove files from the entire repository's history by following this KB. However, that KB does not work if -

  • You have multiple files with the same name in different folders and you want to delete only one set of files

  • You want to delete an entire directory (You must enter individual filenames but this becomes cumbersome with a large number of files).

Prerequisite

  • All of the commands in this KB must be performed in a mirror clone.

  • We are removing the file from all branches of the repository and only a mirror clone will have every branch in the remote. To perform a mirror clone, you must add --mirror to the clone command. Below is an example -

1 git clone --mirror https://<username>@bitbucket.org/<workspace-ID>/<repository-name>.git
  • You must have git filter-repo installed. If you do not have it already installed, please install it as per the instructions here. You will need to install python3 if you do not already have it for git filter-repo to function.

Solution

To resolve this problem, we can use the third-party tool - git filter-repo. You can find a cheatsheet for BFG like commands here and general documentation here. However, this KB will highlight the commands to remove a specific file.

  • The below command will remove the file remove.txt from the repository (It will only remove remove.txt if it is present in the root folder of the repository)

1 git filter-repo --invert-paths --path remove.txt
  • To remove the file dir1/dir2/remove.txt -

1 git filter-repo --invert-paths --path dir1/dir2/remove.txt
  • To remove the file remove.txt from multiple folders -

1 git filter-repo --invert-paths --path-glob '*/remove.txt'

The * includes multiple folders at any level. It will remove dir1/dir2/remove.txt as well as dir1/remove.txt. However, it will not remove remove.txt from the root folder. Whenever we use wildcards like *, we must use path-glob instead of path and enclose the path in quotes.

  • To remove an entire directory called dir1/dir2 in the root of the repository -

1 git filter-repo --invert-paths --path-glob 'dir1/dir2/*'
  • To remove all files with the extension .asset -

1 git filter-repo --invert-paths --path-glob '*.asset' --use-base-name

This behaves like BFG. When we use the use-base-name parameter, it does not find files by absolute path. Instead, it considers the filename. Hence, every file name that ends in '.asset' is deleted.

Once you enter the appropriate command to remove the files, you must now push this back to the remote. You can do it with this command -

1 git push --mirror

It will push all the branches to the remote. This push is an implicit force push. Hence, please verify that only the correct files are removed.

Updated on February 26, 2025

Still need help?

The Atlassian Community is here for you.