Replace Git subprocesses with native APIs
This commit is contained in:
@@ -7,7 +7,6 @@ use sha2::{Digest, Sha256};
|
||||
use std::collections::{BTreeSet, HashMap, HashSet};
|
||||
use std::fs;
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::sync::RwLock;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use time::OffsetDateTime;
|
||||
@@ -1113,35 +1112,34 @@ fn git_revision_matches(root: &Path, revision: &str, current: &str) -> bool {
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Command::new("git")
|
||||
.args(["-C"])
|
||||
.arg(root)
|
||||
.args(["rev-parse", "--verify"])
|
||||
.arg(format!("{revision}^{{commit}}"))
|
||||
.output()
|
||||
git2::Repository::discover(root)
|
||||
.ok()
|
||||
.filter(|output| output.status.success())
|
||||
.is_some_and(|output| String::from_utf8_lossy(&output.stdout).trim() == current)
|
||||
.is_some_and(|repository| {
|
||||
repository
|
||||
.revparse_single(revision)
|
||||
.ok()
|
||||
.and_then(|object| object.peel_to_commit().ok())
|
||||
.is_some_and(|commit| commit.id().to_string() == current)
|
||||
})
|
||||
}
|
||||
|
||||
fn git_state(root: &Path) -> Option<(String, bool)> {
|
||||
let revision = Command::new("git")
|
||||
.args(["-C"])
|
||||
.arg(root)
|
||||
.args(["rev-parse", "HEAD"])
|
||||
.output()
|
||||
.ok()
|
||||
.filter(|output| output.status.success())
|
||||
.map(|output| String::from_utf8_lossy(&output.stdout).trim().to_owned())?;
|
||||
let status = Command::new("git")
|
||||
.args(["-C"])
|
||||
.arg(root)
|
||||
.args(["status", "--porcelain"])
|
||||
.output()
|
||||
.ok()?;
|
||||
let repository = git2::Repository::discover(root).ok()?;
|
||||
let revision = repository
|
||||
.head()
|
||||
.ok()?
|
||||
.peel_to_commit()
|
||||
.ok()?
|
||||
.id()
|
||||
.to_string();
|
||||
let mut options = git2::StatusOptions::new();
|
||||
options
|
||||
.include_untracked(true)
|
||||
.recurse_untracked_dirs(true)
|
||||
.include_ignored(false);
|
||||
Some((
|
||||
revision,
|
||||
status.status.success() && status.stdout.is_empty(),
|
||||
repository.statuses(Some(&mut options)).ok()?.is_empty(),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -1586,29 +1584,18 @@ mod tests {
|
||||
#[test]
|
||||
fn clean_full_and_short_git_revisions_become_stale_when_the_worktree_changes() {
|
||||
let fixture = Fixture::new();
|
||||
for arguments in [
|
||||
vec!["init"],
|
||||
vec!["add", "source.rs"],
|
||||
vec![
|
||||
"-c",
|
||||
"user.name=DS4Server",
|
||||
"-c",
|
||||
"user.email=ds4@example.invalid",
|
||||
"commit",
|
||||
"-m",
|
||||
"Initial",
|
||||
],
|
||||
] {
|
||||
assert!(
|
||||
Command::new("git")
|
||||
.arg("-C")
|
||||
.arg(&fixture.project)
|
||||
.args(arguments)
|
||||
.status()
|
||||
.unwrap()
|
||||
.success()
|
||||
);
|
||||
}
|
||||
let repository = git2::Repository::init(&fixture.project).unwrap();
|
||||
let mut index = repository.index().unwrap();
|
||||
index.add_path(Path::new("source.rs")).unwrap();
|
||||
let tree_id = index.write_tree().unwrap();
|
||||
index.write().unwrap();
|
||||
let tree = repository.find_tree(tree_id).unwrap();
|
||||
let signature = git2::Signature::now("DS4Server", "ds4@example.invalid").unwrap();
|
||||
repository
|
||||
.commit(Some("HEAD"), &signature, &signature, "Initial", &tree, &[])
|
||||
.unwrap();
|
||||
drop(tree);
|
||||
drop(repository);
|
||||
let revision = git_state(&fixture.project).unwrap().0;
|
||||
assert!(git_revision_matches(
|
||||
&fixture.project,
|
||||
|
||||
Reference in New Issue
Block a user