Add support for both bare and non-bare repositories.

Commit
06646957a211f691e0363c0f897b518b0d8cf214
Author
Marius Peter <dev@marius-peter.com>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
Changed files
lib/resolvers.ml
index eb55935d..d96cfd13 100644..100644
@@ -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
index 3ad0fcaa..43133e2d 100644..100644
@@ -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
index b89b94d1..068c5e80 100644..100644
@@ -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 ()