格式化 Git HTML 的日志

Formatting Git Log for HTML

我正在尝试根据 git 日志提供的信息生成 HTML-formatted 输出。我是 bash 的初学者,所以当我在网络和 Whosebug 上搜索帮助时,我很可能错过了显而易见的东西。

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

文件列表也有类似的问题。如果我 select "--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

如果我有这样的提交语句:

My Commit Header

commit line one

commit line two

它会影响以下文件:

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. 如何让提交 body 每条物理线一行(而不是每条 space)?
  2. 如何获取与文件关联的更改类型而不出现与提交消息相同的问题?基本上,我正在寻找“(M) file1.txt”或类似的东西。

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

编辑:解决方案

感谢 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

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

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

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

HuStmpHrrr proposes :

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