Let's say I have a repo that includes this directory structure:
repo/ blog/ _posts/ some-post.html another-file.txt I want to move _posts to the top level of the repo, so the structure will look like this:
repo/ _posts/ some-post.html another-file.txt This is simple enough with git mv, but I want to make the history look as though _posts always existed at the root of the repo, and I want to be able to get the entire history of some-post.html via git log -- _posts/some-post.html. I imagine I can use some magic with git filter-branch to accomplish this, but I haven't figured out exactly how to do that. Any ideas?
You can use the subdirectory filter to achieve this
$ git filter-branch --subdirectory-filter blog/ -- --all EDIT 1: If you don't want to effectively make _posts the root, use a tree-filter instead:
$ git filter-branch --tree-filter 'mv blog/_posts .' HEAD EDIT 2: If blog/_posts did not exist in some of the commits, the above will fail. Use this instead:
$ git filter-branch --tree-filter 'test -d blog/_posts && mv blog/_posts . || echo "Nothing to do"' HEAD
While Ramkumar's answer is very helpful and worthwile, it will not work in many situations. For example, when you want to move a directory with other subdirectories to a new location.
For this, the man page contains the perfect command:
git filter-branch --index-filter \ 'git ls-files -s | sed "s-\t\"*-&NEWSUBDIR/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ git update-index --index-info && mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD Just replace NEWSUBDIR with your desired new directory. You can also use nested dirs like dir1/dir2/dir3/-"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With