【问题标题】:git: identify all commits not complying with a patterngit:识别所有不符合模式的提交
【发布时间】:2015-06-12 10:00:36
【问题描述】:

我正在尝试使用不以[core] 开头的消息来识别所有提交。这些是我失败的尝试:

  1. 简单的方法

    git rev-list --grep '^(?!(\[core\]).).+' "branch1...branch2"
    
    • 空结果
  2. 启用扩展标志

    git rev-list -E --grep '^(?!(\[core\]).).+' "branch1...branch2"
    
    • 错误消息fatal: command line, '^(?!(\[core\]).).+': Invalid preceding regular expression

    • git grep 似乎不支持负前瞻。

  3. 将所有提交的列表与带有标签 (cf. this answer) 的提交列表进行比较:

    git rev-list "branch1...branch2" | grep -Fxv <(git rev-list -E --grep '^\[core\].+' "branch1...branch2")
    
    • sh: syntax error near unexpected token `(' 中的结果

PS:我无法升级到 Git 2.x,所以--invert-grep 不是一个选项

【问题讨论】:

  • 三个中的失败是你在&lt;(之间添加的空格。删除它。但是,如果该正则表达式在前两次尝试中无法与 rev-list 一起使用,为什么您认为它会在第三次尝试中使用?
  • 哦,我实际上在第三次尝试中使用了负等效项。当您尝试为您的问题而不是您的原始问题提供一个最小示例时,这就是问题所在:-)。删除空间并没有改变任何东西
  • 你用的是什么外壳? &lt;(...) 是进程替换,在 bash 中应该可以正常工作,但在 ash/dash/csh/etc 中不行。
  • 好吧,看来进程替换确实是问题所在。我在 Windows 下使用 git bash。当我在 git hook 中执行命令时,错误是 cannot make pipe for process substitution: Function not implemented
  • 是的,似乎 git-bash 中的 bash 不支持进程替换。命令替换虽然有效。试试我的答案中的 sn-p 吗?

标签: git grep git-rev-list


【解决方案1】:

这样的事情可能会奏效。

git rev-list "branch1...branch2" --not $(git rev-list --grep '^\[core\]')

在该列表中选择与您不想要的模式匹配的修订,然后使用--not 在另一个对rev-list 的调用中否定该修订列表。

您还可以通过使用如下的实际文件来避免在第三次尝试中进行进程替换:

git rev-list -E --grep '^\[core\].+' "branch1...branch2" > core.list
git rev-list "branch1...branch2" | grep -Fxvf core.list

【讨论】:

  • 这首先导致 git rev-list 的使用选项(--not 似乎未知),然后是该范围内所有提交的哈希值。为此需要哪个 git 版本?我现在必须保持在 2.0 以下。
  • 我使用的是 1.8.2.1,但它也在 1.7.1 的帮助中。你用的是什么版本?但在对理论的快速测试中,这个列表可能并不完全正确,我不确定为什么。
  • 我现在已经使用 bash 文件解决了这个问题(请参阅 stackoverflow.com/a/30829547/1531708),但由于我并不完全满意,我仍然没有回答这个问题。
  • 这和我的第二个解决方案一样不是吗?仅使用 shell 变量而不是临时文件(如果有效提交列表很大,则可能存在行长度限制问题,但实际上可能没问题)。
【解决方案2】:

如果它符合您使用批处理文件的要求,这是一种解决方案:

#!/bin/sh
range="branch1...branch2"
validCommits=`git rev-list -E --grep '^\[core\]' "$range"`
badCommits=`git rev-list "$range" | grep -Fxv "$validCommits"`

【讨论】:

  • 这实际上不起作用是吗?这将无法正确忽略任何提交,因为您只给 grep 一个参数(在所有由换行符分隔的提交中作为搜索词)。
  • 它确实与您的第二个解决方案相当,它起作用的原因是 $validCommits 是一个换行分隔的提交列表。用"" 包裹它可以保留它们,grep -Fx 可以实现每行匹配
  • 它似乎确实有效,尽管我一生都无法理解为什么。 -x 表示匹配项(来自模式)必须匹配源文本中的整行。我看不出是什么导致 grep 将输入拆分为行,以便它们可以独立匹配......除非这是意外或 grep 中匹配工作方式的每行性质的副作用。不过没关系。
  • 另外-x 似乎不会影响拆分行为,但如果您只想要整行匹配,这很重要(在这种情况下,我不确定您是否真的关心这一点,但肯定更重要正确指定您这样做)。
猜你喜欢
  • 1970-01-01
  • 2017-05-14
  • 2021-04-29
  • 2019-01-31
  • 2018-01-05
  • 1970-01-01
  • 2011-06-02
  • 1970-01-01
相关资源
最近更新 更多