我试图写一个prepare-commit-msg git hook脚本来检查最后10条提交消息的内容,并检查你试图输入的消息是否是唯一的,并阻止用户如果检测到它,则检入(没有--no-verify重载)。当我在Git中运行此命令行时,我得到以下输出。
dacke@MachineName /c/Development/Project (tests) $ git log --pretty=format:'%h|%an|%s' --max-count=10 2919dc2|Eric|Test Message 4ef580c|Eric|Test Message 1a0051b|Eric|Test Message 3e2df42|Eric|Test Commit a08d4c1|Bob|DE6717 - What I did to fix this defect aff8afc|Bob|DE6717 - Here is some more defect info bbbfb67|Ralph|Merge branch 'clean_up' into develop 72d0968|Ralph|Forgot to remove deleted class from the project. bfd1505|Ralph|Clean up. d21c6dc|Bruce|Merge branch 'Icons' into develop
我的prepare-commit-msg是这样编写的。
1 #!/bin/bash
2
3 printf "Prepare-Commit-Msg Hook Running...\n"
4
5 #$1 = "Commit Message File 'COMMIT_EDITMSG'"
6 #$2 = "message"
7 commitMessage=$(cat "$1")
8
9 # Prevent people putting in the same commit message multiple times by looking for an identical message in the last 10 commits
10 declare -a last10CommitMessages
11 rawMessages=$(git log --pretty=format:'%h|%an|%s«' --max-count=10)
12 printf "Raw Messages Length: %d\n" "${#rawMessages[@]}"
13 for line in ${rawMessages//«/ };
14 do
15 #printf "%s\n" $line
16 last10CommitMessages+=($line);
17 done
18 printf "Last 10 Commit Length: %d\n" "${#last10CommitMessages[@]}"
19
20 # Temp exit 1 to prevent commit during testing
21 exit 1
当我尝试运行" commit"我得到以下输出。
原始消息长度:1
最后10个提交时间:63
如果我取消注释第15行,我可以看到,对于每个空格和换行符,我都会将一个项目添加到数组中。最重要的是,我实际上想要分割线条的字符被添加到结尾,这意味着我还需要另一种方法来将其分开。
我是bash脚本的新手,我来自C#/ Windows背景,所以我还在学习。有人可以给我一个解决问题的简单方法吗?对我来说比快速回答更重要的是一个可以解释这实际上如何起作用的答案。我发现很多相互矛盾的信息在网上对我不起作用。我计划写完一篇关于这篇文章的博客文章,因为重要的是我没有得到任何"它只是工作"作为答案。感谢。
答案 0 :(得分:2)
简单地改变
rawMessages=$(git log --pretty=format:'%h|%an|%s«' --max-count=10)
到这个
rawMessages=($(git log --pretty=format:'%h|%an|%s«' --max-count=10))
$()计算内部命令并将其保存为一个字符串,忽略换行符。当您使用()包装内容时,它会将内容评估为数组。
编辑:
如果你这样做,你会发现数组中的元素比你想要的多。这是因为数组将按新行字符和空格分割字符串。要忽略空格,您可以按照hlovdal的建议进行操作。
OLD_IFS="$IFS"
IFS=$'\n'
rawMessages=($(git log --pretty=format:'%h|%an|%s«' --max-count=10))
IFS="$OLD_IFS"
答案 1 :(得分:1)
由于IFS
变量(内部字段分隔符 - 一个古老的unix遗物......),单词被拆分,其默认值为"<space><tab><newline>"
。将你的循环改为
oldIFS=$IFS
IFS=«
for line in ${rawMessages}
do
printf "%s\n" $line
last10CommitMessages+=($line);
done
IFS=$oldIFS