summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Knaack <davidkna@users.noreply.github.com>2023-07-11 11:26:50 +0200
committerGitHub <noreply@github.com>2023-07-11 11:26:50 +0200
commit410f107c722a2f07737d4be01960f2621bf418dd (patch)
treee5d56de8da95d90559dcdad5f555837f4505b24f
parent9bbc7b469ddb7b948bcc44ab8813fcf4ba01631f (diff)
perf(git_status): query git stash count via gitoxide (#5238)
-rw-r--r--src/modules/git_status.rs82
1 files changed, 67 insertions, 15 deletions
diff --git a/src/modules/git_status.rs b/src/modules/git_status.rs
index 451c1e074..dad848b63 100644
--- a/src/modules/git_status.rs
+++ b/src/modules/git_status.rs
@@ -244,18 +244,28 @@ fn get_repo_status(context: &Context, config: &GitStatusConfig) -> Option<RepoSt
}
fn get_stashed_count(context: &Context) -> Option<usize> {
- let stash_output = context.exec_cmd(
- "git",
- &[
- OsStr::new("-C"),
- context.current_dir.as_os_str(),
- OsStr::new("--no-optional-locks"),
- OsStr::new("stash"),
- OsStr::new("list"),
- ],
- )?;
-
- Some(stash_output.stdout.trim().lines().count())
+ let repo = context.get_repo().ok()?.open();
+ let reference = match repo.try_find_reference("refs/stash") {
+ Ok(Some(reference)) => reference,
+ // No stash reference found
+ Ok(None) => return Some(0),
+ Err(err) => {
+ log::warn!("Error finding stash reference: {err}");
+ return None;
+ }
+ };
+
+ match reference.log_iter().all() {
+ Ok(Some(log)) => Some(log.count()),
+ Ok(None) => {
+ log::debug!("No reflog found for stash");
+ Some(0)
+ }
+ Err(err) => {
+ log::warn!("Error getting stash log: {err}");
+ None
+ }
+ }
}
#[derive(Default, Debug, Copy, Clone)]
@@ -744,9 +754,38 @@ mod tests {
.output()?;
let actual = ModuleRenderer::new("git_status")
+ .config(toml::toml! {
+ [git_status]
+ format = "$stashed"
+ })
+ .path(repo_dir.path())
+ .collect();
+ let expected = Some(String::from("$"));
+
+ assert_eq!(expected, actual);
+ repo_dir.close()
+ }
+
+ #[test]
+ fn shows_no_stashed_after_undo() -> io::Result<()> {
+ let repo_dir = fixture_repo(FixtureProvider::Git)?;
+
+ create_stash(repo_dir.path())?;
+ undo_stash(repo_dir.path())?;
+
+ create_command("git")?
+ .args(["reset", "--hard", "HEAD"])
+ .current_dir(repo_dir.path())
+ .output()?;
+
+ let actual = ModuleRenderer::new("git_status")
+ .config(toml::toml! {
+ [git_status]
+ format = "$stashed"
+ })
.path(repo_dir.path())
.collect();
- let expected = format_output("$");
+ let expected = None;
assert_eq!(expected, actual);
repo_dir.close()
@@ -757,6 +796,9 @@ mod tests {
let repo_dir = fixture_repo(FixtureProvider::Git)?;
create_stash(repo_dir.path())?;
+ undo_stash(repo_dir.path())?;
+ create_stash(repo_dir.path())?;
+ create_stash(repo_dir.path())?;
create_command("git")?
.args(["reset", "--hard", "HEAD"])
@@ -770,7 +812,7 @@ mod tests {
})
.path(repo_dir.path())
.collect();
- let expected = format_output("$1");
+ let expected = format_output("$2");
assert_eq!(expected, actual);
repo_dir.close()
@@ -1177,7 +1219,8 @@ mod tests {
}
fn create_stash(repo_dir: &Path) -> io::Result<()> {
- File::create(repo_dir.join("readme.md"))?.sync_all()?;
+ let (file, _path) = tempfile::NamedTempFile::new_in(repo_dir)?.keep()?;
+ file.sync_all()?;
create_command("git")?
.args(["stash", "--all"])
@@ -1187,6 +1230,15 @@ mod tests {
Ok(())
}
+ fn undo_stash(repo_dir: &Path) -> io::Result<()> {
+ create_command("git")?
+ .args(["stash", "pop"])
+ .current_dir(repo_dir)
+ .output()?;
+
+ Ok(())
+ }
+
fn create_untracked(repo_dir: &Path) -> io::Result<()> {
File::create(repo_dir.join("license"))?.sync_all()?;