代码之家  ›  专栏  ›  技术社区  ›  codingninja

使用预提交搜索文件

  •  7
  • codingninja  · 技术社区  · 10 年前

    我正在尝试添加一个git预提交挂钩,它将检查所有已更改和新文件 TODO: 文本

    我试过了

    #!/bin/sh
    
    . git-sh-setup  # for die 
    git-diff-index -p -M --cached HEAD -- | grep '^+' |
    grep TODO: && die Blocking commit because string TODO: detected in patch
    :
    

    我在一个类似的问题中看到了这一点,但没有运气。

    2 回复  |  直到 10 年前
        1
  •  10
  •   Community CDub    4 年前

    是的,这个位在被暂存的文件上循环,但是不管它的哪个部分被暂存,它都会对整个文件进行grep!

       git diff --cached --name-only | \
           grep -E $FILES_PATTERN | \
           echo 'COMMIT REJECTED Found'  $i 'references. Please remove them before commiting' && exit 1
    

    这不好——不要测试未暂存的字符串。

    此解决方案 测试一个或多个FORBIDEN字符串 只有暂存代码,而不是整个文件 :

    预先提交

    #!/bin/bash
    
    RESTORE='\033[0m'
    RED='\033[00;31m'
    YELLOW='\033[00;33m'
    BLUE='\033[00;34m'
    
    FORBIDDEN=( 'TODO:' 'DO NOT COMMIT' 'console.log' 'die' )
    FOUND=''
    
    for j in "${FORBIDDEN[@]}"
    do
      for i in `git diff --cached --name-only`
      do
    
        # the trick is here...use `git show :file` to output what is staged
        # test it against each of the FORBIDDEN strings ($j)
    
        if echo `git show :$i` | grep -q "$j"; then
    
          FOUND+="${BLUE}$i ${RED}contains ${RESTORE}\"$j\"${RESTORE}\n"
    
        fi
      done
    done
    
    # if FOUND is not empty, REJECT the COMMIT
    # PRINT the results (colorful-like)
    
    if [[ ! -z $FOUND ]]; then
      printf "${YELLOW}COMMIT REJECTED\n"
      printf "$FOUND"
      exit 1
    fi
    
    # nothing found? let the commit happen
    exit 0
    

    enter image description here

        2
  •  9
  •   Community CDub    7 年前

    首先,挂钩必须在 .git/hook 文件夹和名称 pre-commit (具有执行权: chmod +x .git/hooks/pre-commit )

    这个 OP jesusjjf 确认 in the comments 这就是问题所在:

    我复制了 pre-commit.sample 文件转换为纯文本文件,而不仅仅是重命名。

    其次,下面是一些脚本示例:


    You have another example 使用类似的技术,使用 git rev-parse git diff-index ,以及 empty tree I mentioned before :

    #!/bin/sh
    
    if git rev-parse --verify HEAD >/dev/null 2>&1; then
        against=HEAD
    else
        against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
    fi
    
    for FILE in `git diff-index --name-status $against -- | cut -c3-` ; do
        # Check if the file contains 'debugger'
        if [ "grep 'debugger' $FILE" ]
        then
            echo $FILE ' contains debugger!'
            exit 1
        fi
    done
    exit 
    

    The comments on this gist 提及:

    在我的系统中, if [ "grep 'debugger' $FILE" ] 始终计算为 true .
    将其更改为 if grep -q 'debugger' "$FILE" 修复了这个问题。


    A. more recent example :

    #!/bin/bash
    
    # Pre commit hook that prevents FORBIDDEN code from being commited.
    # Add unwanted code to the FORBIDDEN array as necessary
    
    FILES_PATTERN='\.(rb|js|coffee)(\..+)?$'
    FORBIDDEN=( debugger ruby-debug )
    
    for i in "${FORBIDDEN[@]}"
    do
      git diff --cached --name-only| grep ".js" |xargs sed 's/ //g'|grep "ha_mobile.debug=true" && \
            echo 'COMMIT REJECTED Found ha_mobile.debug=true references. Please remove them before commiting' && exit 1
    
      git diff --cached --name-only | \
            grep -E $FILES_PATTERN | \
            GREP_COLOR='4;5;37;41' xargs grep --color --with-filename -n $i && \
            echo 'COMMIT REJECTED Found'  $i 'references. Please remove them before commiting' && exit 1
    done
    
    exit 0