Git钩子,修改提交文件

Git钩子,修改提交文件,git,bash,hook,commit,pre-commit-hook,Git,Bash,Hook,Commit,Pre Commit Hook,我正在尝试编写git预提交钩子脚本,它应该在修改文件开始时写入提交日期。我的问题是无法将修改过的文件添加到上一次提交。当我再次尝试调用git commit时,它运行递归。如何编写脚本,在修改文件的末尾追加修改时间 我的代码: #!/bin/bash files_modified=`git diff-index --name-only HEAD` for f in $files_modified; do if [[ $f == *.groovy ]]; then $li

我正在尝试编写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

不能在预提交挂钩中修改提交。
您所做的与关键字扩展机制类似,这不是Git(或任何DVC)的最佳实践,如“”中所述

其他办法包括:

  • 生成包含所需信息的单独文件(然后提交)。
    例如见“”
  • 将该信息存储在git Notes中(与提交分离,不更改SHA1)。
    见“”
您需要的可能是操作:

相关的:

看看你的预提交钩子,你几乎有了某种可以工作的东西。以下是我认为需要进行的最小更改:

    #!/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\u dd\u 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
  • 创建具有以下内容的“.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
    
    #/垃圾箱/垃圾箱
    TMPFILE=“/tmp/${0###*/}.$$”
    对于“$@”中的f;做与上述食谱唯一不同的事
    大写“$f”
    *.groovy):失败;;
    *)继续
    以撒
    cp“$f”$TMPFILE”|继续
    awk-v new=“/%%$(日期+%m\%d\%Y)%%\\”\
    'NR==1{sub(“^/%%.%%\\\\$”,新)}1'\
    <“$TMPFILE”>“$f”
    git add-u--“$f”
    完成
    
  • 上面的实现可以处理您抛出的任何文件名

    #!/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