10

I'm trying to rewrite my history in my git repository because I need to remove a file that contains restricted information.

This is what happens:

$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch FILE' master
Cannot rewrite branch(es) with a dirty working directory.

So I think "that's weird, I'm pretty sure I don't have uncommitted changes", and I run:

$ git status -u
# On branch master
nothing to commit (use -u to show untracked files)

What is going on here? Does anyone have an idea for what could be happening? There are submodules in this repository.

Submodule Staging Info

I have 18 submodules (all Vim plugins), and here are their statuses. Thought this might be useful info.

$ for i in $(ls); do cd $i; git status -u; cd ..; done;
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# On branch master
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)
# Not currently on any branch.
nothing to commit (working directory clean)

Other info

$ git diff-files --ignore-submodules --quiet
$ echo $?
1
$ git diff-index --cached --quiet HEAD --
$ echo $?
0
Dan Loewenherz
  • 10,879
  • 7
  • 50
  • 81
  • did you try `filter-branch` again _after_ running `git status`? Maybe only the timestamp of a file changed and `filter-branch` doesn't check for that to remove the dirty flag – Tobias Kienzler Jun 24 '11 at 05:58
  • Yep, I did. Same result. – Dan Loewenherz Jun 24 '11 at 06:04
  • then it's most likely due to the submodules, with which I don't have any experience, sorry – Tobias Kienzler Jun 24 '11 at 06:06
  • I'm pretty sure it's not. I've run git status in all of the submodules as well--all have clean working directories. – Dan Loewenherz Jun 24 '11 at 06:11
  • 1
    What does `git status -u` show? Also have you tried removing any untracked files and or doing this on a completely new clone? – X-Istence Jun 24 '11 at 06:33
  • @Dan: that's not convincing. You'd have to try _without_ the submodules to get any kind of definitive result. Oh, and file a bug if the submodules prevent the filter-branch :) – sehe Jun 24 '11 at 06:47
  • 3
    The command you pasted does not give the submodule status, but the same supermodule status several times. Please check the exit status of the following commands: "git diff-files --ignore-submodules --quiet", "git diff-index --cached --quiet HEAD --" – drizzd Jun 24 '11 at 07:49
  • @drizzd oops!! updating with the correct output. – Dan Loewenherz Jun 24 '11 at 17:33
  • @X-Istence `git status -u` shows the same output. – Dan Loewenherz Jun 24 '11 at 17:38
  • @drizzd Just updated with the exit statuses you requested. – Dan Loewenherz Jun 24 '11 at 17:42
  • Ok, then the output of "git diff-files --ignore-submodules" should be non-empty and that is the reason why filter-branch refuses to run. – drizzd Jun 25 '11 at 09:40

1 Answers1

7

This is mostly a guess, but the error may be caused by a bug that was fixed in git v1.7.7.1 (which was released after your original post). From the commit message:

Filter-branch already requires that we have a clean work tree before starting. However, it failed to refresh the index before checking, which means it could be wrong in the case of stat-dirtiness.

Richard Hansen
  • 51,690
  • 20
  • 90
  • 97
  • Prior to 1.7.7.1 (I have 1.7.0.4) you'll presumably need to force git to refresh the index. I've found that you can do this by running `git stash` and then `git stash apply`, as if you _did_ have a dirty working dir (taken from [this question](http://stackoverflow.com/questions/2030477/git-error-cannot-rewrite-branches-with-a-dirty-working-directory) ). Git will complain, but filter-branch should then work. If anyone has a less hacky method then please mention it here! – J-P May 16 '12 at 11:02
  • 4
    @J-P: The fix linked in my answer causes `git filter-branch` to run the following to refresh the index: `git update-index -q --ignore-submodules --refresh` – Richard Hansen May 16 '12 at 15:02
  • Switching from 1.7.1 to 1.8.3.4 fixed this issue for me. – Dan Bolser Sep 26 '13 at 12:45
  • I had this issue when trying to split a directory into a separate repo via – Chris Conover Dec 06 '14 at 07:21