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 <gitster@pobox.com>
Junio C Hamano committed
Jan 28, 2013 at 21:49 UTC
390eb36b0a9cbaa5051040c762b986ddd4b3848f
2 files changed
+26
-7
Documentation/config.txt
+7
-1
@@ -2083,7 +2083,13 @@ uploadpack.hiderefs::
2083
are under the hierarchies listed on the value of this
2084
variable is excluded, and is hidden from `git ls-remote`,
2085
`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`.
2093
2094
url.<base>.insteadOf::
2095
Any URL that starts with this value will be rewritten to
upload-pack.c
+19
-6
@@ -26,6 +26,7 @@ static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<
26
#define SHALLOW (1u << 16)
27
#define NOT_SHALLOW (1u << 17)
28
#define CLIENT_SHALLOW (1u << 18)
29
+#define HIDDEN_REF (1u << 19)
30
31
static unsigned long oldest_have;
32
@@ -33,6 +34,7 @@ static int multi_ack;
34
static int no_done;
35
static int use_thin_pack, use_ofs_delta, use_include_tag;
36
static int no_progress, daemon_mode;
37
+static int allow_tip_sha1_in_want;
38
static int shallow_nr;
39
static struct object_array have_obj;
40
static struct object_array want_obj;
@@ -487,6 +489,12 @@ static int get_common_commits(void)
489
}
490
}
491
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
+
498
static void check_non_tip(void)
499
{
500
static const char *argv[] = {
@@ -523,7 +531,7 @@ static void check_non_tip(void)
531
o = get_indexed_object(--i);
532
if (!o)
533
continue;
526
- if (!(o->flags & OUR_REF))
534
+ if (!is_our_ref(o))
535
continue;
536
memcpy(namebuf + 1, sha1_to_hex(o->sha1), 40);
537
if (write_in_full(cmd.in, namebuf, 42) < 0)
@@ -532,7 +540,7 @@ static void check_non_tip(void)
540
namebuf[40] = '\n';
541
for (i = 0; i < want_obj.nr; i++) {
542
o = want_obj.objects[i].item;
535
- if (o->flags & OUR_REF)
543
+ if (is_our_ref(o))
544
continue;
545
memcpy(namebuf, sha1_to_hex(o->sha1), 40);
546
if (write_in_full(cmd.in, namebuf, 41) < 0)
@@ -566,7 +574,7 @@ error:
574
/* Pick one of them (we know there at least is one) */
575
for (i = 0; i < want_obj.nr; i++) {
576
o = want_obj.objects[i].item;
569
- if (!(o->flags & OUR_REF))
577
+ if (!is_our_ref(o))
578
die("git upload-pack: not our ref %s",
579
sha1_to_hex(o->sha1));
580
}
@@ -646,7 +654,7 @@ static void receive_needs(void)
654
sha1_to_hex(sha1_buf));
655
if (!(o->flags & WANTED)) {
656
o->flags |= WANTED;
649
- if (!(o->flags & OUR_REF))
657
+ if (!is_our_ref(o))
658
has_non_tip = 1;
659
add_object_array(o, NULL, &want_obj);
660
}
@@ -725,8 +733,10 @@ static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag
733
{
734
struct object *o = lookup_unknown_object(sha1);
735
728
- if (ref_is_hidden(refname))
736
+ if (ref_is_hidden(refname)) {
737
+ o->flags |= HIDDEN_REF;
738
return 1;
739
+ }
740
if (!o)
741
die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
742
o->flags |= OUR_REF;
@@ -745,9 +755,10 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
755
return 0;
756
757
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",
759
sha1_to_hex(sha1), refname_nons,
760
0, capabilities,
761
+ allow_tip_sha1_in_want ? " allow-tip-sha1-in-want" : "",
762
stateless_rpc ? " no-done" : "",
763
git_user_agent_sanitized());
764
else
@@ -781,6 +792,8 @@ static void upload_pack(void)
792
793
static int upload_pack_config(const char *var, const char *value, void *unused)
794
{
795
+ if (!strcmp("uploadpack.allowtipsha1inwant", var))
796
+ allow_tip_sha1_in_want = git_config_bool(var, value);
797
return parse_hide_refs_config(var, value, "uploadpack");
798
}
799