每次提交后,只打印一行包含换行符的提交历史记录?

时间:2018-03-23 19:16:21

标签: bash git scripting git-log

我正在尝试编写一个bash脚本,为文件中的每一行打印出N,其中N是在提交中编辑该行的次数。也就是说,对于一个五行文件,其中第一行被更改了4次而其余的只被添加(即只有一次提交),脚本将输出:

4
1
1
1

到目前为止,我能够在每一行上记录文件更改:

CTR=0
while IFS= read -r line; do
    ((CTR++))
    echo $(git log --pretty=format:"%h%x09%an%x09%ad%x09%s" -L $CTR,$CTR:"$1")
done < "$1"

但是当我打印结果时,每行的提交历史记录只占用一行结果(下面的第二行包含文件第二行的整个多提交历史记录):

2182a65 Anonymous Fri Mar 23 14:34:36 2018 -0400 second commit diff --git a/hello.py b/hello.py --- a/hello.py +++ b/hello.py @@ -0,0 +1,1 @@ +This is the second commit.
1814257 Anonymous Fri Mar 23 14:35:26 2018 -0400 Fourth commit diff --git a/hello.py b/hello.py --- a/hello.py +++ b/hello.py @@ -2,1 +2,1 @@ -This is the third commit. +This is the fourth commit now! c3f1021 Anonymous Fri Mar 23 14:34:59 2018 -0400 Third commit diff --git a/hello.py b/hello.py --- a/hello.py +++ b/hello.py @@ -2,0 +2,1 @@ +This is the third commit.
c3f1021 Anonymous Fri Mar 23 14:34:59 2018 -0400 Third commit diff --git a/hello.py b/hello.py --- a/hello.py +++ b/hello.py @@ -2,0 +3,1 @@ +This is also the third commit.

我计划通过计算每行历史记录的行数来跟踪每行的提交数量,但这样做是不可能的。

如何在每次提交后打印一行包含换行符的提交历史记录?

1 个答案:

答案 0 :(得分:0)

这是你的:

echo $(...)

正在吃新线。请记住,$(...)在括号中运行命令,然后应用其他替换规则,如the Command Substitution section of the documentation中所述:

  

Bash通过在子shell环境中执行命令并使用命令的标准输出替换命令替换来执行扩展,并删除任何尾随换行符。嵌入的换行不会被删除,但在分词时可能会被删除。 ...

     

如果替换出现在双引号内,则不会对结果执行单词拆分和文件名扩展。

由于此处没有双引号,因此在结果上执行了单词拆分和文件名扩展 。这就是删除换行符的原因。

值得考虑的事情是:Git没有 file 历史记录。 Git有提交,提交历史记录,提交有文件。为了生成伪造的文件历史记录,Git最终将每个提交与其父级进行比较。对1234567:file.ext进行89abcde:file.ext差异会告诉您从提交file.ext(父级)移动到提交1234567(子级)时89abcde中的更改。

这一切都很有意义,并且正如大家所期望的那样,对于只有一个父级的普通提交。但是,对于 merge 提交,提交有两个父项。将孩子中的特定文件与一个或另一个父母进行比较通常会产生不同的答案。应该使用哪个父母? git log实用程序有几个不同的答案,具体取决于您认为应该适用的规则。有关详细信息,请参阅the History Simplification section of the git log documentation