背景: 作为构建脚本的一部分,我们验证项目的所有部分都在适当的分支上,并且被正确标记。
我们一直在使用git submodule foreach --recursive "git branch -r"
来确定分支名称,但是随着时间的流逝,错误报告的分支名称数量不断增加。
我目前有一个项目,其中三个子模块中的两个始终在错误/无效分支上报告。 :-(
这三个子模块最近都已更新,贯穿整个工作流程,现在都已掌握。 主存储库已更新了其子模块,并已在工作流的所有阶段进行了测试。
在构建期间,如果获取了正确的源,则可以验证git标签(如果设置)。但是,对于某些子模块,返回的分支名称错误或无效。 :-(
背景更新:部分修复;原来,无效的分支名称是由于缺少分支历史记录所致,而这又是由于 高级子模块 设置中的“卡住”值所致 Jenkins Git插件 ,从而始终可以在子模块上执行浅表克隆。更新插件解决了问题的这一部分,因此现在总是返回分支,而并非总是期望的分支。 (注意:以下问题中的任何内容都没有更新以反映这一点。)
工作流程:
版本:
到目前为止,我已经尝试了以下操作:
确保签出正确的哈希值:(哈希值正确!)
>git submodule foreach --recursive "echo $name $sha1"
Entering 'submodules/basic'
submodules/basic ab7ce14cfaca960381f7c83bc1e6489c04863ce3
Entering 'submodules/codecs'
submodules/codecs f1329f063970448c5e06aa484df30d8d89683adc
Entering 'submodules/scripts'
submodules/scripts e0c2ceb9b792b45af46a91e3687acafeb0689316
验证日志:
>git submodule foreach --recursive "git log --oneline" (Hashes and Merge message are correct)
Entering 'submodules/basic'
ab7ce14 Merge pull request #53 in REF/basic from develop to master
Entering 'submodules/codecs'
f1329f0 Merge pull request #71 in PROT/codecs from develop to master
Entering 'submodules/scripts'
e0c2ceb Merge pull request #15 in CI/scripts from develop to master
用于确定分支名称的原始方法。 (分支名称应为主名称)
>git submodule foreach --recursive "git branch -r"
Entering 'submodules/basic'
origin/HEAD -> origin/develop
origin/develop
Entering 'submodules/codecs'
origin/HEAD -> origin/develop
origin/develop
Entering 'submodules/scripts'
origin/HEAD -> origin/master
origin/master
检查远程服务器上是否有合并的哈希值:(对受影响的存储库不返回任何内容)
>git submodule foreach --recursive "git branch -r --merged $sha1"
Entering 'submodules/basic'
Entering 'submodules/codecs'
Entering 'submodules/scripts'
origin/HEAD -> origin/master
origin/master
请求哈希的名称修订(--name-name使得易于解析的输出):(分支名称似乎未定义!?!)
>git submodule foreach --recursive "git name-rev $sha1"
Entering 'submodules/basic'
ab7ce14cfaca960381f7c83bc1e6489c04863ce3 undefined
Entering 'submodules/codecs'
f1329f063970448c5e06aa484df30d8d89683adc undefined
Entering 'submodules/scripts'
e0c2ceb9b792b45af46a91e3687acafeb0689316 master
尝试读取人类可读的对象描述符:(返回截断的哈希,而不是分支名称)
>git submodule foreach --recursive "git describe --always --all"
Entering 'submodules/basic'
ab7ce14
Entering 'submodules/codecs'
f1329f0
Entering 'submodules/scripts'
heads/master
搜索散列:(对受影响的存储库不返回任何内容)
>git submodule foreach --recursive "git branch --contains $sha1"
Entering 'submodules/basic'
* (HEAD detached at ab7ce14)
Entering 'submodules/codecs'
* (HEAD detached at f1329f0)
Entering 'submodules/scripts'
* (HEAD detached at e0c2ceb)
master
在远程上搜索哈希:(不为受影响的存储库返回任何内容。)
>git submodule foreach --recursive "git branch -r --contains $sha1"
Entering 'submodules/basic'
* (HEAD detached at ab7ce14)
Entering 'submodules/codecs'
* (HEAD detached at f1329f0)
Entering 'submodules/scripts'
* (HEAD detached at e0c2ceb)
origin/HEAD -> origin/master
origin/master
如@torek所建议,我还测试了以下命令:(两者均未为受影响的子模块提供任何新内容)
>git submodule foreach --recursive "git for-each-ref --contains=HEAD"
Entering 'Submodules/basic'
Entering 'Submodules/codec'
Entering 'Submodules/scripts'
e0c2ceb9b792b45af46a91e3687acafeb0689316 commit refs/heads/master
e0c2ceb9b792b45af46a91e3687acafeb0689316 commit refs/remotes/origin/HEAD
e0c2ceb9b792b45af46a91e3687acafeb0689316 commit refs/remotes/origin/master
>git submodule foreach --recursive "git for-each-ref --contains=$sha1"
Entering 'Submodules/basic'
Entering 'Submodules/codec'
Entering 'Submodules/scripts'
e0c2ceb9b792b45af46a91e3687acafeb0689316 commit refs/heads/master
e0c2ceb9b792b45af46a91e3687acafeb0689316 commit refs/remotes/origin/HEAD
e0c2ceb9b792b45af46a91e3687acafeb0689316 commit refs/remotes/origin/master
我真的很难理解输出。哈希值当然与合并到母版相关联,但是各种命令要么不返回任何内容,要么不返回未知信息,否则将返回错误的分支(此处为develop)或被截断(但正确)的哈希。
对于所有这些,应该注意,BitBucket GUI可以正确显示所有内容,我只是希望能够使用CLI命令进行相同的操作。
如何从这里继续?
如何确保获得可靠且正确的结果?
答案 0 :(得分:0)
在发现Jenkins Git插件正在和我玩弄把戏之后,只剩下了分支名称错误的问题。事实证明,这是git的动态特性,并且是对命令git branch -r
实际工作方式的误解。
git分支文档指出:
git branch
的默认操作为--show-current
。
--show-current
,打印当前分支的名称。在分离的HEAD状态下,不会打印任何内容。
-r
列出或删除(如果与-d一起使用)远程跟踪分支。
上面提到的当前分支,不是已在本地检出的当前分支,而是检出的分支的远程当前HEAD。因此,在分支时间之后发生的所有开发都包含在输出中,例如:
>git submodule foreach --recursive "git branch -r"
Entering 'Submodules/basic'
origin/HEAD -> origin/develop
origin/bugfix/something1_after_the merge
origin/develop
origin/feature/something2_after_the merge
origin/feature/something3_after_the merge
origin/master
Entering 'Submodules/codec'
origin/HEAD -> origin/develop
origin/develop
origin/feature/something4_after_the merge
origin/master
Entering 'scripts'
origin/HEAD -> origin/master
origin/feature/something5_after_the merge
origin/develop
origin/master
为确保仅直接获得输出(包括本地分支的版本),我们需要添加--contains
选项,并提供sha1。此外,通过使用--sort=-committerdate
对反向提交日期进行排序,我们进一步确保了用于提交的确切分支名称将在输出中排在首位:
>git submodule foreach --recursive "git branch -r --sort=-committerdate --contains $sha1"
Entering 'Submodules/basic'
origin/master
Entering 'Submodules/codec'
origin/master
Entering 'Submodules/scripts'
origin/master
origin/HEAD -> origin/master
有了这个,我得到了我期望的输出。
奖金:
要仅获取已检出哈希的分支名称,仅此而已,可以使用以下内容。它仅在第一行上运行,并去除分支名称origin/
之前和之中的所有内容:
>git submodule foreach --recursive "git branch -r --sort=-committerdate --contains $sha1 | while read line ; do line=${line#*> }; line=${line/#origin\/}; echo line; break; done;"
Entering 'Submodules/basic'
master
Entering 'Submodules/codec'
master
Entering 'Submodules/scripts'
master