How to Merge Multiple Git Repositories Preserving Commit History

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
#!/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 ..
```