Combine several Git repositories into one (with subfolders) and preserve individual file history

195 Views Asked by At

I am trying to combine several Git repositories into one. I have the folowing individual repositories:

-mainrepo
-repo1
  |-src
  |-pom.xml
-repo2
  |-src
  |-pom.xml
-repo3
  |-src
  |-pom.xml

I want to combine them into the folowing structure in mainrepo:

-mainrepo
  |-repo1
     |-src
     |-pom.xml
  |-repo2
     |-src
     |-pom.xml
  |-repo3
     |-src
     |-pom.xml

I have tried git subtree to copy the content of subdirectories:

git subtree add --prefix=repo1 https://bitbucket.org/repos/repo1.git master

and then tried to rewrite the history with git filter-repo:

git filter-repo --force --path src/ --path pom.xml --path-rename :repo1/

This approach works, but only for the first repository. When I try to do the same steps to add the second reposity, the history for the firts one vanishes:

git subtree add --prefix=repo2 https://bitbucket.org/repos/repo2.git master
git filter-repo --force --path src/ --path pom.xml --path-rename :repo2/

I have tried the approach from How to merge N git repositories into one preserving their histories? but it doesn't preferve the history of individual files. Have also tried Merge two Git repositories without breaking file history with no luck. The history is not available for individual files as well.

Can someone please come up with a better way to do it?

Edit

I have found the solution. In fact, it is pretty simple. First I need to clone every repo (repo1, repo2 ...) Then I need to rewrite the history in every repo and move the code to the corresponding subfolder with git filter-repo. Next I need init mainrepo and merge all repos. So, I need to:

mkdir mainrepo
cd mainrepo
git init
cd ..

Next, for every repo do the following:

git clone https://bitbucket.org/repos/repo1.git
cd repo1
git filter-repo --path src/ --path pom.xml --to-subdirectory-filter repo1
cd ../mainrepo
git pull --allow-unrelated-histories ../repo1/
cd ..
1

There are 1 best solutions below

3
On

Git submodules are the tool you are looking for.

Their usage is loved by some, hated by others, but they objectively do exactly what you want.

Documentation: Git - Submodules:

It often happens that while working on one project, you need to use another project from within it. Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other.