From 2a4cdc677c7dd093888bf9ff5e3ceb4f7604895d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 2 Nov 2018 07:46:11 -0700 Subject: [PATCH] Never use templates when managing git repos This commit disables usage of git templates whenever Cargo manages repositories in its internal git database. Templates don't want to be used at all in these situations and have been known to cause usability bugs. Closes #6240 --- src/cargo/sources/git/utils.rs | 22 +++++++++++------ tests/testsuite/git.rs | 45 ++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/cargo/sources/git/utils.rs b/src/cargo/sources/git/utils.rs index 66301c1da1b..4722dc2ce97 100644 --- a/src/cargo/sources/git/utils.rs +++ b/src/cargo/sources/git/utils.rs @@ -146,7 +146,7 @@ impl GitRemote { paths::remove_dir_all(dst)?; } fs::create_dir_all(dst)?; - let mut repo = git2::Repository::init_bare(dst)?; + let mut repo = init(dst, true)?; fetch( &mut repo, &self.url, @@ -385,7 +385,7 @@ impl<'a> GitCheckout<'a> { Err(..) => { let path = parent.workdir().unwrap().join(child.path()); let _ = paths::remove_dir_all(&path); - git2::Repository::init(&path)? + init(&path, false)? } }; @@ -833,7 +833,7 @@ fn reinitialize(repo: &mut git2::Repository) -> CargoResult<()> { debug!("reinitializing git repo at {:?}", path); let tmp = path.join("tmp"); let bare = !repo.path().ends_with(".git"); - *repo = git2::Repository::init(&tmp)?; + *repo = init(&tmp, false)?; for entry in path.read_dir()? { let entry = entry?; if entry.file_name().to_str() == Some("tmp") { @@ -842,15 +842,21 @@ fn reinitialize(repo: &mut git2::Repository) -> CargoResult<()> { let path = entry.path(); drop(paths::remove_file(&path).or_else(|_| paths::remove_dir_all(&path))); } - if bare { - *repo = git2::Repository::init_bare(path)?; - } else { - *repo = git2::Repository::init(path)?; - } + *repo = init(&path, bare)?; paths::remove_dir_all(&tmp)?; Ok(()) } +fn init(path: &Path, bare: bool) -> CargoResult { + let mut opts = git2::RepositoryInitOptions::new(); + // Skip anyting related to templates, they just call all sorts of issues as + // we really don't want to use them yet they insist on being used. See #6240 + // for an example issue that comes up. + opts.external_template(false); + opts.bare(bare); + Ok(git2::Repository::init_opts(&path, &opts)?) +} + /// Updating the index is done pretty regularly so we want it to be as fast as /// possible. For registries hosted on GitHub (like the crates.io index) there's /// a fast path available to use [1] to tell us that there's no updates to be diff --git a/tests/testsuite/git.rs b/tests/testsuite/git.rs index 2e4d4633903..ea89a964bdc 100644 --- a/tests/testsuite/git.rs +++ b/tests/testsuite/git.rs @@ -2625,3 +2625,48 @@ fn use_the_cli() { project.cargo("build -v").with_stderr(stderr).run(); } + +#[test] +fn templatedir_doesnt_cause_problems() { + let git_project2 = git::new("dep2", |project| { + project + .file("Cargo.toml", &basic_manifest("dep2", "0.5.0")) + .file("src/lib.rs", "") + }).unwrap(); + let git_project = git::new("dep1", |project| { + project + .file("Cargo.toml", &basic_manifest("dep1", "0.5.0")) + .file("src/lib.rs", "") + }).unwrap(); + let p = project() + .file( + "Cargo.toml", + &format!(r#" + [project] + name = "fo" + version = "0.5.0" + authors = [] + + [dependencies] + dep1 = {{ git = '{}' }} + "#, git_project.url()), + ).file("src/main.rs", "fn main() {}") + .build(); + + File::create(paths::home().join(".gitconfig")) + .unwrap() + .write_all( + &format!(r#" + [init] + templatedir = {} + "#, git_project2.url() + .to_file_path() + .unwrap() + .to_str() + .unwrap() + .replace("\\", "/") + ).as_bytes(), + ).unwrap(); + + p.cargo("build").run(); +}