Skip to content

Commit e68f1a5

Browse files
lucatescariclaude
andcommitted
debug: stress-test the Windows status -f flake with discriminating diagnostics
Temporary. Adds evidence to the assertion that distinguishes the two candidate mechanisms — 'git add skipped the file' vs 'git add ran without the clean filter' — since both produce the same visible symptom of an index blob identical to HEAD. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TYMP8eH52L6rNdjbukfuyZ
1 parent 9c749ec commit e68f1a5

2 files changed

Lines changed: 62 additions & 1 deletion

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# TEMPORARY debugging workflow — delete once the flake is understood.
2+
# Reproduces test_status_fix_restages_only_warning_files on Windows by
3+
# running it repeatedly and stopping at the first failure, so the
4+
# diagnostics in the test's assertion message get captured.
5+
name: stress-windows
6+
7+
on:
8+
push:
9+
branches: [debug/windows-status-fix-flake]
10+
workflow_dispatch:
11+
12+
jobs:
13+
stress:
14+
runs-on: windows-latest
15+
steps:
16+
- uses: actions/checkout@v7
17+
18+
- uses: dtolnay/rust-toolchain@stable
19+
20+
- name: Build test binary once
21+
run: cargo test --test integration --no-run
22+
23+
- name: Run the flaky test until it fails (max 30 attempts)
24+
shell: bash
25+
run: |
26+
for i in $(seq 1 30); do
27+
echo "::group::attempt $i"
28+
if ! cargo test --test integration test_status_fix_restages_only_warning_files -- --exact --nocapture; then
29+
echo "::endgroup::"
30+
echo "FAILED ON ATTEMPT $i"
31+
exit 1
32+
fi
33+
echo "::endgroup::"
34+
done
35+
echo "30/30 attempts passed — no reproduction this run"

‎tests/integration.rs‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1096,12 +1096,38 @@ fn test_status_fix_restages_only_warning_files() {
10961096
gitveil status -f stderr:\n{}\n\
10971097
git diff --cached --name-only stdout: {:?}\n\
10981098
git diff --cached --name-only stderr: {:?}\n\
1099-
git status --porcelain:\n{}",
1099+
git status --porcelain:\n{}\n\
1100+
--- discriminating evidence ---\n\
1101+
index entry (git ls-files -s): {}\
1102+
HEAD blob (rev-parse HEAD:..): {}\
1103+
index blob first bytes: {:?}\n\
1104+
git check-attr filter bad.secret: {}\
1105+
filter.git-crypt.clean: {}\
1106+
filter.git-crypt.required: {}",
11001107
String::from_utf8_lossy(&out.stdout),
11011108
String::from_utf8_lossy(&out.stderr),
11021109
staged_out,
11031110
String::from_utf8_lossy(&staged.stderr),
11041111
String::from_utf8_lossy(&git(dir.path(), &["status", "--porcelain"]).stdout),
1112+
String::from_utf8_lossy(&git(dir.path(), &["ls-files", "-s", "bad.secret"]).stdout),
1113+
String::from_utf8_lossy(&git(dir.path(), &["rev-parse", "HEAD:bad.secret"]).stdout),
1114+
git(dir.path(), &["show", ":bad.secret"])
1115+
.stdout
1116+
.iter()
1117+
.take(10)
1118+
.map(|b| format!("{b:02x}"))
1119+
.collect::<String>(),
1120+
String::from_utf8_lossy(&git(dir.path(), &["check-attr", "filter", "bad.secret"]).stdout),
1121+
String::from_utf8_lossy(
1122+
&git(dir.path(), &["config", "--get", "filter.git-crypt.clean"]).stdout
1123+
),
1124+
String::from_utf8_lossy(
1125+
&git(
1126+
dir.path(),
1127+
&["config", "--get", "filter.git-crypt.required"]
1128+
)
1129+
.stdout
1130+
),
11051131
);
11061132
assert!(
11071133
!staged_out.contains("new.secret"),

0 commit comments

Comments
 (0)