将Git子模块更新为最新的原始提交
我有一个带有Git子模块的项目。 它来自ssh:// ... URL,并且在提交A.提交B已被推送到该URL,我希望子模块检索提交,并更改为它。
现在,我的理解是git submodule update
应该这样做,但事实并非如此。 它没有做任何事情(没有输出,成功退出代码)。 这是一个例子:
$ mkdir foo
$ cd foo
$ git init .
Initialized empty Git repository in /.../foo/.git/
$ git submodule add ssh://user@host/git/mod mod
Cloning into mod...
user@host's password: hunter2
remote: Counting objects: 131, done.
remote: Compressing objects: 100% (115/115), done.
remote: Total 131 (delta 54), reused 0 (delta 0)
Receiving objects: 100% (131/131), 16.16 KiB, done.
Resolving deltas: 100% (54/54), done.
$ git commit -m "Hello world."
[master (root-commit) 565b235] Hello world.2 files changed, 4 insertions(+), 0 deletions(-)create mode 100644 .gitmodulescreate mode 160000 mod
# At this point, ssh://user@host/git/mod changes; submodule needs to change too.
$ git submodule init
Submodule 'mod' (ssh://user@host/git/mod) registered for path 'mod'
$ git submodule update
$ git submodule sync
Synchronizing submodule url for 'mod'
$ git submodule update
$ man git-submodule
$ git submodule update --rebase
$ git submodule update
$ echo $?
0
$ git status
# On branch master
nothing to commit (working directory clean)
$ git submodule update mod
$ ...
我也尝试了git fetch mod
,它似乎做了一个提取(但不可能,因为它不会提示输入密码!),但git log
和git show
否认存在新的提交。 到目前为止,我刚去过的rm
-ing模块并重新添加它,但是这是在原则上都是错误的和繁琐的做法。
#1楼
在项目父目录中,运行:
git submodule update --init
或者如果你有递归子模块运行:
git submodule update --init --recursive
有时这仍然不起作用,因为在更新子模块时,您在本地子模块目录中以某种方式进行了本地更改。
大多数情况下,本地更改可能不是您要提交的更改。 它可能由于子模块中的文件删除等原因而发生。如果是这样,请在本地子模块目录和项目父目录中重置,再次运行:
git submodule update --init --recursive
#2楼
在这个讨论中似乎将两种不同的场景混合在一起:
场景1
使用我的父存储库指向子模块的指针,我想检查父存储库指向的每个子模块中的提交,可能是在首次迭代所有子模块并从远程更新/拉取这些子模块之后。
正如所指出的那样,这是完成的
git submodule foreach git pull origin BRANCH
git submodule update
场景2,我认为是OP的目标
在一个或多个子模块中发生了新的事情,我想1)拉出这些变化,2)更新父存储库以指向这个/这些子模块的HEAD(最新)提交。
这将通过以下方式完成
git submodule foreach git pull origin BRANCH
git add module_1_name
git add module_2_name
......
git add module_n_name
git push origin BRANCH
不太实际,因为你必须硬编码所有n个子模块的n个路径,例如脚本来更新父存储库的提交指针。
通过每个子模块进行自动迭代,更新父存储库指针(使用git add
)指向子模块的头部将会很酷。
为此,我制作了这个小的Bash脚本:
git-update-submodules.sh
#!/bin/bashAPP_PATH=$1
shiftif [ -z $APP_PATH ]; thenecho "Missing 1st argument: should be path to folder of a git repo";exit 1;
fiBRANCH=$1
shiftif [ -z $BRANCH ]; thenecho "Missing 2nd argument (branch name)";exit 1;
fiecho "Working in: $APP_PATH"
cd $APP_PATHgit checkout $BRANCH && git pull --ff origin $BRANCHgit submodule sync
git submodule init
git submodule update
git submodule foreach "(git checkout $BRANCH && git pull --ff origin $BRANCH && git push origin $BRANCH) || true"for i in $(git submodule foreach --quiet 'echo $path')
doecho "Adding $i to root repo"git add "$i"
donegit commit -m "Updated $BRANCH branch of deployment repo to point to latest head of submodules"
git push origin $BRANCH
要运行它,请执行
git-update-submodules.sh /path/to/base/repo BRANCH_NAME
精
首先,我假设所有存储库中都存在名为$ BRANCH(第二个参数)的分支。 随意使这更复杂。
前几节是检查参数是否存在的一些部分。 然后我拉出父存储库的最新东西(我更喜欢使用--ff(快速转发),每当我做拉动时。我已经关闭了,BTW)。
git checkout $BRANCH && git pull --ff origin $BRANCH
如果新的子模块已添加或尚未初始化,则可能需要进行一些子模块初始化:
git submodule sync
git submodule init
git submodule update
然后我更新/拉取所有子模块:
git submodule foreach "(git checkout $BRANCH && git pull --ff origin $BRANCH && git push origin $BRANCH) || true"
请注意以下几点:首先,我使用&&
链接一些Git命令 - 意味着前一个命令必须执行而不会出错。
在可能的成功拉动之后(如果在远程上找到了新的东西),我会进行推送以确保在客户端上不会留下可能的合并提交。 同样, 如果在拉新的东西,实际上把它才会发生。
最后,最后|| true
|| true
是确保脚本继续上的错误。 为了实现这一点,迭代中的所有内容都必须用双引号括起来,Git命令用括号括起来(运算符优先级)。
我最喜欢的部分:
for i in $(git submodule foreach --quiet 'echo $path')
doecho "Adding $i to root repo"git add "$i"
done
迭代所有子模块 - with --quiet
,删除'Entering MODULE_PATH'输出。 使用'echo $path'
(必须使用单引号),子模块的路径将写入输出。
这个相对子模块路径列表在一个数组中捕获( $(...)
) - 最后迭代这个并执行git add $i
来更新父存储库。
最后,提交一些消息,说明父存储库已更新。 如果没有做任何事情,默认情况下将忽略此提交。 把它推到原点,你就完成了。
我有一个在Jenkins工作中运行它的脚本,之后链接到计划的自动部署,它就像一个魅力。
我希望这会对某人有所帮助。
#3楼
Git 1.8.2提供了一个新选项--remote
,可以实现这种行为。 运行
git submodule update --remote --merge
将从每个子模块的上游获取最新的更改,将它们合并,并检查子模块的最新版本。 正如文档所说:
- 远程
此选项仅对update命令有效。 不使用超级项目记录的SHA-1来更新子模块,而是使用子模块的远程跟踪分支的状态。
这相当于在每个子模块中运行git pull
,这通常就是你想要的。
#4楼
这是一个很棒的单行程序,可以将所有内容更新为最新的主服务器:
git submodule foreach 'git fetch origin --tags; git checkout master; git pull' && git pull && git submodule update --init --recursive
感谢Mark Jaquith
#5楼
简单明了,要获取子模块:
git submodule update --init --recursive
现在继续将它们更新到最新的主分支(例如):
git submodule foreach git pull origin master
#6楼
在我的情况下,我希望git
更新到最新版本,同时重新填充任何丢失的文件。
以下恢复了丢失的文件(感谢--force
,这里似乎没有提到),但它没有提取任何新的提交:
git submodule update --init --recursive --force
这样做:
git submodule update --recursive --remote --merge --force
#7楼
git pull --recurse-submodules
这将提取所有最新提交。
#8楼
如果您不知道主机分支,请执行以下操作:
git submodule foreach git pull origin $(git rev-parse --abbrev-ref HEAD)
它将获得主Git存储库的一个分支,然后为每个子模块将拉动相同的分支。
#9楼
注意,虽然更新子模块提交的现代形式是:
git submodule update --recursive --remote --merge --force
较旧的形式是:
git submodule foreach --quiet git pull --quiet origin
除了......这第二种形式并不是真的“安静”。
见NguyễnTháiNgọcDuy( pclouds
) 提交a282f5a (2019年4月12日) 。
(由Junio C gitster
合并- gitster
-在提交f1c9f6c ,2019年4月25日)
submodule foreach
:修复“<command> --quiet
”没有得到尊重罗宾报道说
git submodule foreach --quiet git pull --quiet origin
不再那么安静了。
它应该在fc1b924之前安静 (submodule
:portsubmodule
子命令'foreach
'从shell到C,2018-05-10,Git v2.19.0-rc0)因为parseopt
不能随意吃掉选项。“
git pull
”表现得好像没有给出--quiet
。这是因为
submodule--helper
parseopt
submodule--helper
将尝试解析两个--quiet
选项,就像它们是foreach的选项一样,而不是git-pull
的选项。
已解析的选项将从命令行中删除。 所以当我们稍后拉,我们执行这个git pull origin
调用子模块助手时,在“
git pull
”前添加“--
”将停止parseopt
以解析实际上不属于submodule--helper foreach
选项submodule--helper foreach
。删除
PARSE_OPT_KEEP_UNKNOWN
作为安全措施。parseopt
永远不会看到未知选项或出现问题。 我正在查看它们时还有一些用法字符串更新。在它的同时,我还将“
--
”添加到将“$@
”传递给submodule--helper
其他子命令submodule--helper
。 在这些情况下,“$@
”是路径而且不太可能是--something-like-this
。
但问题仍然存在,git-submodule
已经解析并分类了什么是选项,什么是路径。
submodule--helper
永远不应该将git-submodule
传递的路径视为选项,即使它们看起来像是一个。
并且Git 2.23(Q3 2019)解决了另一个问题:当使用“ --recursive
”选项时,“ git submodule foreach
”不保护传递给命令的命令行选项在每个子模块中正确运行。
参见由momoson
Sonnet( momoson
) 提交的30db18b (2019年6月24日) 。
(由Junio C gitster
合并- gitster
-在提交968eecb ,2017年7月9日)
submodule foreach
:修复选项的递归呼叫:
git submodule foreach --recursive <subcommand> --<option>
导致出现错误,指出
submodule--helper
未知选项--<option>
。
当然,这只是当<option>
不是git submodule foreach
的有效选项时。原因是,上面的调用内部转换为对子模块的调用 - helper:
git submodule--helper foreach --recursive \\ -- <subcommand> --<option>
这个调用与它的第一级子模块中选择执行子开始,并通过调用的下一次迭代不断
submodule foreach
调用git --super-prefix <submodulepath> submodule--helper \\ foreach --recursive <subcommand> --<option>
在第一级子模块内。 请注意,缺少子命令前面的双短划线。
这个问题最近才开始出现,因为在提交a282f5a中删除了参数解析
git submodule foreach
的PARSE_OPT_KEEP_UNKNOWN
标志。
因此,现在抱怨未知选项,因为参数解析未通过双破折号正确结束。此提交通过在递归期间在子命令前添加双短划线来解决问题。
#10楼
git submodule update
命令实际上告诉Git你希望每个子模块都检查已经在超级项目的索引中指定的提交。 如果要将子模块更新为其远程可用的最新提交,则需要在子模块中直接执行此操作。
总结如下:
# Get the submodule initially
git submodule add ssh://bla submodule_dir
git submodule init# Time passes, submodule upstream is updated
# and you now want to update# Change to the submodule directory
cd submodule_dir# Checkout desired branch
git checkout master# Update
git pull# Get back to your project root
cd ..# Now the submodules are in the state you want, so
git commit -am "Pulled down update to submodule_dir"
或者,如果你是一个忙碌的人:
git submodule foreach git pull origin master
#11楼
@Jason在某种程度上是正确的,但并非完全正确。
更新
更新已注册的子模块,即克隆缺少的子模块,并检查包含的存储库索引中指定的提交。 这将使子模块HEAD被分离,除非指定了--rebase或--merge或密钥子模块。$ name.update设置为rebase或merge。
因此, git submodule update
执行checkout,但它是在包含存储库的索引中的提交。 它根本不知道上游的新提交。 因此,转到您的子模块,获取所需的提交并在主存储库中提交更新的子模块状态,然后执行git submodule update
。
#12楼
您的主项目指向子模块应该处于的特定提交。 git submodule update
尝试检查已初始化的每个子模块中的提交。 子模块实际上是一个独立的存储库 - 只是在子模块中创建一个新的提交并推送它是不够的。 您还需要在主项目中显式添加新版本的子模块。
所以,你的情况,你应该找到犯辅助模块中的正确的-假设这是尖master
:
cd mod
git checkout master
git pull origin master
现在回到主项目,暂存子模块并提交:
cd ..
git add mod
git commit -m "Updating the submodule 'mod' to the latest version"
现在推送您的新版主项目:
git push origin master
从这一点开始,如果其他人更新了他们的主项目,那么git submodule update
将更新子模块,假设它已被初始化。
将Git子模块更新为最新的原始提交相关推荐
- 手把手教你把 Git 子模块更新到主项目
本文以 skywalking-rocketbot-ui子模块合并到 skywalking 为例,手把手教你如何把 Git 子模块更新到主项目中去. 首先,把fork的skywalking项目克隆到本地 ...
- 使用Git子模块和开发模式管理Python项目
目录 挑战 什么是开发模式? 什么是Git子模块? 设置项目 设置commonlib的Git存储库 设置myproj的Git存储库 设置Git子模块 将存储库添加为子模块 更新子模块 使用Git子模块 ...
- 【Android面试】Android面试题集锦 (陆续更新)(最新2012-6-18)
1.android开发新浪面试题[开发者必看哦] 下载地址 http://www.eoeandroid.com/thread-177885-1-1.html 2.华为关于android笔试题案例解析 ...
- git 子模块在项目中的使用
在公司的项目中, 经常会遇到一些公共的内容, 多个项目中间通用的, 不可能每次都将整个代码复制一遍, 遇到这种情况有很多不同的解决方案, 一般来说, 项目是通过 git 来管理的, 巧了, git 也 ...
- 【Android面试】Android面试题集锦 (陆续更新)(最新2012-6-18) eoe上看到的
===============eoeAndroid社区推荐:======================= 1.Android开发新浪面试题[开发者必看哦] 下载地址 http://www.eoean ...
- Git子模块引用外部项目
Git子模块(submodule)简介 经常有这样的事情,当你在一个项目上工作时,你需要在其中使用另外一个项目.也许它是一个第三方开发的库或者是你独立开发和并在多个父项目中使用的.这个场景下一个常见的 ...
- github上fork原项目,如何将本地仓库代码更新到最新版本?
https://www.cnblogs.com/eyunhua/p/8463200.html 场景: 在github上fork原项目,项目组成员发起pull request提交了代码,这时自己在本地仓 ...
- git 2.30.1最新版本的使用
git 2.30.1最新版本的使用 git命令是最非常重要的. 常见的命令有很多,掌握并不容易.也有UI页面的操作工具,例如乌龟等工具. 我一般都是使用纯命令去提交. 如何由一个开发好的项目提交到gi ...
- 通过 GitExtensions 来使用 Git 子模块功能
通过 GitExtensions 来使用 Git 子模块功能 目录 一.前言 二.Git 子模块 三.子模块更改提交 四.更新子模块 五.[附] 去除最近的提交记录 独立观察员 2021 年 9 月 ...
最新文章
- ASP.NET Core 在 Swagger UI 中显示自定义的 Header Token
- 计算机及其系统的泄密渠道之三
- R语言之MYSQL数据库获取及输出
- NumPy快速入门-- Less 基础/线性代数
- html列目录带图片,根据目录下的图片的个数,往html文件填充对应数量的img标签,请问有没有实现这种需求的工具?...
- c++ 输出二进制_C语言 printf 格式化输出的详细示例
- 电大 计算机网络 网考,2018-2019年最新电大《计算机网络(本)》网络核心课形考网考作业答案.docx...
- 通过 EWF 创建一个XP Embedded
- 刘知远:在深度学习时代用HowNet搞事情
- Tomcat日志配置,可结合log4j
- iOS日历攻略:提醒调休并过滤法定节假日
- QScrollArea的简单使用
- js获取不同时区时间
- postgresql垃圾清理插件pg_repack
- m苹果放n篮子_【求这个编程】 有m个橘子,n个篮子,把橘子全部放进篮子里的...
- 最深的红尘里,陌上为谁花开
- DrawerLayout must be measured with MeasureSpec.EXACTLY error
- 林业大学计算机专业排名2019,2021年北京林业大学最新排名 全国最新排名
- 阿基米德优化算法AOA附Matlab代码
- Tips系列:西门子HMI之历史曲线的自动刷新