简体   繁体   中英

git subtree: split sub-project, work on it, and merge back

I was trying to make a "sub-project" out of a directory of files in my "super-project" to work with other people, but I have been struggling to make it work in git subtree. Ideally, other people can work on the sub-project, then I pull from the upstream changes, and push my updates.

Here is a MWE for this purpose. I create a "super-project" which contains a "sub-project" then git subtree the sub-project to a remote repo "sub-project":

$ mkdir subtree-test && cd subtree-test

# create super-project
$ mkdir super-project && git init super-project && cd super-project
$ echo "foobar" >> super.txt
$ git add super.txt && git commit -m "add file"

# create sub-project
$ mkdir sub-project
$ echo "foobar" >> sub-project/sub1.txt
$ git add sub-project/sub1.txt && git commit -m "add file"

# prepare a bare subtree repo named "sub"
$ git init --bare ../sub-project
$ git subtree push --prefix=sub-project/ ../sub-project master

Then clone "sub-project" to "sub-live", do some work, and push upstream:

$ cd ../
$ git clone sub-project sub-live
$ cd sub-live
$ echo "foobar" >> sub2.txt
$ git add sub2.txt && git commit -m "add file"
$ git push

Then attempt to merge back to super-project:

$ cd ../super-project
$ git subtree pull --prefix=sub-project/ ../sub-project master

and there is the error:

warning: no common commits
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 5 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (5/5), done.
From ../sub-project
* branch            master     -> FETCH_HEAD
fatal: refusing to merge unrelated histories

I have read articles regarding git subtree usage. However in most situations, the sub-project is added to the super-project later. In my case, the sub-project originates from the super-project, which might have created these complications.

What have I done wrong? And how should I proceed from here?

You could've used git subtree split --rejoin for initial splitting, which makes this a lot easier:

options for 'split'
    --annotate ...        add a prefix to commit message of new commits
    -b, --branch ...      create a new branch from the split subtree
    --ignore-joins        ignore prior --rejoin commits
    --onto ...            try connecting new tree to an existing one
    --rejoin              merge the new branch back into HEAD

However, regarding your problem: I think you need to remove the directory first, and then use git subtree add again, see for example https://www.atlassian.com/blog/git/alternatives-to-git-submodule-git-subtree .

git rm -rf sub-project/
git commit -m "Remover subdir"
git subtree add --prefix=sub-project/ ../sub-project master

Only for future merges, you use pull or merge.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM