Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 22ad6a9

Browse files
author
Naseschwarz
committedMar 18, 2025·
Resolve core.hooksPath relative to GIT_WORK_TREE
git supports relative values in core.hooksPath. `man git-config`: > A relative path is taken as relative to the directory where the hooks are > run (see the "DESCRIPTION" section of githooks[5]). `man githooks`: > Before Git invokes a hook, it changes its working directory to either > $GIT_DIR in a bare repository or the root of the working tree in a > > non-bare repository. I.e. relative paths in core.hooksPath in non-bare repositories are always relative to GIT_WORK_TREE. There is a further exception; I believe this is not considered for path resolution: > An exception are hooks triggered during a push (pre-receive, update, > post-receive, post-update, push-to-checkout) which are always executed > in $GIT_DIR.
1 parent 3ede6b5 commit 22ad6a9

File tree

4 files changed

+55
-3
lines changed

4 files changed

+55
-3
lines changed
 

‎CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2020
* push: respect `branch.*.merge` when push default is upstream [[@vlad-anger](https://github.com/vlad-anger)] ([#2542](https://github.com/gitui-org/gitui/pull/2542))
2121
* set the terminal title to `gitui ({repo_path})` [[@acuteenvy](https://github.com/acuteenvy)] ([#2462](https://github.com/gitui-org/gitui/issues/2462))
2222

23+
### Fixes
24+
* Resolve core.hooksPath relative to `GIT_WORK_TREE` [[@naseschwarz](https://github.com/naseschwarz)] ([#2571](https://github.com/gitui-org/gitui/issues/2571))
25+
2326
## [0.27.0] - 2024-01-14
2427

2528
**new: manage remotes**

‎asyncgit/src/sync/hooks.rs

+36
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,40 @@ mod tests {
174174

175175
assert_eq!(msg, String::from("msg\n"));
176176
}
177+
178+
#[test]
179+
fn test_hooks_commit_msg_reject_in_hooks_folder_githooks_moved_absolute(
180+
) {
181+
let (_td, repo) = repo_init().unwrap();
182+
let root = repo.path().parent().unwrap();
183+
let mut config = repo.config().unwrap();
184+
185+
const HOOKS_DIR: &'static str = "my_hooks";
186+
config.set_str("core.hooksPath", HOOKS_DIR).unwrap();
187+
188+
let hook = b"#!/bin/sh
189+
echo 'msg' > $1
190+
echo 'rejected'
191+
exit 1
192+
";
193+
let hooks_folder = root.join(HOOKS_DIR);
194+
std::fs::create_dir_all(&hooks_folder).unwrap();
195+
git2_hooks::create_hook_in_path(
196+
&hooks_folder.join("commit-msg"),
197+
hook,
198+
);
199+
200+
let mut msg = String::from("test");
201+
let res = hooks_commit_msg(
202+
&hooks_folder.to_str().unwrap().into(),
203+
&mut msg,
204+
)
205+
.unwrap();
206+
assert_eq!(
207+
res,
208+
HookResult::NotOk(String::from("rejected\n"))
209+
);
210+
211+
assert_eq!(msg, String::from("msg\n"));
212+
}
177213
}

‎git2-hooks/src/hookspath.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,17 @@ impl HookPaths {
4949
.ok_or(HooksError::PathToString)?,
5050
)?;
5151

52-
let hook = PathBuf::from_str(hook.as_ref())
53-
.map_err(|_| HooksError::PathToString)?;
52+
let hook = {
53+
let hook_expanded = PathBuf::from_str(hook.as_ref())
54+
.map_err(|_| HooksError::PathToString)?;
55+
if hook_expanded.is_absolute() {
56+
hook_expanded
57+
} else {
58+
let mut hook_absolute = pwd.clone();
59+
hook_absolute.push(hook_expanded);
60+
hook_absolute
61+
}
62+
};
5463

5564
return Ok(Self {
5665
git: git_dir,

‎git2-hooks/src/lib.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,11 @@ pub fn create_hook(
9898
path
9999
}
100100

101-
fn create_hook_in_path(path: &Path, hook_script: &[u8]) {
101+
/// helper method to create a git hook in a custom path (used in unittests)
102+
///
103+
/// # Panics
104+
/// Panics if hook could not be created
105+
pub fn create_hook_in_path(path: &Path, hook_script: &[u8]) {
102106
File::create(path).unwrap().write_all(hook_script).unwrap();
103107

104108
#[cfg(unix)]

0 commit comments

Comments
 (0)
Please sign in to comment.