【问题标题】:How to make a git pre-commit code check?如何进行 git 预提交代码检查?
【发布时间】:2015-01-15 12:55:45
【问题描述】:

第一个问题......甚至可以用 git 完成这个吗? :)

我想要的是这个:

有时我将代码中的一个变量切换为true (localMode = true;) 用于我自己的调试目的。但这不应该被提交。我应该只提交变量设置为false 的代码。当然,有时我会忘记做出这种改变。如果我即将提交“错误”代码,git 是否有可能以某种方式停止或警告我?

统一更新:
感谢您的帮助!我最终得到了以下 shell 脚本:

#!/bin/bash
git diff --cached --name-only | while read FILE; do
if [[ $(echo "$FILE" | grep -E "^.+main\-controller\.js$") ]]; then
    content=$(<"$FILE")
    if [[ $(echo "$content" | grep -E "rootScope\.localMode = true") ]]; then   
        echo -e "\e[1;31m\tCommit contains localMode set to true.\e[0m" >&2
        exit 1
    fi
fi
done

【问题讨论】:

  • 这就是smudge and clean filters 的用途:在提交之前清理工作树副本中的任何脏东西,在签出时涂抹以弄脏它。
  • 很好,现在,您可以制作自定义预挂钩了!

标签: git pre-commit-hook pre-commit


【解决方案1】:

下面的链接呢?

http://wadmiraal.net/lore/2014/07/14/how-git-hooks-made-me-a-better-and-more-lovable-developer/

我认为您可以在链接的示例代码中添加一些正则表达式来检测localMode = true

【讨论】:

  • 谢谢!该链接很有帮助,因为我不熟悉 shell 脚本。当然,在我的 Windows 机器上遇到了一些障碍,但我最终让它工作了。
【解决方案2】:

是的,您可以使用pre-commit 挂钩。

只需将名为 pre-commit(无扩展名)的 shell 脚本放入“.git/hooks”文件夹中,其中包含检查变量的逻辑以及:

  • 将其更改为 false 并继续提交或
  • 打印一条消息,告诉用户手动更正该值,并以非零代码退出以中止提交

hooks 文件夹应该包含一些示例,例如“pre-commit.sample”,您可能会觉得这些示例很有帮助。

来自docs

pre-commit 钩子首先运行,甚至在您输入提交消息之前。它用于检查即将提交的快照,查看您是否忘记了某些内容,确保测试运行,或者检查您需要在代码中检查的任何内容。从这个钩子中退出非零会中止提交,尽管您可以使用 git commit --no-verify 绕过它。您可以检查代码样式(运行 lint 或类似的东西)、检查尾随空格(默认挂钩就是这样做的)或检查有关新方法的适当文档。

【讨论】:

    【解决方案3】:

    这是一个更新,适用于想要找到以前解决方案的替代方案的人。

    现在有很多资源可以使用 git pre-commit hook 检查内容。

    最“有名”的大概是https://pre-commit.com/

    Git 钩子有时难以维护和共享(即使 git 2.9 引入了core.hooksPath 配置使其更容易)。

    我主要使用 JavaScript,我发现了一个名为 Husky 的流行模块,它通过项目管理可共享的钩子。我喜欢它,因为它通过我的package.json 在我的项目中集成、共享和配置。

    我还尝试找到一个补充模块来在提交之前检查我的内容,但我没有发现任何令人满意的东西。我想要类似这样的共享配置(package.json):

    "precommit-checks": [
      {
        "filter": "\\.js$",
        "nonBlocking": "true",
        "message": "You’ve got leftover `console.log`",
        "regex": "console\\.log"
      },
      {
        "message": "You’ve got leftover conflict markers",
        "regex": "/^[<>|=]{4,}/m"
      },
      {
        "message": "You have unfinished devs",
        "nonBlocking": "true",
        "regex": "(?:FIXME|TODO)"
      }
    ]
    

    我终于自己制作了:git-precommit-checks。 如果你愿意,你可以尝试一下,否则你仍然可以寻找替代方案(尤其是如果你不使用 JS)。

    如果您仍想使用 bash 脚本检查您的内容,您可以尝试一种更通用的方法,并遍历应停止提交的搜索模式数组。

    #! /bin/bash
    # If you encounter any error like `declare: -A: invalid option`
    # then you'll have to upgrade bash version to v4.
    # For Mac OS, see http://clubmate.fi/upgrade-to-bash-4-in-mac-os-x/
    
    # Hash using its key as a search Regex, and its value as associated error message
    declare -A PATTERNS;
    PATTERNS['^[<>|=]{4,}']="You've got leftover conflict markers";
    PATTERNS['focus:\s*true']="You've got a focused spec";
    
    # Declare empty errors array
    declare -a errors;
    
    # Loop over staged files and check for any specific pattern listed in PATTERNS keys
    # Filter only added (A), copied (C), modified (M) files
    for file in $(git diff --staged --name-only --diff-filter=ACM --no-color --unified=0); do
      for elem in ${!PATTERNS[*]} ; do
        { git show :0:"$file" | grep -Eq ${elem}; } || continue;
        errors+=("${PATTERNS[${elem}]} in ${file}…");
      done
    done
    
    # Print errors
    # author=$(git config --get user.name)
    for error in "${errors[@]}"; do
      echo -e "\033[1;31m${error}\033[0m"
      # Mac OS only: use auditable speech
      # which -s say && say -v Samantha -r 250 "$author $error"
    done
    
    # If there is any error, then stop commit creation
    if ! [ ${#errors[@]} -eq 0 ]; then
      exit 1
    fi
    

    【讨论】:

      【解决方案4】:

      这是我根据之前的回答得出的结论:

      #! /bin/bash
      #
      # This is a git hook. It exits with non-zero status and thus aborts
      # a running `git commit` if the processed files contain undesirable PATTERNS.
      #
      # To enable this hook, rename this file to .git/hooks/pre-commit and run:
      #   chmod a+x .git/hooks/pre-commit
      # 
      # To make it global:
      #   git config --global core.hooksPath ~/git-central-hooks
      #
      # Source: https://stackoverflow.com/questions/26992576/how-to-make-a-git-pre-commit-code-check
      # 
      # Known problem:
      # If you encounter error `declare: -A: invalid option` or similar upgrade bash 
      # version to v4. For Mac OS, see http://clubmate.fi/upgrade-to-bash-4-in-mac-os-x/
      #
      
      # Declare empty arrays
      declare -A PATTERNS
      declare -a errors
      
      # Customize it:  ['your grep pattern'] ===> "Error message when found"
      PATTERNS['^[<>|=]{4,}']="You've got leftover CONFLICT markers"
      PATTERNS['FIXME']="You've got FIXME hanging (consider changing to TODO)"
      
      while read file 
      do
        for elem in ${!PATTERNS[*]}
        do
          if git show :0:"$file" | grep -Eq "$elem"
          then
              errors+=( "${PATTERNS[${elem}]} in file '$file'" )
          fi
        done
      # The post-loop expression generates only filenames added (A) or modified (M)
      done < <( git diff --staged --name-only --diff-filter=AM --no-color --unified=0 )
      
      # Print errors
      for error in "${errors[@]}"
      do
        echo -e "\033[1;31m${error}\033[0m"
        # Mac OS only: use auditable speech
        # author=$(git config --get user.name)
        # which -s say && say -v Samantha -r 250 "$author $error"
      done
      
      # Fail if there is an error
      if [[ ${#errors[@]} -ne 0 ]]
      then
        exit 1
      fi
      

      【讨论】:

        猜你喜欢
        • 2018-07-22
        • 1970-01-01
        • 1970-01-01
        • 2018-01-07
        • 2023-01-17
        • 2021-02-27
        • 1970-01-01
        • 1970-01-01
        • 2023-04-10
        相关资源
        最近更新 更多