Windows runners exposed platform-specific snapshot metadata and filenames, and could not let external editors replace open temporary files. Use portable snapshots and paths, close editor tempfiles before invoking PowerShell-backed replacement editors, and mark shell fixtures executable. Keep exact-byte and index tests deterministic by disabling automatic line-ending conversion only in their temporary repositories, removing the override before configuration snapshots. Identify the current linked worktree by its canonical per-worktree Git directory so undo and redo update its index when worktree paths have different representations.
Unified · Split
| @@ -1979,8 +1979,13 @@ mod tests { · 1978 unmodified lines | ||
| 1979 | 1979 | } |
| 1980 | 1980 | |
| 1981 | 1981 | let fixture = gix_testtools::scripted_fixture_writable("split_commit.sh")?; |
| 1982 | − let repository = | |
| 1983 | − crate::test_repository::open_with(fixture.path(), ["core.editor=sed -i.bak -e 's/^what$/split/'"])?; | |
| 1982 | + let repository = crate::test_repository::open_with( | |
| 1983 | + fixture.path(), | |
| 1984 | + [format!( | |
| 1985 | + "core.editor={}", | |
| 1986 | + crate::test_repository::replacing_editor("what", "split") | |
| 1987 | + )], | |
| 1988 | + )?; | |
| 1984 | 1989 | let graph = crate::edit::loaded_view_graph(&repository)?; |
| 1985 | 1990 | let original = repository.head_id()?.detach(); |
| 1986 | 1991 | crate::enrich::set_note(&repository, original, Some(b"source marker"))?; |
| @@ -281,7 +281,13 @@ mod tests { · 280 unmodified lines | ||
| 281 | 281 | #[test] |
| 282 | 282 | fn editors_preserve_other_enrichments() -> gix_testtools::Result { |
| 283 | 283 | let fixture = gix_testtools::scripted_fixture_writable("history.sh")?; |
| 284 | − let repository = crate::test_repository::open_with(fixture.path(), ["core.editor=sed -i.bak -e 's/old/new/'"])?; | |
| 284 | + let repository = crate::test_repository::open_with( | |
| 285 | + fixture.path(), | |
| 286 | + [format!( | |
| 287 | + "core.editor={}", | |
| 288 | + crate::test_repository::replacing_editor("old", "new") | |
| 289 | + )], | |
| 290 | + )?; | |
| 285 | 291 | let topic = repository.rev_parse_single("topic")?.detach(); |
| 286 | 292 | crate::enrich::ensure_todo(&repository, topic, true)?; |
| 287 | 293 | crate::enrich::set_note(&repository, topic, Some(b"old\n"))?; |
| @@ -222,6 +222,7 @@ mod tests { · 221 unmodified lines | ||
| 222 | 222 | fn unchanged_selected_trees_require_allow_empty() -> gix_testtools::Result { |
| 223 | 223 | for worktree in [false, true] { |
| 224 | 224 | let fixture = gix_testtools::scripted_fixture_writable("create_commit.sh")?; |
| 225 | + crate::test_repository::disable_autocrlf(fixture.path())?; | |
| 225 | 226 | if worktree { |
| 226 | 227 | git(fixture.path(), &["checkout", "--", "tracked"])?; |
| 227 | 228 | } else { |
| @@ -263,6 +264,7 @@ mod tests { · 35 unmodified lines | ||
| 263 | 264 | #[test] |
| 264 | 265 | fn unchanged_worktree_untracked_requires_allow_empty() -> gix_testtools::Result { |
| 265 | 266 | let fixture = gix_testtools::scripted_fixture_writable("create_commit.sh")?; |
| 267 | + crate::test_repository::disable_autocrlf(fixture.path())?; | |
| 266 | 268 | git(fixture.path(), &["clean", "-fdq"])?; |
| 267 | 269 | git(fixture.path(), &["checkout", "--", "tracked"])?; |
| 268 | 270 | let parent = git(fixture.path(), &["rev-parse", "HEAD^{tree}"])?; |
| @@ -320,7 +320,10 @@ mod tests { · 319 unmodified lines | ||
| 320 | 320 | fn attached_head_needs_no_pin() -> gix_testtools::Result { |
| 321 | 321 | let fixture = gix_testtools::scripted_fixture_writable("rebase_edit.sh")?; |
| 322 | 322 | run( |
| 323 | − open(fixture.path(), "sed -i.bak -e 's/^tip$/rewritten tip/'")?, | |
| 323 | + open( | |
| 324 | + fixture.path(), | |
| 325 | + &crate::test_repository::replacing_editor("tip", "rewritten tip"), | |
| 326 | + )?, | |
| 324 | 327 | args("HEAD"), |
| 325 | 328 | )?; |
| 326 | 329 | |
| @@ -362,7 +365,10 @@ mod tests { · 35 unmodified lines | ||
| 362 | 365 | .to_string(); |
| 363 | 366 | drop(repository); |
| 364 | 367 | run( |
| 365 | − open(path, "sed -i.bak -e 's/^middle$/rewritten middle/'")?, | |
| 368 | + open( | |
| 369 | + path, | |
| 370 | + &crate::test_repository::replacing_editor("middle", "rewritten middle"), | |
| 371 | + )?, | |
| 366 | 372 | args(&change_id), |
| 367 | 373 | )?; |
| 368 | 374 | |
| @@ -412,7 +418,13 @@ mod tests { · 43 unmodified lines | ||
| 412 | 418 | git(path, &["update-ref", "refs/worktree/tix/pins/side", side])?; |
| 413 | 419 | let main = git(path, &["rev-parse", "main"])?; |
| 414 | 420 | |
| 415 | − run(open(path, "sed -i.bak -e 's/^side$/rewritten side/'")?, args("side"))?; | |
| 421 | + run( | |
| 422 | + open( | |
| 423 | + path, | |
| 424 | + &crate::test_repository::replacing_editor("side", "rewritten side"), | |
| 425 | + )?, | |
| 426 | + args("side"), | |
| 427 | + )?; | |
| 416 | 428 | |
| 417 | 429 | assert_eq!( |
| 418 | 430 | git(path, &["rev-parse", "main"])?, |
| @@ -775,6 +775,7 @@ mod tests { · 774 unmodified lines | ||
| 775 | 775 | #[test] |
| 776 | 776 | fn implicit_new_commit_ignores_untracked_files() -> gix_testtools::Result { |
| 777 | 777 | let fixture = gix_testtools::scripted_fixture_writable("create_commit.sh")?; |
| 778 | + crate::test_repository::disable_autocrlf(fixture.path())?; | |
| 778 | 779 | assert!( |
| 779 | 780 | Command::new("git") |
| 780 | 781 | .arg("-C") |
| @@ -186,6 +186,7 @@ mod tests { · 185 unmodified lines | ||
| 186 | 186 | #[test] |
| 187 | 187 | fn forgets_a_tip_atomically_and_preserves_untracked_files() -> gix_testtools::Result { |
| 188 | 188 | let fixture = gix_testtools::scripted_fixture_writable("forget_commit.sh")?; |
| 189 | + crate::test_repository::disable_autocrlf(fixture.path())?; | |
| 189 | 190 | let repository = open(fixture.path())?; |
| 190 | 191 | let top = repository.head_id()?.detach(); |
| 191 | 192 | let parent = repository |
| @@ -125,18 +125,20 @@ pub(crate) fn edit_document_without_terminal( · 124 unmodified lines | ||
| 125 | 125 | gix::tempfile::ContainingDirectory::Exists, |
| 126 | 126 | gix::tempfile::AutoRemove::Tempfile, |
| 127 | 127 | ) |
| 128 | − .context("could not create commit message file")? | |
| 129 | − .take() | |
| 130 | − .context("commit message file disappeared")?; | |
| 128 | + .context("could not create commit message file")?; | |
| 131 | 129 | tempfile |
| 132 | 130 | .write_all(document) |
| 133 | 131 | .context("could not write commit message file")?; |
| 134 | 132 | tempfile.flush().context("could not flush commit message file")?; |
| 133 | + let path = tempfile | |
| 134 | + .with_mut(|tempfile| tempfile.path().to_owned()) | |
| 135 | + .context("commit message file disappeared")?; | |
| 136 | + let _tempfile = tempfile.close().context("could not close commit message file")?; | |
| 135 | 137 | |
| 136 | 138 | if editor != ":" { |
| 137 | 139 | let status = Command::from( |
| 138 | 140 | gix::command::prepare(editor) |
| 139 | − .arg(tempfile.path()) | |
| 141 | + .arg(&path) | |
| 140 | 142 | .command_may_be_shell_script_allow_manual_argument_splitting(), |
| 141 | 143 | ) |
| 142 | 144 | .status() |
| @@ -145,7 +147,7 @@ pub(crate) fn edit_document_without_terminal( · 2 unmodified lines | ||
| 145 | 147 | anyhow::bail!("Git editor {} exited with {status}", editor.to_string_lossy()); |
| 146 | 148 | } |
| 147 | 149 | } |
| 148 | − let edited = std::fs::read(tempfile.path()).context("could not read edited commit message")?; | |
| 150 | + let edited = std::fs::read(path).context("could not read edited commit message")?; | |
| 149 | 151 | Ok((edited != document).then_some(edited)) |
| 150 | 152 | } |
| 151 | 153 | |
| @@ -3299,7 +3299,7 @@ mod tests { · 3298 unmodified lines | ||
| 3299 | 3299 | } |
| 3300 | 3300 | insta::assert_snapshot!( |
| 3301 | 3301 | "reworded-middle-stack", |
| 3302 | − gix_testtools::repository::snapshot(fixture.path())?.to_string() | |
| 3302 | + gix_testtools::repository::snapshot_portable(fixture.path())?.to_string() | |
| 3303 | 3303 | ); |
| 3304 | 3304 | Ok(()) |
| 3305 | 3305 | } |
| @@ -619,6 +619,7 @@ mod tests { · 618 unmodified lines | ||
| 619 | 619 | fn a_changed_review_and_its_successors_are_spliced_before_target_successors() -> gix_testtools::Result { |
| 620 | 620 | let fixture = gix_testtools::tempfile::tempdir()?; |
| 621 | 621 | run(fixture.path(), &["init", "-q", "-b", "main"])?; |
| 622 | + crate::test_repository::disable_autocrlf(fixture.path())?; | |
| 622 | 623 | run(fixture.path(), &["config", "user.name", "reviewer"])?; |
| 623 | 624 | run(fixture.path(), &["config", "user.email", "reviewer@example.com"])?; |
| 624 | 625 | run( |
| @@ -752,9 +753,10 @@ mod tests { · 127 unmodified lines | ||
| 752 | 753 | !super::super::rebase::is_pending(&repo.find_commit(successor)?.decode()?.into_owned()?), |
| 753 | 754 | "the checked-out review return path is fully replayed" |
| 754 | 755 | ); |
| 756 | + crate::test_repository::clear_autocrlf(fixture.path())?; | |
| 755 | 757 | insta::assert_snapshot!( |
| 756 | 758 | "changed-review-with-successors", |
| 757 | − gix_testtools::repository::snapshot(fixture.path())?.to_string() | |
| 759 | + gix_testtools::repository::snapshot_portable(fixture.path())?.to_string() | |
| 758 | 760 | ); |
| 759 | 761 | Ok(()) |
| 760 | 762 | } |
| @@ -1,17 +1,17 @@ | ||
| 1 | 1 | --- |
| 2 | 2 | source: gix-tix/src/edit/rebase.rs |
| 3 | −expression: "gix_testtools::repository::snapshot(fixture.path())?.to_string()" | |
| 3 | +expression: "gix_testtools::repository::snapshot_portable(fixture.path())?.to_string()" | |
| 4 | 4 | --- |
| 5 | 5 | HEAD refs/heads/main -> C2 |
| 6 | 6 | |
| 7 | 7 | [config] |
| 8 | 8 | [core] |
| 9 | − bare = false | |
| 9 | + bare = false | |
| 10 | 10 | [user] |
| 11 | − name = author | |
| 12 | − email = author@example.com | |
| 11 | + name = author | |
| 12 | + email = author@example.com | |
| 13 | 13 | [commit] |
| 14 | − gpgSign = false | |
| 14 | + gpgSign = false | |
| 15 | 15 | |
| 16 | 16 | [refs] |
| 17 | 17 | refs/heads/main = C2 |
| @@ -51,17 +51,6 @@ tree = T2 · 33 unmodified lines | ||
| 51 | 51 | 100644 B2 stage=0 "tip" |
| 52 | 52 | |
| 53 | 53 | [worktree] |
| 54 | −100644 file "base" = "base\n" | |
| 55 | −100644 file "middle" = "middle\n" | |
| 56 | −100644 file "tip" = "tip\n" | |
| 57 | − | |
| 58 | −[objects] | |
| 59 | −C1 = 1583a183c3a57fce524e7acdd5a1c007d5f0f9a9 | |
| 60 | −C0 = 5295d5ce934d18b6a1f48c3b7d836d53b55304e5 | |
| 61 | −T0 = 559dc660acc84805fedbcb75588371240372c173 | |
| 62 | −T2 = 569961a34e2a909d8c7a2940ed4ad365504e64ed | |
| 63 | −T1 = 8552142164d268c95f60dabb74465a2f4ffb51b7 | |
| 64 | −C2 = 91e50045e3c98994aebc74a28953fc04ce49cacf | |
| 65 | −B2 = b218ebde2fc5b78f14aa04eeb42a74b17e2e367d | |
| 66 | −B0 = df967b96a579e45a18b8251732d16804b2e56a55 | |
| 67 | −B1 = ea1a2ae6cdab2b53dee8943ca555c4312a0b798a | |
| 54 | +- file "base" = "base\n" | |
| 55 | +- file "middle" = "middle\n" | |
| 56 | +- file "tip" = "tip\n" | |
| @@ -1,18 +1,18 @@ | ||
| 1 | 1 | --- |
| 2 | 2 | source: gix-tix/src/edit/review.rs |
| 3 | −expression: "gix_testtools::repository::snapshot(fixture.path())?.to_string()" | |
| 3 | +expression: "gix_testtools::repository::snapshot_portable(fixture.path())?.to_string()" | |
| 4 | 4 | --- |
| 5 | 5 | HEAD refs/heads/main -> C4 |
| 6 | 6 | |
| 7 | 7 | [config] |
| 8 | 8 | [core] |
| 9 | − bare = false | |
| 9 | + bare = false | |
| 10 | 10 | [user] |
| 11 | − name = reviewer | |
| 12 | − email = reviewer@example.com | |
| 11 | + name = reviewer | |
| 12 | + email = reviewer@example.com | |
| 13 | 13 | [gitoxide "commit"] |
| 14 | − authorDate = 2001-01-01T00:00:00 +0000 | |
| 15 | − committerDate = 2001-01-01T00:00:00 +0000 | |
| 14 | + authorDate = 2001-01-01T00:00:00 +0000 | |
| 15 | + committerDate = 2001-01-01T00:00:00 +0000 | |
| 16 | 16 | |
| 17 | 17 | [refs] |
| 18 | 18 | refs/heads/main = C4 |
| @@ -68,20 +68,6 @@ tree = T3 · 49 unmodified lines | ||
| 68 | 68 | 100644 B2 stage=0 "successor" |
| 69 | 69 | |
| 70 | 70 | [worktree] |
| 71 | −100644 file "file" = "B\n" | |
| 72 | −100644 file "reviewed" = "new review change\n" | |
| 73 | −100644 file "successor" = "A\n" | |
| 74 | − | |
| 75 | −[objects] | |
| 76 | −T3 = 1104ca61473daa5765f3a6eb0a5fae3e5012a067 | |
| 77 | −C2 = 1a13dc5cbbc857de093c9a007e6b104a1a9ffbdb | |
| 78 | −B0 = 223b7836fb19fdf64ba2d3cd6173c6a283141f78 | |
| 79 | −C1 = 2cb49e443aa675eab8add679938ca6cd303ae353 | |
| 80 | −T1 = 2e457f998ff6a6163f89e091bc4d6b92c8ed2a28 | |
| 81 | −T2 = 6d5f482d15035cdd7733b1b551d1fead28d22592 | |
| 82 | −B1 = 8ab2a145f1f16e50d78eaced3311ac16027db494 | |
| 83 | −T0 = 93664bfc7cc096fcc0d1ac962596031e10f26906 | |
| 84 | −C0 = c38a9f7427b84ed8ba5e187ec385489d82d71695 | |
| 85 | −C3 = e028a8e769407c249d118ddc499f0c064685ba16 | |
| 86 | −B2 = f70f10e4db19068f79bc43844b49f3eece45c4e8 | |
| 87 | −C4 = fb6e9845e1d808bd1257db0bb3462a1747d1d2d9 | |
| 71 | +- file "file" = "B\n" | |
| 72 | +- file "reviewed" = "new review change\n" | |
| 73 | +- file "successor" = "A\n" | |
| @@ -1,19 +1,19 @@ | ||
| 1 | 1 | --- |
| 2 | 2 | source: gix-tix/src/edit/time_travel.rs |
| 3 | −expression: "gix_testtools::repository::snapshot(fixture.path())?\n.to_string().replace(\"\\n \\n\", \"\\n\\n\")" | |
| 3 | +expression: "gix_testtools::repository::snapshot_portable(fixture.path())?\n.to_string().replace(\"\\n \\n\", \"\\n\\n\")" | |
| 4 | 4 | --- |
| 5 | 5 | HEAD detached C1 |
| 6 | 6 | |
| 7 | 7 | [config] |
| 8 | 8 | [core] |
| 9 | − bare = false | |
| 9 | + bare = false | |
| 10 | 10 | [user] |
| 11 | − name = author | |
| 12 | − email = author@example.com | |
| 11 | + name = author | |
| 12 | + email = author@example.com | |
| 13 | 13 | [commit] |
| 14 | − gpgSign = false | |
| 14 | + gpgSign = false | |
| 15 | 15 | [gitoxide "commit"] |
| 16 | − committerDate = 2001-01-01T00:00:00 +0000 | |
| 16 | + committerDate = 2001-01-01T00:00:00 +0000 | |
| 17 | 17 | |
| 18 | 18 | [refs] |
| 19 | 19 | refs/heads/main = C2 |
| @@ -54,14 +54,4 @@ tree = conflicted · 34 unmodified lines | ||
| 54 | 54 | 100644 B2 stage=3 "file" |
| 55 | 55 | |
| 56 | 56 | [worktree] |
| 57 | −100644 file "file" = "<<<<<<< rebased parent\nbase\n=======\ntip\n>>>>>>> commit\n" | |
| 58 | − | |
| 59 | −[objects] | |
| 60 | −C2 = 26d78d03083cfe539c4a94c28bd30d9a548a8394 | |
| 61 | −C1 = 69348f5557de103f6771f9a121ff67f5272ceab5 | |
| 62 | −T1 = 6d5f482d15035cdd7733b1b551d1fead28d22592 | |
| 63 | −T0 = 6f2762b571ef9a93001cc607058818aa5d0d055c | |
| 64 | −B2 = b218ebde2fc5b78f14aa04eeb42a74b17e2e367d | |
| 65 | −C0 = c0b811a58f27425263a4276fe881de38736a9446 | |
| 66 | −B1 = df967b96a579e45a18b8251732d16804b2e56a55 | |
| 67 | −B0 = ea1a2ae6cdab2b53dee8943ca555c4312a0b798a | |
| 57 | +- file "file" = "<<<<<<< rebased parent\nbase\n=======\ntip\n>>>>>>> commit\n" | |
| @@ -382,6 +382,7 @@ mod tests { · 381 unmodified lines | ||
| 382 | 382 | fn manual_stashes_preserve_git_stashes_and_restore_index_and_worktree_state() -> gix_testtools::Result { |
| 383 | 383 | let fixture = gix_testtools::tempfile::tempdir()?; |
| 384 | 384 | git(fixture.path(), &["init", "-q", "-b", "main"])?; |
| 385 | + crate::test_repository::disable_autocrlf(fixture.path())?; | |
| 385 | 386 | git(fixture.path(), &["config", "user.name", "user"])?; |
| 386 | 387 | git(fixture.path(), &["config", "user.email", "user@example.com"])?; |
| 387 | 388 | std::fs::write(fixture.path().join("tracked"), "base\n")?; |
| @@ -1489,6 +1489,7 @@ mod tests { · 1488 unmodified lines | ||
| 1489 | 1489 | history::HistoryGraph, |
| 1490 | 1490 | )> { |
| 1491 | 1491 | let fixture = gix_testtools::scripted_fixture_writable("rebase_conflict.sh")?; |
| 1492 | + crate::test_repository::disable_autocrlf(fixture.path())?; | |
| 1492 | 1493 | git( |
| 1493 | 1494 | fixture.path(), |
| 1494 | 1495 | &["config", "gitoxide.commit.committerDate", "2001-01-01T00:00:00 +0000"], |
| @@ -2063,6 +2064,7 @@ mod tests { · 568 unmodified lines | ||
| 2063 | 2064 | #[test] |
| 2064 | 2065 | fn returning_to_a_commit_restores_its_manual_stash() -> gix_testtools::Result { |
| 2065 | 2066 | let fixture = gix_testtools::scripted_fixture_writable("history.sh")?; |
| 2067 | + crate::test_repository::disable_autocrlf(fixture.path())?; | |
| 2066 | 2068 | let repository = crate::test_repository::open(fixture.path())?; |
| 2067 | 2069 | let repository_path = repository.git_dir().to_owned(); |
| 2068 | 2070 | let head = repository.head_id()?.detach(); |
| @@ -2361,9 +2363,10 @@ mod tests { · 292 unmodified lines | ||
| 2361 | 2363 | .contains_str("<<<<<<<"), |
| 2362 | 2364 | "the checked-out merge tree contains conflict markers" |
| 2363 | 2365 | ); |
| 2366 | + crate::test_repository::clear_autocrlf(fixture.path())?; | |
| 2364 | 2367 | insta::assert_snapshot!( |
| 2365 | 2368 | "accepted-pending-rebase-conflict", |
| 2366 | − gix_testtools::repository::snapshot(fixture.path())? | |
| 2369 | + gix_testtools::repository::snapshot_portable(fixture.path())? | |
| 2367 | 2370 | .to_string() |
| 2368 | 2371 | .replace("\n \n", "\n\n") |
| 2369 | 2372 | ); |
| @@ -1853,7 +1853,12 @@ mod tests { · 1852 unmodified lines | ||
| 1853 | 1853 | |
| 1854 | 1854 | #[test] |
| 1855 | 1855 | fn reference_lines_move_create_delete_and_detach_head() -> gix_testtools::Result { |
| 1856 | − let (fixture, repo) = repo()?; | |
| 1856 | + let (fixture, _) = repo()?; | |
| 1857 | + crate::test_repository::disable_autocrlf(fixture.path())?; | |
| 1858 | + let repo = crate::test_repository::open_with( | |
| 1859 | + fixture.path(), | |
| 1860 | + ["core.abbrev=7", "user.name=todo author", "user.email=todo@example.com"], | |
| 1861 | + )?; | |
| 1857 | 1862 | let (base, middle, tip, commits) = commits(&repo)?; |
| 1858 | 1863 | let prepared = prepare_test(&repo, base, base, &commits, Some(tip))?; |
| 1859 | 1864 | let generated = String::from_utf8(prepared.document.clone())?; |
| @@ -398,6 +398,7 @@ struct WorktreeTransition { · 397 unmodified lines | ||
| 398 | 398 | } |
| 399 | 399 | |
| 400 | 400 | fn worktree_transitions(repo: &gix::Repository, changes: &[RefChange]) -> Result<Vec<WorktreeTransition>> { |
| 401 | + let current_git_dir = gix::path::realpath(repo.git_dir()).context("could not resolve the current Git directory")?; | |
| 401 | 402 | let mut repos = vec![ |
| 402 | 403 | repo.main_repo() |
| 403 | 404 | .context("could not open the main worktree repository")?, |
| @@ -422,7 +423,9 @@ fn worktree_transitions(repo: &gix::Repository, changes: &[RefChange]) -> Result · 18 unmodified lines | ||
| 422 | 423 | .find_reference("HEAD") |
| 423 | 424 | .context("could not read a worktree HEAD reference")?; |
| 424 | 425 | let raw_head = state_from_target_ref(raw_head.target()); |
| 425 | − let current = worktree_repo == *repo; | |
| 426 | + let current = gix::path::realpath(worktree_repo.git_dir()) | |
| 427 | + .context("could not resolve an affected worktree Git directory")? | |
| 428 | + == current_git_dir; | |
| 426 | 429 | let projected_head = projected_ref_state(&worktree_repo, b"HEAD".as_bstr(), &raw_head, changes, current)?; |
| 427 | 430 | ensure!( |
| 428 | 431 | projected_head != State::Missing, |
| @@ -1148,6 +1151,7 @@ mod tests { · 719 unmodified lines | ||
| 1148 | 1151 | #[test] |
| 1149 | 1152 | fn attached_branch_checkout_follows_undo_and_redo() -> gix_testtools::Result { |
| 1150 | 1153 | let fixture = gix_testtools::scripted_fixture_writable("forget_commit.sh")?; |
| 1154 | + crate::test_repository::disable_autocrlf(fixture.path())?; | |
| 1151 | 1155 | let repo = crate::test_repository::open(fixture.path())?; |
| 1152 | 1156 | let top = repo.head_id()?.detach(); |
| 1153 | 1157 | let parent = repo |
| @@ -1204,6 +1208,7 @@ mod tests { · 50 unmodified lines | ||
| 1204 | 1208 | #[test] |
| 1205 | 1209 | fn linked_worktree_head_checkout_follows_undo_and_redo() -> gix_testtools::Result { |
| 1206 | 1210 | let fixture = gix_testtools::scripted_fixture_writable("forget_commit.sh")?; |
| 1211 | + crate::test_repository::disable_autocrlf(fixture.path())?; | |
| 1207 | 1212 | let linked = fixture.path().join("linked"); |
| 1208 | 1213 | let status = std::process::Command::new("git") |
| 1209 | 1214 | .arg("-C") |
| @@ -8671,16 +8671,17 @@ mod tests { · 8670 unmodified lines | ||
| 8671 | 8671 | #[test] |
| 8672 | 8672 | fn incremental_worktree_status_matches_a_full_refresh() -> gix_testtools::Result { |
| 8673 | 8673 | let fixture = gix_testtools::scripted_fixture_writable("history.sh")?; |
| 8674 | + test_repository::disable_autocrlf(fixture.path())?; | |
| 8674 | 8675 | let path = fixture.path(); |
| 8675 | 8676 | let repository = test_repository::open(path)?; |
| 8676 | 8677 | let mut pool = LineDiffPool::new(path, false, 2); |
| 8677 | 8678 | let mut cached = load_worktree_changes(&repository, &mut pool)?; |
| 8678 | 8679 | |
| 8679 | 8680 | std::fs::write(path.join("main"), "changed in worktree\n")?; |
| 8680 | − std::fs::write(path.join("literal[*]"), "untracked\n")?; | |
| 8681 | + std::fs::write(path.join("literal[brackets]"), "untracked\n")?; | |
| 8681 | 8682 | let parts = WorktreeStatusParts { |
| 8682 | 8683 | staged: false, |
| 8683 | − scopes: HashSet::from([BString::from("main"), BString::from("literal[*]")]), | |
| 8684 | + scopes: HashSet::from([BString::from("main"), BString::from("literal[brackets]")]), | |
| 8684 | 8685 | }; |
| 8685 | 8686 | update_worktree_changes(&repository, &mut cached, &parts, &mut pool)?; |
| 8686 | 8687 | assert_eq!( |
| @@ -26,6 +26,50 @@ where · 25 unmodified lines | ||
| 26 | 26 | ) |
| 27 | 27 | } |
| 28 | 28 | |
| 29 | +pub(crate) fn replacing_editor(old: &str, new: &str) -> String { | |
| 30 | + #[cfg(windows)] | |
| 31 | + { | |
| 32 | + let script = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/replace-editor.ps1"); | |
| 33 | + format!("pwsh -NoProfile -File \"{}\" \"{old}\" \"{new}\"", script.display()) | |
| 34 | + } | |
| 35 | + #[cfg(not(windows))] | |
| 36 | + { | |
| 37 | + format!("sed -i.bak -e 's/^{old}$/{new}/'") | |
| 38 | + } | |
| 39 | +} | |
| 40 | + | |
| 41 | +/// Keep Git from converting fixture contents while a test compares exact worktree and index bytes. | |
| 42 | +pub(crate) fn disable_autocrlf(path: impl AsRef<Path>) -> std::io::Result<()> { | |
| 43 | + let status = std::process::Command::new("git") | |
| 44 | + .arg("-C") | |
| 45 | + .arg(path.as_ref()) | |
| 46 | + .args(["config", "--local", "core.autocrlf", "false"]) | |
| 47 | + .status()?; | |
| 48 | + if status.success() { | |
| 49 | + Ok(()) | |
| 50 | + } else { | |
| 51 | + Err(std::io::Error::other( | |
| 52 | + "could not disable core.autocrlf for the test repository", | |
| 53 | + )) | |
| 54 | + } | |
| 55 | +} | |
| 56 | + | |
| 57 | +/// Remove the test-local line-ending override before assertions which snapshot repository configuration. | |
| 58 | +pub(crate) fn clear_autocrlf(path: impl AsRef<Path>) -> std::io::Result<()> { | |
| 59 | + let status = std::process::Command::new("git") | |
| 60 | + .arg("-C") | |
| 61 | + .arg(path.as_ref()) | |
| 62 | + .args(["config", "--local", "--unset", "core.autocrlf"]) | |
| 63 | + .status()?; | |
| 64 | + if status.success() { | |
| 65 | + Ok(()) | |
| 66 | + } else { | |
| 67 | + Err(std::io::Error::other( | |
| 68 | + "could not remove the core.autocrlf test override", | |
| 69 | + )) | |
| 70 | + } | |
| 71 | +} | |
| 72 | + | |
| 29 | 73 | #[test] |
| 30 | 74 | fn defaults_are_deterministic_and_case_specific_overrides_win() -> gix_testtools::Result { |
| 31 | 75 | let fixture = gix_testtools::scripted_fixture_read_only("history.sh")?; |
File mode changed from 100644 to 100755.
File mode changed from 100644 to 100755.
File mode changed from 100644 to 100755.
File mode changed from 100644 to 100755.
| @@ -0,0 +1,9 @@ | ||
| 1 | +param( | |
| 2 | + [Parameter(Mandatory = $true)][string]$Old, | |
| 3 | + [Parameter(Mandatory = $true)][string]$New, | |
| 4 | + [Parameter(Mandatory = $true)][string]$Path | |
| 5 | +) | |
| 6 | + | |
| 7 | +$content = [System.IO.File]::ReadAllText($Path) | |
| 8 | +$utf8WithoutBom = [System.Text.UTF8Encoding]::new($false) | |
| 9 | +[System.IO.File]::WriteAllText($Path, $content.Replace($Old, $New), $utf8WithoutBom) | |
File mode changed from 100644 to 100755.