DEV Community

Cover image for Merge Multiple Git Repositories without Breaking File History
Akshay Kaushik
Akshay Kaushik

Posted on • Updated on • Originally published at blog.akshaykaushik.eu.org

Merge Multiple Git Repositories without Breaking File History

Merging separate Git repositories into a single combined repository is a common need for developers. For example, you may have a frontend and backend repository that are part of the same overall application, but kept in separate repositories during initial development.

Bringing these components together into a single repository makes it easier to view, manage, and work with the full codebase as a unified project. However, preserving the commit history and being able to trace code changes back to their original repository is also important.

The Problem

So, your current setup looks like this:

project structure

You've got separate Git repositories for frontend and backend, and now you want to make the Parent Folder the main repository housing both, all while preserving commit histories. Sounds like a plan! Let's dive into the solution.

Steps to Solve

1. Create a New Repository

First things first, let's create a new repository on GitHub (or your preferred hosting service). This will be the main repository for your combined project.

git clone https://github.com/your-username/combined-repo.git
cd combined-repo

# OR In case of offline

git init combined-repo
git remote add origin https://github.com/your-username/combined-repo
Enter fullscreen mode Exit fullscreen mode

Replace "your-username" and "combined-repo" with your GitHub username and the new repository's name. This allows you to pull commits from the source repositories using the remote names as references.

2. Add Remotes

Now, add remotes for both "frontend" and "backend" repositories:

git remote add frontend /path/to/frontend
git remote add backend /path/to/backend
Enter fullscreen mode Exit fullscreen mode

Replace /path/to/frontend and /path/to/backend with the actual paths to your frontend and backend repositories, whether they are offline or online.

3. Fetch Commits

Fetch the commits from both repositories:

git fetch frontend
git fetch backend
Enter fullscreen mode Exit fullscreen mode

This pulls the branches and associated commits into your local repository without actually merging anything.

With the commits fetched, you can start merging each repository one at a time.

4. Merge Frontend

Create and switch to a new branch for frontend:

First, make a branch for each incoming repository:

git checkout -b frontend-merge frontend/master
Enter fullscreen mode Exit fullscreen mode

Now merge the branch while allowing unrelated histories between the new repo and old repos:

git merge --allow-unrelated-histories FETCH_HEAD
Enter fullscreen mode Exit fullscreen mode

The --allow-unrelated-histories flag is crucial to allow merging branches that do not share a common starting commit.

Next, create directories for the frontend, and move the files accordingly from the merged branches:

mkdir frontend
git ls-tree -z --name-only HEAD | xargs -0 -I {} git mv {} frontend/
git commit -m "Merge frontend repository into combined-repo"
Enter fullscreen mode Exit fullscreen mode

Commit to each step. Keeping the code organized this way keeps things isolated during additional merging later.

5. Repeat for Backend

Repeat the process for the backend repository:

git checkout -b backend-merge backend/master
git merge --allow-unrelated-histories FETCH_HEAD
mkdir backend
git ls-tree -z --name-only HEAD | xargs -0 -I {} git mv {} backend/
git commit -m "Merge backend repository into combined-repo"
Enter fullscreen mode Exit fullscreen mode

6. Merge and Resolve Conflicts

Now, let's bring it all together:

git checkout master
git merge frontend-merge
git merge backend-merge
Enter fullscreen mode Exit fullscreen mode

As files are brought together from different repositories, merge conflicts can happen just like during normal development.

Code changes from different sources may modify the same parts of a file in incompatible ways. When this happens, Git stops the merge and flags the conflict.

If you encounter a "refusing to merge unrelated histories" error, use the following:

git merge --allow-unrelated-histories frontend-merge
git merge --allow-unrelated-histories backend-merge
Enter fullscreen mode Exit fullscreen mode

Resolve any merge conflicts if they occur. Commit the changes:

git commit -m "Merge frontend-merge and backend-merge into master"
git push origin master
Enter fullscreen mode Exit fullscreen mode

And there you have it! Your GitHub repository's master branch should now contain the combined content and commit history from both frontend and backend repositories.

I require immediate work. Entry-level is also acceptable.

Top comments (0)