[OCaml] Mobile-friendly clone of cgit.
fix prefer .git/ over bare detection for repository layout
A non-bare repository whose worktree contains files named HEAD and objects/ (e.g. ~/git/TAOH) was incorrectly classified as bare, causing Store.v to fail on the wrong git directory. Fix by checking for .git/ first: if a .git subdirectory passes is_git_directory, the repository is non-bare regardless of worktree contents. Only fall back to bare detection when .git is absent. Also remove the page header on the root page (now redundant with the root navbar). Add a regression test for the shadowing scenario.
Changed files
lib/resolvers.ml
@@ -69,15 +69,14 @@
69
69
let repository_layout_result path =
70
70
let ( let* ) = Result.bind in
71
71
let dotgit = Filename.concat path ".git" in
72
Removed:
let* bare = is_git_directory_result path in
73
Removed:
if bare then Ok (Some { worktree = path; git_dir = path })
72
Added:
let* worktree = is_directory_result path in
73
Added:
if not worktree then Ok None
74
74
else
75
Removed:
let* worktree = is_directory_result path in
76
Removed:
if not worktree then Ok None
75
Added:
let* non_bare = is_git_directory_result dotgit in
76
Added:
if non_bare then Ok (Some { worktree = path; git_dir = dotgit })
77
77
else
78
Removed:
let* non_bare = is_git_directory_result dotgit in
79
Removed:
if non_bare then Ok (Some { worktree = path; git_dir = dotgit })
80
Removed:
else Ok None
78
Added:
let* bare = is_git_directory_result path in
79
Added:
if bare then Ok (Some { worktree = path; git_dir = path }) else Ok None
81
80
82
81
let repository_layout path =
83
82
match repository_layout_result path with
lib/views/layout.ml
@@ -106,9 +106,9 @@
106
106
(match page_data.repo with
107
107
| None -> rootnav ~title:root_title
108
108
| Some repo -> topnav ~active:page_data.active repo);
109
Removed:
page_header
110
Removed:
~has_repo:(Option.is_some page_data.repo)
111
Removed:
page_data.title page_data.subtitle;
109
Added:
(match page_data.repo with
110
Added:
| None -> HTML.null []
111
Added:
| Some _ -> page_header ~has_repo:true page_data.title page_data.subtitle);
112
112
div [ id "main" ] page_data.content;
113
113
page_footer user;
114
114
]
test/test_discovery.ml
@@ -62,6 +62,28 @@
62
62
"not a repository" false
63
63
(Ogit.Resolvers.is_repository directory))
64
64
65
Added:
let test_layout_non_bare_with_shadowing_files () =
66
Added:
with_temp_directory "ogit-repos" (fun root ->
67
Added:
let repo = Filename.concat root "TAOH" in
68
Added:
Unix.mkdir repo 0o755;
69
Added:
make_git_directory (Filename.concat repo ".git");
70
Added:
(* Create HEAD file and objects/ directory in the worktree that could
71
Added:
confuse bare-repository detection. *)
72
Added:
Out_channel.with_open_text (Filename.concat repo "HEAD") (fun ch ->
73
Added:
output_string ch "ref: refs/heads/master\n");
74
Added:
Unix.mkdir (Filename.concat repo "objects") 0o755;
75
Added:
Alcotest.(check bool)
76
Added:
"is_repository" true
77
Added:
(Ogit.Resolvers.is_repository repo);
78
Added:
match Ogit.Resolvers.repository_layout repo with
79
Added:
| Some { worktree; git_dir } ->
80
Added:
Alcotest.(check string) "worktree" repo worktree;
81
Added:
Alcotest.(check string)
82
Added:
"git_dir uses .git"
83
Added:
(Filename.concat repo ".git")
84
Added:
git_dir
85
Added:
| None -> Alcotest.fail "expected non-bare layout")
86
Added:
65
87
let test_listing () =
66
88
with_temp_directory "ogit-listing" (fun root ->
67
89
make_git_directory (Filename.concat root "visible.git");
@@ -92,6 +114,8 @@
92
114
Alcotest.test_case "description content" `Quick test_description_content;
93
115
Alcotest.test_case "bare layout" `Quick test_layout_bare;
94
116
Alcotest.test_case "non-bare layout" `Quick test_layout_non_bare;
117
Added:
Alcotest.test_case "non-bare with shadowing files" `Quick
118
Added:
test_layout_non_bare_with_shadowing_files;
95
119
Alcotest.test_case "not a repository" `Quick test_layout_not_a_repo;
96
120
Alcotest.test_case "listing" `Quick test_listing;
97
121
Alcotest.test_case "fallback branches" `Quick test_fallback_branches;