In this article, we will go over how to merge multiple git repositories into one, preserving commit history. The key is using `--allow-unrelated-histories` flag of `git merge` command and adding the source repository as a remote to the destination repository.
We will merge `service` repository into `monorepo` repository because moving to a monorepository is a common reason to merge Git repositories together.
Let's say you have `monorepository` and `service` folders next to each other on your computer. Then you need to run the following bash script:
```bash
# Enter service directory
cd service
# Pull latest changes
# Note: I recomment archiving source repository before going further so that you don't loose changes committed by other developers at the same time
git checkout main
git pull
# Make a branch to avoid changing main branch
# This allows you to see what exactly you have merged and make sure that there are no new changes after merge
git checkout -b moving-to-monorepo
# Move all files to a subdirectory called service to avoid conflicts during merge
mkdir <service>
shopt -s extglob dotglob
mv !(.git) <service>
# Commit and push moved files
git add .
git commit -m “Moving to monorepo”
git push --set-upstream origin moving-to-monorepo
# Go to monorepository to pull files from service
cd ../monorepo
# Add remote repository to pull changes from
git remote add -f <service> https://github.com/<organization>/<service>.git
# Merge files from service to monorepository
# --allow-unrelated-histories flag allows to merge branches that do not have common commits.
# This is typical for branches from different repositories
git merge --allow-unrelated-histories <service>/moving-to-monorepo
# Push files merged from service
git push
# Cleanup
git remote remove <service>
cd ..
```
#!/bin/bash
# Enter service directory
cd service
# Pull latest changes
# Note: I recomment archiving source repository before going further so that you don't loose changes committed by other developers at the same time
git checkout main
git pull
# Make a branch to avoid changing main branch
# This allows you to see what exactly you have merged and make sure that there are no new changes after merge
git checkout -b moving-to-monorepo
# Move all files to a subdirectory called service to avoid conflicts during merge
mkdir <service>
shopt -s extglob dotglob
mv !(.git) <service>
# Commit and push moved files
git add .
git commit -m “Moving to monorepo”
git push --set-upstream origin moving-to-monorepo
# Go to monorepository to pull files from service
cd ../monorepo
# Add remote repository to pull changes from
git remote add -f <service> https://github.com/<organization>/<service>.git
# Merge files from service to monorepository
# --allow-unrelated-histories flag allows to merge branches that do not have common commits.
# This is typical for branches from different repositories
git merge --allow-unrelated-histories <service>/moving-to-monorepo
# Push files merged from service
git push
# Cleanup
git remote remove <service>
cd ..
```