Skip to content

Commit 4a1e710

Browse files
committed
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
1 parent f84f3f8 commit 4a1e710

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

src/cargo/sources/git/utils.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ impl<'a> GitCheckout<'a> {
328328
let ok_file = self.location.join(".cargo-ok");
329329
let _ = paths::remove_file(&ok_file);
330330
info!("reset {} to {}", self.repo.path().display(), self.revision);
331+
332+
// Ensure libgit2 won't mess with newlines when we vendor.
333+
if let Ok(mut git_config) = self.repo.config() {
334+
git_config.set_bool("core.autocrlf", false)?;
335+
}
336+
331337
let object = self.repo.find_object(self.revision, None)?;
332338
reset(&self.repo, &object, config)?;
333339
paths::create(ok_file)?;

tests/testsuite/vendor.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
//! "fake" crates.io is used. Otherwise `vendor` would download the crates.io
55
//! index from the network.
66
7+
use std::fs;
8+
79
use cargo_test_support::git;
810
use cargo_test_support::registry::Package;
9-
use cargo_test_support::{basic_lib_manifest, project, Project};
11+
use cargo_test_support::{basic_lib_manifest, paths, project, Project};
1012

1113
#[cargo_test]
1214
fn vendor_simple() {
@@ -631,3 +633,45 @@ fn config_instructions_works() {
631633
.with_stderr_contains("[..]foo/vendor/gitdep/src/lib.rs[..]")
632634
.run();
633635
}
636+
637+
#[cargo_test]
638+
fn git_crlf_preservation() {
639+
// Check that newlines don't get changed when you vendor
640+
// (will only fail if your system is setup with core.autocrlf=true on windows)
641+
let input = "hello \nthere\nmy newline\nfriends";
642+
let git_project = git::new("git", |p| {
643+
p.file("Cargo.toml", &basic_lib_manifest("a"))
644+
.file("src/lib.rs", input)
645+
});
646+
647+
let p = project()
648+
.file(
649+
"Cargo.toml",
650+
&format!(
651+
r#"
652+
[package]
653+
name = "foo"
654+
version = "0.1.0"
655+
656+
[dependencies]
657+
a = {{ git = '{}' }}
658+
"#,
659+
git_project.url()
660+
),
661+
)
662+
.file("src/lib.rs", "")
663+
.build();
664+
665+
fs::write(
666+
paths::home().join(".gitconfig"),
667+
r#"
668+
[core]
669+
autocrlf = true
670+
"#,
671+
)
672+
.unwrap();
673+
674+
p.cargo("vendor --respect-source-config").run();
675+
let output = p.read_file("vendor/a/src/lib.rs");
676+
assert_eq!(input, output);
677+
}

0 commit comments

Comments
 (0)