From 48de2d0216d2fc85e3c46e0f3b4350418c93d100 Mon Sep 17 00:00:00 2001 From: eatradish Date: Thu, 9 Jan 2025 17:49:58 +0800 Subject: [PATCH 1/2] feat: use `gix-status` to get file changed status --- Cargo.lock | 244 +++++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 8 +- src/main.rs | 156 ++++++++++++++++++++++++++++----- 3 files changed, 384 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a3169e4..75dc8f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -213,6 +213,20 @@ dependencies = [ "typenum", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "digest" version = "0.10.7" @@ -240,6 +254,15 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "env_filter" version = "0.1.3" @@ -318,6 +341,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -356,22 +385,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01237e8d3d78581f71642be8b0c2ae8c0b2b5c251c9c5d9ebbea3c1ea280dce8" dependencies = [ "gix-actor", + "gix-attributes", + "gix-command", "gix-commitgraph", "gix-config", "gix-date", "gix-diff", + "gix-dir", "gix-discover", "gix-features", + "gix-filter", "gix-fs", "gix-glob", "gix-hash", "gix-hashtable", + "gix-ignore", "gix-index", "gix-lock", "gix-object", "gix-odb", "gix-pack", "gix-path", + "gix-pathspec", "gix-protocol", "gix-ref", "gix-refspec", @@ -379,12 +414,15 @@ dependencies = [ "gix-revwalk", "gix-sec", "gix-shallow", + "gix-status", + "gix-submodule", "gix-tempfile", "gix-trace", "gix-traverse", "gix-url", "gix-utils", "gix-validate", + "gix-worktree", "once_cell", "smallvec", "thiserror", @@ -404,6 +442,23 @@ dependencies = [ "winnow", ] +[[package]] +name = "gix-attributes" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e26b3ac280ddb25bb6980d34f4a82ee326f78bf2c6d4ea45eef2d940048b8e" +dependencies = [ + "bstr", + "gix-glob", + "gix-path", + "gix-quote", + "gix-trace", + "kstring", + "smallvec", + "thiserror", + "unicode-bom", +] + [[package]] name = "gix-bitmap" version = "0.2.14" @@ -502,8 +557,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e9b43e95fe352da82a969f0c84ff860c2de3e724d93f6681fedbcd6c917f252" dependencies = [ "bstr", + "gix-attributes", + "gix-command", + "gix-filter", + "gix-fs", "gix-hash", + "gix-index", + "gix-object", + "gix-path", + "gix-pathspec", + "gix-tempfile", + "gix-trace", + "gix-traverse", + "gix-worktree", + "imara-diff", + "thiserror", +] + +[[package]] +name = "gix-dir" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01e6e2dc5b8917142d0ffe272209d1671e45b771e433f90186bc71c016792e87" +dependencies = [ + "bstr", + "gix-discover", + "gix-fs", + "gix-ignore", + "gix-index", "gix-object", + "gix-path", + "gix-pathspec", + "gix-trace", + "gix-utils", + "gix-worktree", "thiserror", ] @@ -543,6 +630,27 @@ dependencies = [ "walkdir", ] +[[package]] +name = "gix-filter" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90c21f0d61778f518bbb7c431b00247bf4534b2153c3e85bcf383876c55ca6c" +dependencies = [ + "bstr", + "encoding_rs", + "gix-attributes", + "gix-command", + "gix-hash", + "gix-object", + "gix-packetline-blocking", + "gix-path", + "gix-quote", + "gix-trace", + "gix-utils", + "smallvec", + "thiserror", +] + [[package]] name = "gix-fs" version = "0.15.0" @@ -588,10 +696,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5b5cb3c308b4144f2612ff64e32130e641279fcf1a84d8d40dad843b4f64904" dependencies = [ "gix-hash", - "hashbrown", + "hashbrown 0.14.5", "parking_lot", ] +[[package]] +name = "gix-ignore" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae358c3c96660b10abc7da63c06788dfded603e717edbd19e38c6477911b71c8" +dependencies = [ + "bstr", + "gix-glob", + "gix-path", + "gix-trace", + "unicode-bom", +] + [[package]] name = "gix-index" version = "0.40.0" @@ -611,7 +732,7 @@ dependencies = [ "gix-traverse", "gix-utils", "gix-validate", - "hashbrown", + "hashbrown 0.14.5", "itoa", "libc", "memmap2", @@ -704,6 +825,18 @@ dependencies = [ "thiserror", ] +[[package]] +name = "gix-packetline-blocking" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c44880f028ba46d6cf37a66d27a300310c6b51b8ed0e44918f93df061168e2f3" +dependencies = [ + "bstr", + "faster-hex", + "gix-trace", + "thiserror", +] + [[package]] name = "gix-path" version = "0.10.17" @@ -718,6 +851,21 @@ dependencies = [ "thiserror", ] +[[package]] +name = "gix-pathspec" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce061c50e5f8f7c830cacb3da3e999ae935e283ce8522249f0ce2256d110979d" +dependencies = [ + "bitflags", + "bstr", + "gix-attributes", + "gix-config-value", + "gix-glob", + "gix-path", + "thiserror", +] + [[package]] name = "gix-protocol" version = "0.50.1" @@ -840,12 +988,51 @@ dependencies = [ "thiserror", ] +[[package]] +name = "gix-status" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "072099c2415cfa5397df7d47eacbcb6016d2cd17e0d674c74965e6ad1b17289f" +dependencies = [ + "bstr", + "filetime", + "gix-diff", + "gix-dir", + "gix-features", + "gix-filter", + "gix-fs", + "gix-hash", + "gix-index", + "gix-object", + "gix-path", + "gix-pathspec", + "gix-worktree", + "portable-atomic", + "thiserror", +] + +[[package]] +name = "gix-submodule" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f51472f05a450cc61bc91ed2f62fb06e31e2bbb31c420bc4be8793f26c8b0c1" +dependencies = [ + "bstr", + "gix-config", + "gix-path", + "gix-pathspec", + "gix-refspec", + "gix-url", + "thiserror", +] + [[package]] name = "gix-tempfile" version = "17.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c750e8c008453a2dba67a2b0d928b7716e05da31173a3f5e351d5457ad4470aa" dependencies = [ + "dashmap", "gix-fs", "libc", "once_cell", @@ -912,6 +1099,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5351af2b172caf41a3728eb4455326d84e0d70fe26fc4de74ab0bd37df4191c5" dependencies = [ + "bstr", "fastrand", "unicode-normalization", ] @@ -926,6 +1114,25 @@ dependencies = [ "thiserror", ] +[[package]] +name = "gix-worktree" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54f1916f8d928268300c977d773dd70a8746b646873b77add0a34876a8c847e9" +dependencies = [ + "bstr", + "gix-attributes", + "gix-features", + "gix-fs", + "gix-glob", + "gix-hash", + "gix-ignore", + "gix-index", + "gix-object", + "gix-path", + "gix-validate", +] + [[package]] name = "hash32" version = "0.3.1" @@ -945,6 +1152,15 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" +dependencies = [ + "foldhash", +] + [[package]] name = "heapless" version = "0.8.0" @@ -1103,6 +1319,15 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "imara-diff" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17d34b7d42178945f775e84bc4c36dde7c1c6cdfea656d3354d009056f2bb3d2" +dependencies = [ + "hashbrown 0.15.3", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -1156,6 +1381,15 @@ dependencies = [ "jiff-tzdb", ] +[[package]] +name = "kstring" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1" +dependencies = [ + "static_assertions", +] + [[package]] name = "libc" version = "0.2.172" @@ -1454,6 +1688,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "syn" version = "2.0.101" diff --git a/Cargo.toml b/Cargo.toml index bfc5910..ee433a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,14 @@ edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -gix = {version = "0.72", default-features = false, features = ["max-performance-safe", "revision"] } +gix = {version = "0.72", default-features = false, features = ["max-performance-safe", "revision", "status"] } anyhow = "1.0" env_logger = "0.11" log = "0.4" rustix = { version = "1", features = ["process"] } + + +[profile.release] +lto = "thin" +opt-level = 3 +codegen-units = 1 diff --git a/src/main.rs b/src/main.rs index 716e264..3babfcb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,14 @@ use anyhow::{Context, Result, anyhow}; use gix::commit::describe::SelectRef::{self}; +use gix::progress; use gix::state::InProgress; +use gix::status::Submodule; use gix::{ Repository, ThreadSafeRepository, sec::{self, trust::DefaultForLevel}, }; use log::debug; +use std::borrow::Cow; use std::env; use std::path::Path; use std::process::Command; @@ -38,7 +41,11 @@ fn main() { let path = PathBuf::from("."); - let progress_status = match repo_progress(path) { + let Ok(repo) = get_repo(&path) else { + exit(1); + }; + + let progress_status = match repo_progress(&repo) { Ok(output) => output, Err(e) => { debug!("{e}"); @@ -46,18 +53,123 @@ fn main() { } }; - let status = print_and_get_status(&progress_status); + println!("{progress_status}"); + + let status = get_status(&repo); exit(status) } -fn print_and_get_status(progress_status: &str) -> i32 { - println!("{progress_status}"); - +fn get_status(repo: &Repo) -> i32 { if env::var("BASH_DISABLE_GIT_FILE_TRACKING").is_ok() { return 9; } + let repo = repo.repo.to_thread_local(); + + if repo.index_or_empty().is_ok_and(|repo| repo.is_sparse()) { + return get_status_sparse(); + } + + let Ok(status) = repo + .status(progress::Discard) + .inspect_err(|e| debug!("{e}")) + else { + return 8; + }; + + let status = status.index_worktree_submodules(Submodule::AsConfigured { check_dirty: true }); + let status = status.index_worktree_options_mut(|opts| { + // TODO: figure out good defaults for other platforms, maybe make it configurable. + opts.thread_limit = None; + + if let Some(opts) = opts.dirwalk_options.as_mut() { + opts.set_emit_untracked(gix::dir::walk::EmissionMode::Matching) + .set_emit_ignored(None) + .set_emit_pruned(false) + .set_emit_empty_directories(false); + } + }); + + let status = status.tree_index_track_renames(gix::status::tree_index::TrackRenames::Given({ + let mut config = gix::diff::new_rewrites(&repo.config_snapshot(), true) + .unwrap_or_default() + .0 + .unwrap_or_default(); + + config.limit = 100; + config + })); + + // This will start the status machinery, collecting status items in the background. + // Thus, we can do some work in this thread without blocking, before starting to count status items. + let Ok(status) = status.into_iter(None).inspect_err(|e| debug!("{e}")) else { + return 8; + }; + + for change in status.filter_map(Result::ok) { + use gix::status; + match &change { + status::Item::TreeIndex(_) => { + return 6; + } + status::Item::IndexWorktree(change) => { + use gix::status::index_worktree::Item; + use gix::status::plumbing::index_as_worktree::{Change, EntryStatus}; + match change { + Item::Modification { + status: EntryStatus::Conflict(_), + .. + } => { + return 6; + } + Item::Modification { + status: EntryStatus::Change(Change::Removed), + .. + } => { + return 6; + } + Item::Modification { + status: + EntryStatus::IntentToAdd + | EntryStatus::Change( + Change::Modification { .. } | Change::SubmoduleModification(_), + ), + .. + } => { + return 6; + } + Item::Modification { + status: EntryStatus::Change(Change::Type { .. }), + .. + } => { + return 6; + } + Item::DirectoryContents { + entry: + gix::dir::Entry { + status: gix::dir::entry::Status::Untracked, + .. + }, + .. + } => { + return 7; + } + Item::Rewrite { .. } => { + unreachable!( + "this kind of rename tracking isn't enabled by default and specific to gitoxide" + ) + } + _ => {} + } + } + } + } + + 5 +} + +fn get_status_sparse() -> i32 { let cmd = Command::new("git") .arg("status") .arg("--porcelain") @@ -100,22 +212,24 @@ fn print_and_get_status(progress_status: &str) -> i32 { status } -fn repo_progress(path: PathBuf) -> Result { - // custom open options - let repo = get_repo(&path)?; - +fn repo_progress(repo: &Repo) -> Result { let git_repo = repo.repo.to_thread_local(); - let display_name = repo.branch.or_else(|| get_tag(&git_repo)).or_else(|| { - Some(format!( - "(detached {})", - git_repo.head_id().ok()?.shorten_or_id() - )) - }); + let display_name = repo + .branch + .as_ref() + .map(Cow::Borrowed) + .or_else(|| get_tag(&git_repo).map(Cow::Owned)) + .or_else(|| { + Some(Cow::Owned(format!( + "(detached {})", + git_repo.head_id().ok()?.shorten_or_id() + ))) + }); let display_name = display_name.ok_or_else(|| anyhow!("Failed to get branch/hash"))?; - let s = if let Some(state) = repo.state { + let s = if let Some(state) = &repo.state { match state { InProgress::ApplyMailbox => format!("Mailbox progress {display_name}"), InProgress::ApplyMailboxRebase => { @@ -135,7 +249,7 @@ fn repo_progress(path: PathBuf) -> Result { InProgress::RevertSequence => format!("Revert Sequence progress {display_name}"), } } else { - display_name + display_name.to_string() }; Ok(s) @@ -145,10 +259,10 @@ fn get_repo(path: &Path) -> Result { let mut git_open_opts_map = sec::trust::Mapping::::default(); let config = gix::open::permissions::Config { - git_binary: false, - system: false, - git: false, - user: false, + git_binary: true, + system: true, + git: true, + user: true, env: true, includes: true, }; From d0ae6ebde86f824998885281dc995dacbd419ba1 Mon Sep 17 00:00:00 2001 From: eatradish Date: Tue, 14 Jan 2025 14:44:37 +0800 Subject: [PATCH 2/2] refactor: use `Status` enum to replace return code --- Cargo.lock | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 +- src/main.rs | 55 ++++++++++++++++++++++++++++----------------- 3 files changed, 100 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75dc8f6..3fcdbcf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,6 +117,7 @@ dependencies = [ "env_logger", "gix", "log", + "num_enum", "rustix", ] @@ -286,6 +287,12 @@ dependencies = [ "log", ] +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "errno" version = "0.3.11" @@ -1328,6 +1335,16 @@ dependencies = [ "hashbrown 0.15.3", ] +[[package]] +name = "indexmap" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +dependencies = [ + "equivalent", + "hashbrown 0.15.3", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -1479,6 +1496,27 @@ dependencies = [ "adler2", ] +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -1529,6 +1567,15 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.95" @@ -1774,6 +1821,23 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "toml_datetime" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" + +[[package]] +name = "toml_edit" +version = "0.22.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "typenum" version = "1.18.0" diff --git a/Cargo.toml b/Cargo.toml index ee433a8..96ad0f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ anyhow = "1.0" env_logger = "0.11" log = "0.4" rustix = { version = "1", features = ["process"] } - +num_enum = "0.7.3" [profile.release] lto = "thin" diff --git a/src/main.rs b/src/main.rs index 3babfcb..c3f914a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ use gix::{ sec::{self, trust::DefaultForLevel}, }; use log::debug; +use num_enum::IntoPrimitive; use std::borrow::Cow; use std::env; use std::path::Path; @@ -55,14 +56,24 @@ fn main() { println!("{progress_status}"); - let status = get_status(&repo); + let status = get_status(&repo).into(); exit(status) } -fn get_status(repo: &Repo) -> i32 { +#[derive(Debug, IntoPrimitive)] +#[repr(i32)] +enum Status { + Unchange = 5, + Change = 6, + Untracked = 7, + HasError = 8, + Disable = 9, +} + +fn get_status(repo: &Repo) -> Status { if env::var("BASH_DISABLE_GIT_FILE_TRACKING").is_ok() { - return 9; + return Status::Disable; } let repo = repo.repo.to_thread_local(); @@ -75,7 +86,7 @@ fn get_status(repo: &Repo) -> i32 { .status(progress::Discard) .inspect_err(|e| debug!("{e}")) else { - return 8; + return Status::HasError; }; let status = status.index_worktree_submodules(Submodule::AsConfigured { check_dirty: true }); @@ -104,14 +115,16 @@ fn get_status(repo: &Repo) -> i32 { // This will start the status machinery, collecting status items in the background. // Thus, we can do some work in this thread without blocking, before starting to count status items. let Ok(status) = status.into_iter(None).inspect_err(|e| debug!("{e}")) else { - return 8; + return Status::HasError; }; + let mut is_untracked = false; + for change in status.filter_map(Result::ok) { use gix::status; match &change { status::Item::TreeIndex(_) => { - return 6; + return Status::Change; } status::Item::IndexWorktree(change) => { use gix::status::index_worktree::Item; @@ -121,13 +134,13 @@ fn get_status(repo: &Repo) -> i32 { status: EntryStatus::Conflict(_), .. } => { - return 6; + return Status::Change; } Item::Modification { status: EntryStatus::Change(Change::Removed), .. } => { - return 6; + return Status::Change; } Item::Modification { status: @@ -137,13 +150,13 @@ fn get_status(repo: &Repo) -> i32 { ), .. } => { - return 6; + return Status::Change; } Item::Modification { status: EntryStatus::Change(Change::Type { .. }), .. } => { - return 6; + return Status::Change; } Item::DirectoryContents { entry: @@ -153,7 +166,7 @@ fn get_status(repo: &Repo) -> i32 { }, .. } => { - return 7; + is_untracked = true; } Item::Rewrite { .. } => { unreachable!( @@ -166,16 +179,20 @@ fn get_status(repo: &Repo) -> i32 { } } - 5 + if is_untracked { + return Status::Untracked; + } + + Status::Unchange } -fn get_status_sparse() -> i32 { +fn get_status_sparse() -> Status { let cmd = Command::new("git") .arg("status") .arg("--porcelain") .output(); - let mut status = 0; + let mut status = Status::Unchange; if let Ok(cmd) = cmd { if cmd.status.success() { @@ -187,25 +204,23 @@ fn get_status_sparse() -> i32 { .map(|x| x.0); match out_iter.next() { - None => { - status = 5; - } + None => {} Some(x) if MODIFY_STATUS.contains(x) || MODIFY_STATUS.contains(&x[..1]) || MODIFY_STATUS.contains(&x[1..2]) => { - status = 6; + status = Status::Change; } Some("??") => { - status = 7; + status = Status::Untracked; } _ => {} } debug!("git status --porcelain output: {out}"); } else { - status = 8; + status = Status::HasError; } }