背景:我使用一个自动构建系统,它将git哈希作为输入,以及存在该哈希的分支的名称,并构建它。但是,构建系统仅使用哈希来检查代码并构建它 - 它只是将给定的分支名称存储在构建数据库元数据中。
我担心开发人员在启动构建时会意外提供错误的分支名称,当人们查看构建历史记录时会引起混淆。
那么在将哈希和分支名称传递给构建系统之前,如何确认给定哈希实际上来自给定分支?
答案 0 :(得分:120)
您可以直接询问git branch
哪些分支包含相关提交:
% git branch -a --contains 4f08c85ad
* master
remotes/origin/bug_872
remotes/origin/bug_898
remotes/origin/master
答案 1 :(得分:8)
如果你只关心一个特定的分支,你可以计算分支和提交之间的“合并基础”。
在下图中,构建提交为C
,声明的分支的提示为T
,合并基础在其上方标有M
。
如果M
等于C
等于T
,则构建提交是声明的分支的提示。
M
↓
o--o--o--o--o--x branch # x is both C and T
如果M
等于C
,则声明的分支的提示是构建提交的后代。
M
↓
o--o--C--o--o--T branch
如果M
等于T
,则构建提交是声明的分支的提示的后代。
M
↓
o--o--T branch
\
o--o--C
如果M
等于其他内容,则C
是T
的某个祖先的后代。
M
↓
o--o--o--o--o--T branch
\
o--o--C
如果没有M
,则构建提交与声明的分支无关。
o--o--o--o--o--T branch
o--o--o--o--C
你可以这样检查:
#!/bin/sh
# Usage: is-ancestor-of <branch> <commit>
if test $# -ne 2; then
echo "$0"': invalid arguments'
exit 128
fi
claimed_branch="$1"
commit="$2"
merge_base="$(git merge-base "$commit" "$claimed_branch")" &&
test -n "$merge_base" &&
test "$merge_base" = "$(git rev-parse --verify "$commit")" &&
exit 0
echo "$commit is not an ancestor of $claimed_branch" 1>&2
exit 1
上面的脚本实际上并不要求或检查'branch'参数是否为分支(它可以是任何commit-ish)。要检查某些内容实际上是一个分支,您可以使用以下内容:
#!/bin/sh
# Usage: is-branch <branch>
if test $# -ne 1; then
echo "$0"': invalid arguments'
exit 128
fi
branch="$1"
# check various branch hierarchies, adjust as needed
git show-ref --verify refs/heads/"$branch" ||
git show-ref --verify refs/remotes/"$branch" || {
echo "not a branch name: $branch" 1>&2
exit 1
}
所以你可以一起使用它们来验证某个东西是一个分支,并且某个提交在那个分支中:
is-branch "$claimed_branch" && is-ancestor-of "$claimed_branch" "$commit_to_build"
答案 2 :(得分:1)
一种可能的非解决方案将解析结果:
$ git reflog show myBranch
并查看您的哈希值是否在其中。
C:\Prog\Git\tests\rep\main>git reflog show patches
786a190 patches@{0}: rebase finished: refs/heads/patches onto 74630b983db476c323b1d3f6771e57484551240e
8448d0f patches@{1}: master~1: updating HEAD
74630b9 patches@{2}: commit: test2
1e73e36 patches@{3}: branch: Created from master
我将此作为社区维基回答,以记住Igor Zevaka和Chris Johnsen的评论:
克隆后会有效吗? 克隆遥控器后,请确保您的reflog启动。因此,如果分支在克隆之前有提交,它将不会显示在reflog中。
推送,重新定位,提取(用于“远程跟踪”分支)和提取(合并或重定义类型)也存在问题,其中只有新提示提交结束了reflog。
默认情况下,在裸存储库(推送的最常见目的地)中禁用reflog 此外,如果“作弊”是一个问题,只需编辑文本文件来添加或删除reflog条目,但更改历史图表本身就是一个更大的考验。