diff --git a/git-refspec/src/parse.rs b/git-refspec/src/parse.rs index a242bff43f5..7690cb7175a 100644 --- a/git-refspec/src/parse.rs +++ b/git-refspec/src/parse.rs @@ -29,7 +29,17 @@ pub(crate) mod function { Mode::Force } Some(_) => Mode::Normal, - None => return Err(Error::Empty), + None => { + return match operation { + Operation::Push => Err(Error::Empty), + Operation::Fetch => Ok(RefSpecRef { + mode: Mode::Normal, + op: operation, + src: Some("HEAD".into()), + dst: None, + }), + } + } }; let (src, dst) = match spec.find_byte(b':') { @@ -43,7 +53,10 @@ pub(crate) mod function { let src = (!src.is_empty()).then(|| src.as_bstr()); let dst = (!dst.is_empty()).then(|| dst.as_bstr()); match (src, dst) { - (None, None) => (None, None), + (None, None) => match operation { + Operation::Push => (None, None), + Operation::Fetch => (Some("HEAD".into()), None), + }, (None, Some(dst)) => match operation { Operation::Push => (None, Some(dst)), Operation::Fetch => (Some("HEAD".into()), Some(dst)), diff --git a/git-refspec/src/spec.rs b/git-refspec/src/spec.rs index e982db2b842..49de225ccca 100644 --- a/git-refspec/src/spec.rs +++ b/git-refspec/src/spec.rs @@ -34,11 +34,6 @@ impl RefSpecRef<'_> { (Operation::Push, Mode::Normal | Mode::Force, None, None) => Instruction::Push(Push::AllMatchingBranches { allow_non_fast_forward: matches!(self.mode, Mode::Force), }), - (Operation::Fetch, Mode::Normal | Mode::Force, None, None) => { - Instruction::Fetch(Fetch::AllMatchingBranches { - allow_non_fast_forward: matches!(self.mode, Mode::Force), - }) - } (Operation::Push, Mode::Normal | Mode::Force, Some(src), Some(dst)) if has_pattern(src) => { Instruction::Push(Push::MultipleWithGlob { src, diff --git a/git-refspec/src/types.rs b/git-refspec/src/types.rs index 9588cafbc6d..6ca621aacf7 100644 --- a/git-refspec/src/types.rs +++ b/git-refspec/src/types.rs @@ -70,11 +70,6 @@ pub enum Push<'a> { #[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)] pub enum Fetch<'a> { - /// TODO: figure out what this actually does - it's valid for sure and only fetches HEAD -> FETCH_HEAD apparently - AllMatchingBranches { - /// Unclear what this does, but it's allowed - allow_non_fast_forward: bool, - }, Only { /// The ref name to fetch on the remote side, without updating the local side. src: &'a BStr, diff --git a/git-refspec/tests/fixtures/generated-archives/make_baseline.tar.xz b/git-refspec/tests/fixtures/generated-archives/make_baseline.tar.xz index 73c87d7d28c..5bad0ada60b 100644 --- a/git-refspec/tests/fixtures/generated-archives/make_baseline.tar.xz +++ b/git-refspec/tests/fixtures/generated-archives/make_baseline.tar.xz @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:515045d1eade39e1aeee1f171216ac389b8adc54af541b2ff49bf1b1ab68eae2 -size 9340 +oid sha256:d68f02fcf17b72dfb953ab02f3d448d7b859d822aa71835856045a291a645d5a +size 9344 diff --git a/git-refspec/tests/fixtures/make_baseline.sh b/git-refspec/tests/fixtures/make_baseline.sh index a87d40cbf14..1f8812b038d 100644 --- a/git-refspec/tests/fixtures/make_baseline.sh +++ b/git-refspec/tests/fixtures/make_baseline.sh @@ -64,6 +64,7 @@ baseline push ':' baseline fetch '' baseline fetch ':' +baseline fetch '+' baseline push 'refs/heads/main:refs/remotes/frotz/xyzzy' baseline push 'refs/heads/*:refs/remotes/frotz/*' diff --git a/git-refspec/tests/parse/mod.rs b/git-refspec/tests/parse/mod.rs index 84bdc38e0e6..47020942b11 100644 --- a/git-refspec/tests/parse/mod.rs +++ b/git-refspec/tests/parse/mod.rs @@ -33,7 +33,7 @@ fn baseline() { Ok(res) => match (res.is_ok(), err_code == 0) { (true, true) | (false, false) => {} _ => { - eprintln!("{res:?} {err_code} {} {:?}", kind.as_bstr(), spec.as_bstr()); + eprintln!("{err_code} {res:?} {} {:?}", kind.as_bstr(), spec.as_bstr()); mismatch += 1; } }, @@ -59,7 +59,6 @@ mod invalid { #[test] fn empty() { - assert!(matches!(try_parse("", Operation::Fetch).unwrap_err(), Error::Empty)); assert!(matches!(try_parse("", Operation::Push).unwrap_err(), Error::Empty)); } @@ -142,19 +141,15 @@ mod fetch { } #[test] - fn colon_alone_is_for_fetching_into_fetchhead() { - assert_parse( - ":", - Instruction::Fetch(Fetch::AllMatchingBranches { - allow_non_fast_forward: false, - }), - ); - assert_parse( - "+:", - Instruction::Fetch(Fetch::AllMatchingBranches { - allow_non_fast_forward: true, - }), - ); + fn colon_alone_is_for_fetching_head_into_fetchhead() { + assert_parse(":", Instruction::Fetch(Fetch::Only { src: b("HEAD") })); + let spec = assert_parse("+:", Instruction::Fetch(Fetch::Only { src: b("HEAD") })); + assert_eq!(spec.mode(), Mode::Force, "it's set even though it's not useful"); + } + + #[test] + fn empty_refspec_is_enough_for_fetching_head_into_fetchhead() { + assert_parse("", Instruction::Fetch(Fetch::Only { src: b("HEAD") })); } }