Skip to content

Instantly share code, notes, and snippets.

@jtsternberg
Last active January 31, 2023 21:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jtsternberg/dcae912d2567f2691b34408a92f034b2 to your computer and use it in GitHub Desktop.
Save jtsternberg/dcae912d2567f2691b34408a92f034b2 to your computer and use it in GitHub Desktop.
Merge Git Repos (Child into Parent)
#!/usr/bin/env bash
# =============================================================================
# Merges CHILD repo into PARENT.
# By Justin Sternberg <me@jtsternberg.com>
#
# Version 0.1.0
#
# Uses: https://github.com/newren/git-filter-repo
# References:
# * https://peterbabic.dev/blog/merge-repos-using-git-filter-repo/
# * https://alexharv074.github.io/puppet/2017/10/04/merge-a-git-repository-and-its-history-into-a-subdirectory-of-a-second-git-repository.html
# =============================================================================
PARENT_REMOTE="${1}"
CHILD_REMOTE="${2}"
CHILD_DESTINATION_DIR="${3}"
PARENT_REPO_NAME=`echo "$PARENT_REMOTE" | cut -d "/" -f 2`
PARENT_PATH=${PARENT_REPO_NAME%".git"}
CHILD_REPO_NAME=`echo "$CHILD_REMOTE" | cut -d "/" -f 2`
CHILD_PATH=${CHILD_REPO_NAME%".git"}
echo "PARENT_REMOTE = $PARENT_REMOTE"
echo "CHILD_REMOTE = $CHILD_REMOTE"
echo "CHILD_DESTINATION_DIR = $CHILD_DESTINATION_DIR"
echo "PARENT_REPO_NAME = $PARENT_REPO_NAME"
echo "PARENT_PATH = $PARENT_PATH"
echo "CHILD_REPO_NAME = $CHILD_REPO_NAME"
echo "CHILD_PATH = $CHILD_PATH"
echo ""
# Clone PARENT repo
git clone "$PARENT_REMOTE"
# Clone CHILD repo
git clone "$CHILD_REMOTE"
# CD into CHILD repo:
cd "$CHILD_PATH"
# Move all items in repo to a subdirectory, and rewrite history.
# (where it will live in the PARENT repo)
# Uses: https://github.com/newren/git-filter-repo
git-filter-repo --to-subdirectory-filter "$CHILD_DESTINATION_DIR"
# CD into PARENT repo:
cd "../$PARENT_PATH"
# Add the CHILD repo as a remote, "childrepo"
git remote add -f childrepo "../$CHILD_PATH"
# Ensure the tags are fetched as well.
git fetch childrepo --tags
# Merge from CHILD into PARENT!
git merge --allow-unrelated-histories childrepo/master
wait
# The CHILD remote is no longer needed. We're done!
git remote remove childrepo
echo ''
echo 'ALL DONE! To view changes:'
echo "$ cd $PARENT_PATH && ls -la"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment