简体   繁体   中英

Can I use `git subtree split` to maintain a “fork” of a project's subdirectory?

In short, I want to "fork" a subdirectory of another project (not under my control) to the top-level of a new repository and make enhancements to the code in that subdirectory while preserving the ability to merge in changes from the subdirectory in the upstream project.

I've been reading up on this topic for a while now but can't find a sure answer for my situation. Most of the uses of git subtree break down into these cases:

  • A subdirectory of a project is being spun off as its own separate project. The parent project is removing the subdirectory entirely and the new project lives its own life.
  • A maintainer of a parent project wants to allow maintenance of a subdirectory on its own terms and spins it off into its own repository, which is added back to the main project using git subtree add

These use cases don't apply to me: I'm not forking-and-forgetting, and I don't own both sides of this fork, so the git subtree add flow isn't applicable.

So let's say the original module lives in contrib/foo in the main project. My current idea is to:

  • Use git subtree split -P contrib/foo -b upstream_vx.y to create a new history that "hoists" the subdirectory up to the top-level of a repository
  • Create a master branch from my project with enhancements from this point
  • Keep updating upstream_vx.y by running git subtree split occasionally
  • When I need a bug fix or whatnot from upstream, merge upstream_vx.y into my master

This doesn't feel "git-like" to me. Specifically, I'm basically creating a parallel history of the upstream project's subdirectory and maintaining my own "hoisted" branch for each major upstream branch (to say nothing of being able to reference upstream tags).

Is there a better way to go about this?

I think I have been maintaining a similar situation to you. I have a primary project (ProjA) which has modules, and I am adding a subtree of a second project (ProjB) into the primary's modules. In order to accomplish this, I maintain a copy ProjB.

Split ProjB:

cd ProjB
git checkout -b split-maint
git subtree split --prefix=important/dir --branch=module-for-A 

Add the subtree to ProjA:

cd ProjA
git remote add ProjB_remote /path/to/ProjB
git fetch ProjB_remote
git subtree add --prefix=modules/projB_mod ProjB_remote/module-for-A --message="commit message"

Then to update/maintain, re-split the original (as above). The key here is git subtree split is repeatable , and the SHA of each revision that was previously split will be the same.

Update ProjA with the new details:

cd ProjA
git fetch ProjB_remote
git subtree merge --prefix=modules/projB_mod ProjB_remote/module-for-A --message="commit message"

Technically I do it slightly differently because my ProjB has a lot of commits and the split actually takes an hour to run. I can give you details on how to help with that too if you need it. (Just comment, and I will update this answer).

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