Skip to content

Commit 424be21

Browse files
committed
implement suggested improvement to repository loading
1 parent 7496a23 commit 424be21

File tree

1 file changed

+45
-4
lines changed

1 file changed

+45
-4
lines changed

helix-vcs/src/git.rs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use std::path::Path;
22

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;
57

68
use crate::DiffProvider;
79

@@ -10,13 +12,50 @@ mod test;
1012

1113
pub struct Git;
1214

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+
1352
impl DiffProvider for Git {
1453
fn get_file_head(&self, file: &Path) -> Option<Vec<u8>> {
1554
debug_assert!(!file.exists() || file.is_file());
1655
debug_assert!(file.is_absolute());
1756

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();
2059
let head = repo.head_commit().ok()?;
2160
let file_oid = find_file_in_commit(&repo, &head, file)?;
2261

@@ -40,6 +79,8 @@ fn find_file_in_commit(repo: &Repository, commit: &Commit, file: &Path) -> Optio
4079
}
4180
}
4281

82+
// TODO replace with lookup_path function in git-repository 0.24 once we can update to it
83+
4384
/// On unix paths are always raw bytes (that are usually utf-8) that can be passed to git directly.
4485
/// This function is infallible
4586
#[cfg(any(unix, target_os = "wasi"))]

0 commit comments

Comments
 (0)