Replace gix with configurable libgit2 diffs

This commit is contained in:
Georg Bauer
2026-07-28 18:25:24 +02:00
parent ed2226bc60
commit 31f6426eef
9 changed files with 410 additions and 1295 deletions

View File

@@ -1,5 +1,6 @@
use serde::{Deserialize, Serialize};
use serde_norway::{Mapping, Value};
use std::fmt;
use std::fs;
use std::path::Path;
@@ -19,6 +20,7 @@ pub struct Config {
pub endpoint: EndpointConfig,
pub generation: GenerationPreferences,
pub runtime: RuntimePreferences,
pub git: GitConfig,
pub interface: InterfaceConfig,
}
@@ -32,11 +34,89 @@ impl Default for Config {
endpoint: EndpointConfig::default(),
generation: GenerationPreferences::default(),
runtime: RuntimePreferences::default(),
git: GitConfig::default(),
interface: InterfaceConfig::default(),
}
}
}
pub const GIT_DIFF_ALGORITHMS: [GitDiffAlgorithm; 3] = [
GitDiffAlgorithm::Default,
GitDiffAlgorithm::Patience,
GitDiffAlgorithm::Minimal,
];
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum GitDiffAlgorithm {
#[default]
Default,
Patience,
Minimal,
}
impl fmt::Display for GitDiffAlgorithm {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(match self {
Self::Default => "Default (Myers)",
Self::Patience => "Patience",
Self::Minimal => "Minimal",
})
}
}
pub const GIT_DIFF_WHITESPACE_MODES: [GitDiffWhitespace; 4] = [
GitDiffWhitespace::ShowAll,
GitDiffWhitespace::IgnoreAll,
GitDiffWhitespace::IgnoreChanges,
GitDiffWhitespace::IgnoreEndOfLine,
];
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum GitDiffWhitespace {
#[default]
ShowAll,
IgnoreAll,
IgnoreChanges,
IgnoreEndOfLine,
}
impl fmt::Display for GitDiffWhitespace {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(match self {
Self::ShowAll => "Show all changes",
Self::IgnoreAll => "Ignore all whitespace",
Self::IgnoreChanges => "Ignore whitespace amount",
Self::IgnoreEndOfLine => "Ignore end-of-line whitespace",
})
}
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct GitConfig {
pub diff_algorithm: GitDiffAlgorithm,
pub context_lines: u32,
pub interhunk_lines: u32,
pub indent_heuristic: bool,
pub whitespace: GitDiffWhitespace,
pub ignore_blank_lines: bool,
}
impl Default for GitConfig {
fn default() -> Self {
Self {
diff_algorithm: GitDiffAlgorithm::Default,
context_lines: 3,
interhunk_lines: 0,
indent_heuristic: false,
whitespace: GitDiffWhitespace::ShowAll,
ignore_blank_lines: false,
}
}
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct DevBrainConfig {
@@ -201,6 +281,12 @@ mod tests {
},
..RuntimePreferences::default()
},
git: GitConfig {
diff_algorithm: GitDiffAlgorithm::Patience,
context_lines: 5,
whitespace: GitDiffWhitespace::IgnoreEndOfLine,
..GitConfig::default()
},
..Config::default()
};
config.save(&path).unwrap();
@@ -210,7 +296,8 @@ mod tests {
text,
"model: glm-5.2\na2ui_enabled: false\n\
generation:\n context_tokens: 65536\n reasoning_mode: none\n\
runtime:\n ssd:\n enabled: true\n cache: 64GB\n"
runtime:\n ssd:\n enabled: true\n cache: 64GB\n\
git:\n diff_algorithm: patience\n context_lines: 5\n whitespace: ignore-end-of-line\n"
);
assert_eq!(Config::load(&path).unwrap(), config);
fs::remove_dir_all(&directory).unwrap();