It turns out that the answer is much simpler if you're simply trying to glue two repositories together and make it look like it was that way all along rather than manage an external dependency. You simply need to add remotes to your old repos, merge them to your new master, move the files and folders to a subdirectory, commit the move, and repeat for all additional repos. Submodules, subtree merges, and fancy rebases are intended to solve a slightly different problem and aren't suitable for what I was trying to do.

Here's an example Powershell script to glue two repositories together:

# Assume the current directory is where we want the new repository to be created
# Create the new repository
git init

# Before we do a merge, we have to have an initial commit, so we'll make a dummy commit
git commit --allow-empty -m "Initial dummy commit"

# Add a remote for and fetch the old repo
# (the '--fetch' (or '-f') option will make git immediately fetch commits to the local repo after adding the remote)
git remote add --fetch old_a <OldA repo URL>

# Merge the files from old_a/master into new/master
git merge old_a/master --allow-unrelated-histories

# Move the old_a repo files and folders into a subdirectory so they don't collide with the other repo coming later
mkdir old_a
dir -exclude old_a | foreach { git mv $_.Name old_a }

# Commit the move
git commit -m "Move old_a files into subdir"

# Do the same thing for old_b
git remote add -f old_b <OldB repo URL>
git merge old_b/master --allow-unrelated-histories
mkdir old_b
dir –exclude old_a,old_b | foreach { git mv $_.Name old_b }
git commit -m "Move old_b files into subdir"

Obviously you could instead merge old_b into old_a (which becomes the new combined repo) if you’d rather do that – modify the script to suit.

If you want to bring over in-progress feature branches as well, use this:

# Bring over a feature branch from one of the old repos
git checkout -b feature-in-progress
git merge -s recursive -Xsubtree=old_a old_a/feature-in-progress

That's the only non-obvious part of the process - that's not a subtree merge, but rather an argument to the normal recursive merge that tells Git that we renamed the target and that helps Git line everything up correctly.

I wrote up a slightly more detailed explanation here.

Answer from Eric Lee on Stack Overflow
Top answer
1 of 10
422

It turns out that the answer is much simpler if you're simply trying to glue two repositories together and make it look like it was that way all along rather than manage an external dependency. You simply need to add remotes to your old repos, merge them to your new master, move the files and folders to a subdirectory, commit the move, and repeat for all additional repos. Submodules, subtree merges, and fancy rebases are intended to solve a slightly different problem and aren't suitable for what I was trying to do.

Here's an example Powershell script to glue two repositories together:

# Assume the current directory is where we want the new repository to be created
# Create the new repository
git init

# Before we do a merge, we have to have an initial commit, so we'll make a dummy commit
git commit --allow-empty -m "Initial dummy commit"

# Add a remote for and fetch the old repo
# (the '--fetch' (or '-f') option will make git immediately fetch commits to the local repo after adding the remote)
git remote add --fetch old_a <OldA repo URL>

# Merge the files from old_a/master into new/master
git merge old_a/master --allow-unrelated-histories

# Move the old_a repo files and folders into a subdirectory so they don't collide with the other repo coming later
mkdir old_a
dir -exclude old_a | foreach { git mv $_.Name old_a }

# Commit the move
git commit -m "Move old_a files into subdir"

# Do the same thing for old_b
git remote add -f old_b <OldB repo URL>
git merge old_b/master --allow-unrelated-histories
mkdir old_b
dir –exclude old_a,old_b | foreach { git mv $_.Name old_b }
git commit -m "Move old_b files into subdir"

Obviously you could instead merge old_b into old_a (which becomes the new combined repo) if you’d rather do that – modify the script to suit.

If you want to bring over in-progress feature branches as well, use this:

# Bring over a feature branch from one of the old repos
git checkout -b feature-in-progress
git merge -s recursive -Xsubtree=old_a old_a/feature-in-progress

That's the only non-obvious part of the process - that's not a subtree merge, but rather an argument to the normal recursive merge that tells Git that we renamed the target and that helps Git line everything up correctly.

I wrote up a slightly more detailed explanation here.

2 of 10
221

Here's a way that doesn't rewrite any history, so all commit IDs will remain valid. The end-result is that the second repo's files will end up in a subdirectory.

  1. Add the second repo as a remote:

    cd firstgitrepo/
    git remote add secondrepo username@servername:andsoon
    
  2. Make sure that you've downloaded all of the secondrepo's commits:

    git fetch secondrepo
    
  3. Create a local branch from the second repo's branch:

    git branch branchfromsecondrepo secondrepo/master
    
  4. Move all its files into a subdirectory:

    git checkout branchfromsecondrepo
    mkdir subdir/
    git ls-tree -z --name-only HEAD | xargs -0 -I {} git mv {} subdir/
    git commit -m "Moved files to subdir/"
    
  5. Merge the second branch into the first repo's master branch:

    git checkout master
    git merge --allow-unrelated-histories branchfromsecondrepo
    

Your repository will have more than one root commit, but that shouldn't pose a problem.

🌐
Gfscott
gfscott.com › blog › merge-git-repos-and-keep-commit-history
How to merge multiple Git repos and keep their commit history / Graham F. Scott
# ./ $ cd everything/ $ git checkout ... monorepo" # switch back to the monorepo folder $ cd ../everything $ git remote add -f youtube ../youtube $ git merge youtube/monorepo-prep --no-commit --allow-unrelated-histories # Inspect that everything worked as expecte...
Discussions

How can you merge two repositories while keeping all commit and contribution history?
Select Topic Area General Body If you have two repositories and you want to unify them into one but don't want to lose your contribution or commit history. More on github.com
🌐 github.com
4
3
How can I combine three repositories without losing history?
git merge --allow-unrelated-histories Source: https://git-scm.com/docs/git-merge More on reddit.com
🌐 r/git
3
19
November 28, 2022
git merge - How to combine two separate unrelated Git repositories into one with single history timeline - Stack Overflow
I have two unrelated (not sharing any ancestor check in) Git repositories, one is a super repository which consists a number of smaller projects (Lets call it repository A). Another one is just a More on stackoverflow.com
🌐 stackoverflow.com
github - How to merge two git repositories without loosing the history for either repositories - Stack Overflow
I required to merge two repositories without loosing the history of either. I searched several forums but none could provide a complete solution. After performing several steps taken from various s... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Mozilla Hacks
hacks.mozilla.org › home › articles › merging two github repositories without losing commit history
Merging two GitHub repositories without losing commit history – Mozilla Hacks - the Web developer blog
August 29, 2022 - # Clone your target repository ...dn/sw-test.git # Merge the merge target and allow unrelated history git merge swtest/gh-pages --allow-unrelated-histories # Add and commit your changes git add ....
🌐
Jeff Kreeftmeijer
jeffkreeftmeijer.com › git-combine
Combine Git repositories with unrelated histories
August 9, 2021 - To combine two separate Git repositories into one, merge while using the --allow-unrelated-histories command line option.
🌐
CodeGenes
codegenes.net › blog › merge-two-git-repos-with-full-history-preserved-grafted-not-rewritten
How to Merge Two Git Repositories with Full History Preserved (No Rewrites) — codegenes.net
By fetching the source repo as a remote, merging with --allow-unrelated-histories, resolving conflicts, and optionally organizing files into a subdirectory, you retain full context of both codebases.
Find elsewhere
🌐
SaintGimp
saintgimp.org › 2013 › 01 › 22 › merging-two-git-repositories-into-one-repository-without-losing-file-history
Merging Two Git Repositories Into One Repository Without Losing File History – SaintGimp
August 5, 2014 - And, as mentionned by @AndreaLigios, git merge old_a/master has to be replaced by: git merge old_a/master --allow-unrelated-histories.
🌐
Reddit
reddit.com › r/git › how can i combine three repositories without losing history?
r/git on Reddit: How can I combine three repositories without losing history?
November 28, 2022 -

Lets say I have projects A, B and C. Each project is currently in its own repository on git, but they are typically updated the same and are versioned the same. I want to combine them into a single repo by grouping B and C under A like so:

A
 \-> B
 \-> C

Can I do so without losing history?

Top answer
1 of 3
18
git merge --allow-unrelated-histories Source: https://git-scm.com/docs/git-merge
2 of 3
11
Create a new repository - its often easier to start out from a new blank spot than trying to merge B into A and then C into AB. Lets call Z. Then you add the remote for A to the Z project, fetch it, and then merge with the --allow-unrelated-histories flag. This will bring in everything. I would suggest moving everything that you brought in to a subdirectory a.dir or similar - just something so that when you then do it for B, you don't have merge conflicts with two projects that happen to have the same files that you need to resolve right there and then. Once you've got B merged into Z, and moved to avoid conflicts, do it again for C. Now that Z contains the histories of all of A, B, and C and each project is in its own directory, you can then go about reconciling all of those directories and projects into one. It is likely easier to do this after all are merged in rather than dealing with merge conflicts. (edit / doing it) I had pre set up a repo A and a repo B with a commit each, and then created a directory Z at the same level as A and B and cd'ed into it. Z % git init Initialized empty Git repository in /private/tmp/git/Z/.git/ Z % git commit --allow-empty -m "Initial empty commit" [main (root-commit) d52bf11] Initial empty commit Z % git remote add a ../A Z % git remote add b ../B Z % git fetch a remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), 202 bytes | 202.00 KiB/s, done. From ../A * [new branch] main -> a/main Z % git fetch b remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), 213 bytes | 106.00 KiB/s, done. From ../B * [new branch] main -> b/main Z % git merge a/main --allow-unrelated-histories -m "Merge A" Merge made by the 'ort' strategy. file.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 file.txt Z % ls file.txt Z % mkdir a.dir Z % git mv file.txt a.dir/. Z % git commit -m "added a.dir; mv file.txt" [main daf86fe] added a.dir; mv file.txt Committer: Shagie 1 file changed, 0 insertions(+), 0 deletions(-) rename file.txt => a.dir/file.txt (100%) Z % git merge b/main --allow-unrelated-histories -m "Merge B" Merge made by the 'ort' strategy. file.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 file.txt Z % git lg1 * f57d7d1 - (18 seconds ago) Merge B - Shagie (HEAD -> main) |\ | * 595d003 - (13 minutes ago) Added file.txt here too - Shagie (b/main) * daf86fe - (35 seconds ago) added a.dir; mv file.txt - Shagie * 41b64dc - (73 seconds ago) Merge A - Shagie |\ | * e4a4117 - (14 minutes ago) Added file.txt - Shagie (a/main) * d52bf11 - (3 minutes ago) Initial empty commit - Shagie Z % At this point, you can see the commits. You can see the initial commit, which is then followed by the merge, which brought in an older commit from the other remote - and d52bf11 and e4a4117 don't share a common history which is why that flag is needed. The command for lg1 is: [alias] lg1 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all I find it easier to read and show people what the history is like - it looks even better in color in my terminal.
🌐
codestudy
codestudy.net › blog › merge-two-git-repositories-without-breaking-file-history
How to Merge Two Git Repositories Without Breaking File History: A Complete Guide — codestudy.net
By following these steps—preparing repos, fetching history, merging with --allow-unrelated-histories, resolving conflicts, and organizing files with git mv—you can seamlessly combine projects without losing critical context.
Top answer
1 of 2
9

If both repos are on your machine, for example you have folders

A/.git
A/client-src

B/.git
B/server-src

simply go to one of them:

cd A

and type:

git remote add repo-b ../B

This creates a symbolic link from repo-a to repo-b ("repo-b" is just a symbolic name, you can choose anything you want) and then

git fetch repo-b

will combine the two repos. At this point, you will have both histories in one repository, but still in different branches. Branch "master" (the master of the folder you are in) will contain client code. Branch "repo-b/master" will contain the server code.

Then you only have to merge the two:

git merge repo-b/master --allow-unrelated

After this, you will have in Repo A a combined master branch. If you are sure there is no other meaningful information in Repo B (Tags, other branches), you can discard it and continue working with Repo A. Both histories will be intact.

For completeness, you should finally delete the now useless link from Repo-A to Repo-B:

git remote remove repo-b
2 of 2
2

Below are the steps

git clone <NEW REPO>
cd <NEW REPO FOLDER>
dir > README.MD --> this step is just to initiate the new repository.
git commit -m "initiate the new repository"
git remote add -f <RANDOM NAME A> <OLD BRANCH A>
git remote add -f <RANDOM NAME B> <OLD BRANCH B>
git pull origin master --allow-unrelated-histories
git push -u origin master
git merge --allow-unrelated <RANDOM NAME A>/master
git merge --allow-unrelated <RANDOM NAME B>/master
git push origin master

I believe this post should be of helpful for others.

🌐
Better Programming
betterprogramming.pub › when-projects-collide-combining-two-unrelated-git-repositories-414fba42ff3d
Combining Unrelated Git Repositories: When Projects Collide! | by Sebastian Royer | Better Programming
May 10, 2022 - Rather than dig too deep on the ... entry. In our case we are not merging branches with a shared history, so the --allow-unrelated-histories flag explicitly lets us merge two histories that do not have a common ancest...
🌐
Stack Overflow
stackoverflow.com › questions › 50789724 › merge-changes-of-two-repositores-with-unrelated-histories
git - merge changes of two repositores with unrelated histories - Stack Overflow
You're looking to accept changes ... simply done with a separate clone but only cloning with depth=1 · git clone <repo> --depth=1 --branch=<dev or whatever>...
🌐
Wouter J
wouterj.nl › 2025 › 12 › merging-unrelated-repositories
Merging Unrelated Projects using Git ~ Wouter J
December 3, 2025 - # add a remote, pointing at the new Git project on my local filesystem $ git remote add local ~/projects/github.com/wouterj/docs-builder-new $ git fetch local $ git merge --allow-unrelated-histories local/main
🌐
GitHub
gist.github.com › msrose › 2feacb303035d11d2d05
How to combine two git repositories. · GitHub
Merge master-holder into master. (If you didn't do the delete step above, you have to option of git checkout master-holder; git rebase master instead.) For more recent versions of git, you'll probably have to add the --allow-unrelated-histories ...
🌐
LinkedIn
linkedin.com › pulse › merge-multiple-git-repositories-without-breaking-file-akshay-kaushik-qto1f
Merge Multiple Git Repositories without Breaking File History
November 21, 2023 - git merge --allow-unrelated-histories frontend-merge git merge --allow-unrelated-histories backend-merge
🌐
Medium
alex-v.medium.com › how-to-merge-git-repositories-and-keep-history-587f973f06a0
How to merge Git repositories and keep history | by AlexV | Medium
April 16, 2025 - #!/bin/bash # Example: ./merge_repos.sh # Variables REPO1_BRANCH_NAME="<branch name>" REPO2_BRANCH_NAME="<branch name>" MERGE_BRANCH_NAME="<branch name to create a PR>" REPO1_NAME="<repo 1 name>" REPO2_NAME="<repo 2 name>" REPO1_PATH="<repo 1 full path>" REPO2_PATH="<repo 2 full path>" # Navigate to the first repository cd "$REPO1_PATH" || { echo "Directory $REPO1_PATH not found"; exit 1; } # Checkout the specified branch git checkout "$REPO1_BRANCH_NAME" # Filter the repository into a subdirectory git filter-repo --to-subdirectory-filter "$REPO1_NAME" # Navigate to the second repository cd "$
🌐
tutorialpedia
tutorialpedia.org › blog › how-do-you-merge-two-git-repositories
How to Merge Two Git Repositories: Add Project as Subdirectory Without Losing History — tutorialpedia.org
git stash # Stash changes git merge source-repo/main --allow-unrelated-histories git stash pop # Restore changes (if needed) By following these steps, you’ve merged two Git repositories while preserving the source repository’s history and ...
🌐
Reddit
reddit.com › r/git › efficient workflows for merging two completely separate repositories. looking for out-of-the-box solutions, or tools designed just for this purpose, if any exist...
r/git on Reddit: Efficient workflows for merging two completely separate repositories. Looking for out-of-the-box solutions, or tools designed just for this purpose, if any exist...
January 15, 2022 -

Hey all. I've been wondering about this for a while now. I've found a couple ways of doing it creatively, like putting them in separate branches, using git mergetool, using git subtree, etc. but most of the time the solutions are convoluted and involve some sort of sacrifice (namely, the .git data of one of the repos.) I was curious to see if someone else has come up with an easy way of doing it, or if a tool exists for this purpose. It would be nice to be able to click that little "License" checkbox when making GH remotes for my local git repos. Thanks in advance. Cheers!

-ntolb