有时需要克隆和构建整个“项目”(比如构建服务器),包括其“自定义类库”。有时构建服务器方法是您无法控制的(即更改脚本以克隆多个 repo)。
在这种情况下,必须将类库“添加”到 git 存储库中,但您想单独维护它在这种情况下,我找到了“git subtree”成为一个很好的解决方案。然而,这是有一些混乱的地方。
如果你用谷歌搜索“git subtree”,你会得到 2 个略有不同的结果
- GIT 子树合并工作流
- git 子树
现在我欢迎澄清这个答案,但我的感觉是第二个已经通过总结取代了第一个。
我找到的关于如何使用 git subtree 的最佳文章是 here,还有一篇关于 git subtree 合并工作流程的非常详细的文章 here,它们都与 git submodules 进行了比较如果您有兴趣,请查看他们各自的文章。
我现在如何使用它的总结
将我的类库的最新稳定版本引入主项目:
pullclasslibrary
推送我对主项目中的类库所做的任何更改:
pushclasslibrary
我是如何到达那里的
注意:它可能看起来令人生畏,但大部分都是“设置”的,不需要那么长时间
有两个独立的仓库,例如:
- 路径/to/mainproject/.git
- 路径/to/classlibrary/.git
这里的目的是让“mainproject”包含来自“classlibrary”的最新稳定代码
cd 进入你的主项目。 例如“cd path/to/mainproject”
为您的类库创建一个易于使用的“名称”?1
git remote add -f <a_remote_name> <your seperately maintained repo>
例如
git remote add -f my_class_library path/to/classlibrary/.git
现在将其添加为 子树
git subtree add --prefix <folder within main proj> <a_remote_name> <branch_in_class_library_you_want_to_track> --squash **?2**
例如
git subtree add --prefix source/libraries/class_library my_class_library stable --squash
现在我们执行 fetch,以便您的主项目完全了解类库和我们要跟踪的分支
git fetch <a_remote_name> <branch_in_class_library_you_want_to_track>
例如
git fetch my_class_library stable
此时您可以拉和推 子树(库)
git subtree pull <folder within main proj> <a_remote_name> <branch_in_class_library_you_want_to_track> --squash
git subtree push <folder within main proj> <a_remote_name> <branch_in_class_library_you_want_to_track> --squash
我个人设置了一个 bash 别名,因为要输入很多内容:
例如
alias pullclasslib="git subtree pull --prefix source/libraries/class_library my_class_library stable --squash"
alias pushclasslib="git subtree push --prefix source/libraries/class_library my_class_library stable --squash"
这就是我到达那里的方式:)
我在这里跳过了一些细节,所以我强烈推荐reading the first article
脚注:
?1 所以我们实际上是在创建一个“远程”,就像“起源”是一个远程一样,“名称”在很大程度上是一个过度-简化。 Git 允许您创建任意数量的遥控器,并且结果是完全不同的存储库。默认的“git pull”通常设置为“git pull origin”,其中origin是你克隆的git repo。
?2 --squash 是可选的,值得单独阅读,但脏摘要是当您与 --squash 合并时,你转储提交历史。我个人的偏好是我不希望将类库的丰富历史与我的主仓库捆绑在一起,这对我来说没有意义,最多我想要一个提交说“拉取最新版本的类库”。但是,如果我发现自己对主存储库中的类库进行了更改,并且我想将其推送到类库中,我确实想将历史记录推送到其中。但是,我目前正在考虑压缩它,并且它似乎会推送我的主存储库的所有提交历史记录,就类库而言,这没有任何意义。所以我可能会坚持使用双向“壁球”的文章建议。
--更新--
我对壁球改变了主意,我真的不建议在推送中省略它,因为它会从你的主仓库中获取所有历史记录,现在我已经做了几次,污染了历史记录我的类库
我已将示例更新为双向压缩
稳定 记住这是你的类库repo中的一个分支,你很可能想要跟踪“master”但我想在示例中创建一个清晰的分隔,所以我假装我的类库有一个名为“stable”的分支。如果这实际上造成更多混乱,请道歉