我正在尝试编写git pre-commit钩子脚本,它应该在修改文件的开头写入提交日期。我的问题是我无法将修改过的文件添加到以前的提交中。当我再次尝试调用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
答案 0 :(得分:2)
您无法修改 pre 提交挂钩中的提交
而你所做的与关键字扩展机制类似,这不是Git(或任何DVCS)的最佳实践,如“To put the prefix ?<revision-number>
to codes by Git/Svn”中所述。
其他方法包括:
答案 1 :(得分:2)
答案 2 :(得分:2)
看着你的预提交钩子,你几乎有一些有点工作的东西。这是我认为需要的最小变化:
#!/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
如果文件的第一行与/%% ... %%\
匹配,则使用当前日期/时间(在预提交挂钩时)更新。
然而,这只是为了说明如何简单地完成它。这实际上不是一个完整的解决方案。上述脚本不适用于名称中包含空格的文件,双引号,反斜杠,制表符等。
要获得完整的解决方案:
使用以下预提交挂钩:
#!/bin/sh
git diff --cached --name-only -z --diff-filter=ACM |
xargs -r0 .filters/myfilter
使用以下内容创建“.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
上面的实现可以处理你抛出的任何文件名。