Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ public protocol GitHookInstallerFileManaging {
func readString(at url: URL) throws -> String
func writeString(_ content: String, to url: URL) throws
func setAttributes(_ attributes: [FileAttributeKey: Any], ofItemAtPath path: String) throws
func attributesOfItem(atPath path: String) throws -> [FileAttributeKey: Any]
}
6 changes: 6 additions & 0 deletions Sources/LucaCore/Core/GitHookInstaller/GitHookInstaller.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ public struct GitHookInstaller {
return
}

// In a git worktree, `.git` is a file (not a directory) pointing to the main repo.
// Hooks live in the main repo; skip installation to avoid failing in a worktree context.
guard (try? fileManager.attributesOfItem(atPath: gitDirectory.path)[.type] as? FileAttributeType) == .typeDirectory else {
return
}

let sourceHookPath = fileManager.homeDirectoryForCurrentUser
.appending(components: Constants.toolFolder, "post-checkout")

Expand Down
16 changes: 16 additions & 0 deletions Tests/Core/GitHookInstallerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@ final class GitHookInstallerTests: XCTestCase {
XCTAssertTrue(printer.printedMessages.isEmpty)
}

// MARK: - Git Worktree

func test_installPostCheckoutHook_whenGitWorktree_doesNothing() throws {
// Given: `.git` is a file (worktree), not a directory
let currentDirectory = URL(fileURLWithPath: fileManager.currentDirectoryPath)
try fileManager.createDirectory(at: currentDirectory, withIntermediateDirectories: true)
let gitFile = currentDirectory.appending(component: ".git")
_ = fileManager.createFile(atPath: gitFile.path, contents: Data("gitdir: /some/main/repo/.git/worktrees/feature\n".utf8))

// When
try sut.installPostCheckoutHook()

// Then
XCTAssertTrue(printer.printedMessages.isEmpty)
}

// MARK: - Source Hook Missing

func test_installPostCheckoutHook_whenSourceHookMissing_printsWarning() throws {
Expand Down
Loading