Skip to content

Commit

Permalink
git_backend: write trees involved in conflict in git commit header
Browse files Browse the repository at this point in the history
We haven't used custom Git commit headers for two main reasons:

1. I don't want commits created by jj to be different from any other
   commits. I don't want Git projects to get annoyed by such commit
   and reject them.

2. I've been concerned that tools don't know how to handle such
   headers, perhaps even resulting in crashes.

The first argument doesn't apply to commits with conflicts because
such commits would never be accepted by a project whether or not they
use custom commit headers. The second argument is less relevant for
conflicted commits because most tools will be confused by such commits
anyway.

Storing conflict information in commit headers means that we can
transfer them via the regular Git wire protocol. We already include
the tree objects nested inside the root-level tree, so they will also
be transferred.

So, let's start by writing the information redundantly to the commit
header and to the existing storage. That way we can roll it back if we
realize there's a problem with using commit headers.
  • Loading branch information
martinvonz committed Mar 11, 2024
1 parent ea5a208 commit 4d42604
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 80 deletions.
4 changes: 2 additions & 2 deletions cli/tests/test_chmod_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,13 @@ fn test_chmod_file_dir_deletion_conflicts() {
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
New conflicts appeared in these commits:
kmkuslsw 4cc432b5 file_deletion | (conflict) file_deletion
kmkuslsw b4c38719 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 4cc432b5 file_deletion | (conflict) file_deletion
Working copy now at: kmkuslsw b4c38719 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
Expand Down
6 changes: 3 additions & 3 deletions cli/tests/test_diffedit_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 2b5202ae (conflict) merge
Created royxmykx b90654a0 (conflict) merge
Rebased 1 descendant commits
Working copy now at: yqosqzyt 23b1fe1b (conflict) (empty) (no description set)
Parent commit : royxmykx 2b5202ae (conflict) merge
Working copy now at: yqosqzyt 1de824f2 (conflict) (empty) (no description set)
Parent commit : royxmykx b90654a0 (conflict) merge
Added 0 files, modified 0 files, removed 1 files
"###);
let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "-s", "-r", "@-"]);
Expand Down
2 changes: 1 addition & 1 deletion cli/tests/test_git_push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,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 1973d389875c since it has conflicts
Error: Won't push commit d9ca3146ade7 since it has conflicts
"###);
}

Expand Down
36 changes: 18 additions & 18 deletions cli/tests/test_immutable_commits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ fn test_rewrite_immutable_commands() {
insta::assert_snapshot!(stdout, @r###"
@ yqosqzyt [email protected] 2001-02-03 04:05:13.000 +07:00 3f89addf
│ (empty) (no description set)
│ ◉ mzvwutvl [email protected] 2001-02-03 04:05:11.000 +07:00 main 16ca9d80 conflict
│ ◉ mzvwutvl [email protected] 2001-02-03 04:05:11.000 +07:00 main 3d14df18 conflict
╭─┤ (empty) merge
│ │
│ ~
Expand All @@ -113,61 +113,61 @@ fn test_rewrite_immutable_commands() {
// abandon
let stderr = test_env.jj_cmd_failure(&repo_path, &["abandon", "main"]);
insta::assert_snapshot!(stderr, @r###"
Error: Commit 16ca9d800b08 is immutable
Error: Commit 3d14df18607e 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 16ca9d800b08 is immutable
Error: Commit 3d14df18607e 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 16ca9d800b08 is immutable
Error: Commit 3d14df18607e 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 16ca9d800b08 is immutable
Error: Commit 3d14df18607e 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 16ca9d800b08 is immutable
Error: Commit 3d14df18607e is immutable
Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`.
"###);
// move --from
let stderr = test_env.jj_cmd_failure(&repo_path, &["move", "--from=main"]);
insta::assert_snapshot!(stderr, @r###"
Error: Commit 16ca9d800b08 is immutable
Error: Commit 3d14df18607e is immutable
Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`.
"###);
// move --to
let stderr = test_env.jj_cmd_failure(&repo_path, &["move", "--to=main"]);
insta::assert_snapshot!(stderr, @r###"
Error: Commit 16ca9d800b08 is immutable
Error: Commit 3d14df18607e 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 16ca9d800b08 is immutable
Error: Commit 3d14df18607e 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 16ca9d800b08 is immutable
Error: Commit 3d14df18607e 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 16ca9d800b08 is immutable
Error: Commit 3d14df18607e is immutable
Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`.
"###);
// rebase -b
Expand All @@ -179,43 +179,43 @@ 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 16ca9d800b08 is immutable
Error: Commit 3d14df18607e 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 16ca9d800b08 is immutable
Error: Commit 3d14df18607e 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 16ca9d800b08 is immutable
Error: Commit 3d14df18607e 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 16ca9d800b08 is immutable
Error: Commit 3d14df18607e 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 16ca9d800b08 is immutable
Error: Commit 3d14df18607e is immutable
Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`.
"###);
// squash
let stderr = test_env.jj_cmd_failure(&repo_path, &["squash", "-r=main"]);
insta::assert_snapshot!(stderr, @r###"
Error: Commit 16ca9d800b08 is immutable
Error: Commit 3d14df18607e is immutable
Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`.
"###);
// unsquash
let stderr = test_env.jj_cmd_failure(&repo_path, &["unsquash", "-r=main"]);
insta::assert_snapshot!(stderr, @r###"
Error: Commit 16ca9d800b08 is immutable
Error: Commit 3d14df18607e is immutable
Hint: Configure the set of immutable commits via `revset-aliases.immutable_heads()`.
"###);
}
14 changes: 7 additions & 7 deletions cli/tests/test_obslog_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn test_obslog_with_or_without_diff() {
insta::assert_snapshot!(stdout, @r###"
@ rlvkpnrz [email protected] 2001-02-03 04:05:10.000 +07:00 66b42ad3
│ my description
◉ rlvkpnrz hidden [email protected] 2001-02-03 04:05:09.000 +07:00 5f4634a5 conflict
◉ rlvkpnrz hidden [email protected] 2001-02-03 04:05:09.000 +07:00 ebc23d4b conflict
│ my description
◉ rlvkpnrz hidden [email protected] 2001-02-03 04:05:09.000 +07:00 6fbba7bc
│ my description
Expand All @@ -44,11 +44,11 @@ fn test_obslog_with_or_without_diff() {
insta::assert_snapshot!(stdout, @r###"
@ rlvkpnrz [38;5;[email protected] 2001-02-03 04:05:10.000 +07:00 66b42ad3
│ my description
◉ [1m[39mr[0m[38;5;8mlvkpnrz[39m hidden [38;5;[email protected][39m [38;5;6m2001-02-03 04:05:09.000 +07:00[39m [1m[38;5;4m5[0m[38;5;8mf4634a5[39m [38;5;1mconflict[39m
◉ [1m[39mr[0m[38;5;8mlvkpnrz[39m hidden [38;5;[email protected][39m [38;5;6m2001-02-03 04:05:09.000 +07:00[39m [1m[38;5;4meb[0m[38;5;8mc23d4b[39m [38;5;1mconflict[39m
│ my description
◉ rlvkpnrz hidden [38;5;[email protected] 2001-02-03 04:05:09.000 +07:00 6fbba7bc
│ my description
◉ [1m[39mr[0m[38;5;8mlvkpnrz[39m hidden [38;5;[email protected][39m [38;5;6m2001-02-03 04:05:08.000 +07:00[39m [1m[38;5;4me[0m[38;5;8mac0d0da[39m
◉ [1m[39mr[0m[38;5;8mlvkpnrz[39m hidden [38;5;[email protected][39m [38;5;6m2001-02-03 04:05:08.000 +07:00[39m [1m[38;5;4mea[0m[38;5;8mc0d0da[39m
(empty) my description
"###);

Expand All @@ -66,7 +66,7 @@ fn test_obslog_with_or_without_diff() {
│ 5 : foo
│ 6 : bar
│ 7 : >>>>>>>
◉ rlvkpnrz hidden [email protected] 2001-02-03 04:05:09.000 +07:00 5f4634a5 conflict
◉ rlvkpnrz hidden [email protected] 2001-02-03 04:05:09.000 +07:00 ebc23d4b conflict
│ my description
◉ rlvkpnrz hidden [email protected] 2001-02-03 04:05:09.000 +07:00 6fbba7bc
│ my description
Expand All @@ -84,7 +84,7 @@ fn test_obslog_with_or_without_diff() {
insta::assert_snapshot!(stdout, @r###"
@ rlvkpnrz [email protected] 2001-02-03 04:05:10.000 +07:00 66b42ad3
│ my description
◉ rlvkpnrz hidden [email protected] 2001-02-03 04:05:09.000 +07:00 5f4634a5 conflict
◉ rlvkpnrz hidden [email protected] 2001-02-03 04:05:09.000 +07:00 ebc23d4b conflict
│ my description
"###);

Expand All @@ -93,7 +93,7 @@ fn test_obslog_with_or_without_diff() {
insta::assert_snapshot!(stdout, @r###"
rlvkpnrz [email protected] 2001-02-03 04:05:10.000 +07:00 66b42ad3
my description
rlvkpnrz hidden [email protected] 2001-02-03 04:05:09.000 +07:00 5f4634a5 conflict
rlvkpnrz hidden [email protected] 2001-02-03 04:05:09.000 +07:00 ebc23d4b conflict
my description
rlvkpnrz hidden [email protected] 2001-02-03 04:05:09.000 +07:00 6fbba7bc
my description
Expand All @@ -119,7 +119,7 @@ fn test_obslog_with_or_without_diff() {
-bar
->>>>>>>
+resolved
rlvkpnrz hidden [email protected] 2001-02-03 04:05:09.000 +07:00 5f4634a5 conflict
rlvkpnrz hidden [email protected] 2001-02-03 04:05:09.000 +07:00 ebc23d4b conflict
my description
rlvkpnrz hidden [email protected] 2001-02-03 04:05:09.000 +07:00 6fbba7bc
my description
Expand Down
52 changes: 26 additions & 26 deletions cli/tests/test_repo_change_report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ fn test_report_conflicts() {
insta::assert_snapshot!(stderr, @r###"
Rebased 3 commits
New conflicts appeared in these commits:
kkmpptxz a2593769 (conflict) C
rlvkpnrz 727244df (conflict) B
kkmpptxz 9baab11e (conflict) C
rlvkpnrz de73196a (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 30928080 (conflict) (empty) (no description set)
Parent commit : kkmpptxz a2593769 (conflict) C
Working copy now at: zsuskuln 7dc9bf15 (conflict) (empty) (no description set)
Parent commit : kkmpptxz 9baab11e (conflict) C
Added 0 files, modified 1 files, removed 0 files
"###);

Expand All @@ -50,8 +50,8 @@ fn test_report_conflicts() {
insta::assert_snapshot!(stderr, @r###"
Rebased 3 commits
Existing conflicts were resolved or abandoned from these commits:
kkmpptxz hidden a2593769 (conflict) C
rlvkpnrz hidden 727244df (conflict) B
kkmpptxz hidden 9baab11e (conflict) C
rlvkpnrz hidden de73196a (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
Expand All @@ -64,33 +64,33 @@ 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 9df65f08 (conflict) B
kkmpptxz 7530822d (conflict) C
rlvkpnrz e93270ab (conflict) B
kkmpptxz 4f0eeaa6 (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 203be58b (conflict) (empty) (no description set)
Parent commit : kkmpptxz 7530822d (conflict) C
Working copy now at: zsuskuln 83074dac (conflict) (empty) (no description set)
Parent commit : kkmpptxz 4f0eeaa6 (conflict) C
Added 0 files, modified 1 files, removed 0 files
"###);

// Resolve one of the conflicts by (mostly) following the instructions
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 406f84d0 (conflict) (empty) (no description set)
Parent commit : rlvkpnrz 9df65f08 (conflict) B
Working copy now at: vruxwmqv 2ec0b4c3 (conflict) (empty) (no description set)
Parent commit : rlvkpnrz e93270ab (conflict) B
Added 0 files, modified 1 files, removed 0 files
"###);
std::fs::write(repo_path.join("file"), "resolved\n").unwrap();
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["squash"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Existing conflicts were resolved or abandoned from these commits:
rlvkpnrz hidden 9df65f08 (conflict) B
rlvkpnrz hidden e93270ab (conflict) B
Working copy now at: yostqsxw 8e160bc4 (empty) (no description set)
Parent commit : rlvkpnrz c5319490 B
"###);
Expand Down Expand Up @@ -118,16 +118,16 @@ fn test_report_conflicts_with_divergent_commits() {
Concurrent modification detected, resolving automatically.
Rebased 3 commits
New conflicts appeared in these commits:
zsuskuln?? 76c40a95 (conflict) C3
zsuskuln?? e92329f2 (conflict) C2
kkmpptxz aed319ec (conflict) B
zsuskuln?? 94be9a4c (conflict) C3
zsuskuln?? cdae4322 (conflict) C2
kkmpptxz b76d6a88 (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?? e92329f2 (conflict) C2
Parent commit : kkmpptxz aed319ec (conflict) B
Working copy now at: zsuskuln?? cdae4322 (conflict) C2
Parent commit : kkmpptxz b76d6a88 (conflict) B
Added 0 files, modified 1 files, removed 0 files
"###);

Expand All @@ -136,9 +136,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 76c40a95 (conflict) C3
zsuskuln hidden e92329f2 (conflict) C2
kkmpptxz hidden aed319ec (conflict) B
zsuskuln hidden 94be9a4c (conflict) C3
zsuskuln hidden cdae4322 (conflict) C2
kkmpptxz hidden b76d6a88 (conflict) B
Working copy now at: zsuskuln?? 9c33e9a9 C2
Parent commit : kkmpptxz 9ce42c2a B
Added 0 files, modified 1 files, removed 0 files
Expand All @@ -151,13 +151,13 @@ fn test_report_conflicts_with_divergent_commits() {
insta::assert_snapshot!(stderr, @r###"
Rebased 1 commits
New conflicts appeared in these commits:
zsuskuln?? 0d6cb6b7 (conflict) C2
zsuskuln?? 33752e7e (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?? 0d6cb6b7 (conflict) C2
Working copy now at: zsuskuln?? 33752e7e (conflict) C2
Parent commit : zzzzzzzz 00000000 (empty) (no description set)
Added 0 files, modified 1 files, removed 0 files
"###);
Expand All @@ -168,7 +168,7 @@ fn test_report_conflicts_with_divergent_commits() {
insta::assert_snapshot!(stderr, @r###"
Rebased 1 commits
New conflicts appeared in these commits:
zsuskuln?? 9652a362 (conflict) C3
zsuskuln?? 37bb9c2f (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.
Expand All @@ -184,7 +184,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 0d6cb6b7 (conflict) C2
zsuskuln hidden 33752e7e (conflict) C2
Working copy now at: zsuskuln?? 24f79296 C2
Parent commit : kkmpptxz 9ce42c2a B
Added 0 files, modified 1 files, removed 0 files
Expand All @@ -198,6 +198,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 9652a362 (conflict) C3
zsuskuln hidden 37bb9c2f (conflict) C3
"###);
}
Loading

0 comments on commit 4d42604

Please sign in to comment.