2013-02-01 164 views
8

我正在尝试编写git pre-commit挂接脚本,它应该在修改后的文件开始时写入提交日期。我的问题是,我不能将修改的文件添加到以前的提交。当我尝试再次调用git commit时,它会运行递归。我如何编写脚本,在修改后的文件末尾添加修改时间?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 

回答

2

不能修改在提交commit钩子。
您所做的与关键字扩展机制类似,这不是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. 使用下面的pre-commit钩子:

    #!/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 "[email protected]"; 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 
    

上述工具ntation可以处理任何文件名。