如何列出包含提交更改的所有标签?

How to list all tags containing a commit's changes?

假设我有 2 个标签 XY 这样

tag X log history: C1 C2 ... Cn
tag Y log history: Z1 Z2 ... Zm

如果 hash(Ci) = hash(Zj)(对于给定的 ij)并且我想知道所有具有提交 Ci 的标签我可以做到,如“ ",

git tag --contains Ci

那会给我 XY

对于 hash(Ci) != hash(Zj) 的情况是否有可能获得相同的响应,但它们都应用了相同的更改(例如,它们都在同一文件中添加了相同的行,但它们在提交信息)?


编辑

说标签“包含给定提交的更改”是指在标签的日志历史记录中,有一个提交 C 应用了与给定提交相同的修改。

一般我会想到的是:

  1. 查找含义为“如果标记包含此提交,则它包含更改”的提交列表
  2. 将包含任何这些提交的所有标签组合在一起

最难的部分是确定 1.,所以首先是最简单的部分 :


  • 对于第 2 点:如果您有提交列表:
# in a file, or as the output of a commit :
eacf32c
44df701
...

只是 运行 重复 git tag --contains,然后合并结果:

cat thelist.txt | while read sha; do git tag --contains $sha; done | sort -u

  • 对于第 1 点:查找提交列表

这在很大程度上取决于您打算如何针对上述更改。这里有一些例子:

  • 如果您知道您只想针对使用 git cherry-pick 应用的提交,提交消息很可能会非常相似:git log --all --grep "one discriminating sentence"git log --all --grep "#issuenumber" 将可能会给你一个很好的起点

  • 如果你想针对添加或删除一个特定行的提交:从 git log --all -S "a specific line"git log --all -G "a specific line" 开始(如果你需要更多解释,请阅读 the doc for -S and -G他们是如何工作的)。

您还可以通过 运行ning 发现 that/specific/file.txtthat/specific/dir 的变化:

git log -S "a specific line" -- that/specific/file.txt
git log -G "a specific line" -- that/specific/dir
  • 如果您想发现将 完全相同的补丁 引入您的代码库的提交,事实证明 git 有一个算法:git patch-id
    注意 :它在 git rebase 中用于发现已经在目标上应用的提交)

在你的 repo 的完整提交列表上使用它会有点复杂,但它可以自动化:

首先计算您要发现的更改的补丁 ID :

$ git show A | git patch-id --stable
# this will give you a two fields output :
# a hash for the diff itself             the hash of the commit
3bbe48e8ce5714b78900653e618ff4dc41205ffb 84d48dcd44d440d3a35177c92c897d2efae93346

然后计算所有补丁 ID,然后 grep 找到你想要的:

git rev-list --all | while read sha; do git show $sha | git patch-id; done
  | grep "^3bbe48e8ce5714b78900653e618ff4dc41205ffb"

第二列将是提交列表:... | awk '{ print }'

  • 而不是列出 存储库中的所有提交 (git rev-list --all),您可能希望使用第一个命令来缩小初始搜索范围: 输入由 git log --grep ...git log -S ...git log -- that/specific/dir ...

    生成的列表
  • 您可以通过更改 git show 命令对“特定文件的补丁”使用相同的技巧:

git show $sha -- file1 file2 dir3 | git patch-id
  • 您可以编写自己的脚本,它接受一个提交 ID,并检查它是否包含您想要的内容

  • 等等等等……

注意:如果您有一个 git log 命令可以让您发现您感兴趣的一些提交,您可以通过删除所有格式化选项(--onelin, --graph, --format ...) 并将它们替换为 --format="%H"

不,使用标准 git 功能无法完全自动且可靠地完成此操作。 SHA-1 在挑选时总​​是会发生变化,即使您不编辑提交消息也是如此。不能有 2 次提交具有相同的 SHA-1。

提供了一些跟踪支持
  • git cherry-pick -x 会将原来的 SHA-1 插入到新提交的提交消息中。但是,如果您忘记使用 -x,则“link”会丢失。
  • git log "-S${string}" --all 如果您知道对您的更改具有特征(足够)的字符串,则在所有分支中搜索更改。
  • Using Git, how could I search for a string across all branches?

问题想使用标签。但是标签也没有这样添加这样神奇的功能。

您将需要一个进程来在提交消息中进行必要的交叉引用。 CI 可以执行此类流程