Skip to content

Commit 390eb36

Browse files
committed
upload-pack: optionally allow fetching from the tips of hidden refs
With uploadpack.allowtipsha1inwant configuration option set, future versions of "git fetch" that allow an exact object name (likely to have been obtained out of band) on the LHS of the fetch refspec can make a request with a "want" line that names an object that may not have been advertised due to transfer.hiderefs configuration. Signed-off-by: Junio C Hamano <[email protected]>
1 parent f2db854 commit 390eb36

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

Documentation/config.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2083,7 +2083,13 @@ uploadpack.hiderefs::
20832083
are under the hierarchies listed on the value of this
20842084
variable is excluded, and is hidden from `git ls-remote`,
20852085
`git fetch`, etc. An attempt to fetch a hidden ref by `git
2086-
fetch` will fail.
2086+
fetch` will fail. See also `uploadpack.allowtipsha1inwant`.
2087+
2088+
uploadpack.allowtipsha1inwant::
2089+
When `uploadpack.hiderefs` is in effect, allow `upload-pack`
2090+
to accept a fetch request that asks for an object at the tip
2091+
of a hidden ref (by default, such a request is rejected).
2092+
see also `uploadpack.hiderefs`.
20872093

20882094
url.<base>.insteadOf::
20892095
Any URL that starts with this value will be rewritten to

upload-pack.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@ static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<
2626
#define SHALLOW (1u << 16)
2727
#define NOT_SHALLOW (1u << 17)
2828
#define CLIENT_SHALLOW (1u << 18)
29+
#define HIDDEN_REF (1u << 19)
2930

3031
static unsigned long oldest_have;
3132

3233
static int multi_ack;
3334
static int no_done;
3435
static int use_thin_pack, use_ofs_delta, use_include_tag;
3536
static int no_progress, daemon_mode;
37+
static int allow_tip_sha1_in_want;
3638
static int shallow_nr;
3739
static struct object_array have_obj;
3840
static struct object_array want_obj;
@@ -487,6 +489,12 @@ static int get_common_commits(void)
487489
}
488490
}
489491

492+
static int is_our_ref(struct object *o)
493+
{
494+
return o->flags &
495+
((allow_tip_sha1_in_want ? HIDDEN_REF : 0) | OUR_REF);
496+
}
497+
490498
static void check_non_tip(void)
491499
{
492500
static const char *argv[] = {
@@ -523,7 +531,7 @@ static void check_non_tip(void)
523531
o = get_indexed_object(--i);
524532
if (!o)
525533
continue;
526-
if (!(o->flags & OUR_REF))
534+
if (!is_our_ref(o))
527535
continue;
528536
memcpy(namebuf + 1, sha1_to_hex(o->sha1), 40);
529537
if (write_in_full(cmd.in, namebuf, 42) < 0)
@@ -532,7 +540,7 @@ static void check_non_tip(void)
532540
namebuf[40] = '\n';
533541
for (i = 0; i < want_obj.nr; i++) {
534542
o = want_obj.objects[i].item;
535-
if (o->flags & OUR_REF)
543+
if (is_our_ref(o))
536544
continue;
537545
memcpy(namebuf, sha1_to_hex(o->sha1), 40);
538546
if (write_in_full(cmd.in, namebuf, 41) < 0)
@@ -566,7 +574,7 @@ static void check_non_tip(void)
566574
/* Pick one of them (we know there at least is one) */
567575
for (i = 0; i < want_obj.nr; i++) {
568576
o = want_obj.objects[i].item;
569-
if (!(o->flags & OUR_REF))
577+
if (!is_our_ref(o))
570578
die("git upload-pack: not our ref %s",
571579
sha1_to_hex(o->sha1));
572580
}
@@ -646,7 +654,7 @@ static void receive_needs(void)
646654
sha1_to_hex(sha1_buf));
647655
if (!(o->flags & WANTED)) {
648656
o->flags |= WANTED;
649-
if (!(o->flags & OUR_REF))
657+
if (!is_our_ref(o))
650658
has_non_tip = 1;
651659
add_object_array(o, NULL, &want_obj);
652660
}
@@ -725,8 +733,10 @@ static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag
725733
{
726734
struct object *o = lookup_unknown_object(sha1);
727735

728-
if (ref_is_hidden(refname))
736+
if (ref_is_hidden(refname)) {
737+
o->flags |= HIDDEN_REF;
729738
return 1;
739+
}
730740
if (!o)
731741
die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
732742
o->flags |= OUR_REF;
@@ -745,9 +755,10 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
745755
return 0;
746756

747757
if (capabilities)
748-
packet_write(1, "%s %s%c%s%s agent=%s\n",
758+
packet_write(1, "%s %s%c%s%s%s agent=%s\n",
749759
sha1_to_hex(sha1), refname_nons,
750760
0, capabilities,
761+
allow_tip_sha1_in_want ? " allow-tip-sha1-in-want" : "",
751762
stateless_rpc ? " no-done" : "",
752763
git_user_agent_sanitized());
753764
else
@@ -781,6 +792,8 @@ static void upload_pack(void)
781792

782793
static int upload_pack_config(const char *var, const char *value, void *unused)
783794
{
795+
if (!strcmp("uploadpack.allowtipsha1inwant", var))
796+
allow_tip_sha1_in_want = git_config_bool(var, value);
784797
return parse_hide_refs_config(var, value, "uploadpack");
785798
}
786799

0 commit comments

Comments
 (0)