1
1
use std:: path:: Path ;
2
2
3
- use git_repository:: objs:: tree:: EntryMode ;
4
- use git_repository:: { discover, Commit , ObjectId , Repository } ;
3
+ use git:: objs:: tree:: EntryMode ;
4
+ use git:: sec:: trust:: DefaultForLevel ;
5
+ use git:: { Commit , ObjectId , Repository , ThreadSafeRepository } ;
6
+ use git_repository as git;
5
7
6
8
use crate :: DiffProvider ;
7
9
@@ -10,13 +12,50 @@ mod test;
10
12
11
13
pub struct Git ;
12
14
15
+ impl Git {
16
+ fn open_repo ( path : & Path , ceiling_dir : Option < & Path > ) -> Option < ThreadSafeRepository > {
17
+ // custom open options
18
+ let mut git_open_opts_map = git:: sec:: trust:: Mapping :: < git:: open:: Options > :: default ( ) ;
19
+
20
+ // don't use the global git configs (not needed)
21
+ let config = git:: permissions:: Config {
22
+ system : false ,
23
+ git : false ,
24
+ user : false ,
25
+ env : true ,
26
+ includes : true ,
27
+ } ;
28
+ // change options for config permissions without touching anything else
29
+ git_open_opts_map. reduced = git_open_opts_map. reduced . permissions ( git:: Permissions {
30
+ config,
31
+ ..git:: Permissions :: default_for_level ( git:: sec:: Trust :: Reduced )
32
+ } ) ;
33
+ git_open_opts_map. full = git_open_opts_map. full . permissions ( git:: Permissions {
34
+ config,
35
+ ..git:: Permissions :: default_for_level ( git:: sec:: Trust :: Full )
36
+ } ) ;
37
+
38
+ let mut open_options = git:: discover:: upwards:: Options :: default ( ) ;
39
+ if let Some ( ceiling_dir) = ceiling_dir {
40
+ open_options. ceiling_dirs = vec ! [ ceiling_dir. to_owned( ) ] ;
41
+ }
42
+
43
+ ThreadSafeRepository :: discover_with_environment_overrides_opts (
44
+ path,
45
+ open_options,
46
+ git_open_opts_map,
47
+ )
48
+ . ok ( )
49
+ }
50
+ }
51
+
13
52
impl DiffProvider for Git {
14
53
fn get_file_head ( & self , file : & Path ) -> Option < Vec < u8 > > {
15
54
debug_assert ! ( !file. exists( ) || file. is_file( ) ) ;
16
55
debug_assert ! ( file. is_absolute( ) ) ;
17
56
18
- // discover a repository, requires a directory so we call parent (should not fail but exit gracefully in that case)
19
- let repo = discover ( file. parent ( ) ?) . ok ( ) ? ;
57
+ // TODO cache repository lookup
58
+ let repo = Git :: open_repo ( file. parent ( ) ?, None ) ? . to_thread_local ( ) ;
20
59
let head = repo. head_commit ( ) . ok ( ) ?;
21
60
let file_oid = find_file_in_commit ( & repo, & head, file) ?;
22
61
@@ -40,6 +79,8 @@ fn find_file_in_commit(repo: &Repository, commit: &Commit, file: &Path) -> Optio
40
79
}
41
80
}
42
81
82
+ // TODO replace with lookup_path function in git-repository 0.24 once we can update to it
83
+
43
84
/// On unix paths are always raw bytes (that are usually utf-8) that can be passed to git directly.
44
85
/// This function is infallible
45
86
#[ cfg( any( unix, target_os = "wasi" ) ) ]
0 commit comments