How to merge two or more repos into a new one without losing the history of commits

Thiago Marinho

Thiago Marinho

June 1, 2022

Fell free to read it on Dev.To

Storytelling

I was working on four different repositories projects: frontend, sdk, smart contract, indexer.

But I was spending a bunch of time because the contract generates new types during the build and deployment using typechain lib.

I needed to replace all types in the SDK and indexer project, and we realized that the frontend app will need these types as well.

This work is manually copy/paste, adapt the code with the changes, commit, and push when it happens.

So, I decided to give a try Monorepo with TurboRepo.

My idea was to merge all repos without losing the history of commits on them.

For this, with a help of my friend @rjborba we did:

  1. created a new repo on GitHub: project using TurboRepo and their structure(apps, packages).
  2. cloned each repo (frontend, sdk, smart contract, indexer) in another each folder (frontend2, sdk2, smart-contract2, indexer2).
  3. removed the origin from each repo and added the origin from project.
  4. moved the files and folders to another folder: sample: frontend2 now is frontend2/apps/ keeping only the .git folder in the root folder. sdk2 now is packages/sdk.
  5. committed the changes in each folder, and git push --all and git pull origin main --allow-unrelated-histories to merge and resolve conflicts.

This way I could have my Monorepo with all projects related to the history of commits in chronological order.

Technical Way

talk is cheap to show me the commands:

  1. npx create-turbo@latest project
~/Developer/project (main) » tree -L 3 --gitignore tgmarinho@Thiagos-MacBook-Pro
.
├── README.md
├── apps
│ ├── docs
│ │ ├── README.md
│ │ ├── next-env.d.ts
│ │ ├── next.config.js
│ │ ├── node_modules
│ │ ├── package.json
│ │ ├── pages
│ │ └── tsconfig.json
│ └── web
│ ├── README.md
│ ├── next-env.d.ts
│ ├── next.config.js
│ ├── node_modules
│ ├── package.json
│ ├── pages
│ └── tsconfig.json
├── package.json
├── packages
│ ├── eslint-config-acme
│ │ ├── index.js
│ │ ├── node_modules
│ │ └── package.json
│ ├── tsconfig
│ │ ├── README.md
│ │ ├── base.json
│ │ ├── nextjs.json
│ │ ├── package.json
│ │ └── react-library.json
│ └── ui
│ ├── Button.tsx
│ ├── index.tsx
│ ├── node_modules
│ ├── package.json
│ └── tsconfig.json
├── turbo.json
└── yarn.lock

Then host it to the GitHub and get the origin address: git@github.com:myaccount/project.git

Clone the project frontend:

git clone git@github.com:myaccount/frontend.git frontend2
cd frontend2 && mkdir -p apps/frontend
mv $(ls -la) apps/frontend
mv apps/frontend/.git .
git remote remove origin
git remote add origin git@github.com:myaccount/project.git
git add . && git commit -m "send the frontend to monorepo"
git fetch -a
git pull origin main --allow-unrelated-histories
git push --all

Repeat the process to other repo - SDK: Clone the project sdk:

git clone git@github.com:myaccount/sdk.git sdk
cd sdk && mkdir -p packages/sdk
mv $(ls -la) packages/sdk
mv packages/sdk/.git .
git remote remove origin
git remote add origin git@github.com:myaccount/project.git
git add . && git commit -m "send the sdk to monorepo"
git fetch -a
git pull origin main --allow-unrelated-histories
git push --all

Repeat the process to other repo - INDEXER: Clone the project indexer:

git clone git@github.com:myaccount/indexer.git indexer
cd indexer && mkdir -p packages/indexer
mv $(ls -la) packages/indexer
mv packages/indexer/.git .
git remote remove origin
git remote add origin git@github.com:myaccount/project.git
git add . && git commit -m "send the indexer to monorepo"
git fetch -a
git pull origin main --allow-unrelated-histories
git push --all

Finish ✌🏻

Ref: gist x-yuri

__

Thanks for reading 🚀

Pix-me

If you like my content, consider sending me a Pix!

Have feedback?

Was anything confusing, hard to follow, or out of date? Let me know what you think of the article and I'll make sure to update it with your advice.

Email or twitter handle (optional)

Newsletter

If you like my content, consider signing up for my newsletter. You'll receive updates on new posts. Stay tunned!