首页 > 解决方案 > 用于获取文件更改和错误问题的 Git 日志

问题描述

所以我想获取有关 git 存储库中更改的信息。我使用了以下命令:

git log --name-only --oneline --pretty="%h,%an,%ci,%s" --decorate=full > change_log.csv

它将信息保存在 csv 文件中,但文件名不在 CSV 文件中的同一行。 在此处输入图像描述

1.如何更改格式以获取标题后下一个单元格中的文件名? 2. 我还想获取提供以下信息的故障日志,但不确定如何使用 git log 获取? 在此处输入图像描述

3. 如何获取错误问题的日志信息 在此处输入图像描述

标签: gitgithubgit-log

解决方案


答案#1

git log 输出的问题是提交的某些字段可以包含 CSV 字段分隔符、换行符和引号。CSV 要求这些值用双引号括起来",并且里面的引号应该重复:

aaa,"bbb1""bb
b2",ccc

在此处输入图像描述

Git 只能对文件名进行转义,而不能对其他字段进行转义。考虑这个日志:

commit 4822fc186476b923e6a3a4758983898a4f799cdc (HEAD -> master)
Merge: 7f74ea0 e9d6448
Author: Joe <joe@acme.com>
Date:   Tue Dec 22 10:29:10 2020 +0300

    Merge branch "dev"

commit e9d644831f6c36a98f6868cde76ec2d259d5bc5c (dev)
Author: Joe <joe@acme.com>
Date:   Tue Dec 22 10:28:35 2020 +0300

    commit in side branch

some.txt

commit 7f74ea0542f70d67b51fdf97115ba473b7866c60
Author: Joe <joe@acme.com>
Date:   Tue Dec 22 10:27:37 2020 +0300

    added file with newline

"file\nwith\nnewline.txt"

commit 7a6f4cd0321d92c24e0b8051e8707d83b7d2fce0
Author: Joe <joe@acme.com>
Date:   Tue Dec 22 10:26:27 2020 +0300

    brief message

    detailed message

first file.txt
second file.txt

commit ed4370fb6349f4209c0014c02900af17573d74a0
Author: Joe <joe@acme.com>
Date:   Tue Dec 22 10:25:16 2020 +0300

    root

这就是为什么您需要一个额外的程序来将 git log 输出转换为 CSV 的原因。

我说过提交字段可以包含 CSV 分隔符,但它们可能不能包含 nul 字符'\0'。我们可以使用它。

来自git help log

   -z
       Separate the commits with NULs instead of with new newlines.

       Also, when --raw or --numstat has been given, do not munge pathnames and use NULs as output field terminators.

       Without this option, pathnames with "unusual" characters are quoted as explained for the configuration variable core.quotePath (see git-config(1)).

所以使用 nuls 的输出如下所示:

$ git log --name-only --pretty="tformat:%h%x00%an%x00%ci%x00%s" -z
4822fc1^@Joe^@2020-12-22 10:29:10 +0300^@Merge branch "dev"^@e9d6448^@Joe^@2020-12-22 10:28:35 +0300^@commit in side branch^@
some.txt^@7f74ea0^@Joe^@2020-12-22 10:27:37 +0300^@added file with newline^@
file
with
newline.txt^@7a6f4cd^@Joe^@2020-12-22 10:26:27 +0300^@brief message^@
first file.txt^@second file.txt^@ed4370f^@Joe^@2020-12-22 10:25:16 +0300^@root^@

请注意,您无法摆脱格式化消息和文件列表之间的换行符。

现在如何区分文件和下一次提交?我想唯一的方法是使用一些魔术字符串作为提交前缀:--pretty="tformat:COMMITMAGIC%x00%h...

适用于 Windows 的 Git 带有gawkperl。为了简单起见,我更喜欢 gawk。这是最终的脚本:

git log --name-only --pretty="tformat:COMMITMAGIC%x00%h%x00%an%x00%ci%x00%s" -z | gawk -v RS="COMMITMAGIC." -v FS="\0" '
  function esc(s) {
    if (s ~ /[,"\n]/) s = "\"" gensub(/"/, "\"\"", "g", s) "\""
    return s
  }
  /./ { # /./ skips first blank record
        commonpart = esc($1) "," esc($2) "," esc($3) "," esc($4) ","
        gsub(/^\n/,"",$5) # get rid of newline before file list
        for (i=5;; i++) {
          print commonpart esc($i)
          if (i>=NF-1) break
        }
      }
  '

在此处输入图像描述


推荐阅读