Git:发现哪些提交触及了一系列行

Joa*_*ora 62 git blame

我无法弄清楚如何使用它git blame来获取曾经触及给定范围的行的提交集.还有像类似的问题这一个,但接受的答案没有给我带来更进一步.

假设我的定义从第1000行开始foo.rb.它只有5行长,但改变这些行的提交数量是巨大的.如果我做

git blame foo.rb -L 1000,+5
Run Code Online (Sandbox Code Playgroud)

我引用了(最多)五个不同的提交来改变这些行,但我也对"它们后面的提交"感兴趣.

同样的,

git rev-list HEAD -- foo.rb | xargs git log --oneline
Run Code Online (Sandbox Code Playgroud)

几乎是我想要的,但我无法指定行范围 git rev-list

我可以传递一个标志来git blame获取曾触及这五行的提交列表,或者构建提取此类信息的脚本的最快方法是什么?让我们暂时忽略定义曾经多于或少于5行的可能性.

Mat*_*ure 66

自从Git 1.8.4以来,git log已经-L看到了一系列线路的演变.

例如,假设您查看git blame输出:

((aa27064...))[mlm@macbook:~/w/mlm/git]
$ git blame -L150,+11 -- git-web--browse.sh
a180055a git-web--browse.sh (Giuseppe Bilotta 2010-12-03 17:47:36 +0100 150)            die "The browser $browser is not
a180055a git-web--browse.sh (Giuseppe Bilotta 2010-12-03 17:47:36 +0100 151)    fi
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 152) fi
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 153) 
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 154) case "$browser" in
81f42f11 git-web--browse.sh (Giuseppe Bilotta 2010-12-03 17:47:38 +0100 155) firefox|iceweasel|seamonkey|iceape)
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 156)    # Check version because firefox < 2.0 do
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 157)    vers=$(expr "$($browser_path -version)" 
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 158)    NEWTAB='-new-tab'
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 159)    test "$vers" -lt 2 && NEWTAB=''
a0685a4f git-web--browse.sh (Dmitry Potapov   2008-02-09 23:22:22 -0800 160)    "$browser_path" $NEWTAB "$@" &
Run Code Online (Sandbox Code Playgroud)

而你想知道现在的第155行的历史.

然后:

((aa27064...))[mlm@macbook:~/w/mlm/git]
$ git log --topo-order --graph -u -L 155,155:git-web--browse.sh
* commit 81f42f11496b9117273939c98d270af273c8a463
| Author: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
| Date:   Fri Dec 3 17:47:38 2010 +0100
| 
|     web--browse: support opera, seamonkey and elinks
|     
|     The list of supported browsers is also updated in the documentation.
|     
|     Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
|     Signed-off-by: Junio C Hamano <gitster@pobox.com>
| 
| diff --git a/git-web--browse.sh b/git-web--browse.sh
| --- a/git-web--browse.sh
| +++ b/git-web--browse.sh
| @@ -143,1 +143,1 @@
| -firefox|iceweasel)
| +firefox|iceweasel|seamonkey|iceape)
|  
* commit a180055a47c6793eaaba6289f623cff32644215b
| Author: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
| Date:   Fri Dec 3 17:47:36 2010 +0100
| 
|     web--browse: coding style
|     
|     Retab and deindent choices in case statements.
|     
|     Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
|     Signed-off-by: Junio C Hamano <gitster@pobox.com>
| 
| diff --git a/git-web--browse.sh b/git-web--browse.sh
| --- a/git-web--browse.sh
| +++ b/git-web--browse.sh
| @@ -142,1 +142,1 @@
| -    firefox|iceweasel)
| +firefox|iceweasel)
|  
* commit 5884f1fe96b33d9666a78e660042b1e3e5f9f4d9
  Author: Christian Couder <chriscool@tuxfamily.org>
  Date:   Sat Feb 2 07:32:53 2008 +0100

      Rename 'git-help--browse.sh' to 'git-web--browse.sh'.

      Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
      Signed-off-by: Junio C Hamano <gitster@pobox.com>

  diff --git a/git-web--browse.sh b/git-web--browse.sh
  --- /dev/null
  +++ b/git-web--browse.sh
  @@ -0,0 +127,1 @@
  +    firefox|iceweasel)
Run Code Online (Sandbox Code Playgroud)

如果经常使用此功能,您可能会发现git别名很有用.要做到这一点,请输入您的~/.gitconfig:

[alias]
    # Follow evolution of certain lines in a file
    # arg1=file, arg2=first line, arg3=last line or blank for just the first line
    follow = "!sh -c 'git log --topo-order -u -L $2,${3:-$2}:"$1"'" -
Run Code Online (Sandbox Code Playgroud)

现在你可以做到git follow git-web--browse.sh 155.

  • 别名中最后一个“-”符号是什么意思? (2认同)

Jon*_*ren 20

我想这就是你想要的:

git rev-list HEAD -- foo.rb | ( 
    while read rev; do
        git blame -l -L 1000,+5 $rev -- foo.rb | cut -d ' ' -f 1
    done;
) | awk '{ if (!h[$0]) { print $0; h[$0]=1 } }'
Run Code Online (Sandbox Code Playgroud)

这将输出每个提交的修订号,该提交对您选择的行进行编辑.

以下是步骤:

  1. 第一部分git rev-list HEAD -- foo.rb输出编辑所选文件的所有修订版.

  2. 然后,每个修订版都进入第二部分,每部分都采用一个并将其放入git blame -l -L 1000,+5 $rev -- foo.rb | cut -d ' ' -f 1.这是一个由两部分组成的命令.

    1. git blame -l -L 1000,+5 $rev -- foo.rb输出所选线路的责任.通过向它提供修订号,我们告诉它从该提交开始并从那里开始,而不是从头开始.
    2. 由于blame输出了一堆我们不需要的信息,因此cut -d ' ' -f 1给出了blame输出的第一列(修订版号).
  3. awk '{ if (!h[$0]) { print $0; h[$0]=1 } }'取出不相邻的重复行,同时保持它们出现的顺序.有关此命令的更多信息,请参见http://jeetworks.org/node/94.

你可以在这里添加最后一步以获得更漂亮的输出.将所有内容导入xargs -L 1 git log --oneline -1并获取修订列表的相应提交消息.我有一个奇怪的问题,使用这最后一步,我必须继续按下输出的每几个修订.我不确定为什么会这样,这就是为什么我没有把它包含在我的解决方案中.


Fer*_*rCa 11

不知道你想做什么,但也许git log -S可以为你做到这一点:

-S<string>
    Look for differences that introduce or remove an instance of <string>. 
    Note that this is different than the string simply appearing
    in diff output; see the pickaxe entry in gitdiffcore(7) for more
    details.
Run Code Online (Sandbox Code Playgroud)

您可以在字符串中输入您尝试遵循的更改(或更改的一部分),这将列出曾经触及此更改的提交.

  • +1因为它有助于谷歌与这个问题标题有类似的问题 (5认同)