Skip to content

Instantly share code, notes, and snippets.

@zenlor
Last active December 27, 2018 14:32
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 zenlor/1e99fc643f67da96c5d7488c13cc92bf to your computer and use it in GitHub Desktop.
Save zenlor/1e99fc643f67da96c5d7488c13cc92bf to your computer and use it in GitHub Desktop.
create a monorepo from a list of repos http://sevangelatos.com/monorepo/
#!/bin/sh
# Creates a new monorepo by fusing multiple repositories
# Child repositories that are going to be fused
CHILDREN="bridge-apn bridge-broker-http-gateway bridge-node-gcm bridge-log-elasticsearch bridge-secretary-client bridge-worker-client bridge-legacy-crypto bridge-config hive-worker bridge-support bridge-start bridge-secretary bridge-net bridge-log-rollbar bridge-log bridge-id bridge-hive bridge-broker bridge-bakward"
CHILDREN_FOLDER="packages"
# Name of the created monorepo
MONOREPO="monorepo"
# Exit in case of any error
set -e
# Be verbose
set -x
# create the monorepo
mkdir $MONOREPO
cd $MONOREPO
git init
# Create a first commit. A first commit is needed in order to be able to merge into master afterwards
echo "*~" >.placeholder
git add .placeholder
git commit -m "First commit"
git rm .placeholder
git commit -m "Remove placeholder file"
# Add remotes for all children
for repo in $CHILDREN; do
git remote add "$repo" "git@git.mobilebridge.io:mobilebridge-hive/${repo}.git"
done
# Fetch all child repositories
git fetch --all
# Checkout all the master branches of the child repositories
for repo in $CHILDREN; do
repo_dir="${repo//[^a-zA-Z0-9]/_}"
git checkout -f -b "${repo}_master" "${repo}/master"
# Rewrite history to move all repo files into a subdirectory
export SUBDIRECTORY="${CHILDREN_FOLDER}/${repo_dir}"
git filter-branch -f --index-filter 'git ls-files -s | sed "s-\t-&${SUBDIRECTORY}/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && if [ -f "$GIT_INDEX_FILE.new" ]; then mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"; fi' --
done
# Switch back to our master branch
git checkout -f master
# Merge all the repositories in our master branch.
for repo in $CHILDREN; do
git merge --no-commit --allow-unrelated-histories "${repo}_master"
git commit -a -m "Merge ${repo} in subdir"
done
# remove all child repo branches and remotes
for repo in $CHILDREN; do
git branch -D "${repo}_master"
git remote remove "${repo}"
done
# prune all history and do an aggressive gc
git reflog expire --expire=now --all && git gc --prune=now --aggressive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment