Skip to content

Commit 5f1b3b9

Browse files
committed
Remove the Mutex wrapper on the Repository
1 parent d407c14 commit 5f1b3b9

File tree

5 files changed

+65
-106
lines changed

5 files changed

+65
-106
lines changed

src/application.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ pub(crate) struct Application<ModuleProvider>
2323
where ModuleProvider: module::ModuleProvider + Send + 'static
2424
{
2525
_config: Config,
26-
_repository: Repository,
2726
process: Process<ModuleProvider>,
2827
threads: Option<Vec<Box<dyn Threadable>>>,
2928
thread_statuses: ThreadStatuses,
@@ -44,7 +43,7 @@ where ModuleProvider: module::ModuleProvider + Send + 'static
4443

4544
let module_handler = ModuleHandler::new(
4645
EventHandler::new(KeyBindings::new(&config.key_bindings)),
47-
ModuleProvider::new(&config, repository.clone(), &todo_file),
46+
ModuleProvider::new(&config, repository, &todo_file),
4847
);
4948

5049
let display = Display::new(tui, &config.theme);
@@ -90,7 +89,6 @@ where ModuleProvider: module::ModuleProvider + Send + 'static
9089

9190
Ok(Self {
9291
_config: config,
93-
_repository: repository,
9492
process,
9593
threads: Some(threads),
9694
thread_statuses,

src/git/commit.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,7 @@ mod tests {
228228
#[test]
229229
fn try_from_success() {
230230
with_temp_repository(|repository| {
231-
let repo = repository.repository();
232-
let repo_lock = repo.lock();
233-
let reference = repo_lock.find_reference("refs/heads/main").unwrap();
231+
let reference = repository.repository().find_reference("refs/heads/main").unwrap();
234232
let commit = Commit::try_from(&reference).unwrap();
235233

236234
assert_eq!(commit.reference.unwrap().shortname(), "main");
@@ -241,11 +239,10 @@ mod tests {
241239
fn try_from_error() {
242240
with_temp_repository(|repository| {
243241
let repo = repository.repository();
244-
let repo_lock = repo.lock();
245-
let blob = repo_lock.blob(b"foo").unwrap();
246-
_ = repo_lock.reference("refs/blob", blob, false, "blob").unwrap();
242+
let blob = repo.blob(b"foo").unwrap();
243+
_ = repo.reference("refs/blob", blob, false, "blob").unwrap();
247244

248-
let reference = repo_lock.find_reference("refs/blob").unwrap();
245+
let reference = repo.find_reference("refs/blob").unwrap();
249246
assert_err_eq!(Commit::try_from(&reference), GitError::CommitLoad {
250247
cause: git2::Error::new(
251248
git2::ErrorCode::InvalidSpec,

src/git/commit_diff_loader.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
use std::{
2-
path::PathBuf,
3-
sync::{Arc, LazyLock},
4-
};
1+
use std::{path::PathBuf, sync::LazyLock};
52

63
use git2::{DiffFindOptions, DiffOptions, Oid, Repository};
7-
use parking_lot::{Mutex, MutexGuard};
4+
use parking_lot::Mutex;
85

96
use crate::git::{
107
Commit,
@@ -20,31 +17,29 @@ use crate::git::{
2017

2118
static UNKNOWN_PATH: LazyLock<PathBuf> = LazyLock::new(|| PathBuf::from("unknown"));
2219

23-
pub(crate) struct CommitDiffLoader<'options> {
20+
pub(crate) struct CommitDiffLoader<'options, 'repo> {
2421
config: &'options CommitDiffLoaderOptions,
25-
repo: Arc<Mutex<Repository>>,
22+
repository: &'repo Repository,
2623
}
2724

28-
impl<'options> CommitDiffLoader<'options> {
29-
pub(crate) const fn new(repo: Arc<Mutex<Repository>>, config: &'options CommitDiffLoaderOptions) -> Self {
30-
Self { config, repo }
25+
impl<'options, 'repo> CommitDiffLoader<'options, 'repo> {
26+
pub(crate) const fn new(repository: &'repo Repository, config: &'options CommitDiffLoaderOptions) -> Self {
27+
Self { config, repository }
3128
}
3229

3330
pub(crate) fn load_from_hash(&self, oid: Oid) -> Result<CommitDiff, git2::Error> {
34-
let repo = self.repo.lock();
35-
let commit = repo.find_commit(oid)?;
31+
let commit = self.repository.find_commit(oid)?;
3632
// only the first parent matter for the diff, the second parent, if it exists, was only used
3733
// for conflict resolution
3834
let parent = commit.parents().next();
3935

40-
self.load_diff(&repo, parent, &commit)
36+
self.load_diff(parent, &commit)
4137
}
4238

4339
#[expect(clippy::as_conversions, reason = "Mostly safe difference between APIs.")]
4440
#[expect(clippy::unwrap_in_result, reason = "Unwrap usage failure considered a bug.")]
4541
fn load_diff(
4642
&self,
47-
repo: &MutexGuard<'_, Repository>,
4843
parent: Option<git2::Commit<'_>>,
4944
commit: &git2::Commit<'_>,
5045
) -> Result<CommitDiff, git2::Error> {
@@ -75,10 +70,12 @@ impl<'options> CommitDiffLoader<'options> {
7570
.copies_from_unmodified(self.config.copies);
7671

7772
let mut diff = if let Some(p) = parent {
78-
repo.diff_tree_to_tree(Some(&p.tree()?), Some(&commit.tree()?), Some(&mut diff_options))?
73+
self.repository
74+
.diff_tree_to_tree(Some(&p.tree()?), Some(&commit.tree()?), Some(&mut diff_options))?
7975
}
8076
else {
81-
repo.diff_tree_to_tree(None, Some(&commit.tree()?), Some(&mut diff_options))?
77+
self.repository
78+
.diff_tree_to_tree(None, Some(&commit.tree()?), Some(&mut diff_options))?
8279
};
8380

8481
diff.find_similar(Some(&mut diff_find_options))?;

src/git/reference_kind.rs

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,7 @@ mod tests {
4242
fn from_git2_reference_branch() {
4343
with_temp_repository(|repository| {
4444
assert_eq!(
45-
ReferenceKind::from(
46-
&repository
47-
.repository()
48-
.lock()
49-
.find_reference("refs/heads/main")
50-
.unwrap()
51-
),
45+
ReferenceKind::from(&repository.repository().find_reference("refs/heads/main").unwrap()),
5246
ReferenceKind::Branch
5347
);
5448
});
@@ -57,13 +51,12 @@ mod tests {
5751
#[test]
5852
fn from_git2_reference_note() {
5953
with_temp_repository(|repository| {
60-
let git2_repository = repository.repository();
61-
let git2_lock = git2_repository.lock();
54+
let repo = repository.repository();
6255
let sig = git2::Signature::new("name", "[email protected]", &git2::Time::new(JAN_2021_EPOCH, 0)).unwrap();
63-
let head_id = git2_lock.refname_to_id("HEAD").unwrap();
64-
_ = git2_lock.note(&sig, &sig, None, head_id, "note", false).unwrap();
56+
let head_id = repo.refname_to_id("HEAD").unwrap();
57+
_ = repo.note(&sig, &sig, None, head_id, "note", false).unwrap();
6558
assert_eq!(
66-
ReferenceKind::from(&git2_lock.find_reference("refs/notes/commits").unwrap()),
59+
ReferenceKind::from(&repo.find_reference("refs/notes/commits").unwrap()),
6760
ReferenceKind::Note
6861
);
6962
});
@@ -72,12 +65,11 @@ mod tests {
7265
#[test]
7366
fn from_git2_reference_remote() {
7467
with_temp_repository(|repository| {
75-
let git2_repository = repository.repository();
76-
let git2_lock = git2_repository.lock();
77-
let mut remote = git2_lock.remote("origin", git2_lock.path().to_str().unwrap()).unwrap();
68+
let repo = repository.repository();
69+
let mut remote = repo.remote("origin", repo.path().to_str().unwrap()).unwrap();
7870
remote.fetch(&["main"], None, None).unwrap();
7971
assert_eq!(
80-
ReferenceKind::from(&git2_lock.find_reference("refs/remotes/origin/main").unwrap()),
72+
ReferenceKind::from(&repo.find_reference("refs/remotes/origin/main").unwrap()),
8173
ReferenceKind::Remote
8274
);
8375
});
@@ -86,13 +78,12 @@ mod tests {
8678
#[test]
8779
fn from_git2_reference_tag() {
8880
with_temp_repository(|repository| {
89-
let git2_repository = repository.repository();
90-
let git2_lock = git2_repository.lock();
81+
let repo = repository.repository();
9182
let sig = git2::Signature::new("name", "[email protected]", &git2::Time::new(JAN_2021_EPOCH, 0)).unwrap();
92-
let head_id = git2_lock.revparse_single("HEAD").unwrap();
93-
_ = git2_lock.tag("tag", &head_id, &sig, "note", false).unwrap();
83+
let head_id = repo.revparse_single("HEAD").unwrap();
84+
_ = repo.tag("tag", &head_id, &sig, "note", false).unwrap();
9485
assert_eq!(
95-
ReferenceKind::from(&git2_lock.find_reference("refs/tags/tag").unwrap()),
86+
ReferenceKind::from(&repo.find_reference("refs/tags/tag").unwrap()),
9687
ReferenceKind::Tag
9788
);
9889
});
@@ -101,12 +92,11 @@ mod tests {
10192
#[test]
10293
fn from_git2_reference_other() {
10394
with_temp_repository(|repository| {
104-
let git2_repository = repository.repository();
105-
let git2_lock = git2_repository.lock();
106-
let blob = git2_lock.blob(b"foo").unwrap();
107-
_ = git2_lock.reference("refs/blob", blob, false, "blob").unwrap();
95+
let repo = repository.repository();
96+
let blob = repo.blob(b"foo").unwrap();
97+
_ = repo.reference("refs/blob", blob, false, "blob").unwrap();
10898
assert_eq!(
109-
ReferenceKind::from(&git2_lock.find_reference("refs/blob").unwrap()),
99+
ReferenceKind::from(&repo.find_reference("refs/blob").unwrap()),
110100
ReferenceKind::Other
111101
);
112102
});

src/git/repository.rs

Lines changed: 31 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
1-
use std::{
2-
fmt::{Debug, Formatter},
3-
sync::Arc,
4-
};
5-
6-
use parking_lot::Mutex;
1+
use std::fmt::{Debug, Formatter};
72

83
use crate::git::{CommitDiff, CommitDiffLoader, CommitDiffLoaderOptions, Config, GitError, RepositoryLoadKind};
94

105
/// A light cloneable, simple wrapper around the `git2::Repository` struct
11-
#[derive(Clone)]
126
pub(crate) struct Repository {
13-
repository: Arc<Mutex<git2::Repository>>,
7+
repository: git2::Repository,
148
}
159

1610
impl Repository {
@@ -27,20 +21,15 @@ impl Repository {
2721
cause: e,
2822
}
2923
})?;
30-
Ok(Self {
31-
repository: Arc::new(Mutex::new(repository)),
32-
})
24+
Ok(Self { repository })
3325
}
3426

3527
/// Load the git configuration for the repository.
3628
///
3729
/// # Errors
3830
/// Will result in an error if the configuration is invalid.
3931
pub(crate) fn load_config(&self) -> Result<Config, GitError> {
40-
self.repository
41-
.lock()
42-
.config()
43-
.map_err(|e| GitError::ConfigLoad { cause: e })
32+
self.repository.config().map_err(|e| GitError::ConfigLoad { cause: e })
4433
}
4534

4635
/// Load a diff for a commit hash
@@ -54,12 +43,10 @@ impl Repository {
5443
) -> Result<CommitDiff, GitError> {
5544
let oid = self
5645
.repository
57-
.lock()
5846
.revparse_single(hash)
5947
.map_err(|e| GitError::CommitLoad { cause: e })?
6048
.id();
61-
let diff_loader_repository = Arc::clone(&self.repository);
62-
let loader = CommitDiffLoader::new(diff_loader_repository, config);
49+
let loader = CommitDiffLoader::new(&self.repository, config);
6350

6451
loader
6552
.load_from_hash(oid)
@@ -69,29 +56,23 @@ impl Repository {
6956

7057
impl From<git2::Repository> for Repository {
7158
fn from(repository: git2::Repository) -> Self {
72-
Self {
73-
repository: Arc::new(Mutex::new(repository)),
74-
}
59+
Self { repository }
7560
}
7661
}
7762

7863
impl Debug for Repository {
7964
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
8065
f.debug_struct("Repository")
81-
.field("[path]", &self.repository.lock().path())
66+
.field("[path]", &self.repository.path())
8267
.finish()
8368
}
8469
}
8570

8671
#[cfg(test)]
8772
mod tests {
88-
use std::{
89-
path::{Path, PathBuf},
90-
sync::Arc,
91-
};
73+
use std::path::{Path, PathBuf};
9274

9375
use git2::{Oid, Signature};
94-
use parking_lot::Mutex;
9576

9677
use crate::git::{Commit, GitError, Reference, Repository, RepositoryLoadKind};
9778

@@ -107,18 +88,16 @@ mod tests {
10788
cause: e,
10889
}
10990
})?;
110-
Ok(Self {
111-
repository: Arc::new(Mutex::new(repository)),
112-
})
91+
Ok(Self { repository })
11392
}
11493

11594
/// Find a reference by the reference name.
11695
///
11796
/// # Errors
11897
/// Will result in an error if the reference cannot be found.
11998
pub(crate) fn find_reference(&self, reference: &str) -> Result<Reference, GitError> {
120-
let repo = self.repository.lock();
121-
let git2_reference = repo
99+
let git2_reference = self
100+
.repository
122101
.find_reference(reference)
123102
.map_err(|e| GitError::ReferenceNotFound { cause: e })?;
124103
Ok(Reference::from(&git2_reference))
@@ -129,39 +108,35 @@ mod tests {
129108
/// # Errors
130109
/// Will result in an error if the reference cannot be found or is not a commit.
131110
pub(crate) fn find_commit(&self, reference: &str) -> Result<Commit, GitError> {
132-
let repo = self.repository.lock();
133-
let git2_reference = repo
111+
let reference = self
112+
.repository
134113
.find_reference(reference)
135114
.map_err(|e| GitError::ReferenceNotFound { cause: e })?;
136-
Commit::try_from(&git2_reference)
115+
Commit::try_from(&reference)
137116
}
138117

139118
pub(crate) fn repo_path(&self) -> PathBuf {
140-
self.repository.lock().path().to_path_buf()
119+
self.repository.path().to_path_buf()
141120
}
142121

143122
pub(crate) fn head_id(&self, head_name: &str) -> Result<Oid, git2::Error> {
144-
let repo = self.repository.lock();
145123
let ref_name = format!("refs/heads/{head_name}");
146-
let revision = repo.revparse_single(ref_name.as_str())?;
124+
let revision = self.repository.revparse_single(ref_name.as_str())?;
147125
Ok(revision.id())
148126
}
149127

150128
pub(crate) fn commit_id_from_ref(&self, reference: &str) -> Result<Oid, git2::Error> {
151-
let repo = self.repository.lock();
152-
let commit = repo.find_reference(reference)?.peel_to_commit()?;
129+
let commit = self.repository.find_reference(reference)?.peel_to_commit()?;
153130
Ok(commit.id())
154131
}
155132

156133
pub(crate) fn add_path_to_index(&self, path: &Path) -> Result<(), git2::Error> {
157-
let repo = self.repository.lock();
158-
let mut index = repo.index()?;
134+
let mut index = self.repository.index()?;
159135
index.add_path(path)
160136
}
161137

162138
pub(crate) fn remove_path_from_index(&self, path: &Path) -> Result<(), git2::Error> {
163-
let repo = self.repository.lock();
164-
let mut index = repo.index()?;
139+
let mut index = self.repository.index()?;
165140
index.remove_path(path)
166141
}
167142

@@ -172,15 +147,16 @@ mod tests {
172147
committer: &Signature<'_>,
173148
message: &str,
174149
) -> Result<(), git2::Error> {
175-
let repo = self.repository.lock();
176-
let tree = repo.find_tree(repo.index()?.write_tree()?)?;
177-
let head = repo.find_reference(reference)?.peel_to_commit()?;
178-
_ = repo.commit(Some("HEAD"), author, committer, message, &tree, &[&head])?;
150+
let tree = self.repository.find_tree(self.repository.index()?.write_tree()?)?;
151+
let head = self.repository.find_reference(reference)?.peel_to_commit()?;
152+
_ = self
153+
.repository
154+
.commit(Some("HEAD"), author, committer, message, &tree, &[&head])?;
179155
Ok(())
180156
}
181157

182-
pub(crate) fn repository(&self) -> Arc<Mutex<git2::Repository>> {
183-
Arc::clone(&self.repository)
158+
pub(crate) fn repository(&self) -> &git2::Repository {
159+
&self.repository
184160
}
185161
}
186162
}
@@ -267,10 +243,11 @@ mod unix_tests {
267243
fn load_commit_diff_with_non_commit() {
268244
with_temp_repository(|repository| {
269245
let blob_ref = {
270-
let git2_repository = repository.repository();
271-
let git2_lock = git2_repository.lock();
272-
let blob = git2_lock.blob(b"foo").unwrap();
273-
_ = git2_lock.reference("refs/blob", blob, false, "blob").unwrap();
246+
let blob = repository.repository().blob(b"foo").unwrap();
247+
_ = repository
248+
.repository()
249+
.reference("refs/blob", blob, false, "blob")
250+
.unwrap();
274251
blob.to_string()
275252
};
276253

0 commit comments

Comments
 (0)