为了账号安全,请及时绑定邮箱和手机立即绑定

查找Git分支的父分支

查找Git分支的父分支

Git
HUH函数 2019-06-20 16:16:36
查找Git分支的父分支假设我有下面的本地存储库,其中有一个像这样的提交树:master --> a             \              \       develop c --> d                \                 \          feature f --> g --> hmaster是我的这是最新的稳定版本代码。, develop是我的这是“下一步”发布代码,和feature是一个正在准备的新特性develop.我想要用钩子在我的远程回购系统上做的事情,就是推到feature除非已作出承诺,否则将被拒绝f是直系的后裔develop头。也就是说,提交树看起来是这样的,因为特性已经被git rebase在……上面d.master --> a             \              \       develop c --> d                      \                       \                feature f --> g --> h是否有可能:的父分支。feature?标识父分支中的提交f是他的后代吗?从那里我会检查什么是家长分支的负责人,看看是否f前辈匹配父分支头,以确定是否需要重新建立功能。
查看完整描述

3 回答

?
BIG阳

TA贡献1859条经验 获得超6个赞

假设远程存储库有发展分支(您最初的描述是在本地存储库中描述它,但它似乎也存在于远程),您应该能够实现我认为您想要的结果,但是这种方法与您所设想的略有不同。

Git的历史是基于达格犯下的罪行。分支(和一般的“参考”)只是指持续增长的COMMIT DAG中指向特定提交的临时标签。因此,分支之间的关系可以随时间而变化,但提交之间的关系则不会。

    ---o---1                foo
            \
             2---3---o      bar
                  \
                   4
                    \
                     5---6  baz

看上去baz基于(旧版本的)bar?但如果我们删除bar?

    ---o---1                foo
            \
             2---3
                  \
                   4
                    \
                     5---6  baz

现在看起来baz是基于foo..但是他的祖先baz没有更改,我们只是删除了一个标签(以及由此产生的悬空提交)。如果我们在4?

    ---o---1                foo
            \
             2---3
                  \
                   4        quux
                    \
                     5---6  baz

现在看起来baz是基于quux..然而,祖先并没有改变,只有标签改变了。

然而,如果我们要求“是提交”6承诺的后代3“(假设)36都是完整的sha-1提交名称),则答案将是“,无论barquux标签是否存在。

因此,您可以问这样的问题:“推送提交是当前提示的后代吗?发展“分支?”,但您无法可靠地问:“推送提交的父分支是什么?”

一个最可靠的问题似乎接近你想要的是:

对于所有推送提交的祖先(不包括当前的发展(以及它的祖先),它们目前的尖端是发展作为家长:

  • 至少存在一次这样的提交吗?
  • 所有这些提交都是单亲提交吗?

可作为:

pushedrev=...basename=developif ! baserev="$(git rev-parse --verify refs/heads/"$basename" 2>/dev/null)"; then
    echo "'$basename' is missing, call for help!"
    exit 1fiparents_of_children_of_base="$(
  git rev-list --pretty=tformat:%P "$pushedrev" --not "$baserev" |
  grep -F "$baserev"
)"case ",$parents_of_children_of_base" in
    ,)     echo "must descend from tip of '$basename'"
           exit 1 ;;
    ,*\ *) echo "must not merge tip of '$basename' (rebase instead)"
           exit 1 ;;
    ,*)    exit 0 ;;esac

这将涵盖一些您想要的限制,但可能不是所有。

作为参考,下面是一个扩展的示例历史记录:

    A                                   master
     \
      \                    o-----J
       \                  /       \
        \                | o---K---L
         \               |/
          C--------------D              develop
           \             |\
            F---G---H    | F'--G'--H'
                    |    |\
                    |    | o---o---o---N
                     \   \      \       \
                      \   \      o---o---P
                       \   \   
                        R---S

以上代码可用于拒绝HS接受时H'JK,或N,但它也会接受LP(它们涉及合并,但它们不合并发展).

也拒绝LP,你可以改变问题并问

对于所有推送提交的祖先(不包括当前的发展(及其祖先):

  • 有与父母双方的承诺吗?
  • 如果没有,是否至少有一个这样的提交具有当前提示

    发展

    它(仅)父母?
pushedrev=...basename=developif ! baserev="$(git rev-parse --verify refs/heads/"$basename" 2>/dev/null)"; then
    echo "'$basename' is missing, call for help!"
    exit 1fiparents_of_commits_beyond_base="$(
  git rev-list --pretty=tformat:%P "$pushedrev" --not "$baserev" |
  grep -v '^commit '
)"case "$parents_of_commits_beyond_base" in
    *\ *)          echo "must not push merge commits (rebase instead)"
                   exit 1 ;;
    *"$baserev"*)  exit 0 ;;
    *)             echo "must descend from tip of '$basename'"
                   exit 1 ;;esac


查看完整回答
反对 回复 2019-06-20
?
湖上湖

TA贡献2003条经验 获得超2个赞

重新措辞

另一种表达问题的方法是“在当前分支以外的分支上驻留的最近的提交是什么,这是哪个分支?”

解决方案

你可以用一点命令行魔法找到它。

git show-branch -a \
| grep '\*' \
| grep -v `git rev-parse --abbrev-ref HEAD` \
| head -n1 \
| sed 's/.*\[\(.*\)\].*/\1/' \
| sed 's/[\^~].*//'

下面是它的工作原理:

  1. 显示所有提交的文本历史记录,包括远程分支。
  2. 当前提交的祖先由恒星指示。过滤掉其他的一切。
  3. 忽略当前分支中的所有提交。
  4. 第一个结果是最近的祖先分支。忽略其他结果。
  5. 分支名称显示在[括号中]。忽略括号之外的所有内容和括号。
  6. 有时,分支名称将包含一个~#或^#,以指示在引用的提交和分支提示之间提交了多少次。我们不在乎。别理他们。

结果

上运行上述代码

 A---B---D <-master
      \
       \
        C---E---I <-develop
             \
              \
               F---G---H <-topic

会给你develop如果你从H和master如果你从我那里查到的话。

该代码可作为一个要点使用。


查看完整回答
反对 回复 2019-06-20
?
MMTTMM

TA贡献1869条经验 获得超4个赞

你也可以尝试:

git log --graph --decorate


查看完整回答
反对 回复 2019-06-20
  • 3 回答
  • 0 关注
  • 2780 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信