【问题标题】:Excluding certain file types from a pre-commit hook从预提交挂钩中排除某些文件类型
【发布时间】:2014-11-24 14:28:43
【问题描述】:

我想要一个预提交 git 钩子来检查(如果可能的话,自动删除)尾随空格。

Make git automatically remove trailing whitespace before committing 中,我找到了一个link to a github page,其中实现了这样的钩子。这工作正常,但作为@VonC 该页面上的提及

由于该钩子获取每个文件的文件名,我建议 小心某些类型的文件:你不想删除 .md(降价)文件中的尾随空格! – 冯克

再往下

我宁愿让钩子能够检测 .md 文件而不是删除 空格,而不是要求最终用户添加 --no-verify git commit 上的选项。 – 冯克

据我所知,没有提到解决方案。

由于我在项目中使用带有有意尾随空格的 .md 文件,这对我来说是个问题。
解决方案可能很简单,但我对编写脚本的语言没有经验(目前也对学习它不感兴趣)。

这是脚本(github的副本):

#!/bin/bash
#

# A git hook script to find and fix trailing whitespace
# in your commits. Bypass it with the --no-verify option
# to git-commit
#
# usage: make a soft link to this file, e.g., ln -s ~/config/pre-commit.git.sh ~/some_project/.git/hooks/pre-commit

# detect platform
platform="win"
uname_result=`uname`
if [ "$uname_result" = "Linux" ]; then
  platform="linux"
elif [ "$uname_result" = "Darwin" ]; then
  platform="mac"
fi

# change IFS to ignore filename's space in |for|
IFS="
"
# autoremove trailing whitespace
for line in `git diff --check --cached | sed '/^[+-]/d'` ; do
  # get file name
  if [ "$platform" = "mac" ]; then
    file="`echo $line | sed -E 's/:[0-9]+: .*//'`"
  else
    file="`echo $line | sed -r 's/:[0-9]+: .*//'`"
  fi  
  # display tips
  echo -e "auto remove trailing whitespace in \033[31m$file\033[0m!"
  # since $file in working directory isn't always equal to $file in index, so we backup it
  mv -f "$file" "${file}.save"
  # discard changes in working directory
  git checkout -- "$file"
  # remove trailing whitespace
  if [ "$platform" = "win" ]; then
    # in windows, `sed -i` adds ready-only attribute to $file(I don't kown why), so we use temp file instead
    sed 's/[[:space:]]*$//' "$file" > "${file}.bak"
    mv -f "${file}.bak" "$file"
  elif [ "$platform" == "mac" ]; then
    sed -i "" 's/[[:space:]]*$//' "$file"
  else
    sed -i 's/[[:space:]]*$//' "$file"
  fi  
  git add "$file"
  # restore the $file
  sed 's/[[:space:]]*$//' "${file}.save" > "$file"
  rm "${file}.save"
done

if [ "x`git status -s | grep '^[A|D|M]'`" = "x" ]; then
  # empty commit
  echo
  echo -e "\033[31mNO CHANGES ADDED, ABORT COMMIT!\033[0m"
  exit 1
fi

# Now we can commit
exit

如何修改它以便(例如)在检查中排除 .md 文件?此外,如果可以排除多种文件类型,那就太好了。

【问题讨论】:

    标签: git bash pre-commit-hook


    【解决方案1】:

    试试这个:

    #!/bin/bash
    #
    
    # A git hook script to find and fix trailing whitespace
    # in your commits. Bypass it with the --no-verify option
    # to git-commit
    #
    # usage: make a soft link to this file, e.g., ln -s ~/config/pre-commit.git.sh ~/some_project/.git/hooks/pre-commit
    
    LIST="md txt c cpp"
    
    lookup() {
        IFS=" "
        for i in $LIST
        do
        if [ "$i" = "$1" ]
        then
            return 1
            break
        fi
        done
        return 0
    }
    
    # detect platform
    platform="win"
    uname_result=`uname`
    if [ "$uname_result" = "Linux" ]; then
        platform="linux"
    elif [ "$uname_result" = "Darwin" ]; then
        platform="mac"
    fi
    
    # change IFS to ignore filename's space in |for|
    IFS="
    "
    # autoremove trailing whitespace
    for line in `git diff --check --cached | sed '/^[+-]/d'` ; do
        # get file name
        if [ "$platform" = "mac" ]; then
        file="`echo $line | sed -E 's/:[0-9]+: .*//'`"
        else
        file="`echo $line | sed -r 's/:[0-9]+: .*//'`"
        fi
    
        lookup $(echo "$file" | awk -F . '{print $NF}')
        if [ $? -eq 1 ]
        then
        echo Omitting "$file"
        continue
        fi
    
        # display tips
        echo -e "auto remove trailing whitespace in \033[31m$file\033[0m!"
        # since $file in working directory isn't always equal to $file in index, so we backup it
        mv -f "$file" "${file}.save"
        # discard changes in working directory
        git checkout -- "$file"
        # remove trailing whitespace
        if [ "$platform" = "win" ]; then
        # in windows, `sed -i` adds ready-only attribute to $file(I don't kown why), so we use temp file instead
        sed 's/[[:space:]]*$//' "$file" > "${file}.bak"
        mv -f "${file}.bak" "$file"
        elif [ "$platform" == "mac" ]; then
        sed -i "" 's/[[:space:]]*$//' "$file"
        else
        sed -i 's/[[:space:]]*$//' "$file"
        fi
        git add "$file"
        # restore the $file
        sed 's/[[:space:]]*$//' "${file}.save" > "$file"
        rm "${file}.save"
    done
    
    if [ "x`git status -s | grep '^[A|D|M]'`" = "x" ]; then
        # empty commit
        echo
        echo -e "\033[31mNO CHANGES ADDED, ABORT COMMIT!\033[0m"
        exit 1
    fi
    
    # Now we can commit
    exit
    

    应排除的文件扩展名列表位于脚本开头的LIST

    LIST="md txt c cpp"
    

    【讨论】:

    • 似乎有效,但它通过打印每个文件的 LIST 内容来向终端发送垃圾邮件,你能删除它吗?
    • 对不起,这只是为了调试目的,我确实删除了它
    猜你喜欢
    • 2014-05-10
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    • 2021-11-05
    • 1970-01-01
    • 2015-11-28
    相关资源
    最近更新 更多