如何列出包含提交更改的所有标签?
How to list all tags containing a commit's changes?
假设我有 2 个标签 X
和 Y
这样
tag X log history: C1 C2 ... Cn
tag Y log history: Z1 Z2 ... Zm
如果 hash(Ci) = hash(Zj)
(对于给定的 i
和 j
)并且我想知道所有具有提交 Ci
的标签我可以做到,如“ ",
git tag --contains Ci
那会给我 X
和 Y
。
对于 hash(Ci) != hash(Zj)
的情况是否有可能获得相同的响应,但它们都应用了相同的更改(例如,它们都在同一文件中添加了相同的行,但它们在提交信息)?
编辑
说标签“包含给定提交的更改”是指在标签的日志历史记录中,有一个提交 C
应用了与给定提交相同的修改。
一般我会想到的是:
- 查找含义为“如果标记包含此提交,则它包含更改”的提交列表
- 将包含任何这些提交的所有标签组合在一起
最难的部分是确定 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.txt
或 that/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 可以执行此类流程
假设我有 2 个标签 X
和 Y
这样
tag X log history: C1 C2 ... Cn
tag Y log history: Z1 Z2 ... Zm
如果 hash(Ci) = hash(Zj)
(对于给定的 i
和 j
)并且我想知道所有具有提交 Ci
的标签我可以做到,如“ ",
git tag --contains Ci
那会给我 X
和 Y
。
对于 hash(Ci) != hash(Zj)
的情况是否有可能获得相同的响应,但它们都应用了相同的更改(例如,它们都在同一文件中添加了相同的行,但它们在提交信息)?
编辑
说标签“包含给定提交的更改”是指在标签的日志历史记录中,有一个提交 C
应用了与给定提交相同的修改。
一般我会想到的是:
- 查找含义为“如果标记包含此提交,则它包含更改”的提交列表
- 将包含任何这些提交的所有标签组合在一起
最难的部分是确定 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.txt
或 that/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 可以执行此类流程