'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.

Is it that possible at all? Or is my only solution to split the two projects into their own repos?



Solution 1:[1]

Specify files to include (or exclude to exclude) specific directories, e.g. run hooks only in my_dir:

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

or run everywhere but inside 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/

Solution 2:[2]

You can use git log to find out if the latest commit in a subdir matches the latest commit at your repository root:

#!/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

Solution 3:[3]

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

Solution 4:[4]

Git hooks are scripts that Git runs before or after it does specific things.

If you write a script and save it as <repository_name>/.git/hooks/pre-commit then git will run it before committing. So write a simple script for the operating system you are using that runs jshint against that subfolder and save it to that path.

Git doesn't run your pre-commit hook with any arguments. 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). 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

Solution 5:[5]

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.

Just like below:

exclude: '^(?!javascript/)'

Check the document here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tomasz Bartkowiak
Solution 2 marcusljx
Solution 3 Igor Lyadov
Solution 4 Community
Solution 5 zoron