There is a git repository with multiple branches, each branch contains a different webapp/site (historical reasons). Now branch X contains a webapp that is barely related to the master branch version. Also the git repository contains a lot of deleted data, making it quite big.
I want to clean this mess up by moving the webapp X to a new repository.
But what to do with the history?
I could just push the branch X to the master of a new repository, but this way I wouldn't get rid of the garbage in the history.
I could just copy the latest state of the app to the new repository, but I wanted to keep the newer parts of the history.
First I tried the way everybody suggests. Use git rebase -i to squash some commits. Sadly it doesn't worked out well, I got tons of merge conflicts of files I don't care of and don't exist in the latest version. I propably could solve all of them one way or the other, but I was too annoyed already.
So why not just create a new root and rebase the branch X onto that?
I created a new root at the desired "cut" commit using: git commit-tree <hash of cut>
This looked promising in the beginning, but failed with merge conflicts again.
Then I got a hint to look at git-filter-branch,
--parent-filter does just exactly what I want.
It's able to just replace the old parent of the "cut" commit with the new root/init commit.
For this to work we need a new root like in the upper paragraph, create it with git commit-tree <hash of cut>
Then rewrite history: git filter-branch --parent-filter "sed 's/<hash of parent of "cut">/<hash of new init commit>/'"
Now just push it to a new repository:
git remote add new_repo <git url>
git push -u new_repo branchX:master