Search code examples
gitmergegit-subtreemonorepo

Merge two git repositories with history into subdirs and pretend the files where always there


I need to merge two git repositories into one new repository without losing the history and preserve the feature branches and tags.

This seems like a pretty common question which already has been solved many times (e.g. https://github.com/unravelin/tomono or Merge two Git repositories without breaking file history).

But what none of the solutions managed to solve is, that i can jump back in time and view all files from a specified commit, where both subdirs are present.

So I wonder if something like this is even possible with git.

This is my current setup: Two repositories which were seperatly developed:

  • apprepo
  • librepo

These are both cloned and bundled into a rpm by our build-system (including some config and data-directories)

  • /app/ -> from apprepo
  • /lib/ -> from librepo
  • /data/
  • /config/

Now I want to migrate both repositories into one "monorepo" where I could also store the config, and other basic required subdirs.

If I use one of the many "merge x repos to a single repo"-solutions i will end up with one of two states when looking at the directory-tree of that commit:

  • Files not moved in the history - Commit in apprepo: only files that were in the apprepo are visible and show up under the root directory. Commit in librepo: only files that were in the apprepo are visible and show up under the root directory
  • Files moved in the history - Commit in apprepo: Only subdir app with all the files that were in the apprepo are visible. Commit in librepo shows only subdir lib with all files that were in the librepo.

This also make the tags pretty much useless. I would like to have both app and lib visible at any commit.

A long time ago, when migrating from SVN to git I managed something like this by reading both histories and "replaying" the commits as if the subdirectories where always there.

Is there a way for this particular problem, or do I realy have to live with the lost tags and "incomplete" history?


Solution

  • TLDR; After another full day spent on that topic, I settled with the solution with the least downsides. A combination of subtree-merge-strategy from https://stackoverflow.com/a/14470212/11126816 and git filter-branch from https://stackoverflow.com/a/43340503/11126816

    Maybe the following tools will help others: