just playing with tangled
1// Copyright 2024 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 std::fmt::Write as _;
16use std::path::{Path, PathBuf};
17
18use test_case::test_case;
19
20use crate::common::{strip_last_line, TestEnvironment};
21
22fn init_git_repo(git_repo_path: &Path, bare: bool) -> git2::Repository {
23 init_git_repo_with_opts(git_repo_path, git2::RepositoryInitOptions::new().bare(bare))
24}
25
26fn init_git_repo_with_opts(
27 git_repo_path: &Path,
28 opts: &git2::RepositoryInitOptions,
29) -> git2::Repository {
30 let git_repo = git2::Repository::init_opts(git_repo_path, opts).unwrap();
31 let git_blob_oid = git_repo.blob(b"some content").unwrap();
32 let mut git_tree_builder = git_repo.treebuilder(None).unwrap();
33 git_tree_builder
34 .insert("some-file", git_blob_oid, 0o100644)
35 .unwrap();
36 let git_tree_id = git_tree_builder.write().unwrap();
37 drop(git_tree_builder);
38 let git_tree = git_repo.find_tree(git_tree_id).unwrap();
39 let git_signature = git2::Signature::new(
40 "Git User",
41 "git.user@example.com",
42 &git2::Time::new(123, 60),
43 )
44 .unwrap();
45 git_repo
46 .commit(
47 Some("refs/heads/my-branch"),
48 &git_signature,
49 &git_signature,
50 "My commit message",
51 &git_tree,
52 &[],
53 )
54 .unwrap();
55 drop(git_tree);
56 git_repo.set_head("refs/heads/my-branch").unwrap();
57 git_repo
58}
59
60fn get_branch_output(test_env: &TestEnvironment, repo_path: &Path) -> String {
61 test_env.jj_cmd_success(repo_path, &["branch", "list", "--all-remotes"])
62}
63
64fn read_git_target(workspace_root: &Path) -> String {
65 let mut path = workspace_root.to_path_buf();
66 path.extend([".jj", "repo", "store", "git_target"]);
67 std::fs::read_to_string(path).unwrap()
68}
69
70#[test]
71fn test_git_init_internal() {
72 let test_env = TestEnvironment::default();
73 let (stdout, stderr) = test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
74 insta::assert_snapshot!(stdout, @"");
75 insta::assert_snapshot!(stderr, @r###"
76 Initialized repo in "repo"
77 "###);
78
79 let workspace_root = test_env.env_root().join("repo");
80 let jj_path = workspace_root.join(".jj");
81 let repo_path = jj_path.join("repo");
82 let store_path = repo_path.join("store");
83 assert!(workspace_root.is_dir());
84 assert!(jj_path.is_dir());
85 assert!(jj_path.join("working_copy").is_dir());
86 assert!(repo_path.is_dir());
87 assert!(store_path.is_dir());
88 assert!(store_path.join("git").is_dir());
89 assert_eq!(read_git_target(&workspace_root), "git");
90}
91
92#[test_case(false; "full")]
93#[test_case(true; "bare")]
94fn test_git_init_external(bare: bool) {
95 let test_env = TestEnvironment::default();
96 let git_repo_path = test_env.env_root().join("git-repo");
97 init_git_repo(&git_repo_path, bare);
98
99 let (stdout, stderr) = test_env.jj_cmd_ok(
100 test_env.env_root(),
101 &[
102 "git",
103 "init",
104 "repo",
105 "--git-repo",
106 git_repo_path.to_str().unwrap(),
107 ],
108 );
109 insta::allow_duplicates! {
110 insta::assert_snapshot!(stdout, @"");
111 insta::assert_snapshot!(stderr, @r###"
112 Done importing changes from the underlying Git repo.
113 Working copy now at: sqpuoqvx f6950fc1 (empty) (no description set)
114 Parent commit : mwrttmos 8d698d4a my-branch | My commit message
115 Added 1 files, modified 0 files, removed 0 files
116 Initialized repo in "repo"
117 "###);
118 }
119
120 let workspace_root = test_env.env_root().join("repo");
121 let jj_path = workspace_root.join(".jj");
122 let repo_path = jj_path.join("repo");
123 let store_path = repo_path.join("store");
124 assert!(workspace_root.is_dir());
125 assert!(jj_path.is_dir());
126 assert!(jj_path.join("working_copy").is_dir());
127 assert!(repo_path.is_dir());
128 assert!(store_path.is_dir());
129 let unix_git_target_file_contents = read_git_target(&workspace_root).replace('\\', "/");
130 if bare {
131 assert!(unix_git_target_file_contents.ends_with("/git-repo"));
132 } else {
133 assert!(unix_git_target_file_contents.ends_with("/git-repo/.git"));
134 }
135
136 // Check that the Git repo's HEAD got checked out
137 let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r", "@-"]);
138 insta::allow_duplicates! {
139 insta::assert_snapshot!(stdout, @r###"
140 ◉ mwrttmos git.user@example.com 1970-01-01 11:02:03 my-branch HEAD@git 8d698d4a
141 │ My commit message
142 ~
143 "###);
144 }
145}
146
147#[test]
148fn test_git_init_external_non_existent_directory() {
149 let test_env = TestEnvironment::default();
150 let stderr = test_env.jj_cmd_failure(
151 test_env.env_root(),
152 &["git", "init", "repo", "--git-repo", "non-existent"],
153 );
154 insta::assert_snapshot!(strip_last_line(&stderr), @r###"
155 Error: Failed to access the repository
156 Caused by:
157 1: Cannot access $TEST_ENV/non-existent
158 "###);
159}
160
161#[test]
162fn test_git_init_external_non_existent_git_directory() {
163 let test_env = TestEnvironment::default();
164 let workspace_root = test_env.env_root().join("repo");
165 let stderr = test_env.jj_cmd_failure(
166 test_env.env_root(),
167 &["git", "init", "repo", "--git-repo", "repo"],
168 );
169
170 insta::assert_snapshot!(&stderr, @r###"
171 Error: Failed to access the repository
172 Caused by:
173 1: Failed to open git repository
174 2: "$TEST_ENV/repo" does not appear to be a git repository
175 3: Missing HEAD at '.git/HEAD'
176 "###);
177 let jj_path = workspace_root.join(".jj");
178 assert!(!jj_path.exists());
179}
180
181#[test]
182fn test_git_init_colocated_via_git_repo_path() {
183 let test_env = TestEnvironment::default();
184 let workspace_root = test_env.env_root().join("repo");
185 init_git_repo(&workspace_root, false);
186 let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "init", "--git-repo", "."]);
187 insta::assert_snapshot!(stdout, @"");
188 insta::assert_snapshot!(stderr, @r###"
189 Done importing changes from the underlying Git repo.
190 Initialized repo in "."
191 "###);
192
193 let jj_path = workspace_root.join(".jj");
194 let repo_path = jj_path.join("repo");
195 let store_path = repo_path.join("store");
196 assert!(workspace_root.is_dir());
197 assert!(jj_path.is_dir());
198 assert!(jj_path.join("working_copy").is_dir());
199 assert!(repo_path.is_dir());
200 assert!(store_path.is_dir());
201 assert!(read_git_target(&workspace_root)
202 .replace('\\', "/")
203 .ends_with("../../../.git"));
204
205 // Check that the Git repo's HEAD got checked out
206 let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r", "@-"]);
207 insta::assert_snapshot!(stdout, @r###"
208 ◉ mwrttmos git.user@example.com 1970-01-01 11:02:03 my-branch HEAD@git 8d698d4a
209 │ My commit message
210 ~
211 "###);
212
213 // Check that the Git repo's HEAD moves
214 test_env.jj_cmd_ok(&workspace_root, &["new"]);
215 let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-r", "@-"]);
216 insta::assert_snapshot!(stdout, @r###"
217 ◉ sqpuoqvx test.user@example.com 2001-02-03 08:05:07 HEAD@git f61b77cd
218 │ (no description set)
219 ~
220 "###);
221}
222
223#[test]
224fn test_git_init_colocated_via_git_repo_path_gitlink() {
225 let test_env = TestEnvironment::default();
226 // <workspace_root>/.git -> <git_repo_path>
227 let git_repo_path = test_env.env_root().join("git-repo");
228 let workspace_root = test_env.env_root().join("repo");
229 init_git_repo_with_opts(
230 &git_repo_path,
231 git2::RepositoryInitOptions::new().workdir_path(&workspace_root),
232 );
233 assert!(workspace_root.join(".git").is_file());
234 let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "init", "--git-repo", "."]);
235 insta::assert_snapshot!(stdout, @"");
236 insta::assert_snapshot!(stderr, @r###"
237 Done importing changes from the underlying Git repo.
238 Initialized repo in "."
239 "###);
240 insta::assert_snapshot!(read_git_target(&workspace_root), @"../../../.git");
241
242 // Check that the Git repo's HEAD got checked out
243 let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-r", "@-"]);
244 insta::assert_snapshot!(stdout, @r###"
245 ◉ mwrttmos git.user@example.com 1970-01-01 11:02:03 my-branch HEAD@git 8d698d4a
246 │ My commit message
247 ~
248 "###);
249
250 // Check that the Git repo's HEAD moves
251 test_env.jj_cmd_ok(&workspace_root, &["new"]);
252 let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-r", "@-"]);
253 insta::assert_snapshot!(stdout, @r###"
254 ◉ sqpuoqvx test.user@example.com 2001-02-03 08:05:07 HEAD@git f61b77cd
255 │ (no description set)
256 ~
257 "###);
258}
259
260#[cfg(unix)]
261#[test]
262fn test_git_init_colocated_via_git_repo_path_symlink_directory() {
263 let test_env = TestEnvironment::default();
264 // <workspace_root>/.git -> <git_repo_path>
265 let git_repo_path = test_env.env_root().join("git-repo");
266 let workspace_root = test_env.env_root().join("repo");
267 init_git_repo(&git_repo_path, false);
268 std::fs::create_dir(&workspace_root).unwrap();
269 std::os::unix::fs::symlink(git_repo_path.join(".git"), workspace_root.join(".git")).unwrap();
270 let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "init", "--git-repo", "."]);
271 insta::assert_snapshot!(stdout, @"");
272 insta::assert_snapshot!(stderr, @r###"
273 Done importing changes from the underlying Git repo.
274 Initialized repo in "."
275 "###);
276 insta::assert_snapshot!(read_git_target(&workspace_root), @"../../../.git");
277
278 // Check that the Git repo's HEAD got checked out
279 let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-r", "@-"]);
280 insta::assert_snapshot!(stdout, @r###"
281 ◉ mwrttmos git.user@example.com 1970-01-01 11:02:03 my-branch HEAD@git 8d698d4a
282 │ My commit message
283 ~
284 "###);
285
286 // Check that the Git repo's HEAD moves
287 test_env.jj_cmd_ok(&workspace_root, &["new"]);
288 let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-r", "@-"]);
289 insta::assert_snapshot!(stdout, @r###"
290 ◉ sqpuoqvx test.user@example.com 2001-02-03 08:05:07 HEAD@git f61b77cd
291 │ (no description set)
292 ~
293 "###);
294}
295
296#[cfg(unix)]
297#[test]
298fn test_git_init_colocated_via_git_repo_path_symlink_directory_without_bare_config() {
299 let test_env = TestEnvironment::default();
300 // <workspace_root>/.git -> <git_repo_path>
301 let git_repo_path = test_env.env_root().join("git-repo.git");
302 let workspace_root = test_env.env_root().join("repo");
303 // Set up git repo without core.bare set (as the "repo" tool would do.)
304 // The core.bare config is deduced from the directory name.
305 let git_repo = init_git_repo(&workspace_root, false);
306 git_repo.config().unwrap().remove("core.bare").unwrap();
307 std::fs::rename(workspace_root.join(".git"), &git_repo_path).unwrap();
308 std::os::unix::fs::symlink(&git_repo_path, workspace_root.join(".git")).unwrap();
309 let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "init", "--git-repo", "."]);
310 insta::assert_snapshot!(stdout, @"");
311 insta::assert_snapshot!(stderr, @r###"
312 Done importing changes from the underlying Git repo.
313 Initialized repo in "."
314 "###);
315 insta::assert_snapshot!(read_git_target(&workspace_root), @"../../../.git");
316
317 // Check that the Git repo's HEAD got checked out
318 let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-r", "@-"]);
319 insta::assert_snapshot!(stdout, @r###"
320 ◉ mwrttmos git.user@example.com 1970-01-01 11:02:03 my-branch HEAD@git 8d698d4a
321 │ My commit message
322 ~
323 "###);
324
325 // Check that the Git repo's HEAD moves
326 test_env.jj_cmd_ok(&workspace_root, &["new"]);
327 let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-r", "@-"]);
328 insta::assert_snapshot!(stdout, @r###"
329 ◉ sqpuoqvx test.user@example.com 2001-02-03 08:05:07 HEAD@git f61b77cd
330 │ (no description set)
331 ~
332 "###);
333}
334
335#[cfg(unix)]
336#[test]
337fn test_git_init_colocated_via_git_repo_path_symlink_gitlink() {
338 let test_env = TestEnvironment::default();
339 // <workspace_root>/.git -> <git_workdir_path>/.git -> <git_repo_path>
340 let git_repo_path = test_env.env_root().join("git-repo");
341 let git_workdir_path = test_env.env_root().join("git-workdir");
342 let workspace_root = test_env.env_root().join("repo");
343 init_git_repo_with_opts(
344 &git_repo_path,
345 git2::RepositoryInitOptions::new().workdir_path(&git_workdir_path),
346 );
347 assert!(git_workdir_path.join(".git").is_file());
348 std::fs::create_dir(&workspace_root).unwrap();
349 std::os::unix::fs::symlink(git_workdir_path.join(".git"), workspace_root.join(".git")).unwrap();
350 let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "init", "--git-repo", "."]);
351 insta::assert_snapshot!(stdout, @"");
352 insta::assert_snapshot!(stderr, @r###"
353 Done importing changes from the underlying Git repo.
354 Initialized repo in "."
355 "###);
356 insta::assert_snapshot!(read_git_target(&workspace_root), @"../../../.git");
357
358 // Check that the Git repo's HEAD got checked out
359 let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-r", "@-"]);
360 insta::assert_snapshot!(stdout, @r###"
361 ◉ mwrttmos git.user@example.com 1970-01-01 11:02:03 my-branch HEAD@git 8d698d4a
362 │ My commit message
363 ~
364 "###);
365
366 // Check that the Git repo's HEAD moves
367 test_env.jj_cmd_ok(&workspace_root, &["new"]);
368 let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-r", "@-"]);
369 insta::assert_snapshot!(stdout, @r###"
370 ◉ sqpuoqvx test.user@example.com 2001-02-03 08:05:07 HEAD@git f61b77cd
371 │ (no description set)
372 ~
373 "###);
374}
375
376#[test]
377fn test_git_init_colocated_via_git_repo_path_imported_refs() {
378 let test_env = TestEnvironment::default();
379 test_env.add_config("git.auto-local-branch = true");
380
381 // Set up remote refs
382 test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "remote"]);
383 let remote_path = test_env.env_root().join("remote");
384 test_env.jj_cmd_ok(
385 &remote_path,
386 &["branch", "create", "local-remote", "remote-only"],
387 );
388 test_env.jj_cmd_ok(&remote_path, &["new"]);
389 test_env.jj_cmd_ok(&remote_path, &["git", "export"]);
390
391 let remote_git_path = remote_path.join(PathBuf::from_iter([".jj", "repo", "store", "git"]));
392 let set_up_local_repo = |local_path: &Path| {
393 let git_repo =
394 git2::Repository::clone(remote_git_path.to_str().unwrap(), local_path).unwrap();
395 let git_ref = git_repo
396 .find_reference("refs/remotes/origin/local-remote")
397 .unwrap();
398 git_repo
399 .reference(
400 "refs/heads/local-remote",
401 git_ref.target().unwrap(),
402 false,
403 "",
404 )
405 .unwrap();
406 };
407
408 // With git.auto-local-branch = true
409 let local_path = test_env.env_root().join("local1");
410 set_up_local_repo(&local_path);
411 let (_stdout, stderr) = test_env.jj_cmd_ok(&local_path, &["git", "init", "--git-repo=."]);
412 insta::assert_snapshot!(stderr, @r###"
413 Done importing changes from the underlying Git repo.
414 Initialized repo in "."
415 "###);
416 insta::assert_snapshot!(get_branch_output(&test_env, &local_path), @r###"
417 local-remote: vvkvtnvv 230dd059 (empty) (no description set)
418 @git: vvkvtnvv 230dd059 (empty) (no description set)
419 @origin: vvkvtnvv 230dd059 (empty) (no description set)
420 remote-only: vvkvtnvv 230dd059 (empty) (no description set)
421 @git: vvkvtnvv 230dd059 (empty) (no description set)
422 @origin: vvkvtnvv 230dd059 (empty) (no description set)
423 "###);
424
425 // With git.auto-local-branch = false
426 test_env.add_config("git.auto-local-branch = false");
427 let local_path = test_env.env_root().join("local2");
428 set_up_local_repo(&local_path);
429 let (_stdout, stderr) = test_env.jj_cmd_ok(&local_path, &["git", "init", "--git-repo=."]);
430 insta::assert_snapshot!(stderr, @r###"
431 Done importing changes from the underlying Git repo.
432 Hint: The following remote branches aren't associated with the existing local branches:
433 local-remote@origin
434 Hint: Run `jj branch track local-remote@origin` to keep local branches updated on future pulls.
435 Initialized repo in "."
436 "###);
437 insta::assert_snapshot!(get_branch_output(&test_env, &local_path), @r###"
438 local-remote: vvkvtnvv 230dd059 (empty) (no description set)
439 @git: vvkvtnvv 230dd059 (empty) (no description set)
440 local-remote@origin: vvkvtnvv 230dd059 (empty) (no description set)
441 remote-only@origin: vvkvtnvv 230dd059 (empty) (no description set)
442 "###);
443}
444
445#[test]
446fn test_git_init_colocated_dirty_working_copy() {
447 let test_env = TestEnvironment::default();
448 let workspace_root = test_env.env_root().join("repo");
449 let git_repo = init_git_repo(&workspace_root, false);
450
451 let add_file_to_index = |name: &str, data: &str| {
452 std::fs::write(workspace_root.join(name), data).unwrap();
453 let mut index = git_repo.index().unwrap();
454 index.add_path(Path::new(name)).unwrap();
455 index.write().unwrap();
456 };
457 let get_git_statuses = || {
458 let mut buf = String::new();
459 for entry in git_repo.statuses(None).unwrap().iter() {
460 writeln!(buf, "{:?} {}", entry.status(), entry.path().unwrap()).unwrap();
461 }
462 buf
463 };
464
465 add_file_to_index("some-file", "new content");
466 add_file_to_index("new-staged-file", "new content");
467 std::fs::write(workspace_root.join("unstaged-file"), "new content").unwrap();
468 insta::assert_snapshot!(get_git_statuses(), @r###"
469 Status(INDEX_NEW) new-staged-file
470 Status(INDEX_MODIFIED) some-file
471 Status(WT_NEW) unstaged-file
472 "###);
473
474 let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "init", "--git-repo", "."]);
475 insta::assert_snapshot!(stdout, @"");
476 insta::assert_snapshot!(stderr, @r###"
477 Done importing changes from the underlying Git repo.
478 Initialized repo in "."
479 "###);
480
481 // Working-copy changes should have been snapshotted.
482 let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-s", "--ignore-working-copy"]);
483 insta::assert_snapshot!(stdout, @r###"
484 @ sqpuoqvx test.user@example.com 2001-02-03 08:05:07 cd1e144d
485 │ (no description set)
486 │ A new-staged-file
487 │ M some-file
488 │ A unstaged-file
489 ◉ mwrttmos git.user@example.com 1970-01-01 11:02:03 my-branch HEAD@git 8d698d4a
490 │ My commit message
491 │ A some-file
492 ◉ zzzzzzzz root() 00000000
493 "###);
494
495 // Git index should be consistent with the working copy parent. With the
496 // current implementation, the index is unchanged. Since jj created new
497 // working copy commit, it's also okay to update the index reflecting the
498 // working copy commit or the working copy parent.
499 insta::assert_snapshot!(get_git_statuses(), @r###"
500 Status(IGNORED) .jj/.gitignore
501 Status(IGNORED) .jj/repo/
502 Status(IGNORED) .jj/working_copy/
503 Status(INDEX_NEW) new-staged-file
504 Status(INDEX_MODIFIED) some-file
505 Status(WT_NEW) unstaged-file
506 "###);
507}
508
509#[test]
510fn test_git_init_external_but_git_dir_exists() {
511 let test_env = TestEnvironment::default();
512 let git_repo_path = test_env.env_root().join("git-repo");
513 let workspace_root = test_env.env_root().join("repo");
514 git2::Repository::init(&git_repo_path).unwrap();
515 init_git_repo(&workspace_root, false);
516 let (stdout, stderr) = test_env.jj_cmd_ok(
517 &workspace_root,
518 &["git", "init", "--git-repo", git_repo_path.to_str().unwrap()],
519 );
520 insta::assert_snapshot!(stdout, @"");
521 insta::assert_snapshot!(stderr, @r###"
522 Initialized repo in "."
523 "###);
524
525 // The local ".git" repository is unrelated, so no commits should be imported
526 let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-r", "@-"]);
527 insta::assert_snapshot!(stdout, @r###"
528 ◉ zzzzzzzz root() 00000000
529 "###);
530
531 // Check that Git HEAD is not set because this isn't a colocated repo
532 test_env.jj_cmd_ok(&workspace_root, &["new"]);
533 let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-r", "@-"]);
534 insta::assert_snapshot!(stdout, @r###"
535 ◉ qpvuntsm test.user@example.com 2001-02-03 08:05:07 230dd059
536 │ (empty) (no description set)
537 ~
538 "###);
539}
540
541#[test]
542fn test_git_init_colocated_via_flag_git_dir_exists() {
543 let test_env = TestEnvironment::default();
544 let workspace_root = test_env.env_root().join("repo");
545 init_git_repo(&workspace_root, false);
546
547 let (stdout, stderr) =
548 test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "--colocate", "repo"]);
549 insta::assert_snapshot!(stdout, @"");
550 insta::assert_snapshot!(stderr, @r###"
551 Done importing changes from the underlying Git repo.
552 Initialized repo in "repo"
553 "###);
554
555 // Check that the Git repo's HEAD got checked out
556 let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-r", "@-"]);
557 insta::assert_snapshot!(stdout, @r###"
558 ◉ mwrttmos git.user@example.com 1970-01-01 11:02:03 my-branch HEAD@git 8d698d4a
559 │ My commit message
560 ~
561 "###);
562
563 // Check that the Git repo's HEAD moves
564 test_env.jj_cmd_ok(&workspace_root, &["new"]);
565 let stdout = test_env.jj_cmd_success(&workspace_root, &["log", "-r", "@-"]);
566 insta::assert_snapshot!(stdout, @r###"
567 ◉ sqpuoqvx test.user@example.com 2001-02-03 08:05:07 HEAD@git f61b77cd
568 │ (no description set)
569 ~
570 "###);
571}
572
573#[test]
574fn test_git_init_colocated_via_flag_git_dir_not_exists() {
575 let test_env = TestEnvironment::default();
576 let (stdout, stderr) =
577 test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "--colocate", "repo"]);
578 insta::assert_snapshot!(stdout, @"");
579 insta::assert_snapshot!(stderr, @r###"
580 Initialized repo in "repo"
581 "###);
582}
583
584#[test]
585fn test_git_init_bad_wc_path() {
586 let test_env = TestEnvironment::default();
587 std::fs::write(test_env.env_root().join("existing-file"), b"").unwrap();
588 let stderr = test_env.jj_cmd_failure(test_env.env_root(), &["git", "init", "existing-file"]);
589 assert!(stderr.contains("Failed to create workspace"));
590}