arxanas / git-branchless

High-velocity, monorepo-scale workflow for Git
Apache License 2.0
3.45k stars 87 forks source link

Hooks installed to global `core.hooksPath` and enabled in all repos #235

Closed evanrelf closed 2 years ago

evanrelf commented 2 years ago

Description of the bug

When core.hooksPath is set to a path outside the local Git repository (e.g. ~/.config/git/hooks), git branchless init places hooks in the global hooks path which are then applied to all Git repositories.

I don't think core.hooksPath is commonly changed by users, so this is probably a low priority issue. And this may be more of a problem with how core.hooksPath works with non-relative paths, and not git-branchless. Regardless, I thought I'd mention it.

Expected behavior

git-branchless hooks were installed in the repository-local hooks directory (.git/hooks) and applied to the current Git repository only.

Actual behavior

git-branchless hooks were installed in my global core.hooksPath directory (~/.config/git/hooks) and applied to Git repositories where I hadn't run git branchless init.

Version of git-branchless

9861d7093093ae2a92ff087a44ffd273ae051d37

Version of rustc

No response

arxanas commented 2 years ago

Hi @evanrelf , thanks for reporting!

From the documentation (https://git-scm.com/docs/githooks), it seems to imply that the hooks at core.hooksPath are the repository-local hooks, because by default this value is $GIT_DIR/hooks, where $GIT_DIR refers to the repo's .git directory. You probably don't want to set core.hooksPath globally; instead, you might want to use a template directory with git init to install a set of base hooks (which could be symlinks, I suppose).

From the documentation, it sounds like if we install the hooks to somewhere other than core.hooksPath, they won't be respected at all. Maybe instead we could surface a warning if core.hooksPath appears to be an absolute path, or is set in a global Git configuration file?

arxanas commented 2 years ago

I see that the same issue happens for Git LFS: https://github.com/git-lfs/git-lfs/issues/3240. There doesn't seem to be a compelling solution for this use-case.

evanrelf commented 2 years ago

You probably don't want to set core.hooksPath globally; instead, you might want to use a template directory with git init to install a set of base hooks

The global hooksPath has been useful for me to ensure my pre-push hook always takes effect, without any manual installation or init template required...

From the documentation, it sounds like if we install the hooks to somewhere other than core.hooksPath, they won't be respected at all.

...but this part ^ seems to indicate there's no way for git-branchless to support this use case (without adding a lot of complexity and assumptions for this edge case) ☹️ ...

Maybe instead we could surface a warning if core.hooksPath appears to be an absolute path, or is set in a global Git configuration file?

...so I think a warning is the right thing to do here. If core.hooksPath isn't inside of $GIT_DIR, issue a warning that the hooks may take effect in other repositories. Or something like that.

martinvonz commented 2 years ago

FYI (mostly for @evanrelf), I think Git's new "config-based hooks" will solve this once they're available. See this discussion.

evanrelf commented 2 years ago

@martinvonz Thanks for sharing; I wasn't aware of that. That sounds like exactly what I want 🙂