[OCaml] Mobile-friendly clone of cgit.
Add support for both bare and non-bare repositories.
Changed files
lib/resolvers.ml
@@ -27,10 +27,31 @@
27
27
28
28
let full_path path = Filename.concat config.git_project_root path
29
29
30
Added:
type repository_layout = { worktree : string; git_dir : string }
31
Added:
32
Added:
let is_directory path =
33
Added:
try Sys.is_directory path with Sys_error _ -> false
34
Added:
35
Added:
let is_git_directory path =
36
Added:
is_directory path
37
Added:
&& Sys.file_exists (Filename.concat path "HEAD")
38
Added:
&& is_directory (Filename.concat path "objects")
39
Added:
40
Added:
let repository_layout path =
41
Added:
let dotgit = Filename.concat path ".git" in
42
Added:
if is_git_directory path then Some { worktree = path; git_dir = path }
43
Added:
else if is_directory path && is_git_directory dotgit then
44
Added:
Some { worktree = path; git_dir = dotgit }
45
Added:
else None
46
Added:
47
Added:
let is_repository path = Option.is_some (repository_layout path)
48
Added:
30
49
let store repo =
31
50
let* repo = validate_repo_name repo in
32
Removed:
let path = full_path repo |> Fpath.v in
33
Removed:
Store.v ~dotgit:path path
51
Added:
match repository_layout (full_path repo) with
52
Added:
| Some { worktree; git_dir } ->
53
Added:
Store.v ~dotgit:(Fpath.v git_dir) (Fpath.v worktree)
54
Added:
| None -> Lwt_result.fail (`Msg ("not a Git repository " ^ repo))
34
55
35
56
let default_repo_description = "Unnamed repository"
36
57
@@ -46,8 +67,11 @@
46
67
47
68
let repo_description repo =
48
69
if is_valid_repo_name repo then
49
Removed:
let description_path = Filename.concat (full_path repo) "description" in
50
Removed:
read_description_file description_path
70
Added:
match repository_layout (full_path repo) with
71
Added:
| Some { git_dir; _ } ->
72
Added:
let description_path = Filename.concat git_dir "description" in
73
Added:
read_description_file description_path
74
Added:
| None -> default_repo_description
51
75
else default_repo_description
52
76
53
77
let short_hash hash = String.sub hash 0 8
lib/views.ml
@@ -105,7 +105,10 @@
105
105
let repos =
106
106
Sys.readdir config.git_project_root
107
107
|> Array.to_list
108
Removed:
|> List.filter (fun name -> not (name.[0] = '.'))
108
Added:
|> List.filter (fun name ->
109
Added:
not (name.[0] = '.')
110
Added:
&& Resolvers.is_repository
111
Added:
(Filename.concat config.git_project_root name))
109
112
|> List.sort String.compare
110
113
in
111
114
let li_of_repo repo =
test/test_ogit.ml
@@ -38,6 +38,36 @@
38
38
output_string oc "A useful repository\n");
39
39
assert (Ogit.Resolvers.read_description_file file = "A useful repository")
40
40
41
Added:
let make_git_directory path =
42
Added:
Unix.mkdir path 0o755;
43
Added:
Out_channel.with_open_text (Filename.concat path "HEAD") (fun _ -> ());
44
Added:
Unix.mkdir (Filename.concat path "objects") 0o755
45
Added:
46
Added:
let test_repository_layout () =
47
Added:
let root = Filename.temp_file "ogit-repositories" "" in
48
Added:
Sys.remove root;
49
Added:
Unix.mkdir root 0o755;
50
Added:
let bare = Filename.concat root "bare.git" in
51
Added:
make_git_directory bare;
52
Added:
let clone = Filename.concat root "clone" in
53
Added:
Unix.mkdir clone 0o755;
54
Added:
make_git_directory (Filename.concat clone ".git");
55
Added:
let ordinary_directory = Filename.concat root "not-a-repository" in
56
Added:
Unix.mkdir ordinary_directory 0o755;
57
Added:
assert (Ogit.Resolvers.is_repository bare);
58
Added:
assert (Ogit.Resolvers.is_repository clone);
59
Added:
assert (not (Ogit.Resolvers.is_repository ordinary_directory));
60
Added:
(match Ogit.Resolvers.repository_layout bare with
61
Added:
| Some { worktree; git_dir } ->
62
Added:
assert (worktree = bare);
63
Added:
assert (git_dir = bare)
64
Added:
| None -> failwith "expected a bare repository layout");
65
Added:
match Ogit.Resolvers.repository_layout clone with
66
Added:
| Some { worktree; git_dir } ->
67
Added:
assert (worktree = clone);
68
Added:
assert (git_dir = Filename.concat clone ".git")
69
Added:
| None -> failwith "expected a non-bare repository layout"
70
Added:
41
71
let () =
42
72
assert (Ogit.Resolvers.is_valid_repo_name "project.git");
43
73
assert (Ogit.Resolvers.is_valid_repo_name "project");
@@ -65,4 +95,5 @@
65
95
assert (Ogit.Resolvers.Reference.tag_name "refs/heads/v1.0.0" = None);
66
96
test_config_round_trip ();
67
97
test_config_location ();
68
Removed:
test_description_reader ()
98
Added:
test_description_reader ();
99
Added:
test_repository_layout ()