如何确定给定分支上是否存在给定的git哈希?

时间:2010-03-14 22:39:48

标签: git

背景:我使用一个自动构建系统,它将git哈希作为输入,以及存在该哈希的分支的名称,并构建它。但是,构建系统仅使用哈希来检查代码并构建它 - 它只是将给定的分支名称存储在构建数据库元数据中。

我担心开发人员在启动构建时会意外提供错误的分支名称,当人们查看构建历史记录时会引起混淆。

那么在将哈希和分支名称传递给构建系统之前,如何确认给定哈希实际上来自给定分支?

3 个答案:

答案 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等于其他内容,则CT的某个祖先的后代。

          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 ZevakaChris Johnsen的评论:

  

克隆后会有效吗?   克隆遥控器后,请确保您的reflog启动。因此,如果分支在克隆之前有提交,它将不会显示在reflog中。

     

推送,重新定位,提取(用于“远程跟踪”分支)和提取(合并或重定义类型)也存在问题,其中只有新提示提交结束了reflog。
  默认情况下,在裸存储库(推送的最常见目的地)中禁用reflog   此外,如果“作弊”是一个问题,只需编辑文本文件来添加或删除reflog条目,但更改历史图表本身就是一个更大的考验。