如何在Windows上使用Git commit-msg钩子计算非ASCII字符?

问题描述 投票:0回答:2

我通过TortoiseGit在Windows上使用Git,目前我正在尝试使用this commit-msg hook来检查提交消息行的长度。

当我用ASCII字符专门写消息时,一切都很好。但是当我用俄语写一条消息时,字符计数器会产生比实际长度大两倍的结果。当消息被保存为UTF-8文件时,计数器看起来像是使用默认的Windows编码或类似的东西。

一些亮点:

  • .git/COMMIT_EDITMSG有UTF-8编码;
  • 钩子中的echo $line正确显示非ASCII字符;
  • ${#line}返回一个等于actual_length * 2的值;
  • 我尝试了不同的方法迭代一行中的字符,每次迭代器将每个字节视为一个单独的字符。

更新1:我希望在不添加环境依赖性的情况下实现我的目标(即,不安装像Python这样的其他解释器)。

git githooks tortoisegit
2个回答
1
投票

不计算字节数 - 计数字符。即,在编程语言中将输入从字节转换(解码)到字符。以UTF-8编码的俄语字符占用2个字节。示例(在Python中):

$ python

>>> len('тест')
8

>>> len(u'тест')
4

>>> len('тест'.decode('utf-8'))
4

0
投票

现在,echo $line | iconv --from-code UTF-8 --to-code cp866做了这个伎俩。

它涵盖了我的用例(消息中只有西里尔字符或基本拉丁字符),但缺乏通用性。我希望有人知道更清洁的解决方案。

这是我目前的脚本:

#!/bin/bash
#http://chris.beams.io/posts/git-commit/#seven-rules
cnt=0

while IFS='' read -r line || [[ -n "$line" ]]; do
  cnt=$((cnt+1))
  cp866_line=`echo $line | iconv --from-code UTF-8 --to-code cp866`

  if [ $? -eq 0 ]; then
    length=${#cp866_line}
  else
    length=${#line}
  fi

  if [ $cnt -eq 1 ]; then
    # Checking if subject exceeds 50 characters
    if [ $length -gt 50 ]; then
      echo "Your subject line exceeds 50 characters"
      exit 1
    fi
    i=$(($length-1))
    last_char=${line:$i:1}
    # Subject line must not end with a period
    if [[ $last_char == "." ]]; then
      echo "Your subject line ends with a period"
      exit 1
    fi
  elif [ $cnt -eq 2 ]; then
    # Subject must be followed by a blank line
    if [ $length -ne 0 ]; then
      echo "Your subject line is followed by a non-empty line"
      exit 1
    fi
  else
    # Any line in body must not exceed 72 characters
    if [ $length -gt 72 ]; then
      echo "The line \"$line\" exceeds 72 characters"
      exit 1
    fi
  fi
done < "$1"
© www.soinside.com 2019 - 2024. All rights reserved.