Created
February 12, 2018 09:13
-
-
Save borekb/b4aa4f97ccd826dce1d4793a0d54fd26 to your computer and use it in GitHub Desktop.
Script to merge repositories. Updated version of the original Gist https://gist.github.com/borekb/eccc0af01f3b2c1d47bb7955a08bc214
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Repo merge script used to merge OLD_REPO into TARGET_REPO. | |
# Based on https://gofore.com/merge-multiple-git-repositories-one-retaining-history/ | |
# How to use: | |
# | |
# 1. Create a temp directory | |
# 2. Checkout TARGET_REPO and OLD_REPO there | |
# 3. Put this script into the temp directory, side by side with the repos. | |
# 4. Inspect the script so that you know what you're running, and update if necessary. | |
# 5. Make sure that the OLD_REPO only has the `master` branch and all others have been merged / deleted. | |
# 6. Run it (usually with RUN_PUSH disabled) | |
# 7. Inspect the results, push to GitHub if all was OK | |
#--------------------------------- | |
# Variables | |
#--------------------------------- | |
GITHUB_OWNER='versionpress' | |
TARGET_REPO='versionpress' # path relative to this script | |
OLD_REPO='docs' # path relative to this script | |
OLD_REPO_ESCAPED='docs' # path relative to this script | |
NEW_PATH_ESCAPED='docs' # a subfolder in the target repo; escepa `-` as `\-` | |
BRANCH_TO_USE='123-merge-repo' | |
TARGET_REPO_ISSUE='123' | |
# flags that enable / disable certain sections of this script | |
RUN_OLD_REPO_PROCESSING=true | |
RUN_REPO_MERGE=true | |
RUN_PUSH=false # inspect everything before running this! or perhaps do it manually | |
#--------------------------------- | |
# Prepare the child repo | |
#--------------------------------- | |
if [ "$RUN_OLD_REPO_PROCESSING" = true ] | |
then | |
cd "$OLD_REPO" || exit | |
# Create local branches | |
remote=origin ; for brname in $(git branch -r | grep $remote | grep -v master | grep -v HEAD | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'); do git branch "$brname" $remote/"$brname"; done | |
# Remove remote branches (`/remotes/origin/*` refs) | |
git remote remove origin | |
# Remove all tags | |
git tag | xargs git tag -d | |
# Filter out `exampledir` | |
#git filter-branch --tag-name-filter cat --index-filter 'git rm -r --cached --ignore-unmatch exampledir' --prune-empty -f -- --all | |
# Filter paths so it looks like the commits always went to a path in the target repo. | |
git filter-branch --index-filter \ | |
'git ls-files -s | sed "s-\t\"*-&'$NEW_PATH_ESCAPED'/-" | | |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ | |
git update-index --index-info && | |
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE" | |
' --tag-name-filter cat -f -- --all | |
# Replace `#123` with `owner/oldrepo#123` | |
# Test with: echo '#1 [#123] (#123) issue #2 other/repo#12 [other/repo#12]' | sed -r 's/(\W|^)#([0-9]+)/\1owner\/oldrepo#\2/g' | |
git filter-branch --tag-name-filter cat --msg-filter "sed -r 's/(\\W|^)#([0-9]+)/\\1$GITHUB_OWNER\\/$OLD_REPO_ESCAPED#\\2/g'" -f -- --all | |
# Clean up the `original` refs that Git keeps as a backup | |
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d | |
cd .. || exit | |
fi | |
#--------------------------------- | |
# Merge the repos | |
#--------------------------------- | |
if [ "$RUN_REPO_MERGE" = true ] | |
then | |
cd $TARGET_REPO || exit | |
git checkout -b $BRANCH_TO_USE | |
git remote add -f $OLD_REPO ../$OLD_REPO | |
git merge --allow-unrelated-histories -m "[#$TARGET_REPO_ISSUE] Merge $OLD_REPO repo" $OLD_REPO/master | |
git remote rm $OLD_REPO | |
fi | |
#--------------------------------- | |
# Push | |
#--------------------------------- | |
# After manually inspecting: | |
if [ "$RUN_PUSH" = true ] | |
then | |
git push origin $BRANCH_TO_USE | |
fi | |
cd .. || exit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment