Git 提交到公共子模块(主分支)

我有两个或更多的项目(让我们叫他们 喷火计划项目栏)有一些 共同代码,我把一个 子舱

我的理解是,如果我从 喷火计划内部提交对子模块的更改,那么它将是一个独立的头部,只有所有的 喷火计划克隆都能看到:

(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也会做同样的事情,但是它看起来更加丑陋。

如何有一个共同的代码共享的项目,更新 从内部这些项目使用它?换句话说,提交到这个子模块应该更新所有使用这个子模块的存储库(存储库,而不仅仅是克隆)。

——编辑——

很明显,我的签出存储库被打乱和破坏。它从一开始就应该像这样工作(在本例中的 喷火计划上) :

(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."

然后从其他项目中获得变化,比如 项目栏:

(master) $ cd ProjectFooBarCommoneSubmodule/
(master) $ git pull

将更新到最新的通用代码。如果分离的头部可能需要 git checkout master

31384 次浏览

简短的回答:

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 的角度是可预测的。依赖关系不能改变,除非有人决定将更改合并到项目 A 中,如果项目 B 自动导入了更改,那么可能会发生各种令人讨厌的事情,其中编译错误可能是最好的,因为 A 会立即注意到失败。这就是为什么 B: s 头保持分离状态。

B 的状态存储在 A 中(请查看 git submodule status) ,修订更改必须在 A 中完成并提交,以使其产生任何效果。这就是上面例子中发生的情况,A 修改了存储在回购协议中的修订号,并将版本提升到最新版本。该过程将不得不重复在其他主要回购以及,所以没有自动“使用主”开关 AFAIK。

顺便说一句。Git 图书关于子模块的章节子模块手册页子模块手册页包含许多关于子模块的有用信息,作为正常使用和典型的陷阱。值得一查。


编辑: 我会试着更好地解释这一点

我冒昧地在 我的 Github 账户上创建了示例项目。提交是没有意义的,并且包含垃圾,但是设置应该没问题。请查看以下内容。

ProjectFoo 和 ProjectBar 共享公共子模块中的代码。

ProjectFooBarCommoneSubmodule: master 是 6850e4e4c1fac49de398

在 ProjectFoo:

git submodule status

-6850 e4e4c1fac49de39890703f21486ca04b87a0 common

在 ProjectBar 中:

git submodule status

-6850 e4e4c1fac49de39890703f21486ca04b87a0 common

所以两者都指向同一个版本,对吗?这里的诀窍是要看到,ProjectFoo 和 ProjectBar 指向 修订(6850e4e4c1fac49de39890703f21486ca04b87a0) 不是树枝(master) ,尽管它们是同一个东西。第一个是一个分离的头,另一个是一个命名的分支。

如果你想对 ProjectFooBarCommoneSubmodule 进行一些修复,你可以访问这个 subdir,比如 ProjectFoo 和 选择分支而不是修订版:

git checkout master
<Do your coding and pushing here>

然后去一个目录,并检查 git 子模块的状态。它应该告诉你,你现在不同步了。例如

git submodule status

+ e24bd2bf45d52171a63b67ac05cd4be0ac965f60通用(head/master-1-ge24bd2b)

现在,您可以执行 git add,设置对这个特定提交(ge24bd...)的引用,执行提交,然后子模块引用指向这个修订版本,这个修订版本碰巧也是 ProjectFooBarCommoneSubmodule 上的 master。

现在还需要更新 ProjectBar 中的引用。转到 ProjectBar/common,执行 git 提取原点(这是一个快速前进的 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。希望这个能更好地解释

submodule: git push origin HEAD:master

如果你想同时提交和推送所有的子模块,可以这样做:

git submodule foreach 'git commit -a' ;
git submodule foreach 'git push --all' ;
git commit -a && \
git push --all --recurse-submodules=on-demand

若要从分离的 HEAD 合并到 master,请运行:

git rebase HEAD master

然后结帐主机(使用 -f作为强制) :

git checkout master

如果要处理多个子模块,则使用: git submodule foreach,例如。

git submodule foreach git pull origin master -r

我就是知道:

git submodule foreach git push -u origin master

注意:

git submodule foreach 'git commit -a'

如果其中一个子模块不包含提交操作,则会失败。

为了消除这个问题,必须强制命令 result 为0。

git submodule foreach "git commit -am 'your comment' || echo ' '"

通过使用 echo 管道,您可以强制整个命令返回0并继续在其他子模块上执行 commit 命令