Skip to content

Commit 5a0a702

Browse files
committed
Feature: count stashed changes in stash_count.
1 parent 60c7c99 commit 5a0a702

File tree

5 files changed

+93
-4
lines changed

5 files changed

+93
-4
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
44

55
## main branch
66

7+
* Add `stash_count` variable to output containing the number of stashed changes.
8+
9+
### API breaking changes
10+
11+
* `summarize_opened_repository()` now takes a `mut` reference to a `Repository`.
12+
This is necessary to count the number of stashed changes.
13+
714
## Release 1.0.4 (2024-12-05)
815

916
### Security fixes

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ untracked_count=0
116116
unstaged_count=0
117117
staged_count=0
118118
conflicted_count=0
119+
stash_count=0
119120
~/projects/git-status-vars ❯ cd /
120121
/ ❯ git-status-vars
121122
repo_state=NotFound

src/lib.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ pub fn summarize_repository<W: std::io::Write>(
167167
opened: Result<Repository, git2::Error>,
168168
) {
169169
let result = match opened {
170-
Ok(repository) => summarize_opened_repository(out, &repository),
170+
Ok(mut repository) => summarize_opened_repository(out, &mut repository),
171171
Err(error)
172172
if error.code() == ErrorCode::NotFound
173173
&& error.class() == ErrorClass::Repository =>
@@ -194,7 +194,7 @@ pub fn summarize_repository<W: std::io::Write>(
194194
///
195195
/// summarize_opened_repository(
196196
/// &ShellWriter::default(),
197-
/// &Repository::open_from_env().unwrap(),
197+
/// &mut Repository::open_from_env().unwrap(),
198198
/// ).unwrap();
199199
/// ```
200200
///
@@ -210,21 +210,23 @@ pub fn summarize_repository<W: std::io::Write>(
210210
/// target.
211211
pub fn summarize_opened_repository<W: std::io::Write>(
212212
out: &ShellWriter<W>,
213-
repository: &Repository,
213+
repository: &mut Repository,
214214
) -> Result<(), git2::Error> {
215215
let state = repository.state();
216216
let workdir = display_option(repository.workdir().map(Path::display));
217217
let empty = repository.is_empty()?;
218218
let bare = repository.is_bare();
219219
let head = &head_info(repository);
220220
let changes = &count_changes(repository)?;
221+
let stash = count_stash(repository)?;
221222

222223
out.write_var_debug("repo_state", state);
223224
out.write_var("repo_workdir", workdir);
224225
out.write_var("repo_empty", empty);
225226
out.write_var("repo_bare", bare);
226227
out.group("head").write_vars(head);
227228
out.write_vars(changes);
229+
out.write_var("stash_count", stash);
228230

229231
Ok(())
230232
}
@@ -408,3 +410,24 @@ pub fn count_changes(
408410

409411
Ok(ChangeCounters::from(counters))
410412
}
413+
414+
/// Count entries in stash.
415+
///
416+
/// Not sure why `repository` needs to be `mut` for this.
417+
///
418+
/// If there were somehow more than `usize::MAX` entries in stash, this would
419+
/// return `usize::MAX`.
420+
///
421+
/// # Errors
422+
///
423+
/// This will return [`git2::Error`] if there was an error getting status
424+
/// information from the repository.
425+
pub fn count_stash(repository: &mut Repository) -> Result<usize, git2::Error> {
426+
let mut count: usize = 0;
427+
repository.stash_foreach(|_, _, _| {
428+
count = count.saturating_add(1);
429+
true
430+
})?;
431+
432+
Ok(count)
433+
}

tests/helpers/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ pub fn make_commit(root: &Path, repo: &str, n: u8) {
127127
/// head_ref1_error=''
128128
/// head_hash=@HASH@
129129
/// . . .
130-
/// conflicted_count=0
130+
/// stash_count=0
131131
/// "#,
132132
/// );
133133
/// ```

tests/repos.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ fn empty() {
4545
unstaged_count=0
4646
staged_count=0
4747
conflicted_count=0
48+
stash_count=0
4849
"#,
4950
);
5051
}
@@ -79,6 +80,7 @@ fn empty_untracked() {
7980
unstaged_count=0
8081
staged_count=0
8182
conflicted_count=0
83+
stash_count=0
8284
"#,
8385
);
8486
}
@@ -114,6 +116,7 @@ fn empty_added() {
114116
unstaged_count=0
115117
staged_count=1
116118
conflicted_count=0
119+
stash_count=0
117120
"#,
118121
);
119122
}
@@ -150,6 +153,7 @@ fn empty_untracked_added() {
150153
unstaged_count=0
151154
staged_count=1
152155
conflicted_count=0
156+
stash_count=0
153157
"#,
154158
);
155159
}
@@ -184,6 +188,7 @@ fn commit() {
184188
unstaged_count=0
185189
staged_count=0
186190
conflicted_count=0
191+
stash_count=0
187192
"#,
188193
);
189194
}
@@ -219,6 +224,7 @@ fn commit_delete() {
219224
unstaged_count=1
220225
staged_count=0
221226
conflicted_count=0
227+
stash_count=0
222228
"#,
223229
);
224230
}
@@ -254,6 +260,7 @@ fn commit_delete_staged() {
254260
unstaged_count=0
255261
staged_count=1
256262
conflicted_count=0
263+
stash_count=0
257264
"#,
258265
);
259266
}
@@ -289,6 +296,7 @@ fn commit_modified() {
289296
unstaged_count=1
290297
staged_count=0
291298
conflicted_count=0
299+
stash_count=0
292300
"#,
293301
);
294302
}
@@ -325,6 +333,7 @@ fn commit_modified_staged() {
325333
unstaged_count=0
326334
staged_count=1
327335
conflicted_count=0
336+
stash_count=0
328337
"#,
329338
);
330339
}
@@ -357,6 +366,7 @@ fn detached() {
357366
unstaged_count=0
358367
staged_count=0
359368
conflicted_count=0
369+
stash_count=0
360370
"#,
361371
);
362372
}
@@ -392,6 +402,7 @@ fn branch() {
392402
unstaged_count=0
393403
staged_count=0
394404
conflicted_count=0
405+
stash_count=0
395406
"#,
396407
);
397408
}
@@ -437,6 +448,7 @@ fn sym_ref() {
437448
unstaged_count=0
438449
staged_count=0
439450
conflicted_count=0
451+
stash_count=0
440452
"#,
441453
);
442454
}
@@ -471,6 +483,7 @@ fn tag() {
471483
unstaged_count=0
472484
staged_count=0
473485
conflicted_count=0
486+
stash_count=0
474487
"#,
475488
);
476489
}
@@ -511,6 +524,7 @@ fn cherry_pick() {
511524
unstaged_count=0
512525
staged_count=0
513526
conflicted_count=2
527+
stash_count=0
514528
"#,
515529
);
516530
}
@@ -553,6 +567,7 @@ fn cherry_pick_staged() {
553567
unstaged_count=0
554568
staged_count=1
555569
conflicted_count=1
570+
stash_count=0
556571
"#,
557572
);
558573
}
@@ -596,6 +611,7 @@ fn cherry_pick_unstaged() {
596611
unstaged_count=1
597612
staged_count=0
598613
conflicted_count=1
614+
stash_count=0
599615
"#,
600616
);
601617
}
@@ -636,6 +652,7 @@ fn conflict() {
636652
unstaged_count=0
637653
staged_count=0
638654
conflicted_count=2
655+
stash_count=0
639656
"#,
640657
);
641658
}
@@ -671,6 +688,7 @@ fn bare() {
671688
unstaged_count=0
672689
staged_count=0
673690
conflicted_count=0
691+
stash_count=0
674692
"#,
675693
);
676694
}
@@ -707,6 +725,7 @@ fn ahead_1() {
707725
unstaged_count=0
708726
staged_count=0
709727
conflicted_count=0
728+
stash_count=0
710729
",
711730
);
712731
}
@@ -745,6 +764,7 @@ fn ahead_1_behind_1() {
745764
unstaged_count=0
746765
staged_count=0
747766
conflicted_count=0
767+
stash_count=0
748768
",
749769
);
750770
}
@@ -782,6 +802,44 @@ fn behind_1() {
782802
unstaged_count=0
783803
staged_count=0
784804
conflicted_count=0
805+
stash_count=0
785806
",
786807
);
787808
}
809+
810+
#[test]
811+
#[with_test_dir]
812+
fn stashed_1() {
813+
let root = get_test_dir!();
814+
helpers::prepare_root(&root);
815+
816+
helpers::git_init(&root, "repo");
817+
helpers::make_commit(&root, "repo", 1);
818+
fs::write(root.join("repo").join("a"), "2a").unwrap();
819+
helpers::git(&root, "repo", ["stash", "push", "a"]).unwrap();
820+
821+
helpers::assert_git_status_vars(
822+
&root,
823+
"repo",
824+
r#"
825+
repo_state=Clean
826+
repo_workdir=@REPO@/
827+
repo_empty=false
828+
repo_bare=false
829+
head_ref_length=1
830+
head_ref1_name=refs/heads/main
831+
head_ref1_short=main
832+
head_ref1_kind=direct
833+
head_ref1_error=''
834+
head_hash=@HASH@
835+
head_ahead=''
836+
head_behind=''
837+
head_upstream_error='Error { code: -3, klass: 7, message: "config value '\''branch.main.remote'\'' was not found" }'
838+
untracked_count=0
839+
unstaged_count=0
840+
staged_count=0
841+
conflicted_count=0
842+
stash_count=1
843+
"#,
844+
);
845+
}

0 commit comments

Comments
 (0)