2015-07-02 4 views
1

Я пытаюсь сгенерировать вывод в формате HTML информации, предоставленной git log. Я новичок в bash, поэтому, когда я искал в Интернете и StackOverflow для справки, я вполне мог пропустить очевидное.Форматирование Git Log для HTML

Я пытаюсь вывести каждый оператор фиксации (из последних 5 операторов) в теге div. Внутри div мне нужен заголовок, который является объектом сообщения фиксации, абзацем, который является телом фиксации, а затем списком затронутых файлов с типом изменения (созданным, удаленным или измененным). Сценарий у меня близок. Он создает заголовок, он создает список файлов (без типа изменения) и может отображать тело сообщения одним из двух неправильных способов. Либо тело имеет по одному слову в строке (как в приведенном ниже скрипте), либо имеет все, что вырезано на одну строку (если я просто повторяю переменную $ lines без выполнения цикла 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-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 

Если у меня есть совершить подобное заявление:

Мой коммит Заголовок

совершают линию один

совершить строка 2

и это влияет на следующие файлы:

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» или что-то подобное.

Это не должно сказаться ни на чем, но я запускаю git на Windows.

Edit: Решение

Благодаря помощи 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 
+1

эм ... просто ради любопытства, что делает вы решили написать Баш скрипт для создания HTML с нуля в окнах? – HuStmpHrrr

+0

вы можете преобразовать его в лучшую структуру и продолжить обработку: http://stackoverflow.com/questions/4600445/git-log-output-to-xml-json-or-yaml – HuStmpHrrr

+0

Вы должны использовать нижний уровень (водопровод) а не фарфоровой команды 'git log'. Если разработчики Git решили изменить вывод 'git log', это может сломать ваш синтаксический анализатор. – Jubobs

ответ

2

Это выглядит как "How to read complete line in 'for' loop with spaces":

настройки TRY разделительные 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" 
+0

Это определенно решает проблему № 1. Отличный улов. Я не понимал, что вы можете установить IFS. Теперь мне все еще нужно обрабатывать файлы (получение измените тип рядом с именем файла) .Если я просто изменяю -name-only на -name-status, я получаю тип изменения, пробел, а затем имя файла. Мне очень хотелось бы отформатировать этот бит поэтому я хотел бы обратиться к имени файла отдельно от типа изменения. Есть ли способ, которым я могу разобрать строку на две переменные? – IAmTimCorey

+0

«Есть ли способ, по которому я могу разделить строку на две переменные?» Это то, что должен сделать awk (как, например, в примере и иллюстрации: http://stackoverflow.com/q/9874921/6309) – VonC

+0

предлагает еще один catch: 'while read line; do echo" $ line
"; done <<<" $ lines "' . Котировки вокруг 'lines' необходимы – HuStmpHrrr