UpA*_*dam 23 git version-control
在先前的问题中,有人为查找包含EXACT提交的分支提供了答案:
接受的答案强调,这仅适用于EXACT提交ID,而不适用于相同的提交.有人进一步指出,Git Cherry可以用来解决这个问题.
Git樱桃SEEMS适合反向; 发现提交没有推到上游.如果我不知道哪个分支创建它以及什么是上游,那么这是无用的.所以我不知道它将如何帮助解决这个问题.
有人可以解释/提供一个如何使用git cherry查找包含特定提交的"等效"的所有分支的示例吗?
And*_*w C 20
在您回答哪些分支包含等效提交的问题之前,您必须确定"哪些提交是等效的".完成后,您只需使用git branch --contains
每个提交.
不幸的是,没有100%可靠的方法来确定等效提交.
最可靠的方法是检查提交引入的变更集的补丁ID.这是什么git cherry
,git log --cherry
并且git log --cherry-mark
依赖.在内部,他们都打电话git patch-id
.补丁ID只是标准化变化差异的SHA1.引入相同更改的任何提交都将具有相同的修补程序ID.此外,任何引入大多数相同更改的提交都将具有相同的修补程序ID,这些更改仅在空格或它们在文件中应用的行号不同.如果两个提交具有相同的补丁ID,则几乎可以保证它们是等效的 - 您几乎不会通过补丁ID获得误报.但是经常出现假阴性.任何时候你git cherry-pick
必须手动解决合并冲突,你可能会在变更集中引入差异.即使1个字符的更改也会导致生成不同的修补程序ID.
检查修补程序ID需要按照Chronial建议编写脚本.首先用类似的方法计算原始提交的补丁ID
(注意 - 未经测试的脚本应该合理地接近工作)
origCommitPatchId=$(git diff ORIG_COMMIT^! | git patch-id | awk '{print $1}')
Run Code Online (Sandbox Code Playgroud)
现在,您将不得不搜索历史记录中的所有其他提交并计算它们的修补程序ID,并查看它们是否相同.
for rev in $(git rev-list --all)
do
testPatchId=$(git diff ${rev}^1..${rev} | git patch-id | awk '{print $1}')
if [ "${origCommitPatchId}" = "${testPatchId}" ]; then
echo "${rev}"
fi
done
Run Code Online (Sandbox Code Playgroud)
现在你有了SHA的列表,你可以将它们传递给 git branch -a --contains
如果由于合并冲突,上述内容对您不起作用怎么办?
好吧,还有一些其他的东西你可以试试.通常,当您选择提交时,将保留提交中的原始作者姓名,电子邮件和日期字段.因此,您将获得新的提交,但作者信息将是相同的.
因此,您可以从原始提交中获取此信息
git log -1 --pretty="%an %ae %ad" ORIG_COMMIT
Run Code Online (Sandbox Code Playgroud)
然后和以前一样,您必须完成历史记录中的每个提交,打印出相同的信息并进行比较.这可能会给你一些额外的匹配.
您还可以使用git log --grep=ORIG_COMMIT
哪个会在提交消息中找到引用ORIG_COMMIT的任何提交.
如果这些都不起作用,您可以尝试查找随pickaxe引入的特定行,或者可以git log --grep
查找提交消息中可能唯一的其他内容.
如果这听起来很复杂,那就好了.这就是为什么我告诉人们尽可能避免使用樱桃挑选. git branch --contains
非常有价值且易于使用且100%可靠.其他解决方案都没有接近.
以下似乎有效(但尚未经过多次测试).它git cherry
为每个本地git分支运行,如果git cherry
没有从分支中列出缺少的提交,则打印分支名称.
# USAGE: git-cherry-contains <commit> [refs]
# Prints each local branch containing an equivalent commit.
git-cherry-contains() {
local sha; sha=$(git rev-parse --verify "$1") || return 1
local refs; refs=${2:-refs/heads/}
local branch
while IFS= read -r branch; do
if ! git cherry "$branch" "$sha" "$sha^" | grep -qE "^\+ $sha"; then
echo "$branch"
fi
done < <(git for-each-ref --format='%(refname:short)' $refs)
}
Run Code Online (Sandbox Code Playgroud)
请参阅Andrew C的帖子,了解git cherry
实际工作原理(使用git patch-id
).