From 9d7ed54f8eff082656c72b49135930c7621614fb Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Sun, 21 Apr 2024 12:37:19 -0700 Subject: [PATCH] git_backend: add a README to conflicted commits When you use e.g. `git switch` to check out a conflicted commit, you're going to end up with the `.jjconflicts-*` directories in your working copy. It's probably not obvious what those mean. This patch adds a README file to the root tree to try to explain to users what's going on and how to recover. The authoritative information about conflicts is stored in the `jj:trees` commit header. The contents of conflicted commits is only used for preventing GC. We can therefore add contents to the tree without much consequence. --- cli/tests/test_chmod_command.rs | 6 +-- cli/tests/test_diffedit_command.rs | 6 +-- cli/tests/test_git_push.rs | 2 +- cli/tests/test_immutable_commits.rs | 36 +++++++++--------- cli/tests/test_obslog_command.rs | 16 ++++---- cli/tests/test_repo_change_report.rs | 52 +++++++++++++------------- cli/tests/test_resolve_command.rs | 8 ++-- cli/tests/test_restore_command.rs | 12 +++--- cli/tests/test_squash_command.rs | 24 ++++++------ cli/tests/test_tree_level_conflicts.rs | 2 +- cli/tests/test_workspaces.rs | 4 +- lib/src/git_backend.rs | 38 +++++++++++++++++-- 12 files changed, 118 insertions(+), 88 deletions(-) diff --git a/cli/tests/test_chmod_command.rs b/cli/tests/test_chmod_command.rs index 508195781..4ae1ed63f 100644 --- a/cli/tests/test_chmod_command.rs +++ b/cli/tests/test_chmod_command.rs @@ -120,7 +120,7 @@ fn test_chmod_regular_conflict() { let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["chmod", "x", "nonexistent", "file"]); insta::assert_snapshot!(stderr, @r###" Warning: No matching entries for paths: nonexistent - Working copy now at: yostqsxw cbc43289 conflict | (conflict) conflict + Working copy now at: yostqsxw e5912d62 conflict | (conflict) conflict Parent commit : royxmykx 427fbd2f x | x Parent commit : zsuskuln 3f83a26d n | n Added 0 files, modified 1 files, removed 0 files @@ -213,13 +213,13 @@ fn test_chmod_file_dir_deletion_conflicts() { insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" New conflicts appeared in these commits: - kmkuslsw b4c38719 file_deletion | (conflict) file_deletion + kmkuslsw 1b2ef84c file_deletion | (conflict) file_deletion To resolve the conflicts, start by updating to it: jj new kmkuslswpqwq Then use `jj resolve`, or edit the conflict markers in the file directly. Once the conflicts are resolved, you may want inspect the result with `jj diff`. Then run `jj squash` to move the resolution into the conflicted commit. - Working copy now at: kmkuslsw b4c38719 file_deletion | (conflict) file_deletion + Working copy now at: kmkuslsw 1b2ef84c file_deletion | (conflict) file_deletion Parent commit : zsuskuln c51c9c55 file | file Parent commit : royxmykx 6b18b3c1 deletion | deletion Added 0 files, modified 1 files, removed 0 files diff --git a/cli/tests/test_diffedit_command.rs b/cli/tests/test_diffedit_command.rs index b1ea6f1f9..3b30a3630 100644 --- a/cli/tests/test_diffedit_command.rs +++ b/cli/tests/test_diffedit_command.rs @@ -379,10 +379,10 @@ fn test_diffedit_merge() { let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["diffedit", "-r", "@-"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" - Created royxmykx b90654a0 (conflict) merge + Created royxmykx b9539d6e (conflict) merge Rebased 1 descendant commits - Working copy now at: yqosqzyt 1de824f2 (conflict) (empty) (no description set) - Parent commit : royxmykx b90654a0 (conflict) merge + Working copy now at: yqosqzyt 0a24ed24 (conflict) (empty) (no description set) + Parent commit : royxmykx b9539d6e (conflict) merge Added 0 files, modified 0 files, removed 1 files There are unresolved conflicts at these paths: file2 2-sided conflict diff --git a/cli/tests/test_git_push.rs b/cli/tests/test_git_push.rs index ad6f6161d..6d8bf2b21 100644 --- a/cli/tests/test_git_push.rs +++ b/cli/tests/test_git_push.rs @@ -628,7 +628,7 @@ fn test_git_push_conflict() { test_env.jj_cmd_ok(&workspace_root, &["describe", "-m", "third"]); let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--all"]); insta::assert_snapshot!(stderr, @r###" - Error: Won't push commit d9ca3146ade7 since it has conflicts + Error: Won't push commit 739c4f08a056 since it has conflicts "###); } diff --git a/cli/tests/test_immutable_commits.rs b/cli/tests/test_immutable_commits.rs index a3afb28f0..32d03cd8e 100644 --- a/cli/tests/test_immutable_commits.rs +++ b/cli/tests/test_immutable_commits.rs @@ -116,7 +116,7 @@ fn test_rewrite_immutable_commands() { insta::assert_snapshot!(stdout, @r###" @ yqosqzyt test.user@example.com 2001-02-03 08:05:13 3f89addf │ (empty) (no description set) - │ ◉ mzvwutvl test.user@example.com 2001-02-03 08:05:11 main 3d14df18 conflict + │ ◉ mzvwutvl test.user@example.com 2001-02-03 08:05:11 main 406c181c conflict ╭─┤ (empty) merge │ │ │ ~ @@ -129,31 +129,31 @@ fn test_rewrite_immutable_commands() { // abandon let stderr = test_env.jj_cmd_failure(&repo_path, &["abandon", "main"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // chmod let stderr = test_env.jj_cmd_failure(&repo_path, &["chmod", "-r=main", "x", "file"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // describe let stderr = test_env.jj_cmd_failure(&repo_path, &["describe", "main"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // diffedit let stderr = test_env.jj_cmd_failure(&repo_path, &["diffedit", "-r=main"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // edit let stderr = test_env.jj_cmd_failure(&repo_path, &["edit", "main"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // move --from @@ -161,7 +161,7 @@ fn test_rewrite_immutable_commands() { insta::assert_snapshot!(stderr, @r###" Warning: `jj move` is deprecated; use `jj squash` instead, which is equivalent Warning: `jj move` will be removed in a future version, and this will be a hard error - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // move --to @@ -169,31 +169,31 @@ fn test_rewrite_immutable_commands() { insta::assert_snapshot!(stderr, @r###" Warning: `jj move` is deprecated; use `jj squash` instead, which is equivalent Warning: `jj move` will be removed in a future version, and this will be a hard error - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // new --insert-before let stderr = test_env.jj_cmd_failure(&repo_path, &["new", "--insert-before", "main"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // new --insert-after parent_of_main let stderr = test_env.jj_cmd_failure(&repo_path, &["new", "--insert-after", "description(b)"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // parallelize let stderr = test_env.jj_cmd_failure(&repo_path, &["parallelize", "description(b)", "main"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // rebase -s let stderr = test_env.jj_cmd_failure(&repo_path, &["rebase", "-s=main", "-d=@"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // rebase -b @@ -205,31 +205,31 @@ fn test_rewrite_immutable_commands() { // rebase -r let stderr = test_env.jj_cmd_failure(&repo_path, &["rebase", "-r=main", "-d=@"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // resolve let stderr = test_env.jj_cmd_failure(&repo_path, &["resolve", "-r=description(merge)", "file"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // restore -c let stderr = test_env.jj_cmd_failure(&repo_path, &["restore", "-c=main"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // restore --to let stderr = test_env.jj_cmd_failure(&repo_path, &["restore", "--to=main"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // split let stderr = test_env.jj_cmd_failure(&repo_path, &["split", "-r=main"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); // squash @@ -241,7 +241,7 @@ fn test_rewrite_immutable_commands() { // unsquash let stderr = test_env.jj_cmd_failure(&repo_path, &["unsquash", "-r=main"]); insta::assert_snapshot!(stderr, @r###" - Error: Commit 3d14df18607e is immutable + Error: Commit 406c181c04d8 is immutable Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`. "###); } diff --git a/cli/tests/test_obslog_command.rs b/cli/tests/test_obslog_command.rs index 6f682cf12..4647a6a45 100644 --- a/cli/tests/test_obslog_command.rs +++ b/cli/tests/test_obslog_command.rs @@ -31,7 +31,7 @@ fn test_obslog_with_or_without_diff() { insta::assert_snapshot!(stdout, @r###" @ rlvkpnrz test.user@example.com 2001-02-03 08:05:10 66b42ad3 │ my description - ◉ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 ebc23d4b conflict + ◉ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 cf73917d conflict │ my description ◉ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 6fbba7bc │ my description @@ -44,11 +44,11 @@ fn test_obslog_with_or_without_diff() { insta::assert_snapshot!(stdout, @r###" @ rlvkpnrz test.user@example.com 2001-02-03 08:05:10 66b42ad3 │ my description - ◉ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 ebc23d4b conflict + ◉ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 cf73917d conflict │ my description ◉ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 6fbba7bc │ my description - ◉ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:08 eac0d0da + ◉ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:08 eac0d0da (empty) my description "###); @@ -66,7 +66,7 @@ fn test_obslog_with_or_without_diff() { │ 5 : foo │ 6 : bar │ 7 : >>>>>>> - ◉ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 ebc23d4b conflict + ◉ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 cf73917d conflict │ my description ◉ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 6fbba7bc │ my description @@ -84,7 +84,7 @@ fn test_obslog_with_or_without_diff() { insta::assert_snapshot!(stdout, @r###" @ rlvkpnrz test.user@example.com 2001-02-03 08:05:10 66b42ad3 │ my description - ◉ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 ebc23d4b conflict + ◉ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 cf73917d conflict │ my description "###); @@ -93,7 +93,7 @@ fn test_obslog_with_or_without_diff() { insta::assert_snapshot!(stdout, @r###" rlvkpnrz test.user@example.com 2001-02-03 08:05:10 66b42ad3 my description - rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 ebc23d4b conflict + rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 cf73917d conflict my description rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 6fbba7bc my description @@ -119,7 +119,7 @@ fn test_obslog_with_or_without_diff() { -bar ->>>>>>> +resolved - rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 ebc23d4b conflict + rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 cf73917d conflict my description rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 6fbba7bc my description @@ -162,7 +162,7 @@ fn test_obslog_with_custom_symbols() { insta::assert_snapshot!(stdout, @r###" $ rlvkpnrz test.user@example.com 2001-02-03 08:05:10 66b42ad3 │ my description - ┝ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 ebc23d4b conflict + ┝ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 cf73917d conflict │ my description ┝ rlvkpnrz hidden test.user@example.com 2001-02-03 08:05:09 6fbba7bc │ my description diff --git a/cli/tests/test_repo_change_report.rs b/cli/tests/test_repo_change_report.rs index 333b76932..41cfa660f 100644 --- a/cli/tests/test_repo_change_report.rs +++ b/cli/tests/test_repo_change_report.rs @@ -33,15 +33,15 @@ fn test_report_conflicts() { insta::assert_snapshot!(stderr, @r###" Rebased 3 commits New conflicts appeared in these commits: - kkmpptxz 9baab11e (conflict) C - rlvkpnrz de73196a (conflict) B + kkmpptxz 7afb7d5a (conflict) C + rlvkpnrz 1b74c6ee (conflict) B To resolve the conflicts, start by updating to the first one: jj new rlvkpnrzqnoo Then use `jj resolve`, or edit the conflict markers in the file directly. Once the conflicts are resolved, you may want inspect the result with `jj diff`. Then run `jj squash` to move the resolution into the conflicted commit. - Working copy now at: zsuskuln 7dc9bf15 (conflict) (empty) (no description set) - Parent commit : kkmpptxz 9baab11e (conflict) C + Working copy now at: zsuskuln 6ab4d738 (conflict) (empty) (no description set) + Parent commit : kkmpptxz 7afb7d5a (conflict) C Added 0 files, modified 1 files, removed 0 files There are unresolved conflicts at these paths: file 2-sided conflict including 1 deletion @@ -52,8 +52,8 @@ fn test_report_conflicts() { insta::assert_snapshot!(stderr, @r###" Rebased 3 commits Existing conflicts were resolved or abandoned from these commits: - kkmpptxz hidden 9baab11e (conflict) C - rlvkpnrz hidden de73196a (conflict) B + kkmpptxz hidden 7afb7d5a (conflict) C + rlvkpnrz hidden 1b74c6ee (conflict) B Working copy now at: zsuskuln 355a2e34 (empty) (no description set) Parent commit : kkmpptxz ed071401 C Added 0 files, modified 1 files, removed 0 files @@ -66,16 +66,16 @@ fn test_report_conflicts() { insta::assert_snapshot!(stderr, @r###" Also rebased 2 descendant commits onto parent of rebased commit New conflicts appeared in these commits: - rlvkpnrz e93270ab (conflict) B - kkmpptxz 4f0eeaa6 (conflict) C + rlvkpnrz 262c4c38 (conflict) B + kkmpptxz d1edf578 (conflict) C To resolve the conflicts, start by updating to one of the first ones: jj new rlvkpnrzqnoo jj new kkmpptxzrspx Then use `jj resolve`, or edit the conflict markers in the file directly. Once the conflicts are resolved, you may want inspect the result with `jj diff`. Then run `jj squash` to move the resolution into the conflicted commit. - Working copy now at: zsuskuln 83074dac (conflict) (empty) (no description set) - Parent commit : kkmpptxz 4f0eeaa6 (conflict) C + Working copy now at: zsuskuln b56d36a0 (conflict) (empty) (no description set) + Parent commit : kkmpptxz d1edf578 (conflict) C Added 0 files, modified 1 files, removed 0 files There are unresolved conflicts at these paths: file 2-sided conflict @@ -85,8 +85,8 @@ fn test_report_conflicts() { let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["new", "rlvkpnrzqnoo"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" - Working copy now at: vruxwmqv 2ec0b4c3 (conflict) (empty) (no description set) - Parent commit : rlvkpnrz e93270ab (conflict) B + Working copy now at: vruxwmqv d1eb7305 (conflict) (empty) (no description set) + Parent commit : rlvkpnrz 262c4c38 (conflict) B Added 0 files, modified 1 files, removed 0 files There are unresolved conflicts at these paths: file 2-sided conflict including 1 deletion @@ -96,7 +96,7 @@ fn test_report_conflicts() { insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" Existing conflicts were resolved or abandoned from these commits: - rlvkpnrz hidden e93270ab (conflict) B + rlvkpnrz hidden 262c4c38 (conflict) B Working copy now at: yostqsxw 8e160bc4 (empty) (no description set) Parent commit : rlvkpnrz c5319490 B "###); @@ -124,16 +124,16 @@ fn test_report_conflicts_with_divergent_commits() { Concurrent modification detected, resolving automatically. Rebased 3 commits New conflicts appeared in these commits: - zsuskuln?? 94be9a4c (conflict) C3 - zsuskuln?? cdae4322 (conflict) C2 - kkmpptxz b76d6a88 (conflict) B + zsuskuln?? b535189c (conflict) C3 + zsuskuln?? 97ce1783 (conflict) C2 + kkmpptxz eb93a73d (conflict) B To resolve the conflicts, start by updating to the first one: jj new kkmpptxzrspx Then use `jj resolve`, or edit the conflict markers in the file directly. Once the conflicts are resolved, you may want inspect the result with `jj diff`. Then run `jj squash` to move the resolution into the conflicted commit. - Working copy now at: zsuskuln?? cdae4322 (conflict) C2 - Parent commit : kkmpptxz b76d6a88 (conflict) B + Working copy now at: zsuskuln?? 97ce1783 (conflict) C2 + Parent commit : kkmpptxz eb93a73d (conflict) B Added 0 files, modified 1 files, removed 0 files There are unresolved conflicts at these paths: file 2-sided conflict including 1 deletion @@ -144,9 +144,9 @@ fn test_report_conflicts_with_divergent_commits() { insta::assert_snapshot!(stderr, @r###" Rebased 3 commits Existing conflicts were resolved or abandoned from these commits: - zsuskuln hidden 94be9a4c (conflict) C3 - zsuskuln hidden cdae4322 (conflict) C2 - kkmpptxz hidden b76d6a88 (conflict) B + zsuskuln hidden b535189c (conflict) C3 + zsuskuln hidden 97ce1783 (conflict) C2 + kkmpptxz hidden eb93a73d (conflict) B Working copy now at: zsuskuln?? 9c33e9a9 C2 Parent commit : kkmpptxz 9ce42c2a B Added 0 files, modified 1 files, removed 0 files @@ -159,13 +159,13 @@ fn test_report_conflicts_with_divergent_commits() { insta::assert_snapshot!(stderr, @r###" Rebased 1 commits New conflicts appeared in these commits: - zsuskuln?? 33752e7e (conflict) C2 + zsuskuln?? b15416ac (conflict) C2 To resolve the conflicts, start by updating to it: jj new zsuskulnrvyr Then use `jj resolve`, or edit the conflict markers in the file directly. Once the conflicts are resolved, you may want inspect the result with `jj diff`. Then run `jj squash` to move the resolution into the conflicted commit. - Working copy now at: zsuskuln?? 33752e7e (conflict) C2 + Working copy now at: zsuskuln?? b15416ac (conflict) C2 Parent commit : zzzzzzzz 00000000 (empty) (no description set) Added 0 files, modified 1 files, removed 0 files There are unresolved conflicts at these paths: @@ -178,7 +178,7 @@ fn test_report_conflicts_with_divergent_commits() { insta::assert_snapshot!(stderr, @r###" Rebased 1 commits New conflicts appeared in these commits: - zsuskuln?? 37bb9c2f (conflict) C3 + zsuskuln?? 8cc7fde6 (conflict) C3 To resolve the conflicts, start by updating to it: jj new zsuskulnrvyr Then use `jj resolve`, or edit the conflict markers in the file directly. @@ -194,7 +194,7 @@ fn test_report_conflicts_with_divergent_commits() { insta::assert_snapshot!(stderr, @r###" Rebased 1 commits Existing conflicts were resolved or abandoned from these commits: - zsuskuln hidden 33752e7e (conflict) C2 + zsuskuln hidden b15416ac (conflict) C2 Working copy now at: zsuskuln?? 24f79296 C2 Parent commit : kkmpptxz 9ce42c2a B Added 0 files, modified 1 files, removed 0 files @@ -208,6 +208,6 @@ fn test_report_conflicts_with_divergent_commits() { insta::assert_snapshot!(stderr, @r###" Rebased 1 commits Existing conflicts were resolved or abandoned from these commits: - zsuskuln hidden 37bb9c2f (conflict) C3 + zsuskuln hidden 8cc7fde6 (conflict) C3 "###); } diff --git a/cli/tests/test_resolve_command.rs b/cli/tests/test_resolve_command.rs index 94b01d728..02ea98883 100644 --- a/cli/tests/test_resolve_command.rs +++ b/cli/tests/test_resolve_command.rs @@ -223,13 +223,13 @@ fn test_resolution() { insta::assert_snapshot!(stderr, @r###" Resolving conflicts in: file New conflicts appeared in these commits: - vruxwmqv 8144e92d conflict | (conflict) conflict + vruxwmqv 7699b9c3 conflict | (conflict) conflict To resolve the conflicts, start by updating to it: jj new vruxwmqvtpmx Then use `jj resolve`, or edit the conflict markers in the file directly. Once the conflicts are resolved, you may want inspect the result with `jj diff`. Then run `jj squash` to move the resolution into the conflicted commit. - Working copy now at: vruxwmqv 8144e92d conflict | (conflict) conflict + Working copy now at: vruxwmqv 7699b9c3 conflict | (conflict) conflict Parent commit : zsuskuln aa493daf a | a Parent commit : royxmykx db6a4daf b | b Added 0 files, modified 1 files, removed 0 files @@ -694,13 +694,13 @@ fn test_multiple_conflicts() { insta::assert_snapshot!(stderr, @r###" Resolving conflicts in: another_file New conflicts appeared in these commits: - vruxwmqv 1e22a8e4 conflict | (conflict) conflict + vruxwmqv 6a90e546 conflict | (conflict) conflict To resolve the conflicts, start by updating to it: jj new vruxwmqvtpmx Then use `jj resolve`, or edit the conflict markers in the file directly. Once the conflicts are resolved, you may want inspect the result with `jj diff`. Then run `jj squash` to move the resolution into the conflicted commit. - Working copy now at: vruxwmqv 1e22a8e4 conflict | (conflict) conflict + Working copy now at: vruxwmqv 6a90e546 conflict | (conflict) conflict Parent commit : zsuskuln de7553ef a | a Parent commit : royxmykx f68bc2f0 b | b Added 0 files, modified 1 files, removed 0 files diff --git a/cli/tests/test_restore_command.rs b/cli/tests/test_restore_command.rs index 6bc86a5b6..6a352e3a5 100644 --- a/cli/tests/test_restore_command.rs +++ b/cli/tests/test_restore_command.rs @@ -62,13 +62,13 @@ fn test_restore() { Created rlvkpnrz e25100af (empty) (no description set) Rebased 1 descendant commits New conflicts appeared in these commits: - kkmpptxz 761deaef (conflict) (no description set) + kkmpptxz 4906178a (conflict) (no description set) To resolve the conflicts, start by updating to it: jj new kkmpptxzrspx Then use `jj resolve`, or edit the conflict markers in the file directly. Once the conflicts are resolved, you may want inspect the result with `jj diff`. Then run `jj squash` to move the resolution into the conflicted commit. - Working copy now at: kkmpptxz 761deaef (conflict) (no description set) + Working copy now at: kkmpptxz 4906178a (conflict) (no description set) Parent commit : rlvkpnrz e25100af (empty) (no description set) Added 0 files, modified 1 files, removed 0 files There are unresolved conflicts at these paths: @@ -199,8 +199,8 @@ fn test_restore_conflicted_merge() { let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["restore", "file"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" - Created vruxwmqv 0817af7e conflict | (conflict) (empty) conflict - Working copy now at: vruxwmqv 0817af7e conflict | (conflict) (empty) conflict + Created vruxwmqv 126facb5 conflict | (conflict) (empty) conflict + Working copy now at: vruxwmqv 126facb5 conflict | (conflict) (empty) conflict Parent commit : zsuskuln aa493daf a | a Parent commit : royxmykx db6a4daf b | b Added 0 files, modified 1 files, removed 0 files @@ -240,8 +240,8 @@ fn test_restore_conflicted_merge() { let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["restore"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" - Created vruxwmqv da925083 conflict | (conflict) (empty) conflict - Working copy now at: vruxwmqv da925083 conflict | (conflict) (empty) conflict + Created vruxwmqv b553ebcf conflict | (conflict) (empty) conflict + Working copy now at: vruxwmqv b553ebcf conflict | (conflict) (empty) conflict Parent commit : zsuskuln aa493daf a | a Parent commit : royxmykx db6a4daf b | b Added 0 files, modified 1 files, removed 0 files diff --git a/cli/tests/test_squash_command.rs b/cli/tests/test_squash_command.rs index d640f199f..18a965b2b 100644 --- a/cli/tests/test_squash_command.rs +++ b/cli/tests/test_squash_command.rs @@ -635,20 +635,20 @@ fn test_squash_from_multiple() { insta::assert_snapshot!(stderr, @r###" Rebased 2 descendant commits New conflicts appeared in these commits: - yqosqzyt d5401742 d | (conflict) (no description set) + yqosqzyt 50bd7d24 d | (conflict) (no description set) To resolve the conflicts, start by updating to it: jj new yqosqzytrlsw Then use `jj resolve`, or edit the conflict markers in the file directly. Once the conflicts are resolved, you may want inspect the result with `jj diff`. Then run `jj squash` to move the resolution into the conflicted commit. - Working copy now at: kpqxywon cc9f4cad f | (no description set) - Parent commit : yostqsxw 9f25b62d e | (no description set) + Working copy now at: kpqxywon dd653e49 f | (no description set) + Parent commit : yostqsxw e40f2544 e | (no description set) "###); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ cc9f4cad1a29 f - ◉ 9f25b62ddffc e + @ dd653e494199 f + ◉ e40f2544ad31 e ├─╮ - ◉ │ d54017421f3f d + ◉ │ 50bd7d246d8e d ├─╯ ◉ 37941ee54ace a b c ◉ 000000000000 @@ -761,23 +761,23 @@ fn test_squash_from_multiple_partial() { insta::assert_snapshot!(stderr, @r###" Rebased 2 descendant commits New conflicts appeared in these commits: - yqosqzyt 13468b54 d | (conflict) (no description set) + yqosqzyt 85d3ae29 d | (conflict) (no description set) To resolve the conflicts, start by updating to it: jj new yqosqzytrlsw Then use `jj resolve`, or edit the conflict markers in the file directly. Once the conflicts are resolved, you may want inspect the result with `jj diff`. Then run `jj squash` to move the resolution into the conflicted commit. - Working copy now at: kpqxywon 8aaa7910 f | (no description set) - Parent commit : yostqsxw 5aad25ea e | (no description set) + Working copy now at: kpqxywon 97861bbf f | (no description set) + Parent commit : yostqsxw 2dbaf4e8 e | (no description set) "###); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ 8aaa79109163 f - ◉ 5aad25eae5aa e + @ 97861bbf7ae5 f + ◉ 2dbaf4e8c7f7 e ├─┬─╮ │ │ ◉ ba60ddff2d41 b │ ◉ │ 8ef5a315bf7d c │ ├─╯ - ◉ │ 13468b546ba3 d + ◉ │ 85d3ae290b9b d ├─╯ ◉ 47a1e795d146 a ◉ 000000000000 diff --git a/cli/tests/test_tree_level_conflicts.rs b/cli/tests/test_tree_level_conflicts.rs index d1c1369d0..c5608fc99 100644 --- a/cli/tests/test_tree_level_conflicts.rs +++ b/cli/tests/test_tree_level_conflicts.rs @@ -56,7 +56,7 @@ fn test_enable_tree_level_conflicts() { // non-empty let stdout = test_env.jj_cmd_success(&repo_path, &["log"]); insta::assert_snapshot!(stdout, @r###" - @ mzvwutvl test.user@example.com 2001-02-03 08:05:13 51f1748d conflict + @ mzvwutvl test.user@example.com 2001-02-03 08:05:13 ada1f5f1 conflict │ (no description set) ◉ zsuskuln test.user@example.com 2001-02-03 08:05:10 5100e4e1 conflict ├─╮ (empty) merge diff --git a/cli/tests/test_workspaces.rs b/cli/tests/test_workspaces.rs index 4937f481a..7f4d54203 100644 --- a/cli/tests/test_workspaces.rs +++ b/cli/tests/test_workspaces.rs @@ -321,7 +321,7 @@ fn test_workspaces_conflicting_edits() { "###); insta::assert_snapshot!(get_log_output(&test_env, &secondary_path), @r###" - ◉ b0b43f24d501 (divergent) + ◉ 92498bf020d4 (divergent) │ ◉ fe8f41ed01d6 default@ ├─╯ │ @ a1896a17282f secondary@ (divergent) @@ -333,7 +333,7 @@ fn test_workspaces_conflicting_edits() { let stdout = get_log_output(&test_env, &secondary_path); assert!(!stdout.starts_with("The working copy is stale")); insta::assert_snapshot!(stdout, @r###" - ◉ b0b43f24d501 (divergent) + ◉ 92498bf020d4 (divergent) │ ◉ fe8f41ed01d6 default@ ├─╯ │ @ a1896a17282f secondary@ (divergent) diff --git a/lib/src/git_backend.rs b/lib/src/git_backend.rs index ad5380f2e..fdefd629d 100644 --- a/lib/src/git_backend.rs +++ b/lib/src/git_backend.rs @@ -1239,7 +1239,7 @@ fn write_tree_conflict( conflict: &Merge, ) -> Result { // Tree entries to be written must be sorted by Entry::filename(). - let entries = itertools::chain( + let mut entries = itertools::chain( conflict .removes() .enumerate() @@ -1254,8 +1254,32 @@ fn write_tree_conflict( filename: name.into(), oid: tree_id.as_bytes().try_into().unwrap(), }) - .sorted_unstable() - .collect(); + .collect_vec(); + let readme_id = repo + .write_blob( + r#"This commit was made by jj, https://github.com/martinvonz/jj. +The commit contains file conflicts, and therefore looks wrong when used with plain +Git or other tools that are unfamiliar with jj. + +The .jjconflict-* directories represent the different inputs to the conflict. +For details, see +https://martinvonz.github.io/jj/prerelease/git-compatibility/#format-mapping-details + +If you see this file in your working copy, it probably means that you used a +regular `git` command to check out a conflicted commit. Use `jj abandon` to +recover. +"#, + ) + .map_err(|err| { + BackendError::Other(format!("Failed to write README for conflict tree: {err}").into()) + })? + .detach(); + entries.push(gix::objs::tree::Entry { + mode: gix::object::tree::EntryKind::Blob.into(), + filename: "README".into(), + oid: readme_id, + }); + entries.sort_unstable(); let id = repo .write_object(gix::objs::Tree { entries }) .map_err(|err| BackendError::WriteObject { @@ -1754,7 +1778,10 @@ mod tests { .find_commit(Oid::from_bytes(read_commit_id.as_bytes()).unwrap()) .unwrap(); let git_tree = git_repo.find_tree(git_commit.tree_id()).unwrap(); - assert!(git_tree.iter().all(|entry| entry.filemode() == 0o040000)); + assert!(git_tree + .iter() + .filter(|entry| entry.name() != Some("README")) + .all(|entry| entry.filemode() == 0o040000)); let mut iter = git_tree.iter(); let entry = iter.next().unwrap(); assert_eq!(entry.name(), Some(".jjconflict-base-0")); @@ -1786,6 +1813,9 @@ mod tests { entry.id().as_bytes(), root_tree.get_add(2).unwrap().as_bytes() ); + let entry = iter.next().unwrap(); + assert_eq!(entry.name(), Some("README")); + assert_eq!(entry.filemode(), 0o100644); assert!(iter.next().is_none()); // When writing a single tree using the new format, it's represented by a