How to merge a Git repo into a sub directory

Here’s the scenario:

I’ve got two repositories:

  • github.com/example/web-app-backend.git
  • github.com/example/web-app-frontend.git

I want to merge web-app-frontend into web-app-backend/html-src/ and keep the commit history.

Use git subtree

Ideally I’d like to completely interlace the commit histories as if they had always been in the same repo (like a rebase, which would require a --force push).

Unfortunately, there’s currently no simple way to interleave commits from multiple repositories by commit date, so a merge commit will have to do.

git clone https://github.com/example/web-app-backend.git ./web-app-backend/
pushd ./web-app-backend/
git checkout -b add-frontend
git subtree add -P html-src/ https://github.com/example/web-app-frontend.git master

What that looks like

If that all goes well you’ll see some output like this:

git fetch https://github.com/example/web-app-frontend.git master
From https://github.com/example/web-app-frontend.git
 * branch            master     -> FETCH_HEAD
Added dir 'html-src'

And if you check git log, you’ll see a subtree merge commit:

git log
commit xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (HEAD -> add)
Merge: aaaaaaa bbbbbbb
Author: Jo Doe <jo@example.com>
Date:   Mon Oct 19 11:01:39 2020 +0000

    Add 'html-src/' from commit 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'

    git-subtree-dir: html-src
    git-subtree-mainline: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    git-subtree-split: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

If everything is to your liking, merge it back in to the mainstream:

git checkout master
git merge add-frontend

error: Invalid path

If you get an Invalid path error, it’s likely due to the use of ./.

git subtree add -P ./html-src/ https://github.com/example/web-app-frontend.git master
error: Invalid path './html-src/README.md'