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 | let fixture = gix_testtools::scripted_fixture_writable("split_commit.sh")?; | 1981 | let fixture = gix_testtools::scripted_fixture_writable("split_commit.sh")?; |
| 1982 | let repository = | 1982 | let repository = crate::test_repository::open_with( |
| 1983 | crate::test_repository::open_with(fixture.path(), ["core.editor=sed -i.bak -e 's/^what$/split/'"])?; | 1983 | fixture.path(), |
| 1984 | [format!( | ||
| 1985 | "core.editor={}", | ||
| 1986 | crate::test_repository::replacing_editor("what", "split") | ||
| 1987 | )], | ||
| 1988 | )?; | ||
| 1984 | let graph = crate::edit::loaded_view_graph(&repository)?; | 1989 | let graph = crate::edit::loaded_view_graph(&repository)?; |
| 1985 | let original = repository.head_id()?.detach(); | 1990 | let original = repository.head_id()?.detach(); |
| 1986 | crate::enrich::set_note(&repository, original, Some(b"source marker"))?; | 1991 | crate::enrich::set_note(&repository, original, Some(b"source marker"))?; |
| @@ -281,7 +281,13 @@ mod tests { · 280 unmodified lines | |||
| 281 | #[test] | 281 | #[test] |
| 282 | fn editors_preserve_other_enrichments() -> gix_testtools::Result { | 282 | fn editors_preserve_other_enrichments() -> gix_testtools::Result { |
| 283 | let fixture = gix_testtools::scripted_fixture_writable("history.sh")?; | 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 | let topic = repository.rev_parse_single("topic")?.detach(); | 291 | let topic = repository.rev_parse_single("topic")?.detach(); |
| 286 | crate::enrich::ensure_todo(&repository, topic, true)?; | 292 | crate::enrich::ensure_todo(&repository, topic, true)?; |
| 287 | crate::enrich::set_note(&repository, topic, Some(b"old\n"))?; | 293 | crate::enrich::set_note(&repository, topic, Some(b"old\n"))?; |
| @@ -222,6 +222,7 @@ mod tests { · 221 unmodified lines | |||
| 222 | fn unchanged_selected_trees_require_allow_empty() -> gix_testtools::Result { | 222 | fn unchanged_selected_trees_require_allow_empty() -> gix_testtools::Result { |
| 223 | for worktree in [false, true] { | 223 | for worktree in [false, true] { |
| 224 | let fixture = gix_testtools::scripted_fixture_writable("create_commit.sh")?; | 224 | let fixture = gix_testtools::scripted_fixture_writable("create_commit.sh")?; |
| 225 | crate::test_repository::disable_autocrlf(fixture.path())?; | ||
| 225 | if worktree { | 226 | if worktree { |
| 226 | git(fixture.path(), &["checkout", "--", "tracked"])?; | 227 | git(fixture.path(), &["checkout", "--", "tracked"])?; |
| 227 | } else { | 228 | } else { |
| @@ -263,6 +264,7 @@ mod tests { · 35 unmodified lines | |||
| 263 | #[test] | 264 | #[test] |
| 264 | fn unchanged_worktree_untracked_requires_allow_empty() -> gix_testtools::Result { | 265 | fn unchanged_worktree_untracked_requires_allow_empty() -> gix_testtools::Result { |
| 265 | let fixture = gix_testtools::scripted_fixture_writable("create_commit.sh")?; | 266 | let fixture = gix_testtools::scripted_fixture_writable("create_commit.sh")?; |
| 267 | crate::test_repository::disable_autocrlf(fixture.path())?; | ||
| 266 | git(fixture.path(), &["clean", "-fdq"])?; | 268 | git(fixture.path(), &["clean", "-fdq"])?; |
| 267 | git(fixture.path(), &["checkout", "--", "tracked"])?; | 269 | git(fixture.path(), &["checkout", "--", "tracked"])?; |
| 268 | let parent = git(fixture.path(), &["rev-parse", "HEAD^{tree}"])?; | 270 | let parent = git(fixture.path(), &["rev-parse", "HEAD^{tree}"])?; |
| @@ -320,7 +320,10 @@ mod tests { · 319 unmodified lines | |||
| 320 | fn attached_head_needs_no_pin() -> gix_testtools::Result { | 320 | fn attached_head_needs_no_pin() -> gix_testtools::Result { |
| 321 | let fixture = gix_testtools::scripted_fixture_writable("rebase_edit.sh")?; | 321 | let fixture = gix_testtools::scripted_fixture_writable("rebase_edit.sh")?; |
| 322 | run( | 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 | args("HEAD"), | 327 | args("HEAD"), |
| 325 | )?; | 328 | )?; |
| 326 | 329 | ||
| @@ -362,7 +365,10 @@ mod tests { · 35 unmodified lines | |||
| 362 | .to_string(); | 365 | .to_string(); |
| 363 | drop(repository); | 366 | drop(repository); |
| 364 | run( | 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 | args(&change_id), | 372 | args(&change_id), |
| 367 | )?; | 373 | )?; |
| 368 | 374 | ||
| @@ -412,7 +418,13 @@ mod tests { · 43 unmodified lines | |||
| 412 | git(path, &["update-ref", "refs/worktree/tix/pins/side", side])?; | 418 | git(path, &["update-ref", "refs/worktree/tix/pins/side", side])?; |
| 413 | let main = git(path, &["rev-parse", "main"])?; | 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 | assert_eq!( | 429 | assert_eq!( |
| 418 | git(path, &["rev-parse", "main"])?, | 430 | git(path, &["rev-parse", "main"])?, |
| @@ -775,6 +775,7 @@ mod tests { · 774 unmodified lines | |||
| 775 | #[test] | 775 | #[test] |
| 776 | fn implicit_new_commit_ignores_untracked_files() -> gix_testtools::Result { | 776 | fn implicit_new_commit_ignores_untracked_files() -> gix_testtools::Result { |
| 777 | let fixture = gix_testtools::scripted_fixture_writable("create_commit.sh")?; | 777 | let fixture = gix_testtools::scripted_fixture_writable("create_commit.sh")?; |
| 778 | crate::test_repository::disable_autocrlf(fixture.path())?; | ||
| 778 | assert!( | 779 | assert!( |
| 779 | Command::new("git") | 780 | Command::new("git") |
| 780 | .arg("-C") | 781 | .arg("-C") |
| @@ -186,6 +186,7 @@ mod tests { · 185 unmodified lines | |||
| 186 | #[test] | 186 | #[test] |
| 187 | fn forgets_a_tip_atomically_and_preserves_untracked_files() -> gix_testtools::Result { | 187 | fn forgets_a_tip_atomically_and_preserves_untracked_files() -> gix_testtools::Result { |
| 188 | let fixture = gix_testtools::scripted_fixture_writable("forget_commit.sh")?; | 188 | let fixture = gix_testtools::scripted_fixture_writable("forget_commit.sh")?; |
| 189 | crate::test_repository::disable_autocrlf(fixture.path())?; | ||
| 189 | let repository = open(fixture.path())?; | 190 | let repository = open(fixture.path())?; |
| 190 | let top = repository.head_id()?.detach(); | 191 | let top = repository.head_id()?.detach(); |
| 191 | let parent = repository | 192 | let parent = repository |
| @@ -125,18 +125,20 @@ pub(crate) fn edit_document_without_terminal( · 124 unmodified lines | |||
| 125 | gix::tempfile::ContainingDirectory::Exists, | 125 | gix::tempfile::ContainingDirectory::Exists, |
| 126 | gix::tempfile::AutoRemove::Tempfile, | 126 | gix::tempfile::AutoRemove::Tempfile, |
| 127 | ) | 127 | ) |
| 128 | .context("could not create commit message file")? | 128 | .context("could not create commit message file")?; |
| 129 | .take() | ||
| 130 | .context("commit message file disappeared")?; | ||
| 131 | tempfile | 129 | tempfile |
| 132 | .write_all(document) | 130 | .write_all(document) |
| 133 | .context("could not write commit message file")?; | 131 | .context("could not write commit message file")?; |
| 134 | tempfile.flush().context("could not flush commit message file")?; | 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 | if editor != ":" { | 138 | if editor != ":" { |
| 137 | let status = Command::from( | 139 | let status = Command::from( |
| 138 | gix::command::prepare(editor) | 140 | gix::command::prepare(editor) |
| 139 | .arg(tempfile.path()) | 141 | .arg(&path) |
| 140 | .command_may_be_shell_script_allow_manual_argument_splitting(), | 142 | .command_may_be_shell_script_allow_manual_argument_splitting(), |
| 141 | ) | 143 | ) |
| 142 | .status() | 144 | .status() |
| @@ -145,7 +147,7 @@ pub(crate) fn edit_document_without_terminal( · 2 unmodified lines | |||
| 145 | anyhow::bail!("Git editor {} exited with {status}", editor.to_string_lossy()); | 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 | Ok((edited != document).then_some(edited)) | 151 | Ok((edited != document).then_some(edited)) |
| 150 | } | 152 | } |
| 151 | 153 | ||
| @@ -3299,7 +3299,7 @@ mod tests { · 3298 unmodified lines | |||
| 3299 | } | 3299 | } |
| 3300 | insta::assert_snapshot!( | 3300 | insta::assert_snapshot!( |
| 3301 | "reworded-middle-stack", | 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 | Ok(()) | 3304 | Ok(()) |
| 3305 | } | 3305 | } |
| @@ -619,6 +619,7 @@ mod tests { · 618 unmodified lines | |||
| 619 | fn a_changed_review_and_its_successors_are_spliced_before_target_successors() -> gix_testtools::Result { | 619 | fn a_changed_review_and_its_successors_are_spliced_before_target_successors() -> gix_testtools::Result { |
| 620 | let fixture = gix_testtools::tempfile::tempdir()?; | 620 | let fixture = gix_testtools::tempfile::tempdir()?; |
| 621 | run(fixture.path(), &["init", "-q", "-b", "main"])?; | 621 | run(fixture.path(), &["init", "-q", "-b", "main"])?; |
| 622 | crate::test_repository::disable_autocrlf(fixture.path())?; | ||
| 622 | run(fixture.path(), &["config", "user.name", "reviewer"])?; | 623 | run(fixture.path(), &["config", "user.name", "reviewer"])?; |
| 623 | run(fixture.path(), &["config", "user.email", "reviewer@example.com"])?; | 624 | run(fixture.path(), &["config", "user.email", "reviewer@example.com"])?; |
| 624 | run( | 625 | run( |
| @@ -752,9 +753,10 @@ mod tests { · 127 unmodified lines | |||
| 752 | !super::super::rebase::is_pending(&repo.find_commit(successor)?.decode()?.into_owned()?), | 753 | !super::super::rebase::is_pending(&repo.find_commit(successor)?.decode()?.into_owned()?), |
| 753 | "the checked-out review return path is fully replayed" | 754 | "the checked-out review return path is fully replayed" |
| 754 | ); | 755 | ); |
| 756 | crate::test_repository::clear_autocrlf(fixture.path())?; | ||
| 755 | insta::assert_snapshot!( | 757 | insta::assert_snapshot!( |
| 756 | "changed-review-with-successors", | 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 | Ok(()) | 761 | Ok(()) |
| 760 | } | 762 | } |
| @@ -1,17 +1,17 @@ | |||
| 1 | --- | 1 | --- |
| 2 | source: gix-tix/src/edit/rebase.rs | 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 | HEAD refs/heads/main -> C2 | 5 | HEAD refs/heads/main -> C2 |
| 6 | 6 | ||
| 7 | [config] | 7 | [config] |
| 8 | [core] | 8 | [core] |
| 9 | bare = false | 9 | bare = false |
| 10 | [user] | 10 | [user] |
| 11 | name = author | 11 | name = author |
| 12 | email = author@example.com | 12 | email = author@example.com |
| 13 | [commit] | 13 | [commit] |
| 14 | gpgSign = false | 14 | gpgSign = false |
| 15 | 15 | ||
| 16 | [refs] | 16 | [refs] |
| 17 | refs/heads/main = C2 | 17 | refs/heads/main = C2 |
| @@ -51,17 +51,6 @@ tree = T2 · 33 unmodified lines | |||
| 51 | 100644 B2 stage=0 "tip" | 51 | 100644 B2 stage=0 "tip" |
| 52 | 52 | ||
| 53 | [worktree] | 53 | [worktree] |
| 54 | 100644 file "base" = "base\n" | 54 | - file "base" = "base\n" |
| 55 | 100644 file "middle" = "middle\n" | 55 | - file "middle" = "middle\n" |
| 56 | 100644 file "tip" = "tip\n" | 56 | - 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 | ||
| @@ -1,18 +1,18 @@ | |||
| 1 | --- | 1 | --- |
| 2 | source: gix-tix/src/edit/review.rs | 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 | HEAD refs/heads/main -> C4 | 5 | HEAD refs/heads/main -> C4 |
| 6 | 6 | ||
| 7 | [config] | 7 | [config] |
| 8 | [core] | 8 | [core] |
| 9 | bare = false | 9 | bare = false |
| 10 | [user] | 10 | [user] |
| 11 | name = reviewer | 11 | name = reviewer |
| 12 | email = reviewer@example.com | 12 | email = reviewer@example.com |
| 13 | [gitoxide "commit"] | 13 | [gitoxide "commit"] |
| 14 | authorDate = 2001-01-01T00:00:00 +0000 | 14 | authorDate = 2001-01-01T00:00:00 +0000 |
| 15 | committerDate = 2001-01-01T00:00:00 +0000 | 15 | committerDate = 2001-01-01T00:00:00 +0000 |
| 16 | 16 | ||
| 17 | [refs] | 17 | [refs] |
| 18 | refs/heads/main = C4 | 18 | refs/heads/main = C4 |
| @@ -68,20 +68,6 @@ tree = T3 · 49 unmodified lines | |||
| 68 | 100644 B2 stage=0 "successor" | 68 | 100644 B2 stage=0 "successor" |
| 69 | 69 | ||
| 70 | [worktree] | 70 | [worktree] |
| 71 | 100644 file "file" = "B\n" | 71 | - file "file" = "B\n" |
| 72 | 100644 file "reviewed" = "new review change\n" | 72 | - file "reviewed" = "new review change\n" |
| 73 | 100644 file "successor" = "A\n" | 73 | - 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 | ||
| @@ -1,19 +1,19 @@ | |||
| 1 | --- | 1 | --- |
| 2 | source: gix-tix/src/edit/time_travel.rs | 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 | HEAD detached C1 | 5 | HEAD detached C1 |
| 6 | 6 | ||
| 7 | [config] | 7 | [config] |
| 8 | [core] | 8 | [core] |
| 9 | bare = false | 9 | bare = false |
| 10 | [user] | 10 | [user] |
| 11 | name = author | 11 | name = author |
| 12 | email = author@example.com | 12 | email = author@example.com |
| 13 | [commit] | 13 | [commit] |
| 14 | gpgSign = false | 14 | gpgSign = false |
| 15 | [gitoxide "commit"] | 15 | [gitoxide "commit"] |
| 16 | committerDate = 2001-01-01T00:00:00 +0000 | 16 | committerDate = 2001-01-01T00:00:00 +0000 |
| 17 | 17 | ||
| 18 | [refs] | 18 | [refs] |
| 19 | refs/heads/main = C2 | 19 | refs/heads/main = C2 |
| @@ -54,14 +54,4 @@ tree = conflicted · 34 unmodified lines | |||
| 54 | 100644 B2 stage=3 "file" | 54 | 100644 B2 stage=3 "file" |
| 55 | 55 | ||
| 56 | [worktree] | 56 | [worktree] |
| 57 | 100644 file "file" = "<<<<<<< rebased parent\nbase\n=======\ntip\n>>>>>>> commit\n" | 57 | - 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 | ||
| @@ -382,6 +382,7 @@ mod tests { · 381 unmodified lines | |||
| 382 | fn manual_stashes_preserve_git_stashes_and_restore_index_and_worktree_state() -> gix_testtools::Result { | 382 | fn manual_stashes_preserve_git_stashes_and_restore_index_and_worktree_state() -> gix_testtools::Result { |
| 383 | let fixture = gix_testtools::tempfile::tempdir()?; | 383 | let fixture = gix_testtools::tempfile::tempdir()?; |
| 384 | git(fixture.path(), &["init", "-q", "-b", "main"])?; | 384 | git(fixture.path(), &["init", "-q", "-b", "main"])?; |
| 385 | crate::test_repository::disable_autocrlf(fixture.path())?; | ||
| 385 | git(fixture.path(), &["config", "user.name", "user"])?; | 386 | git(fixture.path(), &["config", "user.name", "user"])?; |
| 386 | git(fixture.path(), &["config", "user.email", "user@example.com"])?; | 387 | git(fixture.path(), &["config", "user.email", "user@example.com"])?; |
| 387 | std::fs::write(fixture.path().join("tracked"), "base\n")?; | 388 | std::fs::write(fixture.path().join("tracked"), "base\n")?; |
| @@ -1489,6 +1489,7 @@ mod tests { · 1488 unmodified lines | |||
| 1489 | history::HistoryGraph, | 1489 | history::HistoryGraph, |
| 1490 | )> { | 1490 | )> { |
| 1491 | let fixture = gix_testtools::scripted_fixture_writable("rebase_conflict.sh")?; | 1491 | let fixture = gix_testtools::scripted_fixture_writable("rebase_conflict.sh")?; |
| 1492 | crate::test_repository::disable_autocrlf(fixture.path())?; | ||
| 1492 | git( | 1493 | git( |
| 1493 | fixture.path(), | 1494 | fixture.path(), |
| 1494 | &["config", "gitoxide.commit.committerDate", "2001-01-01T00:00:00 +0000"], | 1495 | &["config", "gitoxide.commit.committerDate", "2001-01-01T00:00:00 +0000"], |
| @@ -2063,6 +2064,7 @@ mod tests { · 568 unmodified lines | |||
| 2063 | #[test] | 2064 | #[test] |
| 2064 | fn returning_to_a_commit_restores_its_manual_stash() -> gix_testtools::Result { | 2065 | fn returning_to_a_commit_restores_its_manual_stash() -> gix_testtools::Result { |
| 2065 | let fixture = gix_testtools::scripted_fixture_writable("history.sh")?; | 2066 | let fixture = gix_testtools::scripted_fixture_writable("history.sh")?; |
| 2067 | crate::test_repository::disable_autocrlf(fixture.path())?; | ||
| 2066 | let repository = crate::test_repository::open(fixture.path())?; | 2068 | let repository = crate::test_repository::open(fixture.path())?; |
| 2067 | let repository_path = repository.git_dir().to_owned(); | 2069 | let repository_path = repository.git_dir().to_owned(); |
| 2068 | let head = repository.head_id()?.detach(); | 2070 | let head = repository.head_id()?.detach(); |
| @@ -2361,9 +2363,10 @@ mod tests { · 292 unmodified lines | |||
| 2361 | .contains_str("<<<<<<<"), | 2363 | .contains_str("<<<<<<<"), |
| 2362 | "the checked-out merge tree contains conflict markers" | 2364 | "the checked-out merge tree contains conflict markers" |
| 2363 | ); | 2365 | ); |
| 2366 | crate::test_repository::clear_autocrlf(fixture.path())?; | ||
| 2364 | insta::assert_snapshot!( | 2367 | insta::assert_snapshot!( |
| 2365 | "accepted-pending-rebase-conflict", | 2368 | "accepted-pending-rebase-conflict", |
| 2366 | gix_testtools::repository::snapshot(fixture.path())? | 2369 | gix_testtools::repository::snapshot_portable(fixture.path())? |
| 2367 | .to_string() | 2370 | .to_string() |
| 2368 | .replace("\n \n", "\n\n") | 2371 | .replace("\n \n", "\n\n") |
| 2369 | ); | 2372 | ); |
| @@ -1853,7 +1853,12 @@ mod tests { · 1852 unmodified lines | |||
| 1853 | 1853 | ||
| 1854 | #[test] | 1854 | #[test] |
| 1855 | fn reference_lines_move_create_delete_and_detach_head() -> gix_testtools::Result { | 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 | let (base, middle, tip, commits) = commits(&repo)?; | 1862 | let (base, middle, tip, commits) = commits(&repo)?; |
| 1858 | let prepared = prepare_test(&repo, base, base, &commits, Some(tip))?; | 1863 | let prepared = prepare_test(&repo, base, base, &commits, Some(tip))?; |
| 1859 | let generated = String::from_utf8(prepared.document.clone())?; | 1864 | let generated = String::from_utf8(prepared.document.clone())?; |
| @@ -398,6 +398,7 @@ struct WorktreeTransition { · 397 unmodified lines | |||
| 398 | } | 398 | } |
| 399 | 399 | ||
| 400 | fn worktree_transitions(repo: &gix::Repository, changes: &[RefChange]) -> Result<Vec<WorktreeTransition>> { | 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 | let mut repos = vec![ | 402 | let mut repos = vec![ |
| 402 | repo.main_repo() | 403 | repo.main_repo() |
| 403 | .context("could not open the main worktree repository")?, | 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 | .find_reference("HEAD") | 423 | .find_reference("HEAD") |
| 423 | .context("could not read a worktree HEAD reference")?; | 424 | .context("could not read a worktree HEAD reference")?; |
| 424 | let raw_head = state_from_target_ref(raw_head.target()); | 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 | let projected_head = projected_ref_state(&worktree_repo, b"HEAD".as_bstr(), &raw_head, changes, current)?; | 429 | let projected_head = projected_ref_state(&worktree_repo, b"HEAD".as_bstr(), &raw_head, changes, current)?; |
| 427 | ensure!( | 430 | ensure!( |
| 428 | projected_head != State::Missing, | 431 | projected_head != State::Missing, |
| @@ -1148,6 +1151,7 @@ mod tests { · 719 unmodified lines | |||
| 1148 | #[test] | 1151 | #[test] |
| 1149 | fn attached_branch_checkout_follows_undo_and_redo() -> gix_testtools::Result { | 1152 | fn attached_branch_checkout_follows_undo_and_redo() -> gix_testtools::Result { |
| 1150 | let fixture = gix_testtools::scripted_fixture_writable("forget_commit.sh")?; | 1153 | let fixture = gix_testtools::scripted_fixture_writable("forget_commit.sh")?; |
| 1154 | crate::test_repository::disable_autocrlf(fixture.path())?; | ||
| 1151 | let repo = crate::test_repository::open(fixture.path())?; | 1155 | let repo = crate::test_repository::open(fixture.path())?; |
| 1152 | let top = repo.head_id()?.detach(); | 1156 | let top = repo.head_id()?.detach(); |
| 1153 | let parent = repo | 1157 | let parent = repo |
| @@ -1204,6 +1208,7 @@ mod tests { · 50 unmodified lines | |||
| 1204 | #[test] | 1208 | #[test] |
| 1205 | fn linked_worktree_head_checkout_follows_undo_and_redo() -> gix_testtools::Result { | 1209 | fn linked_worktree_head_checkout_follows_undo_and_redo() -> gix_testtools::Result { |
| 1206 | let fixture = gix_testtools::scripted_fixture_writable("forget_commit.sh")?; | 1210 | let fixture = gix_testtools::scripted_fixture_writable("forget_commit.sh")?; |
| 1211 | crate::test_repository::disable_autocrlf(fixture.path())?; | ||
| 1207 | let linked = fixture.path().join("linked"); | 1212 | let linked = fixture.path().join("linked"); |
| 1208 | let status = std::process::Command::new("git") | 1213 | let status = std::process::Command::new("git") |
| 1209 | .arg("-C") | 1214 | .arg("-C") |
| @@ -8671,16 +8671,17 @@ mod tests { · 8670 unmodified lines | |||
| 8671 | #[test] | 8671 | #[test] |
| 8672 | fn incremental_worktree_status_matches_a_full_refresh() -> gix_testtools::Result { | 8672 | fn incremental_worktree_status_matches_a_full_refresh() -> gix_testtools::Result { |
| 8673 | let fixture = gix_testtools::scripted_fixture_writable("history.sh")?; | 8673 | let fixture = gix_testtools::scripted_fixture_writable("history.sh")?; |
| 8674 | test_repository::disable_autocrlf(fixture.path())?; | ||
| 8674 | let path = fixture.path(); | 8675 | let path = fixture.path(); |
| 8675 | let repository = test_repository::open(path)?; | 8676 | let repository = test_repository::open(path)?; |
| 8676 | let mut pool = LineDiffPool::new(path, false, 2); | 8677 | let mut pool = LineDiffPool::new(path, false, 2); |
| 8677 | let mut cached = load_worktree_changes(&repository, &mut pool)?; | 8678 | let mut cached = load_worktree_changes(&repository, &mut pool)?; |
| 8678 | 8679 | ||
| 8679 | std::fs::write(path.join("main"), "changed in worktree\n")?; | 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 | let parts = WorktreeStatusParts { | 8682 | let parts = WorktreeStatusParts { |
| 8682 | staged: false, | 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 | update_worktree_changes(&repository, &mut cached, &parts, &mut pool)?; | 8686 | update_worktree_changes(&repository, &mut cached, &parts, &mut pool)?; |
| 8686 | assert_eq!( | 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 | #[test] | 73 | #[test] |
| 30 | fn defaults_are_deterministic_and_case_specific_overrides_win() -> gix_testtools::Result { | 74 | fn defaults_are_deterministic_and_case_specific_overrides_win() -> gix_testtools::Result { |
| 31 | let fixture = gix_testtools::scripted_fixture_read_only("history.sh")?; | 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.