简体   繁体   English

Git 仅针对特定子文件夹的预提交挂钩?

[英]Git pre-commit hooks only for a specific subfolder?

I currently have a single repo with two projects, each in their own subfolder: one in C# and one in Javascript. I want to have a pre-commit hook that will run jshint but only if any of the staged files are in the Javascript folder If the staged files are only from the C# folder, then the pre-commit hook won't run.我目前有一个包含两个项目的回购协议,每个项目都在自己的子文件夹中:一个在 C# 中,一个在 Javascript 中。我想要一个预提交挂钩,它将运行 jshint,但前提是任何暂存文件都在 Javascript 文件夹中如果暂存文件仅来自 C# 文件夹,则预提交挂钩将不会运行。

Is it that possible at all?这可能吗? Or is my only solution to split the two projects into their own repos?还是我将这两个项目拆分成自己的回购协议的唯一解决方案?

Specify files to include (or exclude to exclude) specific directories, eg run hooks only in my_dir :指定files以包含(或exclude以排除)特定目录,例如仅在my_dir运行钩子:

files: ^my_dir/
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    hooks:
        ...

or run everywhere but inside my_dir :或到处运行,但在my_dir

exclude: ^my_dir/
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    hooks:
        ...

If you have a long list of exclusions, use verbose regex:如果您有很长的排除列表,请使用详细的正则表达式:

exclude: >
  (?x)^(
      path/to/file1.py|
      path/to/file2.py|
      path/to/file3.py
  )$

you can also apply these to specific hooks only, just do:您也可以仅将这些应用于特定的钩子,只需执行以下操作:

-   id: my-hook
    exclude: ^my_dir/

You can use git log to find out if the latest commit in a subdir matches the latest commit at your repository root:您可以使用git log找出子目录中的最新提交是否与存储库根目录中的最新提交匹配:

#!/bin/env bash

function get_commit {
    git log --oneline -- $1 | head -n 1 | cut -d " " -f1
}

ROOT_COMMIT=$(get_commit)
SUBDIR_COMMIT=$(get_commit my/subdir/path)

if [ "$SUBDIR_COMMIT" == "$ROOT_COMMIT" ]; then
    # do pre-commit hook stuff here
fi

Here are good native solutions. 这里有很好的本地解决方案。

I use something like this我用这样的东西

if git diff --cached --quiet -- "frontend/"
then
  echo "Unchanged"
  exit 0
else
  echo "Changed"
fi

Git hooks are scripts that Git runs before or after it does specific things. Git 钩子是 Git 在执行特定操作之前或之后运行的脚本。

If you write a script and save it as <repository_name>/.git/hooks/pre-commit then git will run it before committing.如果您编写脚本并将其保存为<repository_name>/.git/hooks/pre-commit那么 git 将在提交之前运行它。 So write a simple script for the operating system you are using that runs jshint against that subfolder and save it to that path.因此,为您正在使用的操作系统编写一个简单的脚本,该脚本针对该子文件夹运行 jshint,并将其保存到该路径。

Git doesn't run your pre-commit hook with any arguments. Git 不会使用任何参数运行您的预提交挂钩。 You can use git commands to figure out the state of your repository (the changes added as part of the commit are still just staged and accessible through --cached).您可以使用 git 命令来确定存储库的状态(作为提交的一部分添加的更改仍然只是暂存并可以通过 --cached 访问)。 If you make any changes and want them to become part of the commit, you'll need to add them before the script exits.如果您进行任何更改并希望它们成为提交的一部分,则需要在脚本退出之前添加它们。

You are working with C# so you should be aware that git hooks on windows are a bit quirky: Executing Git hooks on Windows您正在使用 C#,因此您应该意识到 Windows 上的 git hooks 有点古怪: Executing Git hooks on Windows

If you are using pre-commit newer than v1.1.0, then you can add a exclude field to your .pre-commit-config.yaml which is located in the root folder of your repo.如果您使用比 v1.1.0 更新的预提交,那么您可以向位于存储库根文件夹中的.pre-commit-config.yaml添加一个exclude字段。

Just like below:就像下面一样:

exclude: '^(?!javascript/)'

Check the document here此处检查文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM