【问题标题】:Formatting Git Log for HTML为 HTML 格式化 Git 日志
【发布时间】:2015-09-20 13:17:27
【问题描述】:

我正在尝试生成 git log 提供的信息的 HTML 格式输出。我是 bash 的初学者,所以当我搜索网络和 StackOverflow 寻求帮助时,我很可能错过了显而易见的事情。

我正在尝试在 div 标记中输出每个提交语句(过去 5 条语句)。在 div 中,我想要一个作为提交消息主题的标题,一个作为提交正文的段落,然后是一个包含更改类型(创建、删除或修改)的受影响文件的列表。我的脚本很接近。它创建标题,创建文件列表(不更改类型),并且可以以两种不正确的方式之一显示消息正文。正文要么每行一个单词(如下面的脚本中所示),要么将所有内容混合到一行(如果我只是回显 $lines 变量而不对其执行 for 循环)。

文件列表也有类似的问题。如果我选择“--name-status”,它会给我更改类型和文件名,但在单独的行上。这就是为什么当前名称列表查找“--name-only”的原因。它有效,但它没有给我我想要的所有信息。

这是我当前的 bash 脚本:

revlist=$(git rev-list -n 5 HEAD)
(
  echo '<div>'
  for rev in $revlist
  do
    lines=$(git log -1 --pretty="format:%b" $rev) 
    files=$(git log -1 --pretty="format:" --name-only $rev)
    echo '<div><h2>'
    echo "$(git log -1 --pretty="%s" $rev)"
    echo '</h2>'
    for line in $lines
    do
      echo "$line <br />"
    done
    echo '<h3>Files Affected</h3><ul>'
    for file in $files
    do
      echo "<li>$file</li>"
    done
    echo '</ul></div>'
  done
  echo '</div>'
) > out.html

如果我有这样的提交声明:

我的提交标头

提交第一行

提交第二行

它会影响以下文件:

file1.txt

file2.txt

我会得到这样的输出:

<div><h2>
My Commit Header
</h2>
commit <br />
line <br />
one <br />
commit <br />
line <br />
two <br />
<h3>Files Affected</h3><ul>
<li>file1.txt</li>
<li>file2.txt</li>
</ul></div>

显然这不是我想要的。所以,我的两个问题是:

  1. 如何让提交正文每物理行一行(而不是每个空格一行)?
  2. 如何获得与文件关联的更改类型,而不会出现与提交消息相同的问题?基本上,我正在寻找“(M) file1.txt”或类似的东西。

它应该不会影响任何东西,但我在 Windows 上运行 git。

编辑:解决方案

感谢 VonC 和评论者的帮助,我能够完成我的脚本。我在第一个循环中使用了 IFS,并通过 while 语句而不是 for 循环来运行第二个循环。这是工作结果:

revlist=$(git rev-list -n 5 HEAD)
(
  echo '<div>'
  for rev in $revlist
  do
    lines=$(git log -1 --pretty="format:%b" $rev) 
    files=$(git log -1 --pretty="format:" --name-status $rev)
    echo '<div><h2>'
    echo "$(git log -1 --pretty="%s" $rev)"
    echo '</h2>'
    IFS=$'\n'
    for line in $lines
    do
      echo "$line <br />"
    done
    unset IFS
    echo '<h3>Files Affected</h3><ul>'
    while read change file; do 
      if [ ${#file} -gt 0 ]
      then
        echo "<li>($change) $file </li>"; 
      fi
    done <<< "$files"
    echo '</ul></div><hr>'
  done
  echo '</div>'
) > out.html

【问题讨论】:

  • em...只是出于好奇,是什么让您决定编写一个 bash 脚本在 Windows 中从头开始生成 html?
  • 您可以将其转换为更好的结构并继续处理:stackoverflow.com/questions/4600445/…
  • 您应该使用较低级别的(管道)命令而不是瓷器命令git log。如果 Git 开发人员决定更改 git log 的输出,那可能会破坏您的解析器。
  • "如何让提交主体每物理行一行?" BashFAQ/001.
  • @HuStmpHrrr - 我决定编写一个 bash 脚本,因为这是我看到的推荐(我在 CI 服务器上执行此操作)。我看到了你提到的问题,但当我可以迈出一步时,我真的不想迈出两三步。

标签: git bash git-bash


【解决方案1】:

看起来像“How to read complete line in 'for' loop with spaces”:

尝试将分隔符 IFS 设置为 \n

IFS=$'\n'  
for line in $lines
do
  echo "$line <br />"
done

HuStmpHrrr提议in the comments

while read line; do 
  echo "$line <br />"; 
done <<< "$lines"

【讨论】:

  • 这绝对解决了问题 #1。出色的抓地力。我没有意识到你可以设置 IFS。现在我仍然需要处理文件(获取文件名旁边的更改类型)。如果我只是将 --name-only 修改为 --name-status,我会得到更改类型、空格和文件名。我希望能够对其进行格式化,因此我想将文件名与更改类型分开处理。有没有办法可以将行解析为两个变量?
  • "有没有办法可以将行解析为两个变量?"这就是 awk 应该做的(例如和插图:stackoverflow.com/q/9874921/6309
  • 提供另一个捕获:while read line; do echo "$line &lt;br /&gt;"; done &lt;&lt;&lt; "$lines"lines 周围的引号是必要的
  • @BiggsTRC 用于parse into two vars 事物。我不知道你的意思,但这里是插图:while read a b; do echo a= $a b= $b; done &lt;&lt;&lt; "$t"。只是玩 IFS
  • @HuStmpHrrr 很好的变化。我已将其包含在答案中以提高知名度。
猜你喜欢
  • 2011-04-07
  • 1970-01-01
  • 2018-09-06
  • 1970-01-01
  • 2019-07-16
  • 2011-12-12
  • 2019-03-31
  • 1970-01-01
  • 2023-03-20
相关资源
最近更新 更多