Description
According to the documentation, we can use the --refs
argument to limit rewriting to only the later part of the history. However, removing files from part of the history (up to and including the last commit) using --refs
doesn’t seem to work.
Here’s a very simple example with three commits and three files. The file foo.txt
is present in all three commits, bar.txt
in the last two commits and baz
in only the last commit:
First commit:
foo.txt
Second commit:
foo.txt
bar.txt
Third commit:
foo.txt
bar.txt
baz.txt
I want to delete the file foo.txt
, but only from the last two commits. Based on the documentation, I would expect the following to work:
git-filter-repo --invert-paths --path foo.txt --force --refs HEAD~1..HEAD
But it doesn’t seem to have any effect. Reproducible example:
mkdir gfr-test
cd gfr-test
git init
echo foo > foo.txt
git add foo.txt
git commit -m "Add foo"
echo foo2 >> foo.txt
echo bar > bar.txt
git add foo.txt bar.txt
git commit -m "Add bar, modify foo"
echo baz > baz.txt
git add baz.txt
git commit -m "Add baz"
git-filter-repo --invert-paths --path foo.txt --force --refs HEAD~1..HEAD
Nothing seems to have changed:
$ git log --name-status
commit 67e998bd460feb06795e392e535a42af84baebc9 (HEAD -> main, origin/main, origin/HEAD)
Author: Nomen Nescio <nobody@example.com>
Date: Sat Mar 29 18:00:52 2025 +0100
Add baz
A baz.txt
commit 476e3a829652c6bb89c19a32d92172ca2a982986
Author: Nomen Nescio <nobody@example.com>
Date: Sat Mar 29 18:00:52 2025 +0100
Add bar, modify foo
A bar.txt
M foo.txt
commit 3dbbc2c33bc4eb550f51f9df39695ca1f0b1f599
Author: Nomen Nescio <nobody@example.com>
Date: Sat Mar 29 18:00:52 2025 +0100
Add foo
A foo.txt
The commits contain the same files as before:
$ git ls-tree HEAD
100644 blob 5716ca5987cbf97d6bb54920bea6adde242d87e6 bar.txt
100644 blob 76018072e09c5d31c8c6e3113b8aa0fe625195ca baz.txt
100644 blob b210800439ffe3f2db0d47d9aab1969b38a770a5 foo.txt
$ git ls-tree HEAD~1
100644 blob 5716ca5987cbf97d6bb54920bea6adde242d87e6 bar.txt
100644 blob b210800439ffe3f2db0d47d9aab1969b38a770a5 foo.txt
$ git ls-tree HEAD~2
100644 blob 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 foo.txt
Expected results:
$ git log --name-status
commit 67e998bd460feb06795e392e535a42af84baebc9 (HEAD -> main, origin/main, origin/HEAD)
Author: Nomen Nescio <nobody@example.com>
Date: Sat Mar 29 18:00:52 2025 +0100
Add baz
A baz.txt
commit 476e3a829652c6bb89c19a32d92172ca2a982986
Author: Nomen Nescio <nobody@example.com>
Date: Sat Mar 29 18:00:52 2025 +0100
Add bar, modify foo
A bar.txt
D foo.txt
commit 3dbbc2c33bc4eb550f51f9df39695ca1f0b1f599
Author: Nomen Nescio <nobody@example.com>
Date: Sat Mar 29 18:00:52 2025 +0100
Add foo
A foo.txt
$ git ls-tree HEAD
100644 blob 5716ca5987cbf97d6bb54920bea6adde242d87e6 bar.txt
100644 blob 76018072e09c5d31c8c6e3113b8aa0fe625195ca baz.txt
$ git ls-tree HEAD~1
100644 blob 5716ca5987cbf97d6bb54920bea6adde242d87e6 bar.txt
$ git ls-tree HEAD~2
100644 blob 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 foo.txt
If I leave out the --refs
argument, so that the removal is not limited to the later part of the history, everything is working fine (foo.txt
is removed from all commits, and the first commit, which is now empty, is completely removed). (But if I use --refs HEAD~2..HEAD
, which should in theory also affect the entire history, nothing happens.)