Skip to content

Commit d04d75b

Browse files
committed
Auto merge of #6800 - ehuss:git-cli-force, r=alexcrichton
Support force-pushed repos with git-fetch-with-cli. If a git repo had a force push, then the `git-fetch-with-cli` feature would fail to fetch an update. This adds the `--force` flag to force the fetch. There's a bit of a lengthy discussion in the [git docs](https://git-scm.com/docs/git-fetch#Documentation/git-fetch.txt-ltrefspecgt) about why this is needed when a refspec is supplied. I also changed it to remove the `--quiet` flag and to capture the output, which is only displayed on error. I'm not sure what the reasoning for the `--quiet` flag was, but I don't see any harm since the output was previously unused. This can maybe help people debug problems, however in this situation all you would see is ` ! [rejected] master -> master (non-fast-forward)` which isn't terribly informative. Fixes #6795.
2 parents fccca68 + 1667b75 commit d04d75b

File tree

2 files changed

+71
-6
lines changed

2 files changed

+71
-6
lines changed

src/cargo/sources/git/utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -765,15 +765,15 @@ fn fetch_with_cli(
765765
let mut cmd = process("git");
766766
cmd.arg("fetch")
767767
.arg("--tags") // fetch all tags
768-
.arg("--quiet")
768+
.arg("--force") // handle force pushes
769769
.arg("--update-head-ok") // see discussion in #2078
770770
.arg(url.to_string())
771771
.arg(refspec)
772772
.cwd(repo.path());
773773
config
774774
.shell()
775775
.verbose(|s| s.status("Running", &cmd.to_string()))?;
776-
cmd.exec()?;
776+
cmd.exec_with_output()?;
777777
Ok(())
778778
}
779779

tests/testsuite/git.rs

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ use crate::support::sleep_ms;
1313
use crate::support::Project;
1414
use crate::support::{basic_lib_manifest, basic_manifest, git, main_file, path2url, project};
1515

16+
fn disable_git_cli() -> bool {
17+
// mingw git on Windows does not support Windows-style file URIs.
18+
// Appveyor in the rust repo has that git up front in the PATH instead
19+
// of Git-for-Windows, which causes this to fail.
20+
env::var("CARGO_TEST_DISABLE_GIT_CLI") == Ok("1".to_string())
21+
}
22+
1623
#[test]
1724
fn cargo_compile_simple_git_dep() {
1825
let project = project();
@@ -2772,10 +2779,7 @@ fn failed_submodule_checkout() {
27722779

27732780
#[test]
27742781
fn use_the_cli() {
2775-
if env::var("CARGO_TEST_DISABLE_GIT_CLI") == Ok("1".to_string()) {
2776-
// mingw git on Windows does not support Windows-style file URIs.
2777-
// Appveyor in the rust repo has that git up front in the PATH instead
2778-
// of Git-for-Windows, which causes this to fail.
2782+
if disable_git_cli() {
27792783
return;
27802784
}
27812785
let project = project();
@@ -2880,3 +2884,64 @@ fn templatedir_doesnt_cause_problems() {
28802884

28812885
p.cargo("build").run();
28822886
}
2887+
2888+
#[test]
2889+
fn git_with_cli_force() {
2890+
if disable_git_cli() {
2891+
return;
2892+
}
2893+
// Supports a force-pushed repo.
2894+
let git_project = git::new("dep1", |project| {
2895+
project
2896+
.file("Cargo.toml", &basic_lib_manifest("dep1"))
2897+
.file("src/lib.rs", r#"pub fn f() { println!("one"); }"#)
2898+
})
2899+
.unwrap();
2900+
let p = project()
2901+
.file(
2902+
"Cargo.toml",
2903+
&format!(
2904+
r#"
2905+
[project]
2906+
name = "foo"
2907+
version = "0.0.1"
2908+
edition = "2018"
2909+
2910+
[dependencies]
2911+
dep1 = {{ git = "{}" }}
2912+
"#,
2913+
git_project.url()
2914+
),
2915+
)
2916+
.file("src/main.rs", "fn main() { dep1::f(); }")
2917+
.file(
2918+
".cargo/config",
2919+
"
2920+
[net]
2921+
git-fetch-with-cli = true
2922+
",
2923+
)
2924+
.build();
2925+
p.cargo("build").run();
2926+
p.rename_run("foo", "foo1").with_stdout("one").run();
2927+
2928+
// commit --amend a change that will require a force fetch.
2929+
let repo = git2::Repository::open(&git_project.root()).unwrap();
2930+
git_project.change_file("src/lib.rs", r#"pub fn f() { println!("two"); }"#);
2931+
git::add(&repo);
2932+
let id = repo.refname_to_id("HEAD").unwrap();
2933+
let commit = repo.find_commit(id).unwrap();
2934+
let tree_id = t!(t!(repo.index()).write_tree());
2935+
t!(commit.amend(
2936+
Some("HEAD"),
2937+
None,
2938+
None,
2939+
None,
2940+
None,
2941+
Some(&t!(repo.find_tree(tree_id)))
2942+
));
2943+
// Perform the fetch.
2944+
p.cargo("update").run();
2945+
p.cargo("build").run();
2946+
p.rename_run("foo", "foo2").with_stdout("two").run();
2947+
}

0 commit comments

Comments
 (0)