fix: commit & push now saves pending content and refreshes modified files

Root cause: Two problems caused "0 files changed":
1. loadModifiedFiles() was only called on mount, never refreshed after saves
2. Pending editor content wasn't flushed to disk before git commit

Fix:
- useEditorSave: add savePending() to flush unsaved content, onAfterSave
  callback to refresh git status after Cmd+S
- useCommitFlow: new hook managing save→commit→push flow with proper
  sequencing (save pending → refresh files → show dialog → commit)
- App.tsx: wire onAfterSave to loadModifiedFiles, use useCommitFlow
- git.rs: include stdout in error when stderr is empty (fixes "nothing
  to commit" message being swallowed)
- mock-tauri: track saved files so get_modified_files reflects edits

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
lucaronin
2026-02-23 20:34:12 +01:00
parent a5e465d0f9
commit e2bc3ef4c0
7 changed files with 280 additions and 41 deletions

View File

@@ -277,7 +277,10 @@ pub fn git_commit(vault_path: &str, message: &str) -> Result<String, String> {
if !commit.status.success() {
let stderr = String::from_utf8_lossy(&commit.stderr);
return Err(format!("git commit failed: {}", stderr));
let stdout = String::from_utf8_lossy(&commit.stdout);
// git writes "nothing to commit" to stdout, not stderr
let detail = if stderr.trim().is_empty() { stdout } else { stderr };
return Err(format!("git commit failed: {}", detail.trim()));
}
Ok(String::from_utf8_lossy(&commit.stdout).to_string())
@@ -543,4 +546,60 @@ mod tests {
let log_str = String::from_utf8_lossy(&log.stdout);
assert!(log_str.contains("Test commit"));
}
#[test]
fn test_commit_flow_modified_files_then_commit_clears() {
let dir = setup_git_repo();
let vault = dir.path();
let vp = vault.to_str().unwrap();
// Create and commit initial file
fs::write(vault.join("flow.md"), "# Original\n").unwrap();
git_commit(vp, "initial").unwrap();
// Modify the file on disk
fs::write(vault.join("flow.md"), "# Modified\n").unwrap();
// get_modified_files should detect the change
let modified = get_modified_files(vp).unwrap();
assert!(
modified.iter().any(|f| f.relative_path == "flow.md"),
"Modified file should be detected after write"
);
// Commit the change
let result = git_commit(vp, "update flow").unwrap();
assert!(
result.contains("1 file changed") || result.contains("flow.md"),
"Commit output should reference the changed file: {}",
result
);
// After commit, get_modified_files should return empty
let after = get_modified_files(vp).unwrap();
assert!(
after.is_empty(),
"No modified files should remain after commit, found: {:?}",
after
);
}
#[test]
fn test_commit_nothing_to_commit_returns_error() {
let dir = setup_git_repo();
let vault = dir.path();
let vp = vault.to_str().unwrap();
// Create and commit, so working tree is clean
fs::write(vault.join("clean.md"), "# Clean\n").unwrap();
git_commit(vp, "initial").unwrap();
// Committing again with no changes should fail
let result = git_commit(vp, "nothing here");
assert!(result.is_err(), "Commit should fail when nothing to commit");
assert!(
result.unwrap_err().contains("nothing to commit"),
"Error should mention 'nothing to commit'"
);
}
}