Skip to content

Instantly share code, notes, and snippets.

@ryancat
Last active April 23, 2019 20:58
Show Gist options
  • Save ryancat/5700ad5e5218fcb898235bd934c75a39 to your computer and use it in GitHub Desktop.
Save ryancat/5700ad5e5218fcb898235bd934c75a39 to your computer and use it in GitHub Desktop.
How to merge one repo into another repo's sub directory

How to add another repo foo under current repo's subdirectory bar/my_foo?

First time add repo under subdirectory

It's easy to add foo for the first time. Just run the following one-liner to add foo's remote master branch to bar/my_foo

git subtree add --prefix=bar/my_foo REMOTE_PATH_TO_FOO master

You can optionally add --squash in the end to squash all commit history if that's what you want.

Update bar/my_foo with new changes in foo repo

Update is a bit more complicated. You will fistly need to read the root tree of foo branch in your local, and to merge it with or without history.

Add repo foo as a remote target to current repo, and fetch all commits to local. It's easier to add foo's remote as you don't have to type the REMOTE_PATH_TO_FOO every time.

git remote add origin_foo REMOTE_PATH_TO_FOO
git fetch origin_foo

After this, there are two ways to do it. The first one is a one liner, which basically allow you to pull from foo's remote master branch to your local, and update bar/my_foo directory using subtree merge

git pull -s subtree -Xsubtree=bar/my_foo origin_foo master

The second one is more steps, but it helps you do more than just pull. You need to first checkout (use git branch foo_master origin_foo/master if foo_master is not existed, and you can skip git pull) a branch which contains current master branch of foo, and update it

git checkout foo_master origin_foo/master
git pull origin_foo master
git checkout master

Now you can use a normal git merge to merge changes from foo_master branch

git merge -s subtree -Xsubtree=bar/my_foo foo_master

Note that the extra -Xsubtree option is required and not properly documented. You need to specify the location of your sub-directory of foo everytime you merge changes in. Otherwise despite your commit histroy will look like its updated, nothing will be actually updated.

Similarly, if you don't need commit histroy for the updates, you can add --squash to it.

Lastly, resolve all conflicts, and you are all updated!

git add .
git merge --continue

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment