1
1
use anyhow:: Result ;
2
- use but_graph:: VirtualBranchesTomlMetadata ;
3
2
use but_settings:: AppSettings ;
3
+ use gitbutler_project:: access:: { WorktreeReadPermission , WorktreeWritePermission } ;
4
4
use gitbutler_project:: Project ;
5
+ use std:: ops:: { Deref , DerefMut } ;
5
6
use std:: path:: Path ;
6
7
7
8
pub struct CommandContext {
@@ -14,6 +15,42 @@ pub struct CommandContext {
14
15
db_handle : Option < but_db:: DbHandle > ,
15
16
}
16
17
18
+ /// A [`but_graph::VirtualBranchesTomlMetadata`] instance that is only accessible if it sees a read
19
+ /// permission upon instantiation.
20
+ ///
21
+ /// This is necessary only while the `virtual_branches.toml` file is used as it's read eagerly on
22
+ /// instantiation, and must thus not interleave with other writers.
23
+ pub struct VirtualBranchesTomlMetadata ( but_graph:: VirtualBranchesTomlMetadata ) ;
24
+
25
+ impl Deref for VirtualBranchesTomlMetadata {
26
+ type Target = but_graph:: VirtualBranchesTomlMetadata ;
27
+
28
+ fn deref ( & self ) -> & Self :: Target {
29
+ & self . 0
30
+ }
31
+ }
32
+
33
+ /// A [`but_graph::VirtualBranchesTomlMetadata`] instance that is only accessible if it sees a write
34
+ /// permission upon instantiation.
35
+ ///
36
+ /// This is necessary only while the `virtual_branches.toml` file is used as it's read eagerly on
37
+ /// instantiation, and must thus not interleave with other writers.
38
+ pub struct VirtualBranchesTomlMetadataMut ( but_graph:: VirtualBranchesTomlMetadata ) ;
39
+
40
+ impl Deref for VirtualBranchesTomlMetadataMut {
41
+ type Target = but_graph:: VirtualBranchesTomlMetadata ;
42
+
43
+ fn deref ( & self ) -> & Self :: Target {
44
+ & self . 0
45
+ }
46
+ }
47
+
48
+ impl DerefMut for VirtualBranchesTomlMetadataMut {
49
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
50
+ & mut self . 0
51
+ }
52
+ }
53
+
17
54
impl CommandContext {
18
55
/// Open the repository identified by `project` and perform some checks.
19
56
pub fn open ( project : & Project , app_settings : AppSettings ) -> Result < Self > {
@@ -29,10 +66,6 @@ impl CommandContext {
29
66
pub fn project ( & self ) -> & Project {
30
67
& self . project
31
68
}
32
- //
33
- // pub fn meta(&self) -> Result<VirtualBranchesTomlMetadata> {
34
- // VirtualBranchesTomlMetadata::from_path(project.gb_dir().join("virtual_branches.toml"))
35
- // }
36
69
37
70
/// Return the [`project`](Self::project) repository.
38
71
pub fn repo ( & self ) -> & git2:: Repository {
@@ -65,38 +98,42 @@ impl CommandContext {
65
98
66
99
/// Create a new Graph traversal from the current HEAD, using (and returning) the given `repo` (configured by the caller),
67
100
/// along with a new metadata instance, and the graph itself.
101
+ ///
102
+ /// The read-permission is required to obtain a shared metadata instance. Note that it must be held
103
+ /// for until the end of the operation for the protection to be effective.
68
104
pub fn graph_and_meta (
69
105
& self ,
70
106
repo : gix:: Repository ,
107
+ _read_only : & WorktreeReadPermission ,
71
108
) -> Result < (
72
109
gix:: Repository ,
73
110
VirtualBranchesTomlMetadata ,
74
111
but_graph:: Graph ,
75
112
) > {
76
113
let meta = self . meta ( ) ?;
77
114
let graph = but_graph:: Graph :: from_head ( & repo, & meta, meta. graph_options ( ) ) ?;
78
- Ok ( ( repo, meta, graph) )
115
+ Ok ( ( repo, VirtualBranchesTomlMetadata ( meta) , graph) )
79
116
}
80
117
81
118
/// Open the repository with standard options and create a new Graph traversal from the current HEAD,
82
119
/// along with a new metadata instance, and the graph itself.
83
120
///
121
+ /// The write-permission is required to obtain a mutable metadata instance. Note that it must be held
122
+ /// for until the end of the operation for the protection to be effective.
123
+ ///
84
124
/// Use [`Self::graph_and_meta()`] if control over the repository configuration is needed.
85
- pub fn graph_and_meta_and_repo (
125
+ pub fn graph_and_meta_mut_and_repo (
86
126
& self ,
127
+ _write : & mut WorktreeWritePermission ,
87
128
) -> Result < (
88
129
gix:: Repository ,
89
- VirtualBranchesTomlMetadata ,
130
+ VirtualBranchesTomlMetadataMut ,
90
131
but_graph:: Graph ,
91
132
) > {
92
133
let repo = self . gix_repo ( ) ?;
93
- self . graph_and_meta ( repo)
94
- }
95
-
96
- /// Return the `RefMetadata` implementation based on the `virtual_branches.toml` file.
97
- /// This can one day be changed to auto-migrate away from the toml and to the database.
98
- pub fn meta ( & self ) -> Result < VirtualBranchesTomlMetadata > {
99
- VirtualBranchesTomlMetadata :: from_path ( self . project . gb_dir ( ) . join ( "virtual_branches.toml" ) )
134
+ let meta = self . meta ( ) ?;
135
+ let graph = but_graph:: Graph :: from_head ( & repo, & meta, meta. graph_options ( ) ) ?;
136
+ Ok ( ( repo, VirtualBranchesTomlMetadataMut ( meta) , graph) )
100
137
}
101
138
102
139
/// Return a newly opened `gitoxide` repository, with all configuration available
@@ -133,6 +170,17 @@ impl CommandContext {
133
170
}
134
171
}
135
172
173
+ /// Keep these private
174
+ impl CommandContext {
175
+ /// Return the `RefMetadata` implementation based on the `virtual_branches.toml` file.
176
+ /// This can one day be changed to auto-migrate away from the toml and to the database.
177
+ fn meta ( & self ) -> Result < but_graph:: VirtualBranchesTomlMetadata > {
178
+ but_graph:: VirtualBranchesTomlMetadata :: from_path (
179
+ self . project . gb_dir ( ) . join ( "virtual_branches.toml" ) ,
180
+ )
181
+ }
182
+ }
183
+
136
184
/// Return a newly opened `gitoxide` repository, with all configuration available
137
185
/// to correctly figure out author and committer names (i.e. with most global configuration loaded),
138
186
/// *and* which will perform diffs quickly thanks to an adequate object cache.
0 commit comments