From ccdd65195313dd721e09a7a1373ba378f6b96ec1 Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Tue, 31 Aug 2021 09:38:28 -0700 Subject: [PATCH] working_copy: ignore `.git` directory/file when writing tree to store Git doesn't want `.git` entries in its trees, so at least when using the Git backend, we need to ignore such paths. Let's just ignore `.git` paths regardless of backend to keep it simple. Closes #24. --- lib/src/working_copy.rs | 2 +- lib/tests/test_working_copy.rs | 35 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/lib/src/working_copy.rs b/lib/src/working_copy.rs index e42954d76..db3cef1e3 100644 --- a/lib/src/working_copy.rs +++ b/lib/src/working_copy.rs @@ -333,7 +333,7 @@ impl TreeState { let file_type = entry.file_type().unwrap(); let file_name = entry.file_name(); let name = file_name.to_str().unwrap(); - if name == ".jj" { + if name == ".jj" || name == ".git" { continue; } let sub_path = dir.join(&RepoPathComponent::from(name)); diff --git a/lib/tests/test_working_copy.rs b/lib/tests/test_working_copy.rs index 5721eef03..d8f99de79 100644 --- a/lib/tests/test_working_copy.rs +++ b/lib/tests/test_working_copy.rs @@ -430,3 +430,38 @@ fn test_gitignores_ignored_directory_already_tracked(use_git: bool) { .unwrap(); assert!(new_tree.path_value(&file_path).is_some()); } + +#[test_case(false ; "local store")] +#[test_case(true ; "git store")] +fn test_dotgit_ignored(use_git: bool) { + // Tests that .git directories and files are always ignored (we could accept + // them if the backend is not git). + + let _home_dir = testutils::new_user_home(); + let settings = testutils::user_settings(); + let (_temp_dir, repo) = testutils::init_repo(&settings, use_git); + + let wc = repo.working_copy_locked(); + + // Test with a .git/ directory (with a file in, since we don't write empty + // trees) + let dotgit_path = repo.working_copy_path().join(".git"); + std::fs::create_dir(&dotgit_path).unwrap(); + testutils::write_working_copy_file( + &repo, + &RepoPath::from_internal_string(".git/file"), + "contents", + ); + let locked_working_copy = wc.write_tree(); + let new_tree_id = locked_working_copy.new_tree_id(); + assert_eq!(new_tree_id, *repo.store().empty_tree_id()); + locked_working_copy.discard(); + std::fs::remove_dir_all(&dotgit_path).unwrap(); + + // Test with a .git file + testutils::write_working_copy_file(&repo, &RepoPath::from_internal_string(".git"), "contents"); + let locked_working_copy = wc.write_tree(); + let new_tree_id = locked_working_copy.new_tree_id(); + assert_eq!(new_tree_id, *repo.store().empty_tree_id()); + locked_working_copy.discard(); +}