Skip to content

Commit d8faf50

Browse files
pks-tgitster
authored andcommitted
builtin/receive-pack: fix exclude patterns when announcing refs
In `write_head_info()` we announce references to the remote client. We need to honor "transfer.hideRefs" here so that we do not announce any references that the client shouldn't be able to learn about. This is done via two separate mechanisms: - We hand over exclude patterns to the reference backend. We can only honor "plain" exclude patterns here that do not have prefixes with special meaning such as "^" or "!". Filtering down the references is handled by `hidden_refs_to_excludes()`. - In `show_ref_cb()` we perform a second check against hidden refs. For one this is done such that we can handle those special prefixes. And second, handling exclude patterns in ref backends is optional, so we also have to handle "normal" patterns. The special-meaning "^" prefix alters whether a hidden ref applies to the namespace-stripped reference name or the full name. So while we would usually call `refs_for_each_namespaced_ref()` to only get those references in the current namespace, we can't because we'd get the already-rewritten reference names. Instead, we are forced to use `refs_for_each_fullref_in()` and then manually strip away the namespace prefix such that we have access to both names. But this also means that we do not get namespace handling for exclude patterns, which `refs_for_each_namespaced_ref()` brings for free. This results in a bug because we potentially end up hiding away references based on their namespaced name and not on the stripped name as we really should be doing. Fix this by manually rewriting the exclude patterns to their namespaced variants. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 155dc84 commit d8faf50

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

builtin/receive-pack.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,12 +339,26 @@ static void show_one_alternate_ref(const struct object_id *oid,
339339
static void write_head_info(void)
340340
{
341341
static struct oidset seen = OIDSET_INIT;
342+
struct strvec excludes_vector = STRVEC_INIT;
343+
const char **exclude_patterns;
344+
345+
/*
346+
* We need access to the reference names both with and without their
347+
* namespace and thus cannot use `refs_for_each_namespaced_ref()`. We
348+
* thus have to adapt exclude patterns to carry the namespace prefix
349+
* ourselves.
350+
*/
351+
exclude_patterns = get_namespaced_exclude_patterns(
352+
hidden_refs_to_excludes(&hidden_refs),
353+
get_git_namespace(), &excludes_vector);
342354

343355
refs_for_each_fullref_in(get_main_ref_store(the_repository), "",
344-
hidden_refs_to_excludes(&hidden_refs),
345-
show_ref_cb, &seen);
356+
exclude_patterns, show_ref_cb, &seen);
346357
for_each_alternate_ref(show_one_alternate_ref, &seen);
358+
347359
oidset_clear(&seen);
360+
strvec_clear(&excludes_vector);
361+
348362
if (!sent_capabilities)
349363
show_ref("capabilities^{}", null_oid());
350364

t/t5509-fetch-push-namespaces.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,14 @@ test_expect_success 'try to update a ref that is not hidden' '
124124
git -C original push pushee-namespaced main
125125
'
126126

127+
test_expect_success 'git-receive-pack(1) with transfer.hideRefs does not match unstripped refs during advertisement' '
128+
git -C pushee update-ref refs/namespaces/namespace/refs/heads/foo/1 refs/namespaces/namespace/refs/heads/main &&
129+
git -C pushee pack-refs --all &&
130+
test_config -C pushee transfer.hideRefs refs/namespaces/namespace/refs/heads/foo &&
131+
GIT_TRACE_PACKET="$(pwd)/trace" git -C original push pushee-namespaced main &&
132+
test_grep refs/heads/foo/1 trace
133+
'
134+
127135
test_expect_success 'try to update a hidden full ref' '
128136
test_config -C pushee transfer.hideRefs "^refs/namespaces/namespace/refs/heads/main" &&
129137
test_must_fail git -C original push pushee-namespaced main

0 commit comments

Comments
 (0)