Skip to content

Add single case inspection to slider report - #2972

Merged
Sebastian Thiel (Byron) merged 2 commits into
GitoxideLabs:mainfrom
cruessler:inspect-single-slider-mismatch-case
Sep 8, 2026
Merged

Add single case inspection to slider report#2972
Sebastian Thiel (Byron) merged 2 commits into
GitoxideLabs:mainfrom
cruessler:inspect-single-slider-mismatch-case

Conversation

@cruessler

@cruessler Christoph Rüßler (cruessler) commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

This PR is a follow-up to #2931.

In 7192d9a and 169ae96, we added support for printing a detailed aggregate report of the differences between Git and gix for a corpus of diff slider cases. This PR adds a report for a single individual case, so we can dig deeper and inspect where Git and gix differ at the file level. The main work is done by pretty_assertions::StrComparison which is used to print a diff between the Git diff and the gix diff.

Example output that can be run if you followed gix-diff/tests/README.md for setting up the slider corpus and creating make_diff_for_sliders_repo.sh (in a terminal, there would also be colors):

❯ env GIX_DIFF_SLIDER_CASE='1333f781cf1f7ec617c7ebed21dbf067048c8140-d6bab352bb9271bde213e73626bd91cc9348be22.myers.baseline' cargo test -p gix-diff --test diff blob::slider::baseline -- --exact --nocapture
   Compiling gix-diff v0.67.1 (/home/christoph/worktrees/gitoxide/branch-8/gix-diff)
    Finished `test` profile [unoptimized + debuginfo] target(s) in 1.39s
     Running tests/diff/main.rs (/home/christoph/worktrees/gitoxide/branch-8/target/debug/deps/diff-4cb879f80474636c)

running 1 test
Selected baseline: gix-diff/tests/fixtures/generated-do-not-edit/make_diff_for_sliders_repo/sha1/696894535-unix/1333f781cf1f7ec617c7ebed21dbf067048c8140-d6bab352bb9271bde213e73626bd91cc9348be22.myers.baseline
Algorithm: Myers
Left: gix with slider heuristics
Right: Git with indent heuristic

Diff < left / right > :
 @@ -1,7 +1,6 @@
 +use crate::{bstr::ByteSlice, config};
  use std::{collections::BTreeSet, ffi::OsString};

 -use crate::{bstr::ByteSlice, config, config::tree::Core};
 -
  /// General Configuration
  impl crate::Repository {
      /// Return the compression level used when writing loose objects.
 @@ -25,26 +24,68 @@
          config::Snapshot { repo: self }
      }

 -    /// Return the editor program selected by Git's precedence rules.
 +    /// Return the editor selected by Git's precedence rules.
      ///
      /// `GIT_EDITOR` takes precedence over `core.editor`. If the terminal isn't dumb, `VISUAL` is considered next,
 -    /// followed by `EDITOR`. If none are set, `vi` is returned unless `TERM` is unset or `dumb`, in which case there
 -    /// is no usable editor.
 +    /// followed by `EDITOR`. If none are set, a bundled `vi` (or its `vim` implementation) is returned when available
 +    /// unless `TERM` is unset or `dumb`, in which case there is no usable editor.
 +    ///
 +    /// Use [`editor_command()`](Self::editor_command) to obtain a command prepared for execution.
      pub fn editor(&self) -> Option<OsString> {
 -        if let Some(editor) = self.config_snapshot().trusted_program(Core::EDITOR) {
 -            return Some(editor);
 -        }
 +        use crate::config::tree::{Core, Gitoxide};
<+
>
>-        let terminal_is_dumb = std::env::var_os("TERM").is_none_or(|terminal| terminal == "dumb");
>-        if !terminal_is_dumb {
>-            if let Some(editor) = std::env::var_os("VISUAL") {
>-                return Some(editor);
>-            }
>-        }
>-        if let Some(editor) = std::env::var_os("EDITOR") {
>-            return Some(editor);
 +        let config = self.config_snapshot();
 +        let terminal_is_dumb = config.string(Gitoxide::TERM).is_none_or(|terminal| terminal == "dumb");
 +        config
 +            .trusted_program(Core::EDITOR)
 +            .or_else(|| {
 +                (!terminal_is_dumb)
 +                    .then(|| config.trusted_program(Gitoxide::VISUAL))
 +                    .flatten()
 +            })
 +            .or_else(|| config.trusted_program(Gitoxide::EDITOR))
 +            .or_else(|| {
 +                (!terminal_is_dumb).then(|| {
 +                    gix_path::env::installation_program("vi")
 +                        // Current Git for Windows versions provide `vi` as a shell script that delegates to `vim.exe`.
 +                        // Select the directly executable implementation when no `vi.exe` is installed.
 +                        .or_else(|| {
 +                            cfg!(windows)
 +                                .then(|| gix_path::env::installation_program("vim"))
 +                                .flatten()
 +                        })
 +                        .unwrap_or_else(|| "vi".into())
 +                        .into_os_string()
 +                })
 +            })
 +            .filter(|editor| !editor.is_empty())
 +    }
<
<-        let terminal_is_dumb = std::env::var_os("TERM").is_none_or(|terminal| terminal == "dumb");
<-        if !terminal_is_dumb {
<-            if let Some(editor) = std::env::var_os("VISUAL") {
<-                return Some(editor);
<-            }
<-        }
<-        if let Some(editor) = std::env::var_os("EDITOR") {
<-            return Some(editor);
>+
 +    /// Return the prepared [`editor`](Self::editor) command.
 +    ///
 +    /// The returned command has repository context and inherited standard streams. Add the paths to edit as arguments
 +    /// before spawning it.
 +    #[cfg(feature = "command")]
 +    pub fn editor_command(&self) -> Result<Option<gix_command::Prepare>, config::command_context::Error> {
 +        use std::{path::Path, process::Stdio};
 +
 +        let Some(editor) = self.editor() else {
 +            return Ok(None);
 +        };
 +
 +        let mut command = gix_command::prepare(&editor);
 +        if editor.to_string_lossy().trim_ascii() == ":" {
 +            command = command.with_shell();
 +        } else if !Path::new(&editor).is_file() {
 +            command = command.command_may_be_shell_script();
          }
 -        (!terminal_is_dumb).then(|| "vi".into())
 +        Ok(Some(
 +            command
 +                .with_context(self.command_context()?)
 +                .stdin(Stdio::inherit())
 +                .stdout(Stdio::inherit())
 +                .stderr(Stdio::inherit()),
 +        ))
      }

      /// Resolve all Git configuration needed to sign a commit with [`gix_object::Commit::sign()`].
 @@ -157,7 +198,7 @@

      /// Return the context to be passed to any spawned program that is supposed to interact with the repository, like
      /// hooks or filters.
 -    #[cfg(feature = "attributes")]
 +    #[cfg(feature = "command")]
      pub fn command_context(&self) -> Result<gix_command::Context, config::command_context::Error> {
          use crate::config::{cache::util::ApplyLeniency, tree::gitoxide};



test blob::slider::baseline ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 92 filtered out; finished in 0.03s

@cruessler
Christoph Rüßler (cruessler) force-pushed the inspect-single-slider-mismatch-case branch from 372b570 to 7db16a3 Compare September 7, 2026 09:51
@cruessler
Christoph Rüßler (cruessler) marked this pull request as ready for review September 7, 2026 11:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7db16a3832

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "Codex (@codex) address that feedback".

Comment thread gix-diff/tests/diff/blob/slider.rs
In 7192d9a and
169ae96, we added support for printing
a detailed aggregate report of the differences between Git and `gix` for
a corpus of diff slider cases. This commit adds a report for a single
individual case, so we can dig deeper and inspect where Git and `gix`
differ at the file level. The main work is done by
`pretty_assertions::StrComparison` which is used to print a diff between
the Git diff and the `gix` diff.

Assisted-by: GPT 6.0
@cruessler
Christoph Rüßler (cruessler) force-pushed the inspect-single-slider-mismatch-case branch from 7db16a3 to 5596b16 Compare September 7, 2026 12:35
Assisted-by: GPT 6.0
@Byron

Copy link
Copy Markdown
Member

Thanks a lot!
Please feel free to add whatever helps.

@Byron
Sebastian Thiel (Byron) merged commit e731790 into GitoxideLabs:main Sep 8, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants