Created
June 14, 2023 14:21
-
-
Save warting/fc5dca84e5af8419e66eefc5c249c566 to your computer and use it in GitHub Desktop.
Script to automate the process of absorbing a standalone Git repository into a monorepo while preserving history, and handling submodules if they exist.
This file contains hidden or 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
#!/usr/bin/env bash | |
# This script is used to absorb one git repository into another, making the absorbed | |
# repository a subdirectory within a monorepo. It allows for easy merging of multiple | |
# repositories into a monolithic structure (monorepo) while preserving each repository's | |
# git history. This is useful when you want to consolidate your repositories into a single | |
# repository for easier management and tracking. | |
# | |
# The script works as follows: | |
# 1. It clones the repositories to be merged into temporary directories. | |
# 2. Prepares the repository to be absorbed by moving its content into a subdirectory. | |
# 3. Removes unnecessary git files that may conflict with the target monorepo. | |
# 4. Moves to the monorepo, and if the path where the repository is to be absorbed already exists, it is removed. | |
# 5. Adds the old repository as a remote to the monorepo. | |
# 6. Merges the repository to be absorbed into the monorepo. | |
# 7. Pushes the changes to the monorepo. | |
# 8. Cleans up the temporary directories used during the process. | |
# | |
# Usage: | |
# ./merge_into_monorepo.sh <repository_to_absorb_from> <repository_to_absorb_into> <path_in_monorepo> | |
# | |
# Example: | |
# ./merge_into_monorepo.sh https://github.com/old-org/old-repo.git https://github.com/new-org/monorepo.git old-repo | |
# Define the input variables. | |
REPOSITORY_TO_ABSORB_FROM=$1 | |
REPOSITORY_TO_ABSORB_INTO=$2 | |
PATH_IN_MONOREPOSITORY=$3 | |
# Temporary branch name and directory. | |
TEMPORARY_BRANCH_NAME=prepare_monorepo | |
TEMPORARY_DIR=temp_dir | |
# Function to clean up the temporary directory. | |
clean_up() { | |
echo "Cleaning up temporary directory..." | |
rm -Rf $TEMPORARY_DIR | |
} | |
# Check if temporary directory exists, if so, delete it. | |
if [ -d "$TEMPORARY_DIR" ] | |
then | |
echo "Temp dir already exists, deleting it.." | |
clean_up | |
fi | |
# Create the necessary directories. | |
mkdir -p "$TEMPORARY_DIR/oldRepo" | |
mkdir -p "$TEMPORARY_DIR/monoRepo" | |
# Clone the repositories into temporary directories. | |
git clone $REPOSITORY_TO_ABSORB_FROM $TEMPORARY_DIR/oldRepo | |
git clone $REPOSITORY_TO_ABSORB_INTO $TEMPORARY_DIR/monoRepo | |
# Switch to the old repository directory and prepare it for merging. | |
cd $TEMPORARY_DIR/oldRepo | |
git checkout -b "$TEMPORARY_BRANCH_NAME" | |
mkdir -p $PATH_IN_MONOREPOSITORY | |
# Enable extended globbing for moving everything except for the monorepo path. | |
shopt -s extglob | |
shopt -s dotglob | |
git mv -k !($PATH_IN_MONOREPOSITORY) $PATH_IN_MONOREPOSITORY | |
# Remove unneeded files. | |
git rm -f --ignore-unmatch .gitattributes | |
git rm -f --ignore-unmatch .editorconfig | |
git commit -m "Preparing $PATH_IN_MONOREPOSITORY for monorepo $TEMPORARY_DIR" | |
# Switch to the monorepo and prepare it for merging. | |
cd ../monoRepo/ | |
git checkout -b $TEMPORARY_BRANCH_NAME | |
# Check if the submodule exists, if so, delete it. | |
if [ -d "$PATH_IN_MONOREPOSITORY" ] | |
then | |
git rm -f $PATH_IN_MONOREPOSITORY | |
git commit -m "Preparing $PATH_IN_MONOREPOSITORY for monorepo $TEMPORARY_DIR, removing old git submodule" | |
fi | |
# Add the old repository as a remote and merge it. | |
OLD_REPO_NAME=$(basename $REPOSITORY_TO_ABSORB_FROM) | |
git remote add -f $OLD_REPO_NAME ../oldRepo | |
git merge -m "Preparing $PATH_IN_MONOREPOSITORY for monorepo $TEMPORARY_DIR, Integrating $OLD_REPO_NAME" $OLD_REPO_NAME/$TEMPORARY_BRANCH_NAME --allow-unrelated-histories | |
# Push the changes to the monorepo. | |
git push -f --set-upstream origin $TEMPORARY_BRANCH_NAME | |
# Clean up temporary directory. | |
clean_up | |
# Exit the script. | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment