Created
October 5, 2023 09:18
-
-
Save serguk89/0087f1d7337555c3db383aa5edd268ab to your computer and use it in GitHub Desktop.
Creates a new monorepofrom multiple monolit repositories
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/sh | |
# Creates a new monorepo by fusing multiple repositories | |
# Child repositories that are going to be fused | |
CHILDREN="wp/theme/master plugins/gutenblocks/master wp/theme-core/master" | |
# 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 "Initial" | |
git rm .placeholder | |
git commit -m "Remove placeholder file" | |
# Add remotes for all children | |
for repo in $CHILDREN; do | |
repo=$(echo $repo | cut --delimiter / --fields=1,2,3) | |
remote=${repo##*/} | |
git remote add "${remote}" "git@gitlab.co:user/${repo}.git" | |
done | |
# Fetch all child repositories | |
git fetch --all | |
# Checkout all the master branches of the child repositories | |
for repo in $CHILDREN; do | |
branch=$(echo $repo|rev| cut -f 1 -d "/" | rev) | |
remote=$(echo $repo|rev| cut -f 2 -d "/" | rev) | |
git checkout -f -b "${remote}_master" "${remote}/${branch}" | |
# Rewrite history to move all repo files into a subdirectory | |
export SUBDIRECTORY="${remote}" | |
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 | |
remote=$(echo $repo | rev | cut -f 2 -d "/" | rev) | |
git merge --no-commit --allow-unrelated-histories "${remote}_master" | |
git commit -a -m "Merge ${remote} in subdir" | |
done | |
# remove all child repo branches and remotes | |
for repo in $CHILDREN; do | |
remote=$(echo $repo | rev | cut -f 2 -d "/" | rev) | |
git branch -D "${remote}_master" | |
git remote remove "${remote}" | |
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