is it possible with Git's tools to move files into a new folder while modifying its full history, as if the files had been there from their first add?

I came up on this after merging some repos together: I moved the files from several repos to distinct folders inside one "super" repo, however the merged history behaves very bad with git rebase and git svn tools as totally different files may collide at their old locations of course.

2 Answers
2

In order to modify your full history, you will need to rewrite every commit. git filter-branch is the best way to do this. In particular, for your case, git filter-branch --tree-filter some-command will check out every version of your history, run your command in which you can modify the working tree as you see fit (such as moving the directories in question), and then rewrite that commit to contain the new contents of the tree.

Ok cool. So basically, git filter-branch checks out every revision and checks it in again, replacing the old one? Sounds wild, I thought I would just rewrite the stored pathes.. Anyway, I give it a try!
–
dronusApr 14 '11 at 20:16

@dronus Actually, for your case, in which you're just moving things around, you should be able to do a git filter-branch --index-filter, which is like --tree-filter but doesn't actually check the files out, it requires you to manipulate everything in the index directly. It will be faster to run than --tree-filter, but will be a little harder to write since you'll need to be modifying the index directly instead of just moving files. There's an example towards the end of the filter-branch documentation that demonstrates how to do it.
–
Brian CampbellApr 14 '11 at 20:29

I don't know why, but --index-filter doesn't iterate all revisions in my branch. Maybe has something to do with merges enroute etc. But --tree-filter worked very well; see below.
–
dronusApr 15 '11 at 0:18

@dronus Yeah, as I said, it's a little harder with --index-filter, because it doesn't actually check out the revisions. You need to do all of the work via the index; there's an example in the documentation I linked to. Anyhow, the only reason you'd want to do that is because it's faster; if --tree-filter is fast enough for you, it's perfectly fine, and much simpler to user.
–
Brian CampbellApr 15 '11 at 2:03