From 42c977f66e93a0768acd24f268a91a2c8067d558 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 2 Nov 2022 15:03:52 +0100 Subject: [PATCH] don't degenerate information about the unborn fetch ref's path. (#450) Previously we assumed this could only happen for `HEAD`, but in fact dangling symrefs are possible and they might end up in the server response that way. --- git-protocol/src/fetch/refs/mod.rs | 12 +++++++++--- git-protocol/src/fetch/refs/shared.rs | 5 ++++- git-protocol/src/fetch/tests/refs.rs | 6 ++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/git-protocol/src/fetch/refs/mod.rs b/git-protocol/src/fetch/refs/mod.rs index 850a638fb2..7c8f4c4c9b 100644 --- a/git-protocol/src/fetch/refs/mod.rs +++ b/git-protocol/src/fetch/refs/mod.rs @@ -77,9 +77,12 @@ pub enum Ref { /// The hash of the object the `target` ref points to. object: git_hash::ObjectId, }, - /// `HEAD` is unborn on the remote and just points to the initial, unborn branch. + /// A ref is unborn on the remote and just points to the initial, unborn branch, as is the case in a newly initialized repository + /// or dangling symbolic refs. Unborn { - /// The path of the ref the symbolic ref points to, like `refs/heads/main`. + /// The name at which the ref is located, typically `HEAD`. + full_ref_name: BString, + /// The path of the ref the symbolic ref points to, like `refs/heads/main`, even though the `target` does not yet exist. target: BString, }, } @@ -100,7 +103,10 @@ impl Ref { tag: object, object: peeled, } => (full_ref_name.as_ref(), Some(object), Some(peeled)), - Ref::Unborn { target: _ } => ("HEAD".into(), None, None), + Ref::Unborn { + full_ref_name, + target: _, + } => (full_ref_name.as_ref(), None, None), } } } diff --git a/git-protocol/src/fetch/refs/shared.rs b/git-protocol/src/fetch/refs/shared.rs index 4c096ce45d..38ae499500 100644 --- a/git-protocol/src/fetch/refs/shared.rs +++ b/git-protocol/src/fetch/refs/shared.rs @@ -207,7 +207,10 @@ pub(in crate::fetch::refs) fn parse_v2(line: &str) -> Result { object: id, target: name.into(), }, - None => Ref::Unborn { target: name.into() }, + None => Ref::Unborn { + full_ref_name: path.into(), + target: name.into(), + }, }, }, _ => { diff --git a/git-protocol/src/fetch/tests/refs.rs b/git-protocol/src/fetch/tests/refs.rs index 325d4885e8..4f4259df55 100644 --- a/git-protocol/src/fetch/tests/refs.rs +++ b/git-protocol/src/fetch/tests/refs.rs @@ -8,6 +8,7 @@ async fn extract_references_from_v2_refs() { let input = &mut "808e50d724f604f69ab93c6da2919c014667bedb HEAD symref-target:refs/heads/main 808e50d724f604f69ab93c6da2919c014667bedb MISSING_NAMESPACE_TARGET symref-target:(null) unborn HEAD symref-target:refs/heads/main +unborn refs/heads/symbolic symref-target:refs/heads/target 808e50d724f604f69ab93c6da2919c014667bedb refs/heads/main 7fe1b98b39423b71e14217aa299a03b7c937d656 refs/tags/foo peeled:808e50d724f604f69ab93c6da2919c014667bedb 7fe1b98b39423b71e14217aa299a03b7c937d6ff refs/tags/blaz @@ -29,8 +30,13 @@ unborn HEAD symref-target:refs/heads/main object: oid("808e50d724f604f69ab93c6da2919c014667bedb") }, Ref::Unborn { + full_ref_name: "HEAD".into(), target: "refs/heads/main".into(), }, + Ref::Unborn { + full_ref_name: "refs/heads/symbolic".into(), + target: "refs/heads/target".into(), + }, Ref::Direct { full_ref_name: "refs/heads/main".into(), object: oid("808e50d724f604f69ab93c6da2919c014667bedb")