File tree 2 files changed +51
-5
lines changed
2 files changed +51
-5
lines changed Original file line number Diff line number Diff line change @@ -35,13 +35,55 @@ public function locate(string $gitDir): string
35
35
36
36
$ gitRepositoryDir = $ matches [1 ];
37
37
38
- if ($ this ->filesystem -> isAbsolutePath ($ gitRepositoryDir )) {
39
- return $ gitRepositoryDir ;
38
+ if ($ this ->isWorktree ($ gitRepositoryDir )) {
39
+ return $ this -> locateWorktreeRoot ( $ gitRepositoryDir) ;
40
40
}
41
41
42
42
return $ this ->filesystem ->buildPath (
43
43
dirname ($ gitDir ),
44
44
$ gitRepositoryDir
45
45
);
46
46
}
47
+
48
+ /**
49
+ * If a given path (from gitdir value) is absolute and there is a commondir file, it is
50
+ * a worktree.
51
+ */
52
+ private function isWorktree (string $ gitDir ): bool
53
+ {
54
+ return $ this ->filesystem ->isAbsolutePath ($ gitDir )
55
+ && $ this ->filesystem ->isFile ($ gitDir .DIRECTORY_SEPARATOR .'commondir ' );
56
+ }
57
+
58
+ /**
59
+ * Retreiving repository dir for worktree nominally returns path to the configured worktree,
60
+ * which does not hold hooks. We need to resolve the actual repository root.
61
+ *
62
+ * Example directory structure:
63
+ * ```
64
+ * /project
65
+ * .git/
66
+ * .git/hooks/
67
+ * .git/worktrees/
68
+ * worktree1
69
+ * commondir: relative path to /project/.git
70
+ * /worktree1
71
+ * .git: file with path to /project/.git/worktrees/worktree1
72
+ * ```
73
+ */
74
+ private function locateWorktreeRoot (string $ gitRepositoryDir ): string
75
+ {
76
+ $ worktreeRelativeRoot = trim (
77
+ $ this ->filesystem ->readPath (
78
+ $ gitRepositoryDir .DIRECTORY_SEPARATOR .'commondir '
79
+ )
80
+ );
81
+
82
+ return $ this ->filesystem ->realpath (
83
+ $ this ->filesystem ->makePathAbsolute (
84
+ $ worktreeRelativeRoot ,
85
+ $ gitRepositoryDir
86
+ )
87
+ );
88
+ }
47
89
}
Original file line number Diff line number Diff line change @@ -31,7 +31,7 @@ protected function setUp(): void
31
31
32
32
$ this ->filesystem = new Filesystem ();
33
33
$ this ->locator = new GitRepositoryDirLocator ($ this ->filesystem );
34
- $ this ->gitDir = $ this ->workspace . DIRECTORY_SEPARATOR . '.git ' ;
34
+ $ this ->gitDir = $ this ->workspace . DIRECTORY_SEPARATOR . '.git ' ;
35
35
}
36
36
37
37
/**
@@ -69,7 +69,11 @@ public function it_can_passthrough_git_dir_path_if_file_is_not_parseable(): void
69
69
*/
70
70
public function it_can_locate_git_dir_in_workspaces (): void
71
71
{
72
- $ this ->filesystem ->dumpFile ($ this ->gitDir , 'gitdir: /dev/null ' );
73
- $ this ->assertEquals ('/dev/null ' , $ this ->locator ->locate ($ this ->gitDir ));
72
+ $ ourWorktreeProject = $ this ->workspace .'/project1/ ' ;
73
+ $ worktreeGitRoot = $ this ->gitDir .'/worktrees/worktree1/ ' ;
74
+ mkdir ($ worktreeGitRoot , 0777 , true );
75
+ $ this ->filesystem ->dumpFile ($ worktreeGitRoot .'/commondir ' , '../.. ' );
76
+ $ this ->filesystem ->dumpFile ($ ourWorktreeProject .'/.git ' , 'gitdir: ' .$ this ->gitDir .'/worktrees/worktree1 ' );
77
+ $ this ->assertEquals ($ this ->gitDir , $ this ->locator ->locate ($ this ->gitDir ));
74
78
}
75
79
}
You can’t perform that action at this time.
0 commit comments