I am trying to generate a HTML-formatted output of the information provided by git log. I am a beginner in bash so while I searched the web and StackOverflow for help, I could well have missed the obvious.
What I am attempting is to output each commit statement (of the past 5 statements) in a div tag. Inside the div, I want a header that is the commit message subject, a paragraph that is the commit body and then a list of affected files with the type of change (created, deleted or modified). The script I have is close. It creates the header, it creates the list of files (without change type) and it can display the message body in one of two incorrect ways. Either the body has one word per line (as it is in the script below) or it has everything mashed onto one line (if I just echo the $lines variable without doing a for loop on it).
The file list has a similar issue. If I select "--name-status", it gives me the change type and the file name but on separate lines. That is why currently the name list looks up "--name-only". It works but it doesn't give me all the information I want.
Here is my current bash script:
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
If I have a commit statement like this:
My Commit Header
commit line one
commit line two
and it affects the following files:
file1.txt
file2.txt
I'll get an output like so:
<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>
Obviously that isn't what I want. So, my two questions are:
- How do I get the commit body to have one line per physical line (not one per space)?
- How do I get the change type associated with the file without the same issue as the commit message? Basically, I'm looking for "(M) file1.txt" or something similar.
It shouldn't affect anything, but I am running git on Windows.
Edit: Solution
Thanks to the help of VonC and those who commented, I was able to complete my script. I utilized the IFS on the first loop and I ran the second loop through a while statement instead of a for loop. Here is the working result:
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