fix: set git author before app commits
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use super::git_command;
|
||||
use super::{ensure_author_config, git_command};
|
||||
use std::path::Path;
|
||||
|
||||
struct CommitFailure {
|
||||
@@ -22,6 +22,8 @@ pub fn git_commit(vault_path: &str, message: &str) -> Result<String, String> {
|
||||
return Err(format!("git add failed: {}", stderr));
|
||||
}
|
||||
|
||||
ensure_author_config(vault)?;
|
||||
|
||||
match run_commit(vault, message, false) {
|
||||
Ok(stdout) => Ok(stdout),
|
||||
Err(failure) if is_commit_signing_failure(&failure.detail()) => {
|
||||
@@ -89,6 +91,30 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::git::tests::setup_git_repo;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
fn unset_local_author_config(vault: &Path) {
|
||||
for key in ["user.name", "user.email"] {
|
||||
let status = git_command()
|
||||
.args(["config", "--local", "--unset-all", key])
|
||||
.current_dir(vault)
|
||||
.status()
|
||||
.unwrap();
|
||||
assert!(status.success(), "failed to unset {key}");
|
||||
}
|
||||
}
|
||||
|
||||
fn local_config_value(vault: &Path, key: &str) -> Option<String> {
|
||||
let output = git_command()
|
||||
.args(["config", "--local", key])
|
||||
.current_dir(vault)
|
||||
.output()
|
||||
.unwrap();
|
||||
output
|
||||
.status
|
||||
.success()
|
||||
.then(|| String::from_utf8_lossy(&output.stdout).trim().to_string())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_git_commit() {
|
||||
@@ -110,6 +136,40 @@ mod tests {
|
||||
assert!(log_str.contains("Test commit"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_git_commit_sets_missing_local_author_identity() {
|
||||
let dir = setup_git_repo();
|
||||
let vault = dir.path();
|
||||
unset_local_author_config(vault);
|
||||
|
||||
fs::write(vault.join("identity-fallback.md"), "# Identity fallback\n").unwrap();
|
||||
|
||||
let result = git_commit(vault.to_str().unwrap(), "Commit without local identity");
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"commit should set local fallback identity: {result:?}"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
local_config_value(vault, "user.name").as_deref(),
|
||||
Some("Tolaria")
|
||||
);
|
||||
assert_eq!(
|
||||
local_config_value(vault, "user.email").as_deref(),
|
||||
Some("vault@tolaria.md")
|
||||
);
|
||||
|
||||
let author = git_command()
|
||||
.args(["log", "-1", "--format=%an <%ae>"])
|
||||
.current_dir(vault)
|
||||
.output()
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&author.stdout).trim(),
|
||||
"Tolaria <vault@tolaria.md>"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_commit_nothing_to_commit_returns_error() {
|
||||
let dir = setup_git_repo();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::path::Path;
|
||||
|
||||
use super::{git_command, run_git};
|
||||
use super::{ensure_author_config, git_command, run_git};
|
||||
|
||||
/// List files with merge conflicts (unmerged paths).
|
||||
///
|
||||
@@ -90,6 +90,8 @@ pub fn git_commit_conflict_resolution(vault_path: &str) -> Result<String, String
|
||||
));
|
||||
}
|
||||
|
||||
ensure_author_config(vault)?;
|
||||
|
||||
let mode = get_conflict_mode(vault_path);
|
||||
let output = match mode.as_str() {
|
||||
"rebase" => git_command()
|
||||
@@ -130,8 +132,32 @@ mod tests {
|
||||
use crate::git::tests::{setup_git_repo, setup_remote_pair};
|
||||
use crate::git::{git_commit, git_pull, git_push};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn unset_local_author_config(vault: &Path) {
|
||||
for key in ["user.name", "user.email"] {
|
||||
let status = git_command()
|
||||
.args(["config", "--local", "--unset-all", key])
|
||||
.current_dir(vault)
|
||||
.status()
|
||||
.unwrap();
|
||||
assert!(status.success(), "failed to unset {key}");
|
||||
}
|
||||
}
|
||||
|
||||
fn local_config_value(vault: &Path, key: &str) -> Option<String> {
|
||||
let output = git_command()
|
||||
.args(["config", "--local", key])
|
||||
.current_dir(vault)
|
||||
.output()
|
||||
.unwrap();
|
||||
output
|
||||
.status
|
||||
.success()
|
||||
.then(|| String::from_utf8_lossy(&output.stdout).trim().to_string())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_conflict_files_empty_when_clean() {
|
||||
let dir = setup_git_repo();
|
||||
@@ -282,6 +308,30 @@ mod tests {
|
||||
assert_eq!(get_conflict_mode(vp_b), "none");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_commit_conflict_resolution_sets_missing_local_author_identity() {
|
||||
let (_bare, _clone_a, clone_b) = setup_conflict_pair();
|
||||
let vault = clone_b.path();
|
||||
let vp_b = vault.to_str().unwrap();
|
||||
|
||||
git_resolve_conflict(vp_b, "conflict.md", "ours").unwrap();
|
||||
unset_local_author_config(vault);
|
||||
|
||||
let result = git_commit_conflict_resolution(vp_b);
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"conflict commit should set local fallback identity: {result:?}"
|
||||
);
|
||||
assert_eq!(
|
||||
local_config_value(vault, "user.name").as_deref(),
|
||||
Some("Tolaria")
|
||||
);
|
||||
assert_eq!(
|
||||
local_config_value(vault, "user.email").as_deref(),
|
||||
Some("vault@tolaria.md")
|
||||
);
|
||||
}
|
||||
|
||||
/// Set up a rebase conflict: clone_b has diverged from origin and
|
||||
/// `git pull --rebase` causes a conflict.
|
||||
fn setup_rebase_conflict_pair() -> (TempDir, TempDir, TempDir) {
|
||||
|
||||
Reference in New Issue
Block a user