git子模块add -b如何工作?
在添加带有特定分支的子模块后,一个新的克隆存储库(在git子模块update——init之后)将在特定的提交处,而不是分支本身(子模块上的git状态显示为“not current on any branch”)。
我在.gitmodules或.git/config中找不到任何关于子模块分支或任何特定提交的信息,那么Git是如何解决的呢?
另外,是否可以指定一个标记而不是分支?
我使用的是1.6.5.2版本。
git子模块add -b如何工作?
在添加带有特定分支的子模块后,一个新的克隆存储库(在git子模块update——init之后)将在特定的提交处,而不是分支本身(子模块上的git状态显示为“not current on any branch”)。
我在.gitmodules或.git/config中找不到任何关于子模块分支或任何特定提交的信息,那么Git是如何解决的呢?
另外,是否可以指定一个标记而不是分支?
我使用的是1.6.5.2版本。
当前回答
Git子模块add -b develop——name branch-name——https://branch.git
其他回答
为了切换子模块的分支(假设你已经将子模块作为存储库的一部分):
CD到包含子模块的存储库的根目录 打开.gitmodules进行编辑 在path =…url =…对于每个子模块,它说branch = your-branch;保存文件。gitmodules。 然后在不改变目录的情况下执行$ git子模块update——remote
...对于这样修改的每个子模块,这应该拉入指定分支上的最新提交。
我们使用Quack从另一个Git存储库中提取特定的模块。我们需要在不使用所提供的存储库的整个代码库的情况下提取代码——我们需要从庞大的存储库中获得一个非常特定的模块/文件,并且应该在每次运行update时进行更新。
所以我们是这样实现的:
创建配置
name: Project Name
modules:
local/path:
repository: https://github.com/<username>/<repo>.git
path: repo/path
branch: dev
other/local/path/filename.txt:
repository: https://github.com/<username>/<repo>.git
hexsha: 9e3e9642cfea36f4ae216d27df100134920143b9
path: repo/path/filename.txt
profiles:
init:
tasks: ['modules']
通过上述配置,它从第一个模块配置中指定的提供的GitHub存储库创建了一个目录,而另一个目录是从给定的存储库中提取并创建一个文件。
其他开发人员只需要运行
$ quack
它从上面的配置中提取代码。
(Git 2.22, Q2 2019,引入了Git子模块set-branch——branch branch——<submodule_path>)
注意,如果你有一个现有的子模块,它还没有跟踪分支,那么(如果你有git 1.8.2+):
确保父repo知道它的子模块现在跟踪一个分支: cd /道路/ /你/父母/回购 Git config -f . Git modules submodule.<path>。分支<分支> 确保你的子模块实际上位于该分支的最新位置: cd路径/ /你/子模块 Git checkout -b branch——跟踪原点/分支 #如果主分支已经存在: Git branch -u origin/master master
(其中'origin'是子模块克隆的上游远程repo的名称。 该子模块中的git remote -v将显示它。通常是“origin”)
不要忘记在父repo中记录子模块的新状态: cd /道路/ /你/父母/回购 Git添加路径/到/your/子模块 让子模块跟踪一个分支 该子模块的后续更新必须使用——remote选项: #更新子模块 #——remote也将获取并确保 #使用来自分支的最新提交 Git子模块update——remote #来避免抓取使用 Git子模块更新——remote——no-fetch
注意,在Git 2.10+(2016年Q3)中,您可以使用'。'作为分支名称:
分支的名称被记录为submodule.<name>。在.gitmodules中分支update——remote。 的特殊值用于指示子模块中的分支名称应与当前存储库中的当前分支名称相同。
但是,正如LubosD所评论的那样
使用git签出,如果分支名称是“。”,它将终止您未提交的工作! 使用git switch代替。
这意味着Git 2.23(2019年8月)或更高版本。
参见“git checkout让人困惑”
如果你想更新分支后面的所有子模块:
git submodule update --recursive --remote
注意,对于每个更新的子模块,结果几乎总是一个分离的HEAD,正如Dan Cameron在他的回答中指出的那样。
(Clintm在评论中指出,如果你运行git子模块update -remote,结果sha1与子模块当前所在的分支相同,它将不会做任何事情,并让子模块仍然“在该分支上”,而不是处于分离头状态。)
为了确保分支被实际签出(这不会修改代表父repo子模块的特殊条目的SHA1),他建议:
git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; git switch $branch'
每个子模块仍然会引用相同的SHA1,但是如果你做了新的提交,你将能够推送它们,因为它们将被你希望子模块跟踪的分支引用。 在子模块内的推送之后,不要忘记返回父repo,为那些修改后的子模块添加、提交和推送新的SHA1。
注意使用$ topllevel,这是Alexander Pogrebnyak在评论中推荐的。 $ topllevel于2010年5月在git1.7.2中引入:commit f030c96。
它包含顶级目录(.gitmodules所在目录)的绝对路径。
Dtmland在评论中补充道:
foreach脚本将无法签出不遵循分支的子模块。 然而,这个命令会给你两个:
git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; [ "$branch" = "" ] && git checkout master || git switch $branch' –
同样的命令,但更容易阅读:
git submodule foreach -q --recursive \
'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; \
[ "$branch" = "" ] && \
git checkout master || git switch $branch' –
Umläute在评论中提炼了dtmland命令的简化版本:
git submodule foreach -q --recursive 'git switch $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
多行:
git submodule foreach -q --recursive \
'git switch \
$(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
在Git 2.26 (Q1 2020)之前,在子模块中递归地获取更新不可避免地会产生大量的输出,并且很难发现错误消息。
该命令已被教导枚举在操作结束时出现错误的子模块。
参见Emily Shaffer (nasamuffin)提交的0222540(2020年1月16日)。 (由Junio C Hamano—gitster—在commit b5c71cc中合并,2020年2月5日)
获取:强调子模块获取失败 署名:Emily Shaffer
在有很多子模块的情况下,当一个子模块读取失败时,如果多个读取返回到按oid读取,那么来自唯一失败的子模块读取的错误将被隐藏在其他子模块的活动之下。 延迟调用故障,这样用户就能意识到哪里出了问题。
因为fetch_finish()只由run_processes_parallel同步调用,所以在submodules_with_errors周围不需要互斥。
注意,在Git 2.28 (Q3 2020)中,继续重写脚本化的“Git子模块”Porcelain命令的部分内容;这次轮到“git submodule set-branch”子命令了。
参见Shourya Shukla (periperidip)提交2964d6e (02 Jun 2020)。 (由Junio C Hamano—gitster—在commit 1046282中合并,2020年6月25日)
子模块:端口子命令'set-branch'从shell到C 导师:Christian Couder 导师:karartic Sivaraam 帮助:Denton Liu 资助人:Eric Sunshine 帮助:Đoàn trn Công Danh 署名:Shourya Shukla
将子模块子命令“set-branch”转换为内置命令,并通过git submodule.sh调用它。
使用下面的命令
添加子模块(分支-分支)
git submodule add -b stage git@github.optum.com:orgname/${reponame}.git
更新子模块(分支-分支)
######Clone########
> git clone -b master --single-branch --recurse-submodules git@github.com:orgname/project.git
or
> git clone -b stage --single-branch --recurse-submodules git@github.com:orgname/project.git
######Update#######
> git submodule update --remote (only for remote branch -ie master)
or
> git submodule update --recursive --remote
> git submodule update --init --recursive (for remaining branchs)
if you get fatal need single revision error then use below commands:-
before:-
*** stage
remotes/origin/stage**
git branch -a
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/{branch name}
ex:- git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/stage
after:-
*** stage
remotes/origin/HEAD -> origin/stage
remotes/origin/stage**
then
> git reset --hard
#hard reset revisions#
> git submodule foreach git reset --hard origin/develop
> git submodule foreach git pull origin develop
在提交和推送相应的.. 现在子模块将得到更新。
Git子模块add -b develop——name branch-name——https://branch.git