Skip to content

Resolve repository hooks from the common directory - #2813

Open
YuriNachos wants to merge 1 commit into
git-up:masterfrom
YuriNachos:fix/worktree-hooks-common-dir
Open

Resolve repository hooks from the common directory#2813
YuriNachos wants to merge 1 commit into
git-up:masterfrom
YuriNachos:fix/worktree-hooks-common-dir

Conversation

@YuriNachos

Copy link
Copy Markdown

Fixes #1053

Summary

pre-commit, pre-push, and other Git hooks are now found when the repository is a linked worktree. Previously GitUp silently skipped hooks for worktrees because it looked them up in the wrong directory.

Root Cause

-pathForHookWithName: built the default hooks directory from self.repositoryPath, i.e. git_repository_path(). For a linked worktree that returns the per-worktree git directory (e.g. <main>/.git/worktrees/<name>), which never contains a hooks directory. Git stores hooks in the repository common directory (<main>/.git/hooks), shared by all linked worktrees, so GitUp never found them and runHookWithName: (used for the pre-push hook in -sendLocalBranchesToRemote:...) silently treated them as absent.

Changes

  • GitUpKit/Core/GCRepository.m
    • In -pathForHookWithName:, derive the default hooks path from git_repository_commondir(_private) instead of self.repositoryPath. For a plain repository the common directory equals the git directory, so behavior is unchanged; only linked worktrees are affected.

Test plan

  • Added testPathForHookWithName_FoundFromLinkedWorktree to GCRepository-Tests.m (GCMultipleCommitsRepositoryTests): creates a linked worktree via git worktree add, installs an executable pre-commit hook in the main repository hooks directory, and asserts the worktree resolves the hook to that shared path.
  • Verified red→green locally:
    cd GitUpKit
    xcodebuild test -scheme "GitUpKit (macOS)" -destination "platform=macOS" \
      -only-testing:Tests/GCMultipleCommitsRepositoryTests/testPathForHookWithName_FoundFromLinkedWorktree \
      CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
    
    The new test fails on master (worktree cannot resolve the hook) and passes with this change.
  • Existing testPathForHookWithName, testPathForHookWithName_AbsoluteCustomHooksPath, and testPathForHookWithName_RelativeCustomHooksPath are unaffected (a plain repo has commondir == gitdir, and the custom core.hooksPath branch is untouched).

I AGREE TO THE GITUP CONTRIBUTOR LICENSE AGREEMENT

Git stores hooks in the repository's common directory, which is shared by
all linked worktrees. -pathForHookWithName: derived the default hooks path
from self.repositoryPath, i.e. git_repository_path(), which for a linked
worktree is the per-worktree git directory. That directory never contains a
hooks directory, so GitUp silently failed to find pre-commit, pre-push, and
other hooks when operating on a worktree (issue git-up#1053).

Use git_repository_commondir() for the default hooks path instead. For a
plain (non-worktree) repository the common directory is the git directory,
so behavior is unchanged there; only linked worktrees now resolve hooks
correctly.

Fixes git-up#1053
@greptile-apps

greptile-apps Bot commented Aug 11, 2026

Copy link
Copy Markdown

Greptile Summary

The PR corrects default Git hook discovery for linked worktrees by resolving hooks relative to libgit2’s shared repository common directory.

  • Uses git_repository_commondir while leaving custom core.hooksPath handling unchanged.
  • Adds a regression test that creates a linked worktree and verifies discovery of a shared executable hook.

Confidence Score: 5/5

The PR appears safe to merge, with no actionable correctness or security issues identified.

The common-directory API supplies the correct hook base for linked worktrees while preserving plain and bare repository behavior, and the regression test directly covers the corrected path.

Important Files Changed

Filename Overview
GitUpKit/Core/GCRepository.m Correctly changes default hook resolution from the per-worktree Git directory to the shared common directory.
GitUpKit/Core/GCRepository-Tests.m Adds focused linked-worktree coverage that exercises the previous failure and verifies the resolved shared hook path.

Reviews (1): Last reviewed commit: "Resolve repository hooks from the common..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

GitUp does not execute pre-commit/pre-push hook for worktrees

1 participant