我有两个或多个项目(我们称它们为 ProjectFoo 和 ProjectBar),它们有一些通用代码,我将它们放入了一个>子模块。
我的理解是,如果我从 ProjectFoo 中提交对子模块的更改,它将位于一个分离的头中,只有所有 ProjectFoo 克隆才能看到:
(master) $ cd ProjectFooBarCommoneSubmodule/
(master) $ git commit -am "Common code fix."
(56f21fb0...) $ git push
Everything up-to-date
这可能是因为 master
分支没有改变。我可能会做一些类似 git checkout master && git merge Everything up-to-date
的事情,但这看起来很丑陋。可能是一个 git reset --hard master
会做同样的事情,但它看起来更丑陋。
如何让项目共享通用代码,从内部使用它的项目进行更新?换句话说,提交到该子模块应该更新使用同一子模块的所有各种存储库(存储库,而不仅仅是克隆)。
---- 编辑----
很明显,我 checkout 的存储库被弄乱了。它从一开始就应该像那样工作(在这个例子中是在 ProjectFoo 上):
(master) $ cd ProjectFooBarCommoneSubmodule/
(master) $ git commit -am "Common code fix."
(master) $ git push
....
fbfdd71..0acce63 master -> master
(master) $ cd ..
(master) $ git add ProjectFooBarCommoneSubmodule
(master) $ git commit -m "Submodule update."
然后从其他项目(如 ProjectBar)获取更改:
(master) $ cd ProjectFooBarCommoneSubmodule/
(master) $ git pull
将更新到最新的通用代码。 git checkout master
如果它位于独立的头上,则可能需要它。
最佳答案
简答:
cd ProjectFooBarCommoneSubmodule
git checkout master
<Do your editing>
git commit --all -m "Lots of fixes"
git push submodule_origin master
cd ..
git add ProjectFooBarCommoneSubmodule
git commit -m "Bumped up the revision of ProjectFooBarCommoneSubmodule"
git push origin master
较长的一个:
Git 子模块是一种依赖机制,其中主项目(比如 A)在子项目(比如 B)中定义了一个指定的修订版,该修订版将用于构建项目 A。为了使工具有用,行为具有从 A:s 的角度来看是可以预测的。依赖关系无法更改,除非有人决定将更改 merge 到项目 A。如果自动导入项目 B:s 更改,则可能会发生各种糟糕的事情,其中编译错误可能是最好的错误,因为 A 会立即注意到失败。这就是 B:s 的头部保持分离状态的原因。
B 的状态存储在 A 中(查看 git submodule status
),并且必须在 A 中完成并提交修订更改才能使其生效。这就是上面示例中发生的情况,A 更改存储在 repo 中的修订号,并将版本升级到最新版本。这个过程也必须在其他主要 repo 中重复,所以没有自动“使用主”开关 AFAIK。
顺便说一句。 Git book chapter on submodules和 submodule man page包含很多关于子模块的有用信息,如正常使用和典型的陷阱。值得一试。
编辑:我会尝试更好地解释这一点
我冒昧地在 my github account 上创建示例项目.提交没有意义并且包含垃圾,但设置应该没问题。请查看并关注。
ProjectFoo 和 ProjectBar 共享公共(public)子模块中的代码。
ProjectFooBarCommoneSubmodule:master 是6850e4e4c1fac49de398
在 ProjectFoo 中:
git submodule status
-6850e4e4c1fac49de39890703f21486ca04b87a0 常见
在项目栏中:
git submodule status
-6850e4e4c1fac49de39890703f21486ca04b87a0 常见
所以两者都指向同一个版本,对吧?这里的诀窍是,ProjectFoo 和 ProjectBar 指向修订版 (6850e4e4c1fac49de39890703f21486ca04b87a0) 不是分支(master),尽管它们是同一件事。第一个是分离的头,另一个是命名的分支。
如果你想对 ProjectFooBarCommoneSubmodule 做一些修复,你可以转到子目录,例如ProjectFoo,并选择分支而不是修订版:
git checkout master
<Do your coding and pushing here>
然后向上一个目录,检查 git 子模块状态。它应该告诉你,你现在不同步了。例如
git submodule status
+e24bd2bf45d52171a63b67ac05cd4be0ac965f60 通用 (heads/master-1-ge24bd2b)
现在你可以做一个 git add,设置对这个特定提交(ge24bd...)的引用,做一个提交,然后子模块引用指向这个修订,它也恰好是 ProjectFooBarCommoneSubmodule 上的 master。
现在您还需要更新 ProjectBar 中的引用。转到 ProjectBar/common,然后执行 git fetch origin(这是一个快进 merge ),执行
git checkout master
cd ..
git add common
git commit -m "Bumped up the revision"
git push origin master # to publish the revision bump to everybody else
因此,与任何 git 存储库一样,您无需在独立的头上工作。您可以在 master 上工作,也可以创建一个命名分支。无论哪种方式,请确保上游包含 ProjectFooBarCommoneSubmodule 更改,否则如果 ProjectFoo 和 ProjectBar 引用了不存在的内容,您将同时破坏它们。希望这能更好地解释它
关于Git 提交到公共(public)子模块(master 分支),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3590400/