From 2400158d6ce2ff28d428402f2d4030c04cd5f470 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 5 May 2025 05:42:12 +0000 Subject: [PATCH 1/2] Flip `:/` baseline skip from CI to local and extend For #1622, baseline comparisons in `find_youngest_matching_commit` where Git 2.47.* produces incorrect results were conditionally suppressed in the `regex_matches` test case in #1635. That was refined in #1719, and further refined in #1774. This builds on those, making substantial changes, in view of how: - We expect that CI have a very recent Git. The runners have been past 2.47.* for some time, and now have 2.49.*. Therefore it is no longer desirable to suppress the baseline comparison on CI. - #1774 only examined the `regex_matches` test case. That test runs when the `revparse-regex` feature, which is a default `gix` feature, is enabled. But when `revparse-regex` is not enabled, the `contained_string_matches` test case runs instead. This test suffers the same baseline comparison failures with the same Git versions, due to assertions analogous to those that were adjusted to let `regex_matches` proceed and pass. This can be verified by running PATH="$HOME/git-2.47.2/bin:$PATH" GIX_TEST_IGNORE_ARCHIVES=1 \ cargo nextest run -p gix \ revision::spec::from_bytes::regex::find_youngest_matching_commit \ --no-fail-fast --no-default-features \ --features max-performance-safe,comfort,basic where the `PATH` environment variable is set differently if the `git` command provided in a Git 2.47.* installation is elsewhere than `~/git-2.47.2/bin`. Output from such a run can be seen in: https://gist.github.com/EliahKagan/bd8525d048350fc80a7666d8819089db Therefore, if a conditional suppression of the baseline comparison is to be preserved in `regex_matches`, then an analogous suppression under the same conditions should be added to `contained_string_matches`. - Although most operating systems that package Git seem not to have 2.47.* as their latest available downstream version in any release, it seems a few do. In particular, Alpine Linux v3.21 has git 2.47.2-r0, as shown at: https://pkgs.alpinelinux.org/packages?name=git&branch=v3.21&repo=&arch=x86_64&origin=&flagged=&maintainer= Therefore, if it is desirable to work with as wide a range as possible of (currently supported) operating system releases as development environments, there may be a benefit to conditionally suppressing the baseline tests when Git 2.47.* is used *locally*. - However, doing this locally carries two downsides. First, the test code (even if refactored to decrease duplication) will be more complicated than if this is not done. Second, such an environment will still not be suitable for all development tasks, because generating the relevant test fixtures on it will contain incorrect baselines and therefore must not be committed. If they were to be committed by accident, then the problem would most likely be caught, because the tests would fail on CI, in other environments, and even in the same environment when run without `GIX_TEST_IGNORE_ARCHIVES` (in the absence of which the baseline comparisons are not suppressed). So this is not likely to have severely harmful effects. But it could be frustrating, because suppressing the baseline comparisons locally hides the usual evidence that the generated archives might not be suitable for committing. This commit keeps the baseline comparison in `regex_matches` but inverts its CI check so the suppression is only done locally rather than only on CI, adds the same (modified) suppression to the analogous `contained_string_matches` test case, and updates comments accordingly. We may or may not keep this approach. --- .../gix/revision/spec/from_bytes/regex.rs | 50 ++++++++++++++----- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/gix/tests/gix/revision/spec/from_bytes/regex.rs b/gix/tests/gix/revision/spec/from_bytes/regex.rs index 1ea5324d5cf..b71e09e0030 100644 --- a/gix/tests/gix/revision/spec/from_bytes/regex.rs +++ b/gix/tests/gix/revision/spec/from_bytes/regex.rs @@ -67,10 +67,22 @@ mod find_youngest_matching_commit { fn contained_string_matches() { let repo = repo("complex_graph").unwrap(); - assert_eq!( - parse_spec(":/message", &repo).unwrap(), - Spec::from_id(hex_to_id("ef80b4b77b167f326351c93284dc0eb00dd54ff4").attach(&repo)) - ); + // See the comment on `skip_some_baselines` in the `regex_matches` test function below. + let skip_some_baselines = !is_ci::cached() + && std::env::var_os("GIX_TEST_IGNORE_ARCHIVES").is_some() + && ((2, 47, 0)..(2, 48, 0)).contains(&gix_testtools::GIT_VERSION); + + if skip_some_baselines { + assert_eq!( + parse_spec_no_baseline(":/message", &repo).unwrap(), + Spec::from_id(hex_to_id("ef80b4b77b167f326351c93284dc0eb00dd54ff4").attach(&repo)) + ); + } else { + assert_eq!( + parse_spec(":/message", &repo).unwrap(), + Spec::from_id(hex_to_id("ef80b4b77b167f326351c93284dc0eb00dd54ff4").attach(&repo)) + ); + } assert_eq!( parse_spec("@^{/!-B}", &repo).unwrap(), @@ -78,10 +90,17 @@ mod find_youngest_matching_commit { "negations work as well" ); - assert_eq!( - parse_spec(":/!-message", &repo).unwrap(), - Spec::from_id(hex_to_id("55e825ebe8fd2ff78cad3826afb696b96b576a7e").attach(&repo)) - ); + if skip_some_baselines { + assert_eq!( + parse_spec_no_baseline(":/!-message", &repo).unwrap(), + Spec::from_id(hex_to_id("55e825ebe8fd2ff78cad3826afb696b96b576a7e").attach(&repo)) + ); + } else { + assert_eq!( + parse_spec(":/!-message", &repo).unwrap(), + Spec::from_id(hex_to_id("55e825ebe8fd2ff78cad3826afb696b96b576a7e").attach(&repo)) + ); + } assert_eq!( parse_spec_no_baseline(":/messa.e", &repo).unwrap_err().to_string(), @@ -95,16 +114,21 @@ mod find_youngest_matching_commit { fn regex_matches() { let repo = repo("complex_graph").unwrap(); - // The full Linux CI `test` job regenerates baselines instead of taking them from archives. - // Traversal order with `:/` is broken in Git 2.47.*, so some `parse_spec` assertions fail. - // The fix is in Git 2.48.* but is not backported. For now, we use `parse_spec_no_baseline` - // in affected test cases when they are run on CI with Git 2.47.*. For details, see: + // Traversal order with `:/` was broken in Git 2.47.*, so some `parse_spec` assertions + // fail. The fix is in Git 2.48.* but is not backported. This causes incorrect baselines to + // be computed when `GIX_TEST_IGNORE_ARCHIVES` is set. If that is not set, then archived + // baselines are used and there is no problem. On CI, we assume a sufficiently new version + // of Git. Otherwise, if `GIX_TEST_IGNORE_ARCHIVES` is set and Git 2.47.* is used, we skip + // the baseline check, to allow the rest of the test to proceed. This accommodates local + // development environments with a system-provided Git 2.47.*, though archives generated on + // such a system should not be committed, as they would still contain incorrect baselines. + // Please note that this workaround may be removed in the future. For more details, see: // // - https://lore.kernel.org/git/Z1LJSADiStlFicTL@pks.im/T/ // - https://lore.kernel.org/git/Z1LtS-8f8WZyobz3@pks.im/T/ // - https://github.com/git/git/blob/v2.48.0/Documentation/RelNotes/2.48.0.txt#L294-L296 // - https://github.com/GitoxideLabs/gitoxide/issues/1622 - let skip_some_baselines = is_ci::cached() + let skip_some_baselines = !is_ci::cached() && std::env::var_os("GIX_TEST_IGNORE_ARCHIVES").is_some() && ((2, 47, 0)..(2, 48, 0)).contains(&gix_testtools::GIT_VERSION); From b623bf1802474d92dbd0b63856c0b3b1f664e8d7 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Mon, 5 May 2025 06:49:12 +0000 Subject: [PATCH 2/2] Completely remove `:/` baseline skip This rolls back all changes made to work around the Git 2.47.* bug that underlies #1622, including the change made in the immediately preceding commit. This undoes the changes to `regex.rs` from #1635, #1719, #1774, and 2400158 (which is the immediately preceding commit). That file is now as it was in 3745212. The rationale is that the disadvantages of inverting the CI check and extending the suppresson, as described in the previous commit, really outweigh the advantages. This is mainly due to the risk of generating archives that should not be committed but seem based on test results like they could be committed. (The suppressions being removed here will most likely not be needed in the future, but if they are then this commit can be reverted, and the suppression will be done locally but on on CI, consistently across feature for which the relevant tests are run, and only when Git is found to be a version in the 2.47.* range.) Closes #1622 --- .../gix/revision/spec/from_bytes/regex.rs | 83 ++++--------------- 1 file changed, 16 insertions(+), 67 deletions(-) diff --git a/gix/tests/gix/revision/spec/from_bytes/regex.rs b/gix/tests/gix/revision/spec/from_bytes/regex.rs index b71e09e0030..fe7b4a5446d 100644 --- a/gix/tests/gix/revision/spec/from_bytes/regex.rs +++ b/gix/tests/gix/revision/spec/from_bytes/regex.rs @@ -67,22 +67,10 @@ mod find_youngest_matching_commit { fn contained_string_matches() { let repo = repo("complex_graph").unwrap(); - // See the comment on `skip_some_baselines` in the `regex_matches` test function below. - let skip_some_baselines = !is_ci::cached() - && std::env::var_os("GIX_TEST_IGNORE_ARCHIVES").is_some() - && ((2, 47, 0)..(2, 48, 0)).contains(&gix_testtools::GIT_VERSION); - - if skip_some_baselines { - assert_eq!( - parse_spec_no_baseline(":/message", &repo).unwrap(), - Spec::from_id(hex_to_id("ef80b4b77b167f326351c93284dc0eb00dd54ff4").attach(&repo)) - ); - } else { - assert_eq!( - parse_spec(":/message", &repo).unwrap(), - Spec::from_id(hex_to_id("ef80b4b77b167f326351c93284dc0eb00dd54ff4").attach(&repo)) - ); - } + assert_eq!( + parse_spec(":/message", &repo).unwrap(), + Spec::from_id(hex_to_id("ef80b4b77b167f326351c93284dc0eb00dd54ff4").attach(&repo)) + ); assert_eq!( parse_spec("@^{/!-B}", &repo).unwrap(), @@ -90,17 +78,10 @@ mod find_youngest_matching_commit { "negations work as well" ); - if skip_some_baselines { - assert_eq!( - parse_spec_no_baseline(":/!-message", &repo).unwrap(), - Spec::from_id(hex_to_id("55e825ebe8fd2ff78cad3826afb696b96b576a7e").attach(&repo)) - ); - } else { - assert_eq!( - parse_spec(":/!-message", &repo).unwrap(), - Spec::from_id(hex_to_id("55e825ebe8fd2ff78cad3826afb696b96b576a7e").attach(&repo)) - ); - } + assert_eq!( + parse_spec(":/!-message", &repo).unwrap(), + Spec::from_id(hex_to_id("55e825ebe8fd2ff78cad3826afb696b96b576a7e").attach(&repo)) + ); assert_eq!( parse_spec_no_baseline(":/messa.e", &repo).unwrap_err().to_string(), @@ -114,52 +95,20 @@ mod find_youngest_matching_commit { fn regex_matches() { let repo = repo("complex_graph").unwrap(); - // Traversal order with `:/` was broken in Git 2.47.*, so some `parse_spec` assertions - // fail. The fix is in Git 2.48.* but is not backported. This causes incorrect baselines to - // be computed when `GIX_TEST_IGNORE_ARCHIVES` is set. If that is not set, then archived - // baselines are used and there is no problem. On CI, we assume a sufficiently new version - // of Git. Otherwise, if `GIX_TEST_IGNORE_ARCHIVES` is set and Git 2.47.* is used, we skip - // the baseline check, to allow the rest of the test to proceed. This accommodates local - // development environments with a system-provided Git 2.47.*, though archives generated on - // such a system should not be committed, as they would still contain incorrect baselines. - // Please note that this workaround may be removed in the future. For more details, see: - // - // - https://lore.kernel.org/git/Z1LJSADiStlFicTL@pks.im/T/ - // - https://lore.kernel.org/git/Z1LtS-8f8WZyobz3@pks.im/T/ - // - https://github.com/git/git/blob/v2.48.0/Documentation/RelNotes/2.48.0.txt#L294-L296 - // - https://github.com/GitoxideLabs/gitoxide/issues/1622 - let skip_some_baselines = !is_ci::cached() - && std::env::var_os("GIX_TEST_IGNORE_ARCHIVES").is_some() - && ((2, 47, 0)..(2, 48, 0)).contains(&gix_testtools::GIT_VERSION); - - if skip_some_baselines { - assert_eq!( - parse_spec_no_baseline(":/mes.age", &repo).unwrap(), - Spec::from_id(hex_to_id("ef80b4b77b167f326351c93284dc0eb00dd54ff4").attach(&repo)) - ); - } else { - assert_eq!( - parse_spec(":/mes.age", &repo).unwrap(), - Spec::from_id(hex_to_id("ef80b4b77b167f326351c93284dc0eb00dd54ff4").attach(&repo)) - ); - } + assert_eq!( + parse_spec(":/mes.age", &repo).unwrap(), + Spec::from_id(hex_to_id("ef80b4b77b167f326351c93284dc0eb00dd54ff4").attach(&repo)) + ); assert_eq!( parse_spec(":/not there", &repo).unwrap_err().to_string(), "None of 10 commits reached from all references matched regex \"not there\"" ); - if skip_some_baselines { - assert_eq!( - parse_spec_no_baseline(":/!-message", &repo).unwrap(), - Spec::from_id(hex_to_id("55e825ebe8fd2ff78cad3826afb696b96b576a7e").attach(&repo)) - ); - } else { - assert_eq!( - parse_spec(":/!-message", &repo).unwrap(), - Spec::from_id(hex_to_id("55e825ebe8fd2ff78cad3826afb696b96b576a7e").attach(&repo)) - ); - } + assert_eq!( + parse_spec(":/!-message", &repo).unwrap(), + Spec::from_id(hex_to_id("55e825ebe8fd2ff78cad3826afb696b96b576a7e").attach(&repo)) + ); assert_eq!( parse_spec("@^{/!-B}", &repo).unwrap(),