###Moving one repo into a subdirectory of the other
Preserves notes and sets commit details to author details
in newrepo
git filter-branch --index-filter \
'git ls-files -s | \
sed "s-\t-&'"[[new subdir]]"'/-" | \
GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && \
mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE
' --commit-filter 'export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export NEW_COMMIT=$(git commit-tree "$@"); git notes copy $GIT_COMMIT $NEW_COMMIT > /dev/null 2>&1; echo $NEW_COMMIT' repo2
###Preserving Notes
NOTE: there appears to be a patch to allow this to work with cherry-pick, but today (1.8.5) it appears only rebase will work.
This should be done after the initial merge creating the new root commit but before the rebase/cherry-pick script.
git notes add -m "deleteme"
git notes remove
git fetch ../repo1 refs/notes/commits:refs/notes/repo1
git fetch ../repo2 refs/notes/commits:refs/notes/repo2
git notes merge refs/notes/repo1
git notes merge refs/notes/repo2
git config notes.rewriteRef refs/notes/commits
###Using Cherry-Pick
cherry-pick will essentially replay all the diffs in order, creating a new set of commits in the order you want.
mkdir newrepo
cd newrepo
git init
git fetch ../repo1 master:repo1
git fetch ../repo2 master:repo2
git merge [[new root sha]]
(git log --format=format:"%ct %H" repo1 && echo -e "\n" && git log --format=format:"%ct %H" repo2 ) | sort -g | gawk '{print $2}' | tail -n +3 | git cherry-pick --stdin
###Using Rebase
(git log --format=format:"%ct %H" repo1 && echo -e "\n" && git log --format=format:"%ct %H" repo2 ) | sort -g | gawk '{print $2}' | tail -n +3 | while read line; do git checkout $line -b $line-branch; git rebase master; git checkout master; git merge $line-branch; git branch -D $line-branch; done;
###Reset committer data
This will reset committer and commit date to the original author and author date, while preserving notes:
git filter-branch --commit-filter 'export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export NEW_COMMIT=$(git commit-tree "$@"); git notes copy $GIT_COMMIT $NEW_COMMIT > /dev/null 2>&1; echo $NEW_COMMIT'
I have a problem using these scripts. It gets stuck on merge commits.