pub fn carry_hooks_path(primary: &Path, worktree: &Path) -> HooksPathExpand description
Bind worktree to the hooks directory of its own tree, when the repository tracks one
and git would otherwise run another worktree’s.
primary is the primary checkout, whose effective core.hooksPath is the repository’s
policy. Never fails: the worst outcome is a worktree left as git left it, reported. The
primary checkout itself is answered with what it runs and never changed.
use std::process::Command;
use majordomus_cli::worktree::{carry_hooks_path, HooksPath};
let dir = tempfile::tempdir().unwrap();
let r = dir.path().join("r");
let wt = dir.path().join("r-wt").join("x");
let git = |cwd: &std::path::Path, args: &[&str]| {
assert!(Command::new("git").arg("-C").arg(cwd).args(args).status().unwrap().success());
};
std::fs::create_dir_all(r.join(".githooks")).unwrap();
std::fs::write(r.join(".githooks/pre-commit"), "#!/bin/sh\n").unwrap();
git(dir.path(), &["init", "-q", r.to_str().unwrap()]);
git(&r, &["add", "."]);
git(&r, &["-c", "user.name=t", "-c", "user.email=t@t", "commit", "-qm", "hooks"]);
// The value that sent every worktree to the primary's hooks: absolute, shared.
let primary_hooks = r.join(".githooks");
git(&r, &["config", "core.hooksPath", primary_hooks.to_str().unwrap()]);
git(&r, &["worktree", "add", "-q", "-b", "x", wt.to_str().unwrap()]);
match carry_hooks_path(&r, &wt) {
HooksPath::Set { path, .. } => assert!(path.ends_with("r-wt/x/.githooks")),
other => panic!("expected the worktree's own hooks to be set, got {other:?}"),
}
// A second call finds it done.
assert!(matches!(carry_hooks_path(&r, &wt), HooksPath::Own { .. }));