【问题标题】:How to list all tags containing a commit's changes?如何列出包含提交更改的所有标签?
【发布时间】:2021-03-15 21:56:20
【问题描述】:

假设我有 2 个标签 XY 这样

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

如果hash(Ci) = hash(Zj)(对于给定的ij)并且我想知道所有具有提交Ci 的标签,我可以这样做,如“https://stackoverflow.com/questions/ 7923091/how-to-list-all-tags-that-c​​ontain-a-commit”,

git tag --contains Ci

那会给我XY

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


编辑

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

【问题讨论】:

  • “包含给定提交的更改”是什么意思?你心中有一个准确的定义吗?
  • 标签不包含提交。标签只是提交的指针。提交不包含更改,每个提交都包含完整的文件树(快照)。 Git 是基于快照的 DVCS,而不是基于更改的。
  • @LeGEC 看看我的编辑!

标签: git git-commit git-tag


【解决方案1】:

不,这不能通过标准git 功能完全自动且可靠地完成。即使您不编辑提交消息,SHA-1 也会在挑选时发生变化。不能有 2 个具有相同 SHA-1 的提交。

对跟踪的一些支持由

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

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

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

【讨论】:

  • 谢谢!是的,我已经编辑了帖子以使问题更易于理解 =)
【解决方案2】:

我会想到的一般是:

  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)。

您还可以通过运行发现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 $2 }'

  • 而不是列出 您的 repo 中的所有提交 (git rev-list --all),您可能希望使用第一个命令之一来缩小初始搜索范围:git log --grep ... 或 @ 生成的列表中的 feed 987654340@或git log -- that/specific/dir ...

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

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

  • 等等等等等等……

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

【讨论】:

    猜你喜欢
    • 2011-12-16
    • 2015-05-26
    • 1970-01-01
    • 2019-04-04
    • 2011-04-11
    • 2015-03-30
    • 2011-05-31
    • 2017-05-09
    • 1970-01-01
    相关资源
    最近更新 更多