Git hook, модифицира файловете за ангажиране

Опитвам се да напиша git скрипт за предварително ангажиране, той трябва да напише датата на ангажиране в началото на модифицираните файлове. Проблемът ми е, че не мога да добавя модифицирани файлове към предишния комит. Когато се опитвам да извикам git commit отново, той работи рекурсивно. Как мога да напиша скрипт, който добавя време на модификация в края на модифицираните файлове?

Моят код:

#!/bin/bash

files_modified=`git diff-index --name-only HEAD`

for f in $files_modified; do
    if [[ $f == *.groovy ]]; then
        $line = $(head -1 f)
        if [[ $line == "/%%*" ]];
        then
            sed -i 1d
        fi
        echo "/%% " + $(date +"%m_%d_%Y") + " %%\\" >> f
        git add f
    fi
done 
git commit --amend #recursive
exit

person SerCe    schedule 01.02.2013    source източник


Отговори (3)


Не можете да промените ангажимент в pre кука към ангажимент.
И това, което правите, е подобно на механизма за разширяване на ключови думи, което не е най-добрата практика с Git (или който и да е DVCS), както е обяснено в "За да поставите префикса ?<revision-number> към кодове от Git/Svn".

Други подходи включват:

person VonC    schedule 01.02.2013


Гледайки вашата кука преди ангажимент, почти сте имали нещо, което работи. Ето минималните промени, които виждам като необходими:

    #!/bin/bash
    files_modified=`git diff --cache --name-only --diff-filter=ACM`
            ### fix: use current branch; cached; and only files
    for f in $files_modified; do ### broken: if space in filename(s)
        if [[ $f == *.groovy ]]; then
            line=$(head -1 $f) ### fix: forgot a $ before f
            if [[ $line == "/%%*" ]];
            then
                sed -i 1d "$f" ### fix: forgot file argument
            fi
            echo "/%% " + $(date +"%m_%d_%Y") + " %%\\" >> $f
                    ### fix: forgot a $ before f
            git add -u $f ### fix: forgot a $ before f
        fi
    done
    ### undesired ### git commit --amend #recursive
    ### unneeded ### exit

Забелязвам обаче няколко проблема с внедряването ви. Ще премахнете ред, съответстващ на "/%%*" от горната част на файла и ще добавите нов в долната част. Всеки път, когато стартирате това, завинаги ще добавяте нов /%% mm_dd_YYYY %%\ ред към края на файла. Това може да не е това, което искате (1000 ангажимента по-късно, преди това празен файл ще има 1000 реда). Мисля, че искахте да замените съществуващия ред. В който случай би работил sed превод за замяна на съвпадащи редове.

Ето една рецепта, която според мен се доближава до това, което искахте:

    #!/bin/sh
    TMPFILE="/tmp/${0##*/}.$$"
    for f in $( git diff --cached --name-only --diff-filter=ACM ); do
            # XXX broken: if space in filename(s)
            case "$f" in
            *.groovy) : fall through ;;
            *) continue
            esac
            cp "$f" "$TMPFILE" || continue
            awk -v new="/%% $(date +%m_%d_%Y) %%\\" \
                    'NR==1{sub("^/%% .* %%\\\\$",new)}1' \
                    < "$TMPFILE" > "$f"
            git add -u -- "$f"
    done

Ако първият ред на файла съвпада с /%% ... %%\, тогава той се актуализира с текущата дата/час (по време на куката за предварително ангажиране).

Това обаче беше само за да илюстрира как може да се направи просто. Това всъщност не е пълно решение. Горният скрипт няма да работи с файлове, които съдържат интервали в името си, двойни кавички, обратни наклонени черти, раздели и т.н.

За цялостно решение:

  1. Използвайте следната кука за предварително ангажиране:

    #!/bin/sh
    git diff --cached --name-only -z --diff-filter=ACM |
            xargs -r0 .filters/myfilter
    
  2. Създайте ".filters/myfilter" със следното съдържание:

    #!/bin/sh
    TMPFILE="/tmp/${0##*/}.$$"
    for f in "$@"; do ### the only difference from above recipe
            case "$f" in
            *.groovy) : fall through ;;
            *) continue
            esac
            cp "$f" "$TMPFILE" || continue
            awk -v new="/%% $(date +%m_%d_%Y) %%\\" \
                    'NR==1{sub("^/%% .* %%\\\\$",new)}1' \
                    < "$TMPFILE" > "$f"
            git add -u -- "$f"
    done
    

Горната реализация може да обработва всяко име на файл, което хвърлите към нея.

person src committer    schedule 22.10.2015