如何在一行中获取短stat的Git日志?

r3i60tvu  于 2023-05-27  发布在  Git
关注(0)|答案(8)|浏览(74)

以下命令在控制台上输出以下文本行

git log --pretty=format:"%h;%ai;%s" --shortstat
ed6e0ab;2014-01-07 16:32:39 +0530;Foo
 3 files changed, 14 insertions(+), 13 deletions(-)

cdfbb10;2014-01-07 14:59:48 +0530;Bar
 1 file changed, 21 insertions(+)

5fde3e1;2014-01-06 17:26:40 +0530;Merge Baz
772b277;2014-01-06 17:09:42 +0530;Qux
 7 files changed, 72 insertions(+), 7 deletions(-)

我有兴趣有上述格式显示这样

ed6e0ab;2014-01-07 16:32:39 +0530;Foo;3;14;13
cdfbb10;2014-01-07 14:59:48 +0530;Bar;1;21;0
5fde3e1;2014-01-06 17:26:40 +0530;Merge Baz;0;0;0
772b277;2014-01-06 17:09:42 +0530;Qux;7;72;7

这将在一些可以解析分号分隔值的报告中使用。问题是文本"\n 3 files changed, 14 insertions(+), 13 deletions(-)"(包含新行)被转换为3;14;13(没有新行)一个可能的角落情况是像"5fde3e1;2014-01-06 17:26:40 +0530;Merge Baz"这样的文本没有这样的行。在这种情况下,我需要;0;0;0
总的来说,目标是分析一段时间内的文件更改统计信息。我阅读了git log文档,但找不到任何可以帮助我以这种格式呈现的格式。我想到的最好的是上面提到的命令。
因此,任何可以生成预期格式的命令或shell脚本都将有很大的帮助。
谢谢!

xzabzqsa

xzabzqsa1#

git log  --oneline --pretty="@%h"  --stat   |grep -v \| |  tr "\n" " "  |  tr "@" "\n"

这将显示如下内容:

a596f1e   1 file changed, 6 insertions(+), 3 deletions(-) 
4a9a4a1   1 file changed, 6 deletions(-) 
b8325fd   1 file changed, 65 insertions(+), 4 deletions(-) 
968ef81   1 file changed, 4 insertions(+), 5 deletions(-)
htrmnn0y

htrmnn0y2#

不幸的是,仅使用git log无法实现这一点。人们必须使用其他脚本来补偿大多数人没有意识到的东西:一些提交没有统计数据,即使它们不是合并。
我一直在做一个将git log转换为JSON的项目,为了完成它,我必须做你需要做的事情:在一行中获取每个提交和统计信息。该项目名为Gitlogg,欢迎您根据自己的需要进行调整:https://github.com/dreamyguy/gitlogg
下面是Gitlogg的相关部分,这将使您接近您想要的内容:

git log --all --no-merges --shortstat --reverse --pretty=format:'commits\tcommit_hash\t%H\tcommit_hash_abbreviated\t%h\ttree_hash\t%T\ttree_hash_abbreviated\t%t\tparent_hashes\t%P\tparent_hashes_abbreviated\t%p\tauthor_name\t%an\tauthor_name_mailmap\t%aN\tauthor_email\t%ae\tauthor_email_mailmap\t%aE\tauthor_date\t%ad\tauthor_date_RFC2822\t%aD\tauthor_date_relative\t%ar\tauthor_date_unix_timestamp\t%at\tauthor_date_iso_8601\t%ai\tauthor_date_iso_8601_strict\t%aI\tcommitter_name\t%cn\tcommitter_name_mailmap\t%cN\tcommitter_email\t%ce\tcommitter_email_mailmap\t%cE\tcommitter_date\t%cd\tcommitter_date_RFC2822\t%cD\tcommitter_date_relative\t%cr\tcommitter_date_unix_timestamp\t%ct\tcommitter_date_iso_8601\t%ci\tcommitter_date_iso_8601_strict\t%cI\tref_names\t%d\tref_names_no_wrapping\t%D\tencoding\t%e\tsubject\t%s\tsubject_sanitized\t%f\tcommit_notes\t%N\tstats\t' |
  sed '/^[ \t]*$/d' |               # remove all newlines/line-breaks, including those with empty spaces
  tr '\n' 'ò' |                     # convert newlines/line-breaks to a character, so we can manipulate it without much trouble
  tr '\r' 'ò' |                     # convert carriage returns to a character, so we can manipulate it without much trouble
  sed 's/tòcommits/tòòcommits/g' |  # because some commits have no stats, we have to create an extra line-break to make `paste -d ' ' - -` consistent
  tr 'ò' '\n' |                     # bring back all line-breaks
  sed '{
      N
      s/[)]\n\ncommits/)\
  commits/g
  }' |                              # some rogue mystical line-breaks need to go down to their knees and beg for mercy, which they're not getting
  paste -d ' ' - -                  # collapse lines so that the `shortstat` is merged with the rest of the commit data, on a single line

请注意,我使用了制表符(\t)来分隔字段,因为;可以用于提交消息。
这个脚本的另一个重要部分是每行必须以一个唯一的字符串开始(在本例中是commits)。这是因为我们的脚本需要知道行从哪里开始。事实上,git log命令之后的任何内容都是为了补偿某些提交 * 可能没有stats* 的事实。
但我突然想到,你想要实现的是以一种你可以可靠消费的格式整齐地输出提交。Gitlogg是完美的!它的一些特点是:

  • 多个仓库的git log解析为一个JSON文件
  • 引入**repository**键/值。
  • 引入**files changedinsertionsdeletions**键/值。
  • 引入了**impact**键/值,表示提交的累积更改(insertions-deletions)。
  • 清理双引号",将所有允许或由用户输入创建的值(如subject)转换为单引号'
  • 几乎所有的pretty=format:占位符都可用。
  • 通过注解掉/取消注解可用的键/值,轻松包含/排除哪些键/值将被解析为JSON
  • 易于阅读的代码,彻底注解。
  • 控制台上的脚本执行反馈。
  • 错误处理(因为需要正确设置存储库的路径)。

x1c 0d1x成功,解析并保存JSON。


错误001:到存储库的路径不存在。
错误002:存储库路径存在,但为空。

dgsult0t

dgsult0t3#

结合上面的所有答案,这里是我的2美分,以防有人正在寻找:

echo "commit id,author,date,comment,changed files,lines added,lines deleted" > res.csv 
git log --since='last year'  --date=local --all --pretty="%x40%h%x2C%an%x2C%ad%x2C%x22%s%x22%x2C" --shortstat | tr "\n" " " | tr "@" "\n" >> res.csv
sed -i 's/ files changed//g' res.csv
sed -i 's/ file changed//g' res.csv
sed -i 's/ insertions(+)//g' res.csv
sed -i 's/ insertion(+)//g' res.csv
sed -i 's/ deletions(-)//g' res.csv
sed -i 's/ deletion(-)//g' res.csv

然后将其保存到git-logs-into-csv.sh文件中,或者只是复制/粘贴到控制台。
我认为这是相对自我解释,但以防万一:

  • --all从所有分支获取日志
  • --since限制了我们想要查看的提交数量
  • --shortstat-了解在提交中做了什么
beq87vna

beq87vna4#

git不支持纯--格式的stat信息,这很遗憾:(但很容易将其脚本化,这是我的快速和肮脏的解决方案,应该是相当可读的:

#!/bin/bash

format_log_entry ()
{
    read commit
    read date
    read summary
    local statnum=0
    local add=0
    local rem=0
    while true; do
        read statline
        if [ -z "$statline" ]; then break; fi
        ((statnum += 1))
        ((add += $(echo $statline | cut -d' ' -f1)))
        ((rem += $(echo $statline | cut -d' ' -f2)))
    done
    if [ -n "$commit" ]; then
        echo "$commit;$date;$summary;$statnum;$add;$rem"
    else
        exit 0
    fi
}

while true; do
    format_log_entry
done

我敢肯定,它可以更好地脚本,但嘿-它的快速和肮脏;)
用法:

$ git log --pretty=format:"%h%n%ai%n%s" --numstat | ./script

请注意,您指定的格式不是防弹的。分号可以出现在commit summary中,这将打破该行中字段的数量-您可以将summary移动到行尾或以某种方式转义它-您希望如何做到这一点?

wwodge7n

wwodge7n5#

这是awk的一种方法。

awk 'BEGIN{FS="[,;]"; OFS=";"} /;/ {a=$0} /^ /{gsub(/[a-z(+-) ]/,"") gsub(",",";"); print a,$0}'

对于给定的输入,它返回:

ed6e0ab;2014-01-07 16:32:39 +0530;Foo;3;14;13
cdfbb10;2014-01-07 14:59:48 +0530;Bar;1;21
772b277;2014-01-06 17:09:42 +0530;Qux;7;72;7

仍然不适用于像5fde3e1;2014-01-06 17:26:40 +0530;Merge Baz这样后面没有3 files changed, 14 insertions(+), 13 deletions(-)的行。

yhuiod9q

yhuiod9q6#

跟踪@user2461539将其解析为列。也适用于更复杂的cols,如“Subject”。请自行选择合适的分隔符。目前需要削减主题行,因为它会截断其他列时,它溢出。

#!/bin/bash
# assumes "_Z_Z_Z_" and "_Y_Y_" "_X_X_" as unused characters 
# Truncate subject line sanitized (%f) or not (%s) to 79 %<(79,trunc)%f
echo commit,author_name,time_sec,subject,files_changed,lines_inserted,lines_deleted>../tensorflow_log.csv;
git log --oneline --pretty="_Z_Z_Z_%h_Y_Y_\"%an\"_Y_Y_%at_Y_Y_\"%<(79,trunc)%f\"_Y_Y__X_X_"  --stat    \
    | grep -v \| \
    | sed -E 's/@//g' \
    | sed -E 's/_Z_Z_Z_/@/g' \
    |  tr "\n" " "   \
    |  tr "@" "\n" |sed -E 's/,//g'  \
    | sed -E 's/_Y_Y_/, /g' \
    | sed -E 's/(changed [0-9].*\+\))/,\1,/'  \
    | sed -E 's/(changed [0-9]* deleti.*-\)) /,,\1/' \
    | sed -E 's/insertion.*\+\)//g' \
    | sed -E 's/deletion.*\-\)//g' \
    | sed -E 's/,changed/,/' \
    | sed -E 's/files? ,/,/g'  \
    | sed -E 's/_X_X_ $/,,/g'  \
    | sed -E 's/_X_X_//g'>>../tensorflow_log.csv
nx7onnlm

nx7onnlm7#

我在~/.bashrc中写了这样的代码:

function git-lgs() {
   git --no-pager log --numstat --format=%ai "$1" | sed ':a;N;$!ba;s/\n\n/\t/g' | sed 's/\(\t[0-9]*\t*[0-9]*\).*/\1/'
}

其中git-lgs的参数是要显示日志的文件名。

pexxcrt2

pexxcrt28#

将日志输出格式化为制表符分隔的格式,以便更容易解析,包括shortstat,然后通过awk管道输出并重新排列它:

git log -c --shortstat --first-parent --format="commit%x09%H%x09%cI%x09%sd"| \
  awk -v FS="\t" '/^commit/ { commit=$2; timestamp=$3; summary=$4 } /^ [0-9]+ files? changed/ { stats=$1; printf "https://github.com/timabell/gitopolis/commit/%s\t%s\t%-55s\t\"%s\"\n", commit, timestamp, stats, summary}'

说明

格式化字符串

  • commit awk要查找的文字字符串
  • %x09制表符的十六进制代码。(这里的Tabs are added with %x09是为了避免复制粘贴问题,但是你可以使用`ctrl-v+tab在你的终端中插入文本制表符)
  • 提交的%H sha1
  • %x09选项卡
  • %cI iso格式提交日期
  • %x09选项卡
  • %sd"提交摘要

Awk参数

  • -v FS="\t"将字段分隔符更改为制表符

Awk命令

  • /^commit/ { commit=$2; timestamp=$3; summary=$4 }在提交行被消耗时被触发,并将字段2、3和4分配给命名变量
  • 使用stats行时会触发/^ [0-9]+ files? changed/
  • {是要在该匹配上运行的内容的开始
  • stats=$1;将第一个字段(整个stat行)分配给命名变量stats,分号结束语句
  • printf "https://github.com/timabell/gitopolis/commit/%s\t%s\t%-55s\t\"%s\"\n", commit, timestamp, stats, summary'输出格式化行
  • %s从变量列表中插入字符串
  • %-52s填充字符串,使所有内容都排列得很好
  • \t插入一个制表符(比空格对齐更好,也更容易被进一步的工具解析)
  • \"转义引号,以便我们引用摘要
  • \n换行符开始输出中的下一条记录
  • }是要在该匹配上运行的内容的结尾

示例

shortstat输出

commit  58fb0e1d111f8131c58eb244bc6c3ae6cff42886        2023-05-05T16:54:58+01:00       Add product hunt badged

 1 file changed, 11 insertions(+), 1 deletion(-)
commit  66c0d44676d0f7c3f88444ac1877c1bd00a75a31        2023-04-26T10:43:14+01:00       cargo upgraded

 1 file changed, 5 insertions(+), 5 deletions(-)
commit  ea90a1a7efc448834cb15cf12c0d9a7f31e95350        2023-04-26T10:32:43+01:00       cargo updated

 1 file changed, 150 insertions(+), 95 deletions(-)

awk输出

https://github.com/timabell/gitopolis/commit/58fb0e1d111f8131c58eb244bc6c3ae6cff42886   2023-05-05T16:54:58+01:00        1 file changed, 11 insertions(+), 1 deletion(-)        "Add product hunt badged"
https://github.com/timabell/gitopolis/commit/66c0d44676d0f7c3f88444ac1877c1bd00a75a31   2023-04-26T10:43:14+01:00        1 file changed, 5 insertions(+), 5 deletions(-)        "cargo upgraded"
https://github.com/timabell/gitopolis/commit/ea90a1a7efc448834cb15cf12c0d9a7f31e95350   2023-04-26T10:32:43+01:00        1 file changed, 150 insertions(+), 95 deletions(-)     "cargo updated"

相关问题