Git钩子,修改提交文件

10

我正在尝试编写一个Git预提交钩子脚本。它应该在修改文件的开头写入提交日期。

我的问题是,我无法将修改后的文件添加到先前的提交中。当我尝试再次调用Git提交时,它会递归运行。如何编写脚本,在修改文件的末尾追加修改时间?

我的代码:

#!/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
3个回答

4
您不能在预提交钩子中修改提交。
您所做的类似于关键字扩展机制,这不是使用Git(或任何DVCS)的最佳实践,如在“To put the prefix ?<revision-number> to codes by Git/Svn”中解释的那样。其他方法包括:

2

看了你的pre-commit钩子,你几乎有一个差不多能用的东西。这里是我认为需要的最小更改:

    #!/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. Use the following pre-commit hook:

    #!/bin/sh
    git diff --cached --name-only -z --diff-filter=ACM |
            xargs -r0 .filters/myfilter
    
  2. Create ".filters/myfilter" with the following content:

    #!/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
    
以上实现可以处理任何您提供的文件名。

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接