Last Updated: February 25, 2016
·
603
· stucki

Relocate the entire history of a Git repository

Goal

  • Move all contents of a Git repository into a new subdirectory
  • Apply the change on all commits in the entire history

Notes

  • You can also just move the contents of the last commit in your repository. Git is able to follow moved contents in the history using git log --follow.
  • This code moves the contents of every commit, so --follow is not needed anymore.
  • However, this means that every commit will be changed. Old SHAs are no longer valid. Every clone of the repository needs to be cloned from start again.

How it works

  • For every commit, create a new directory "html"
  • Move everything into the new directory except ".git*" (includes ".gitignore") and "html" (otherwise a simple mv . html would do)

Code

git filter-branch --tree-filter 'mkdir html && find . -mindepth 1 -maxdepth 1 ! -name ".git*" ! -name "html" -exec mv {} html/ \;' HEAD

2 Responses
Add your response

Small update: I removed the end-of-line marker on of the greps, to make sure that ".git" as well as ".gitignore" are not moved.

over 1 year ago ·

Another update: Don't read files from a subshell. Instead, use "find ... -exec" (solves issues with files that contain whitespaces).

Old version:

git filter-branch --tree-filter 'mkdir html && mv $(find . -mindepth 1 -maxdepth 1 | grep -v "^./.git" | grep -v "^./html$") html/' HEAD
over 1 year ago ·