Let\'s say you have the repository:
myCode/megaProject/moduleA
myCode/megaProject/moduleB
Over time (months), you re-organise the project.
I'm aware of no simple way to do this, but it can be done.
The problem with filter-branch is that it works by
applying custom filters on each revision
If you can create a filter which won't delete your files they will be tracked between directories. Of course this is likely to be non-trivial for any repository which isn't trivial.
To start: Let's assume it is a trivial repository. You have never renamed a file, and you have never had files in two modules with the same name. All you need to do is get a list of the files in your module find megaProject/moduleA -type f -printf "%f\n" > preserve and then run your filter using those filenames, and your directory:
preserve.sh
cmd="find . -type f ! -name d1"
while read f; do
cmd="$cmd ! -name $f"
done < /path/to/myCode/preserve
for i in $($cmd)
do
rm $i
done
git filter-branch --prune-empty --tree-filter '/path/to/myCode/preserve.sh' HEAD
Of course it's renames that make this difficult. One of the nice things that git filter-branch does is gives you the $GIT_COMMIT environment variable. You can then get fancy and use things like:
for f in megaProject/moduleA
do
git log --pretty=format:'%H' --name-only --follow -- $f | awk '{ if($0 != ""){ printf $0 ":"; next; } print; }'
done > preserve
to build a filename history, with commits, that could be used in place of the simple preserve file in the trivial example, but the onus is going to be on you to keep track of what files should be present at each commit. This actually shouldn't be too hard to code out, but I haven't seen anybody who's done it yet.