Merge Multiple Git Repositories without Breaking File History
Tags: git, webdev, softwaredevelopment, github
Published: 2023-12-12 09:12:52

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n3qshua2rthbq64rkgee.png)

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.

```bash
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
```

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:

```bash
git remote add frontend /path/to/frontend
git remote add backend /path/to/backend
```

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:

```bash
git fetch frontend
git fetch backend
```

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:

```bash
git checkout -b frontend-merge frontend/master
```

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

```bash
git merge --allow-unrelated-histories FETCH_HEAD
```

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:

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

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:

```bash
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"
```

### 6\. Merge and Resolve Conflicts

Now, let's bring it all together:

```bash
git checkout master
git merge frontend-merge
git merge backend-merge
```

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:

```bash
git merge --allow-unrelated-histories frontend-merge
git merge --allow-unrelated-histories backend-merge
```

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

```bash
git commit -m "Merge frontend-merge and backend-merge into master"
git push origin master
```

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.](https://www.linkedin.com/in/iamakshaykaushik/)