Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

filter-branch --index-filter always failing with "fatal: bad source"

Tags:

git

So, I am trying to rename a folder in my repository using git filter-branch --index-filter, but I always end up with a "fatal: bad source" error.

The problem is easily demonstrated on a test repository using a file instead of a folder.

Preparation:

$ git init
$ echo whatever >> my_file.txt
$ git add .
$ git commit -m "initial"
$ echo whatever2 >> my_file2.txt
$ git add .
$ git commit -m "second"

Now, I am trying to change my_file.txt to your_file.txt:

$ git filter-branch --index-filter 'git mv my_file.txt your_file.txt' HEAD

But it doesn't work:

Rewrite dac9a2023bdf9dd0159fab46213d9e1342ae9f75 (1/2)fatal: bad source, source=my_file.txt, destination=your_file.txt
index filter failed: git mv my_file.txt your_file.txt

However, the very same git mv command executed normally works without problems:

$ git mv my_file.txt your_file.txt
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       renamed:    my_file.txt -> your_file.txt
#

I am sure, I am missing something essential here - but what is it?

like image 928
Daniel Hilgarth Avatar asked Feb 22 '13 16:02

Daniel Hilgarth


2 Answers

As twalberg points out in his answer, git mv doesn't just access the index, it also access the disk. That's probably the reason why it doesn't work.

I didn't want to use the slow --tree-filter so I tried to change the sample from the git filter-branch man page that shows how to move the complete repository into a subfolder.

The result is this - and it actually works ;-)

git filter-branch --index-filter '
git ls-files -s | \
sed "s-\(\t\"*\)my_file.txt-\1your_file.txt-" | \
GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && \
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
' HEAD
like image 110
Daniel Hilgarth Avatar answered Oct 20 '22 15:10

Daniel Hilgarth


git mv is not really appropriate in an --index-filter clause. Since --index-filter does not check out each commit it's rewriting into the working directory, and git mv operates on the working directory (in addition to the index), using git mv in --index-filter will not accomplish what is expected. Use a --tree-filter instead. (It might be possible to accomplish this still with --index-filter by using git update-index instead, but I don't have that available off the top of my head).

like image 22
twalberg Avatar answered Oct 20 '22 16:10

twalberg