From 064a1461d7a3c1bd33419ac8a123d7be752ad01d Mon Sep 17 00:00:00 2001 From: Without Boats Date: Tue, 17 Jul 2018 02:27:43 -0400 Subject: [PATCH] Respect .gitignore during `cargo new` When running `cargo new`, we check to see if you are inside a git repository. If you are, we do not initialize a new git repo for your project unless you specifically asked for it using --vcs. (See #1210 for more background). This commit changes that behavior to *also* create a new repo if the project would be an ignored path in the parent repository. This way, if your home directory is a git repository, as long as you have ignored the directory you are creating a new project in, we will instantiate a git repository without you having to specifically request it. --- src/cargo/ops/cargo_new.rs | 13 ++++++++++++- tests/testsuite/fix.rs | 4 ++-- tests/testsuite/new.rs | 30 ++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/cargo/ops/cargo_new.rs b/src/cargo/ops/cargo_new.rs index 2a0f4c818..e431d11d0 100644 --- a/src/cargo/ops/cargo_new.rs +++ b/src/cargo/ops/cargo_new.rs @@ -409,8 +409,19 @@ pub fn init(opts: &NewOptions, config: &Config) -> CargoResult<()> { Ok(()) } +// Check if we are in an existing repo. We define that to be true if either: +// +// 1. We are in a git repo and the path to the new project is not an ignored +// path in that repo. +// 2. We are in an HG repo. pub fn existing_vcs_repo(path: &Path, cwd: &Path) -> bool { - GitRepo::discover(path, cwd).is_ok() || HgRepo::discover(path, cwd).is_ok() + fn in_git_repo(path: &Path, cwd: &Path) -> bool { + if let Ok(repo) = GitRepo::discover(path, cwd) { + repo.is_path_ignored(path).map(|ignored| !ignored).unwrap_or(true) + } else { false } + } + + in_git_repo(path, cwd) || HgRepo::discover(path, cwd).is_ok() } fn mk(config: &Config, opts: &MkOptions) -> CargoResult<()> { diff --git a/tests/testsuite/fix.rs b/tests/testsuite/fix.rs index f79777434..a699de196 100644 --- a/tests/testsuite/fix.rs +++ b/tests/testsuite/fix.rs @@ -826,7 +826,7 @@ fn does_not_warn_about_clean_working_directory() { fn does_not_warn_about_dirty_ignored_files() { let p = project() .file("src/lib.rs", "pub fn foo() {}") - .file(".gitignore", "foo\n") + .file(".gitignore", "bar\n") .build(); let repo = git2::Repository::init(&p.root()).unwrap(); @@ -836,7 +836,7 @@ fn does_not_warn_about_dirty_ignored_files() { drop(cfg); git::add(&repo); git::commit(&repo); - File::create(p.root().join("foo")).unwrap(); + File::create(p.root().join("bar")).unwrap(); assert_that( p.cargo("fix"), diff --git a/tests/testsuite/new.rs b/tests/testsuite/new.rs index 847dde9f3..12ca2c92c 100644 --- a/tests/testsuite/new.rs +++ b/tests/testsuite/new.rs @@ -495,6 +495,36 @@ fn subpackage_no_git() { ); } +#[test] +fn subpackage_git_with_gitignore() { + assert_that( + cargo_process("new").arg("foo").env("USER", "foo"), + execs().with_status(0), + ); + + let gitignore = paths::root().join("foo").join(".gitignore"); + fs::write(gitignore, b"components").unwrap(); + + let subpackage = paths::root().join("foo").join("components"); + fs::create_dir(&subpackage).unwrap(); + assert_that( + cargo_process("new") + .arg("foo/components/subcomponent") + .env("USER", "foo"), + execs().with_status(0), + ); + + assert_that( + &paths::root().join("foo").join("components").join("subcomponent").join(".git"), + existing_dir(), + ); + assert_that( + &paths::root().join("foo").join("components").join("subcomponent").join(".gitignore"), + existing_file(), + ); + +} + #[test] fn subpackage_git_with_vcs_arg() { assert_that(