just playing with tangled
at ig/vimdiffwarn 251 lines 9.7 kB view raw
1// Copyright 2022 The Jujutsu Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15use itertools::Itertools as _; 16 17use crate::common::CommandOutput; 18use crate::common::TestEnvironment; 19use crate::common::TestWorkDir; 20 21#[test] 22fn test_concurrent_operation_divergence() { 23 let test_env = TestEnvironment::default(); 24 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 25 let work_dir = test_env.work_dir("repo"); 26 27 work_dir.run_jj(["describe", "-m", "message 1"]).success(); 28 work_dir 29 .run_jj(["describe", "-m", "message 2", "--at-op", "@-"]) 30 .success(); 31 32 // "--at-op=@" disables op heads merging, and prints head operation ids. 33 let output = work_dir.run_jj(["op", "log", "--at-op=@"]); 34 insta::assert_snapshot!(output, @r#" 35 ------- stderr ------- 36 Error: The "@" expression resolved to more than one operation 37 Hint: Try specifying one of the operations by ID: 0162305507cc, d74dff64472e 38 [EOF] 39 [exit status: 1] 40 "#); 41 42 // "op log --at-op" should work without merging the head operations 43 let output = work_dir.run_jj(["op", "log", "--at-op=d74dff64472e"]); 44 insta::assert_snapshot!(output, @r" 45 @ d74dff64472e test-username@host.example.com 2001-02-03 04:05:09.000 +07:00 - 2001-02-03 04:05:09.000 +07:00 46 │ describe commit 230dd059e1b059aefc0da06a2e5a7dbf22362f22 47 │ args: jj describe -m 'message 2' --at-op @- 48 ○ eac759b9ab75 test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00 49 │ add workspace 'default' 50 ○ 000000000000 root() 51 [EOF] 52 "); 53 54 // We should be informed about the concurrent modification 55 let output = work_dir.run_jj(["log", "-T", "description"]); 56 insta::assert_snapshot!(output, @r" 57 @ message 1 58 │ ○ message 2 59 ├─╯ 60 61 [EOF] 62 ------- stderr ------- 63 Concurrent modification detected, resolving automatically. 64 [EOF] 65 "); 66} 67 68#[test] 69fn test_concurrent_operations_auto_rebase() { 70 let test_env = TestEnvironment::default(); 71 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 72 let work_dir = test_env.work_dir("repo"); 73 74 work_dir.write_file("file", "contents"); 75 work_dir.run_jj(["describe", "-m", "initial"]).success(); 76 let output = work_dir.run_jj(["op", "log"]); 77 insta::assert_snapshot!(output, @r" 78 @ c62ace5c0522 test-username@host.example.com 2001-02-03 04:05:08.000 +07:00 - 2001-02-03 04:05:08.000 +07:00 79 │ describe commit 4e8f9d2be039994f589b4e57ac5e9488703e604d 80 │ args: jj describe -m initial 81 ○ 82d32fc68fc3 test-username@host.example.com 2001-02-03 04:05:08.000 +07:00 - 2001-02-03 04:05:08.000 +07:00 82 │ snapshot working copy 83 │ args: jj describe -m initial 84 ○ eac759b9ab75 test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00 85 │ add workspace 'default' 86 ○ 000000000000 root() 87 [EOF] 88 "); 89 let op_id_hex = output.stdout.raw()[3..15].to_string(); 90 91 work_dir.run_jj(["describe", "-m", "rewritten"]).success(); 92 work_dir 93 .run_jj(["new", "--at-op", &op_id_hex, "-m", "new child"]) 94 .success(); 95 96 // We should be informed about the concurrent modification 97 let output = get_log_output(&work_dir); 98 insta::assert_snapshot!(output, @r" 99 ○ db141860e12c2d5591c56fde4fc99caf71cec418 new child 100 @ 07c3641e495cce57ea4ca789123b52f421c57aa2 rewritten 101 ◆ 0000000000000000000000000000000000000000 102 [EOF] 103 ------- stderr ------- 104 Concurrent modification detected, resolving automatically. 105 Rebased 1 descendant commits onto commits rewritten by other operation 106 [EOF] 107 "); 108} 109 110#[test] 111fn test_concurrent_operations_wc_modified() { 112 let test_env = TestEnvironment::default(); 113 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 114 let work_dir = test_env.work_dir("repo"); 115 116 work_dir.write_file("file", "contents\n"); 117 work_dir.run_jj(["describe", "-m", "initial"]).success(); 118 let output = work_dir.run_jj(["op", "log"]).success(); 119 let op_id_hex = output.stdout.raw()[3..15].to_string(); 120 121 work_dir 122 .run_jj(["new", "--at-op", &op_id_hex, "-m", "new child1"]) 123 .success(); 124 work_dir 125 .run_jj(["new", "--at-op", &op_id_hex, "-m", "new child2"]) 126 .success(); 127 work_dir.write_file("file", "modified\n"); 128 129 // We should be informed about the concurrent modification 130 let output = get_log_output(&work_dir); 131 insta::assert_snapshot!(output, @r" 132 @ 4eadcf3df11f46ef3d825c776496221cc8303053 new child1 133 │ ○ 68119f1643b7e3c301c5f7c2b6c9bf4ccba87379 new child2 134 ├─╯ 135 ○ 2ff7ae858a3a11837fdf9d1a76be295ef53f1bb3 initial 136 ◆ 0000000000000000000000000000000000000000 137 [EOF] 138 ------- stderr ------- 139 Concurrent modification detected, resolving automatically. 140 [EOF] 141 "); 142 let output = work_dir.run_jj(["diff", "--git"]); 143 insta::assert_snapshot!(output, @r" 144 diff --git a/file b/file 145 index 12f00e90b6..2e0996000b 100644 146 --- a/file 147 +++ b/file 148 @@ -1,1 +1,1 @@ 149 -contents 150 +modified 151 [EOF] 152 "); 153 154 // The working copy should be committed after merging the operations 155 let output = work_dir.run_jj(["op", "log", "-Tdescription"]); 156 insta::assert_snapshot!(output, @r" 157 @ snapshot working copy 158 ○ reconcile divergent operations 159 ├─╮ 160 ○ │ new empty commit 161 │ ○ new empty commit 162 ├─╯ 163 ○ describe commit 506f4ec3c2c62befa15fabc34ca9d4e6d7bef254 164 ○ snapshot working copy 165 ○ add workspace 'default' 166167 [EOF] 168 "); 169} 170 171#[test] 172fn test_concurrent_snapshot_wc_reloadable() { 173 let test_env = TestEnvironment::default(); 174 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 175 let work_dir = test_env.work_dir("repo"); 176 let op_heads_dir = work_dir 177 .root() 178 .join(".jj") 179 .join("repo") 180 .join("op_heads") 181 .join("heads"); 182 183 work_dir.write_file("base", ""); 184 work_dir.run_jj(["commit", "-m", "initial"]).success(); 185 186 // Create new commit and checkout it. 187 work_dir.write_file("child1", ""); 188 work_dir.run_jj(["commit", "-m", "new child1"]).success(); 189 190 let template = r#"id ++ "\n" ++ description ++ "\n" ++ tags"#; 191 let output = work_dir.run_jj(["op", "log", "-T", template]); 192 insta::assert_snapshot!(output, @r" 193 @ ec6bf266624bbaed55833a34ae62fa95c0e9efa651b94eb28846972da645845052dcdc8580332a5628849f23f48b9e99fc728dc3fb13106df8d0666d746f8b85 194 │ commit 554d22b2c43c1c47e279430197363e8daabe2fd6 195 │ args: jj commit -m 'new child1' 196 ○ 23858df860b789e8176a73c0eb21804e3f1848f26d68b70d234c004d08980c41499b6669042bca20fbc2543c437222a084c7cd473e91c7a9a095a02bf38544ab 197 │ snapshot working copy 198 │ args: jj commit -m 'new child1' 199 ○ e1db5fa988fc66e5cc0491b00c53fb93e25e730341c850cb42e1e0db0c76d2b4065005787563301b1d292c104f381918897f7deabeb92d2532f42ce75d3fe588 200 │ commit de71e09289762a65f80bb1c3dae2a949df6bcde7 201 │ args: jj commit -m initial 202 ○ 7de878155a459b7751097222132c935f9dcbb8f69a72b0f3a9036345a963010a553dc7c92964220128679ead72b087ca3aaf4ab9e20a221d1ffa4f9e92a32193 203 │ snapshot working copy 204 │ args: jj commit -m initial 205 ○ eac759b9ab75793fd3da96e60939fb48f2cd2b2a9c1f13ffe723cf620f3005b8d3e7e923634a07ea39513e4f2f360c87b9ad5d331cf90d7a844864b83b72eba1 206 │ add workspace 'default' 207 ○ 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 208 209 [EOF] 210 "); 211 let op_log_lines = output.stdout.raw().lines().collect_vec(); 212 let current_op_id = op_log_lines[0].split_once(" ").unwrap().1; 213 let previous_op_id = op_log_lines[6].split_once(" ").unwrap().1; 214 215 // Another process started from the "initial" operation, but snapshots after 216 // the "child1" checkout has been completed. 217 std::fs::rename( 218 op_heads_dir.join(current_op_id), 219 op_heads_dir.join(previous_op_id), 220 ) 221 .unwrap(); 222 work_dir.write_file("child2", ""); 223 let output = work_dir.run_jj(["describe", "-m", "new child2"]); 224 insta::assert_snapshot!(output, @r" 225 ------- stderr ------- 226 Working copy (@) now at: kkmpptxz 1795621b new child2 227 Parent commit (@-) : rlvkpnrz 86f54245 new child1 228 [EOF] 229 "); 230 231 // Since the repo can be reloaded before snapshotting, "child2" should be 232 // a child of "child1", not of "initial". 233 let template = r#"commit_id ++ " " ++ description"#; 234 let output = work_dir.run_jj(["log", "-T", template, "-s"]); 235 insta::assert_snapshot!(output, @r" 236 @ 1795621b54f4ebb435978b65d66bc0f90d8f20b6 new child2 237 │ A child2 238 ○ 86f54245e13f850f8275b5541e56da996b6a47b7 new child1 239 │ A child1 240 ○ 84f07f6bca2ffeddac84a8b09f60c6b81112375c initial 241 │ A base 242 ◆ 0000000000000000000000000000000000000000 243 [EOF] 244 "); 245} 246 247#[must_use] 248fn get_log_output(work_dir: &TestWorkDir) -> CommandOutput { 249 let template = r#"commit_id ++ " " ++ description"#; 250 work_dir.run_jj(["log", "-T", template]) 251}