如何判断集成分支是否包含特性分支
How to determine if integration branch contains feature branch
我正在做删除本地分支的可怕工作。我从我们的集成分支获取最新的:
git fetch origin dev
然后我想将 origin/dev 与本地功能分支进行比较。但是我不想签出origin/dev。我相信目标是确保 origin/dev 的 git 日志包含每个功能分支的提示(最新提交)。
以下命令对我的情况不是很有效:
git branch --contains <commit-id>
- 不清楚如何使用当前分支以外的分支。
- 我没有比较分支的commit-id,但是我有分支名称。
所以我正在寻找替代命令:
git branch origin/dev --contains-branch <some-feature-branch>
是否有可以执行此操作的命令?
git branch --contains
所做的是:
- 将
HEAD
解析为提交哈希。如果您在分支 br
上,这会将 name br
解析为提交哈希。 (让一些变量 h 代表这个散列。)
对于所有分支名称:
- 将名称解析为提交哈希。我们将此称为 b 作为分支哈希。
- 测试祖先性:b 是 h 的祖先吗?
- 如果 b 是 h 的祖先,打印该分支的名称。
命令现在完成:它列出了分支的名称,其分支尖端提交包含在该分支中。
你的问题很相似,但更简单。您想要将名称 origin/dev
解析为某个散列 h。然后,对于分支名称的某些子集——您关心的功能名称——您想要:
- 将名称解析为哈希 ID b.
- 测试祖先性:b 是 h 的祖先吗? (换句话说:这个分支的 tip 提交是否包含在
origin/dev
中,是因为它是 origin/dev
的 tip 提交的祖先?)
- 如果是,打印名称。
有一个命令实现了这个 "is-ancestor" 测试,但有点令人惊讶:它是 git merge-base
。命令:
git merge-base $b $h
如果 $b 是 $h 的祖先则报告成功(退出零),否则报告失败(退出非零)。它实施的 "is ancestor" 测试与 git branch --contains
使用的相同,因此这直接提供了您想要的答案。
剩下的问题是找到所需的分支名称。 git for-each-ref
命令就是专门为此而设计的。
因此:
hname=origin/dev
h=$(git rev-parse $hname) || die "cannot get commit hash ID for $hname"
git for-each-ref --format='%(refname:short) %(objectname)' refs/heads/feature |
while read name b; do
if git merge-base --is-ancestor $h $b; then
echo $name is contained within $hname
fi
done
(注:未经测试)。这里的 refs/heads/feature
代表名为 feature/*
的分支;如果你有一个不同的模式,你需要匹配,使用那个不同的模式,或者使用 refs/heads
本身并在循环中放一些东西来跳过 "uninteresting" 分支名称,或者任何需要的东西。
有关详细信息,请参阅 git merge-base
and git for-each-ref
(and git rev-parse
的文档。
要列出可从 origin/dev
到达的分支提示,您可以使用
git branch --merged origin/dev
请注意,如果它是本地分支机构(我假设不是您的情况),它会列出 origin/dev
。
如果您想围绕 git branch
编写脚本,请注意这是一个 "porcelain" 命令,即它的输出格式并非一成不变,可能会在 [= 的未来版本中发生变化21=].
我正在做删除本地分支的可怕工作。我从我们的集成分支获取最新的:
git fetch origin dev
然后我想将 origin/dev 与本地功能分支进行比较。但是我不想签出origin/dev。我相信目标是确保 origin/dev 的 git 日志包含每个功能分支的提示(最新提交)。
以下命令对我的情况不是很有效:
git branch --contains <commit-id>
- 不清楚如何使用当前分支以外的分支。
- 我没有比较分支的commit-id,但是我有分支名称。
所以我正在寻找替代命令:
git branch origin/dev --contains-branch <some-feature-branch>
是否有可以执行此操作的命令?
git branch --contains
所做的是:
- 将
HEAD
解析为提交哈希。如果您在分支br
上,这会将 namebr
解析为提交哈希。 (让一些变量 h 代表这个散列。) 对于所有分支名称:
- 将名称解析为提交哈希。我们将此称为 b 作为分支哈希。
- 测试祖先性:b 是 h 的祖先吗?
- 如果 b 是 h 的祖先,打印该分支的名称。
命令现在完成:它列出了分支的名称,其分支尖端提交包含在该分支中。
你的问题很相似,但更简单。您想要将名称 origin/dev
解析为某个散列 h。然后,对于分支名称的某些子集——您关心的功能名称——您想要:
- 将名称解析为哈希 ID b.
- 测试祖先性:b 是 h 的祖先吗? (换句话说:这个分支的 tip 提交是否包含在
origin/dev
中,是因为它是origin/dev
的 tip 提交的祖先?) - 如果是,打印名称。
有一个命令实现了这个 "is-ancestor" 测试,但有点令人惊讶:它是 git merge-base
。命令:
git merge-base $b $h
如果 $b 是 $h 的祖先则报告成功(退出零),否则报告失败(退出非零)。它实施的 "is ancestor" 测试与 git branch --contains
使用的相同,因此这直接提供了您想要的答案。
剩下的问题是找到所需的分支名称。 git for-each-ref
命令就是专门为此而设计的。
因此:
hname=origin/dev
h=$(git rev-parse $hname) || die "cannot get commit hash ID for $hname"
git for-each-ref --format='%(refname:short) %(objectname)' refs/heads/feature |
while read name b; do
if git merge-base --is-ancestor $h $b; then
echo $name is contained within $hname
fi
done
(注:未经测试)。这里的 refs/heads/feature
代表名为 feature/*
的分支;如果你有一个不同的模式,你需要匹配,使用那个不同的模式,或者使用 refs/heads
本身并在循环中放一些东西来跳过 "uninteresting" 分支名称,或者任何需要的东西。
有关详细信息,请参阅 git merge-base
and git for-each-ref
(and git rev-parse
的文档。
要列出可从 origin/dev
到达的分支提示,您可以使用
git branch --merged origin/dev
请注意,如果它是本地分支机构(我假设不是您的情况),它会列出 origin/dev
。
如果您想围绕 git branch
编写脚本,请注意这是一个 "porcelain" 命令,即它的输出格式并非一成不变,可能会在 [= 的未来版本中发生变化21=].