如何反转`git log --grep = <pattern>`或如何显示与模式不匹配的git日志

sal*_*ane 34 git git-log

我想用来git log显示与给定模式不匹配的所有提交.我知道我可以使用以下内容来显示与模式匹配的所有提交:

git log --grep=<pattern>
Run Code Online (Sandbox Code Playgroud)

如何反转匹配感?

我试图忽略消息中"碰到版本..."的提交.

编辑:我希望我的最终输出非常详细.例如git log --pretty --stat.所以输出git log --format=oneline对我来说不起作用.

Von*_*onC 25

这将有可能与Git的2.4及以上(2015年第二季度):见犯22dfa8a克里斯托夫·容汉斯(junghans):

log:教--invert-grep选项

" git log --grep=<string>"仅显示具有与给定字符串匹配的消息的提交,但有时能够仅显示没有特定消息的提交(例如"向我显示不是FIXUP提交的提交")是有用的.

最初,我们有了invert-grep旗帜grep_opt,但是因为" git grep --invert-grep"没有意义,除了与" --files-with-matches"已经涵盖的" --files-without-matches"相关,它被移动到修改结构.
要在那里有标志更好地表达功能的功能.

当新插入的两个测试运行时,历史记录将提交消息" initial"," second"," third"," fourth"," fifth"," sixth"和" Second",按此顺序提交.
与" th"或" Sec" 不匹配的提交是" second"和" initial".对于不区分大小写的情况,只有" initial"匹配.

--invert-grep
Run Code Online (Sandbox Code Playgroud)

将提交输出限制为具有与指定模式不匹配的日志消息的输出--grep=<pattern>.

例:

我首先在其中使用"sequencer"grep消息:

vonc@voncm C:\Users\vonc\prog\git\git

> git log -2 --pretty="tformat:%s" --grep=sequencer
Merge branch 'js/sequencer-wo-die'
sequencer: ensure to release the lock when we could not read the index
Run Code Online (Sandbox Code Playgroud)

如果我想要没有音序器的消息:

> git log -2 --pretty="tformat:%s" --grep=sequencer --invert-grep
Second batch for 2.11
Merge branch 'js/git-gui-commit-gpgsign'
Run Code Online (Sandbox Code Playgroud)

  • @VonC啊,是的,我没有意识到这是一个开关.我在做`--invert-grep = foo`.这对我现在有用,虽然它没有我想象的那么有用.能够在一个命令中指定"包含此AND并不包含此内容"会很好.谢谢! (2认同)

Gre*_*con 15

生成所有提交的列表,减去其日志消息包含违规模式的提交,并将结果git log提供给所需的选项.在最后阶段,有两个方案可以git log使用:

--stdin
除了命令行中列出的提交外,还要从标准输入中读取它们.

--no-walk
只显示给定的转速,但不要遍历它们的祖先.

您可以使用单个管道和流程替换来完成此操作.

#! /bin/bash

if (( $# < 1 )); then
  echo >&2 "Usage: $0 pattern [<since>..<until>]"
  exit 1
fi

pattern=$1
shift

git log --format=%H $@ |
  grep -v -f <(git log --format=%H "--grep=$pattern" $@) |
  git log --pretty --stat --stdin --no-walk
Run Code Online (Sandbox Code Playgroud)

如果您不想使用bash,可以使用Perl.

#! /usr/bin/env perl

use strict;
use warnings;
no warnings "exec";

sub usage { "Usage: $0 pattern\n" }

sub commits_to_omit {
  my($pattern) = @_;

  open my $fh, "-|", "git", "log", "--grep=$pattern", "--format=%H", @ARGV
    or die "$0: exec: $!";
  my %omit = map +($_ => 1), <$fh>;
  %omit;
}

die usage unless @ARGV >= 1;
my $pattern = shift;

my %omit = commits_to_omit $pattern;

open my $all, "-|", "git", "log", "--format=%H", @ARGV
  or die "$0: exec: $!";

open my $out, "|-", "git", "log", "--pretty", "--stat", "--stdin", "--no-walk"
  or die "$0: exec: $!";

while (<$all>) {
  print $out $_ unless $omit{$_};
}
Run Code Online (Sandbox Code Playgroud)

假设上面的一个在你的PATH中,git-log-vgrep并且有一个表格的历史

$ git lola
* b0f2a28 (tmp, feature1) D
* 68f87b0 C
* d311c65 B
* a092126 A
| * 83052e6 (HEAD, origin/master, master) Z
| * 90c3d28 Y
| * 4165a42 X
| * 37844cb W
|/  
* f8ba9ea V

我们可以说

$ git log-vgrep X

获得Z,Y,W和V.

您也可以记录其他分支

$ git log-vgrep A tmp

给出D,C,B和V; 和

$ git log-vgrep C tmp~2..tmp

收益率只是D.

上述实现的一个限制是,如果您使用匹配所有提交的模式,例如,.或者^,那么您将获得HEAD.这是如何git log工作:

$ git log --stdin --no-walk --pretty=oneline </dev/null
83052e62f0dc1c6ddfc1aff3463504a4bf23e3c4 Z


the*_*guy 8

一个具有很大灵活性的相对简单的方法是使用git log并将-z选项通过管道输入到awk.-z选项在提交记录之间添加空值,因此可以使用awk轻松解析:

git log --color=always -z | awk -v RS=\\0
Run Code Online (Sandbox Code Playgroud)

(color =始终需要在输出为管道时保持着色).然后,它很简单地添加你希望在每个字段上工作的任何布尔表达式.例如,这将打印作者电子邮件不是来自fugly.com的所有条目,并且提交日期是星期日:

git log --color=always -z | awk -v RS=\\0 '!/Author:.*fugly.com>/ && /Date:.* Sun /'
Run Code Online (Sandbox Code Playgroud)

另一个好处是你可以在git日志中添加任何格式化选项或修订版本范围,它仍然有效.

最后一件事,如果你想分页,使用"less -r"来保持颜色.

编辑:改为在awk中使用-v使其更简单一些.