Skip to content

Feature: count stashed changes in stash_count. #61

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.

## main branch

* Add `stash_count` variable to output containing the number of stashed changes.

### API breaking changes

* `summarize_opened_repository()` now takes a `mut` reference to a `Repository`.
This is necessary to count the number of stashed changes.

## Release 1.0.4 (2024-12-05)

### Security fixes
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ untracked_count=0
unstaged_count=0
staged_count=0
conflicted_count=0
stash_count=0
~/projects/git-status-vars ❯ cd /
/ ❯ git-status-vars
repo_state=NotFound
Expand Down
29 changes: 26 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ pub fn summarize_repository<W: std::io::Write>(
opened: Result<Repository, git2::Error>,
) {
let result = match opened {
Ok(repository) => summarize_opened_repository(out, &repository),
Ok(mut repository) => summarize_opened_repository(out, &mut repository),
Err(error)
if error.code() == ErrorCode::NotFound
&& error.class() == ErrorClass::Repository =>
Expand All @@ -194,7 +194,7 @@ pub fn summarize_repository<W: std::io::Write>(
///
/// summarize_opened_repository(
/// &ShellWriter::default(),
/// &Repository::open_from_env().unwrap(),
/// &mut Repository::open_from_env().unwrap(),
/// ).unwrap();
/// ```
///
Expand All @@ -210,21 +210,23 @@ pub fn summarize_repository<W: std::io::Write>(
/// target.
pub fn summarize_opened_repository<W: std::io::Write>(
out: &ShellWriter<W>,
repository: &Repository,
repository: &mut Repository,
) -> Result<(), git2::Error> {
let state = repository.state();
let workdir = display_option(repository.workdir().map(Path::display));
let empty = repository.is_empty()?;
let bare = repository.is_bare();
let head = &head_info(repository);
let changes = &count_changes(repository)?;
let stash = count_stash(repository)?;

out.write_var_debug("repo_state", state);
out.write_var("repo_workdir", workdir);
out.write_var("repo_empty", empty);
out.write_var("repo_bare", bare);
out.group("head").write_vars(head);
out.write_vars(changes);
out.write_var("stash_count", stash);

Ok(())
}
Expand Down Expand Up @@ -408,3 +410,24 @@ pub fn count_changes(

Ok(ChangeCounters::from(counters))
}

/// Count entries in stash.
///
/// Not sure why `repository` needs to be `mut` for this.
///
/// If there were somehow more than `usize::MAX` entries in stash, this would
/// return `usize::MAX`.
///
/// # Errors
///
/// This will return [`git2::Error`] if there was an error getting status
/// information from the repository.
pub fn count_stash(repository: &mut Repository) -> Result<usize, git2::Error> {
let mut count: usize = 0;
repository.stash_foreach(|_, _, _| {
count = count.saturating_add(1);
true
})?;

Ok(count)
}
2 changes: 1 addition & 1 deletion tests/helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ pub fn make_commit(root: &Path, repo: &str, n: u8) {
/// head_ref1_error=''
/// head_hash=@HASH@
/// . . .
/// conflicted_count=0
/// stash_count=0
/// "#,
/// );
/// ```
Expand Down
58 changes: 58 additions & 0 deletions tests/repos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ fn empty() {
unstaged_count=0
staged_count=0
conflicted_count=0
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -79,6 +80,7 @@ fn empty_untracked() {
unstaged_count=0
staged_count=0
conflicted_count=0
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -114,6 +116,7 @@ fn empty_added() {
unstaged_count=0
staged_count=1
conflicted_count=0
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -150,6 +153,7 @@ fn empty_untracked_added() {
unstaged_count=0
staged_count=1
conflicted_count=0
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -184,6 +188,7 @@ fn commit() {
unstaged_count=0
staged_count=0
conflicted_count=0
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -219,6 +224,7 @@ fn commit_delete() {
unstaged_count=1
staged_count=0
conflicted_count=0
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -254,6 +260,7 @@ fn commit_delete_staged() {
unstaged_count=0
staged_count=1
conflicted_count=0
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -289,6 +296,7 @@ fn commit_modified() {
unstaged_count=1
staged_count=0
conflicted_count=0
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -325,6 +333,7 @@ fn commit_modified_staged() {
unstaged_count=0
staged_count=1
conflicted_count=0
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -357,6 +366,7 @@ fn detached() {
unstaged_count=0
staged_count=0
conflicted_count=0
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -392,6 +402,7 @@ fn branch() {
unstaged_count=0
staged_count=0
conflicted_count=0
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -437,6 +448,7 @@ fn sym_ref() {
unstaged_count=0
staged_count=0
conflicted_count=0
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -471,6 +483,7 @@ fn tag() {
unstaged_count=0
staged_count=0
conflicted_count=0
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -511,6 +524,7 @@ fn cherry_pick() {
unstaged_count=0
staged_count=0
conflicted_count=2
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -553,6 +567,7 @@ fn cherry_pick_staged() {
unstaged_count=0
staged_count=1
conflicted_count=1
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -596,6 +611,7 @@ fn cherry_pick_unstaged() {
unstaged_count=1
staged_count=0
conflicted_count=1
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -636,6 +652,7 @@ fn conflict() {
unstaged_count=0
staged_count=0
conflicted_count=2
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -671,6 +688,7 @@ fn bare() {
unstaged_count=0
staged_count=0
conflicted_count=0
stash_count=0
"#,
);
}
Expand Down Expand Up @@ -707,6 +725,7 @@ fn ahead_1() {
unstaged_count=0
staged_count=0
conflicted_count=0
stash_count=0
",
);
}
Expand Down Expand Up @@ -745,6 +764,7 @@ fn ahead_1_behind_1() {
unstaged_count=0
staged_count=0
conflicted_count=0
stash_count=0
",
);
}
Expand Down Expand Up @@ -782,6 +802,44 @@ fn behind_1() {
unstaged_count=0
staged_count=0
conflicted_count=0
stash_count=0
",
);
}

#[test]
#[with_test_dir]
fn stashed_1() {
let root = get_test_dir!();
helpers::prepare_root(&root);

helpers::git_init(&root, "repo");
helpers::make_commit(&root, "repo", 1);
fs::write(root.join("repo").join("a"), "2a").unwrap();
helpers::git(&root, "repo", ["stash", "push", "a"]).unwrap();

helpers::assert_git_status_vars(
&root,
"repo",
r#"
repo_state=Clean
repo_workdir=@REPO@/
repo_empty=false
repo_bare=false
head_ref_length=1
head_ref1_name=refs/heads/main
head_ref1_short=main
head_ref1_kind=direct
head_ref1_error=''
head_hash=@HASH@
head_ahead=''
head_behind=''
head_upstream_error='Error { code: -3, klass: 7, message: "config value '\''branch.main.remote'\'' was not found" }'
untracked_count=0
unstaged_count=0
staged_count=0
conflicted_count=0
stash_count=1
"#,
);
}