Why does git filter-branch tree-filter fail to rewrite commit but then leave working directory dirty?

StackOverflow https://stackoverflow.com/questions/23530698

Question

I am attempting to revise a repo (not yet shared, so no worries about breaking anyone else's history) and git filter-branch is behaving in a rather odd fashion.

$ git filter-branch -f --tree-filter /path/to/fixup.sh cross-check
Rewrite ae78489a98f2a9429c559833d8320d5f50a99903 (1/1)Hello? Hello?
Goodbye

WARNING: Ref 'refs/heads/cross-check' is unchanged

The "Hello? Hello?" output is from the script, so I know the script is running.

What's frustrating is that after the command completes, the working directory is then dirty:

$ git status
On branch cross-check
Your branch is up-to-date with 'origin/cross-check'.

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   .gitattributes
    modified:   tools/lua/lib/lfs.so.1.2.1
    modified:   tools/lua/lib/luadoc/config.lua
    modified:   tools/lua/lib/luadoc/doclet/debug.lua
    modified:   tools/lua/lib/luadoc/doclet/formatter.lua
    modified:   tools/lua/lib/luadoc/doclet/html.lua
    modified:   tools/lua/lib/luadoc/doclet/raw.lua
    modified:   tools/lua/lib/luadoc/init.lua
    modified:   tools/lua/lib/luadoc/lp.lua
    modified:   tools/lua/lib/luadoc/taglet/standard.lua
    modified:   tools/lua/lib/luadoc/taglet/standard/tags.lua

Those are exactly the changes I wanted in the revised commit, but for some reason git isn't able to see them during the git filter-branch operation.

What am I doing wrong here?

(FWIW I've run git filter-branch many, many times before. I'm pretty familiar with it in general, but this one has me stumped.)

Was it helpful?

Solution

(converting comments to answer)

The tree filter is run in a directory that is not the normal working directory for the repository. (The actual directory is derived from from the -d argument to git filter-branch, if you supply one; if you don't supply one, filter-branch starts with .git-rewrite. To this, it looks like the filter-branch script adds /t:

orig_dir=$(pwd)
mkdir -p "$tempdir/t" &&
tempdir="$(cd "$tempdir"; pwd)" &&
cd "$tempdir/t" &&
workdir="$(pwd)" ||
die ""

and then uses files in $tempdir for everything else.)

Thus, if any paths in fixup.sh refer back to the original working directory, git won't see those changes in the temporary trees.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top