Auto merge of #8523 - Gankra:crlf, r=alexcrichton

Mask out system core.autocrlf settings before resetting git repos

This fixes an issue the gecko developers noticed when vendoring
on windows. \[0\] If a user has `core.autocrlf=true` set
(a reasonable default on windows), vendoring from a git source
would cause all the newlines to be rewritten to include carriage
returns, creating churn and platform-specific results.

To fix this, we simply set the global cargo checkout's "local"
core.autocrlf value before performing a `reset`. This masks out
the system configuration without interfering with the user's
own system/project settings.

\[0\]:  https://bugzilla.mozilla.org/show_bug.cgi?id=1647582
This commit is contained in:
bors 2020-07-23 06:11:01 +00:00
commit 04c0875ed6
2 changed files with 51 additions and 1 deletions

View File

@ -328,6 +328,12 @@ impl<'a> GitCheckout<'a> {
let ok_file = self.location.join(".cargo-ok");
let _ = paths::remove_file(&ok_file);
info!("reset {} to {}", self.repo.path().display(), self.revision);
// Ensure libgit2 won't mess with newlines when we vendor.
if let Ok(mut git_config) = self.repo.config() {
git_config.set_bool("core.autocrlf", false)?;
}
let object = self.repo.find_object(self.revision, None)?;
reset(&self.repo, &object, config)?;
paths::create(ok_file)?;

View File

@ -4,9 +4,11 @@
//! "fake" crates.io is used. Otherwise `vendor` would download the crates.io
//! index from the network.
use std::fs;
use cargo_test_support::git;
use cargo_test_support::registry::Package;
use cargo_test_support::{basic_lib_manifest, project, Project};
use cargo_test_support::{basic_lib_manifest, paths, project, Project};
#[cargo_test]
fn vendor_simple() {
@ -631,3 +633,45 @@ fn config_instructions_works() {
.with_stderr_contains("[..]foo/vendor/gitdep/src/lib.rs[..]")
.run();
}
#[cargo_test]
fn git_crlf_preservation() {
// Check that newlines don't get changed when you vendor
// (will only fail if your system is setup with core.autocrlf=true on windows)
let input = "hello \nthere\nmy newline\nfriends";
let git_project = git::new("git", |p| {
p.file("Cargo.toml", &basic_lib_manifest("a"))
.file("src/lib.rs", input)
});
let p = project()
.file(
"Cargo.toml",
&format!(
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
a = {{ git = '{}' }}
"#,
git_project.url()
),
)
.file("src/lib.rs", "")
.build();
fs::write(
paths::home().join(".gitconfig"),
r#"
[core]
autocrlf = true
"#,
)
.unwrap();
p.cargo("vendor --respect-source-config").run();
let output = p.read_file("vendor/a/src/lib.rs");
assert_eq!(input, output);
}