I'm trying to use the git filter-branch
feature to remove a file that was recently updated and committed. I tried running the following command:
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch myfile' --prune-empty --tag-name-filter cat -- 6f7fda9..HEAD
However this only removes the file from the master branch, and I want it removed from all branches.
Starting with commit 6f7fda9
to HEAD
I want the file removed. Is the command I'm running wrong?
git-filter-branch can be used to get rid of a subset of files, usually with some combination of --index-filter and --subdirectory-filter .
git-commit-tree is a low level command which commits a single tree object but does not perform any of the follow-up reference and Head work that git-commit does.
You cannot remove sensitive data from other users' clones of your repository, but you can permanently remove cached views and references to the sensitive data in pull requests on GitHub by contacting GitHub Support.
The git commit command captures a snapshot of the project's currently staged changes. Committed snapshots can be thought of as “safe” versions of a project—Git will never change them unless you explicitly ask it to.
Your requirements as stated are contradictory. Specifically
I want it removed from all branches.
and
Starting with commit 6f7fda9 to HEAD I want the file removed.
need to be reconciled. I suspect this comes down to an inaccurate understanding of commit ranges - which are only sort-of a thing in git.
Consider this commit graph:
x -- 6f7fda9 -- A -- B -- C -- F <--(master)
\ ^(HEAD)
D -- E <--(branch)
So HEAD
is at master
which is at F
; and there's a branch which was (apparently) created from A
(after 6f7fda9
but before HEAD
).
Now the question is, given this graph what does 6f7fda9..HEAD
mean? And unfortunately, the answer isn't what a lot of people intuitively think.
6f7fda9..HEAD
is short for HEAD ^6f7fda9
- meaning "everything reachable from HEAD
but not reachable from 6f7fda9
". "Reachable" means "the commit itself, and any commits you find by following parent pointers". So in this case, it means A
, B
, C
, and F
; but not x
or 6f7fda9
(because they're reachable from 6f7fda9
) and also not D
, or E
(because they aren't reachable from HEAD
).
There are several ways to get filter-branch
to process all the branches. For example you could
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch myfile' --prune-empty --tag-name-filter cat -- --all
But this will include all refs (not just all branches); if that's a problem
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch myfile' --prune-empty --tag-name-filter cat -- --branches
One other caveat - if you specifically don't want commits before 6f7fda9
rewritten, then you need to include one or more negative commit references. But assuming you do intend to include 6f7fda9
itself, you'd exclude its parent (not itself).
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch myfile' --prune-empty --tag-name-filter cat -- ^6f7fda9^ --branches
If 6f7fda9
is a merge, you'd have to list negative commit references for each of its parents.
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