我怎样才能确定给定的分支上是否存在给定的git散列? [英] How can I determine if a given git hash exists on a given branch?

查看:109
本文介绍了我怎样才能确定给定的分支上是否存在给定的git散列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

所以我该如何确认,在将散列和分支名称传递给构建系统之前,给定的散列实际上来自给定的分支?解析方案

嗯,这个分支名称的使用看起来很腥。正如在Dustin的回答中那样,可能有多个包含提交的分支。为什么这些分支名称中的任何一个比另一个更好?






如果您只关心一个特定的分支,您可以计算分支和提交之间的合并基。

在下面的图中,构建提交是 C ,声明的分支的尖端是 T ,并且合并基底上面标有 M > 。


  • / code>等于 T ,那么构建的提交是声明分支的提示。

     M 

    o - o - o - o - o - x分支#x既是C也是T


  • / code>,那么声明的分支的提示是提交生成的后代。

      M 

    o - o - C - o - o - T分支


  • 如果 M 等于 T ,那么构建的提交就是声明分支尖端的后代。

      M 

    o - o - T分支
    \
    o - o - C

  • 如果 M 等于别的东西,那么 C 是一个 T

      M 
    ↓的某个祖先的后代
    o - o - o - o - o - T分支
    \
    o - o - C


  • 如果没有 M ,则构建提交与声明无关

      o  -  o  -  o  -  o  -  o  -  T分支

    o - o - o - o - C




您可以这样检查:

 #!/ bin / sh 

#用法:is-ancestor-of< branch> <提交>

如果测试$#-ne 2;那么
回显$ 0:无效参数'
出口128
fi
claims_branch =$ 1
提交=$ 2

merge_base =$(git merge-base$ commit$ claims_branch)&&
test -n$ merge_base&&
test$ merge_base=$(git rev-parse --verify$ commit)&&
exit 0

echo$ commit不是$ claim_branch的祖先1& 2
exit 1

上面的脚本实际上并不需要或检查'branch'参数是否是分支(它可以是任何提交 - ish)。要检查某件事实际上是一个分支,你可以使用类似这样的东西:

 #!/ bin / sh 

#用法:is-branch< branch>

如果测试$#-ne 1;然后
echo$ 0':无效参数'
退出128
fi
分支=$ 1

#检查各种分支层级,需要
git show-ref --verify refs / heads /$ branch||
git show-ref --verify refs / remotes /$ branch|| {
echo不是分行名称:$ branch1>& 2
exit 1
}

所以你可以一起使用它们来验证某个事物是分支,并且某个提交在该分支中:

  is-branch$ claims_branch&& $ claims_branch的祖先$ commit_to_build


Background: I use an automated build system which takes a git hash as input, as well as the name of the branch on which that hash exists, and builds it. However, the build system uses the hash alone to check out the code and build it -- it simply stores the branch name, as given, in the build DB metadata.

I'm worried about developers accidentally providing the wrong branch name when they kick off a build, causing confusion when people are looking through the build history.

So how can I confirm, before passing along the hash and branch name to the build system, that the given hash does in fact come from the given branch?

解决方案

Hmm, this use of a branch name seems fishy. As in Dustin's answer, there may be multiple branches that contain a commit. Why is any one of those branch names better than another for this purpose?


If you only care about one specific branch, you could compute the "merge base" between the branch and the commit.

In the following diagrams, the commit to build is C, the tip of the claimed branch is T, and the merge base is labeled with M above it.

  • If M equals C equals T, then the the commit to build is the tip of the claimed branch.

                   M
                   ↓
    o--o--o--o--o--x  branch  # x is both C and T
    

  • If M equals C, then the tip of the claimed branch is a descendent of the commit to build.

          M
          ↓
    o--o--C--o--o--T  branch
    

  • If M equals T, then the commit to build is a descendent of the tip of the claimed branch.

          M
          ↓
    o--o--T           branch
           \
            o--o--C
    

  • If M equals something else, then C is a descendent of some ancestor of T.

          M
          ↓
    o--o--o--o--o--T  branch
           \
            o--o--C
    

  • If there is no M, then the commit to build is not related to the claimed branch.

    o--o--o--o--o--T branch
    
    o--o--o--o--C
    

You can make this check like this:

#!/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

The above script does not actually require or check that the ‘branch’ argument is a branch (it could be any commit-ish). To check that something is actually a branch, you might use something like this:

#!/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
}

So you could use them together to verify that something is a branch and that a certain commit is in that branch:

is-branch "$claimed_branch" && is-ancestor-of "$claimed_branch" "$commit_to_build"

这篇关于我怎样才能确定给定的分支上是否存在给定的git散列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆