提交 390eb36b 编写于 作者: J Junio C Hamano

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: NJunio C Hamano <gitster@pobox.com>
上级 f2db854d
...@@ -2083,7 +2083,13 @@ uploadpack.hiderefs:: ...@@ -2083,7 +2083,13 @@ uploadpack.hiderefs::
are under the hierarchies listed on the value of this are under the hierarchies listed on the value of this
variable is excluded, and is hidden from `git ls-remote`, variable is excluded, and is hidden from `git ls-remote`,
`git fetch`, etc. An attempt to fetch a hidden ref by `git `git fetch`, etc. An attempt to fetch a hidden ref by `git
fetch` will fail. fetch` will fail. See also `uploadpack.allowtipsha1inwant`.
uploadpack.allowtipsha1inwant::
When `uploadpack.hiderefs` is in effect, allow `upload-pack`
to accept a fetch request that asks for an object at the tip
of a hidden ref (by default, such a request is rejected).
see also `uploadpack.hiderefs`.
url.<base>.insteadOf:: url.<base>.insteadOf::
Any URL that starts with this value will be rewritten to Any URL that starts with this value will be rewritten to
......
...@@ -26,6 +26,7 @@ static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=< ...@@ -26,6 +26,7 @@ static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<
#define SHALLOW (1u << 16) #define SHALLOW (1u << 16)
#define NOT_SHALLOW (1u << 17) #define NOT_SHALLOW (1u << 17)
#define CLIENT_SHALLOW (1u << 18) #define CLIENT_SHALLOW (1u << 18)
#define HIDDEN_REF (1u << 19)
static unsigned long oldest_have; static unsigned long oldest_have;
...@@ -33,6 +34,7 @@ static int multi_ack; ...@@ -33,6 +34,7 @@ static int multi_ack;
static int no_done; static int no_done;
static int use_thin_pack, use_ofs_delta, use_include_tag; static int use_thin_pack, use_ofs_delta, use_include_tag;
static int no_progress, daemon_mode; static int no_progress, daemon_mode;
static int allow_tip_sha1_in_want;
static int shallow_nr; static int shallow_nr;
static struct object_array have_obj; static struct object_array have_obj;
static struct object_array want_obj; static struct object_array want_obj;
...@@ -487,6 +489,12 @@ static int get_common_commits(void) ...@@ -487,6 +489,12 @@ static int get_common_commits(void)
} }
} }
static int is_our_ref(struct object *o)
{
return o->flags &
((allow_tip_sha1_in_want ? HIDDEN_REF : 0) | OUR_REF);
}
static void check_non_tip(void) static void check_non_tip(void)
{ {
static const char *argv[] = { static const char *argv[] = {
...@@ -523,7 +531,7 @@ static void check_non_tip(void) ...@@ -523,7 +531,7 @@ static void check_non_tip(void)
o = get_indexed_object(--i); o = get_indexed_object(--i);
if (!o) if (!o)
continue; continue;
if (!(o->flags & OUR_REF)) if (!is_our_ref(o))
continue; continue;
memcpy(namebuf + 1, sha1_to_hex(o->sha1), 40); memcpy(namebuf + 1, sha1_to_hex(o->sha1), 40);
if (write_in_full(cmd.in, namebuf, 42) < 0) if (write_in_full(cmd.in, namebuf, 42) < 0)
...@@ -532,7 +540,7 @@ static void check_non_tip(void) ...@@ -532,7 +540,7 @@ static void check_non_tip(void)
namebuf[40] = '\n'; namebuf[40] = '\n';
for (i = 0; i < want_obj.nr; i++) { for (i = 0; i < want_obj.nr; i++) {
o = want_obj.objects[i].item; o = want_obj.objects[i].item;
if (o->flags & OUR_REF) if (is_our_ref(o))
continue; continue;
memcpy(namebuf, sha1_to_hex(o->sha1), 40); memcpy(namebuf, sha1_to_hex(o->sha1), 40);
if (write_in_full(cmd.in, namebuf, 41) < 0) if (write_in_full(cmd.in, namebuf, 41) < 0)
...@@ -566,7 +574,7 @@ static void check_non_tip(void) ...@@ -566,7 +574,7 @@ static void check_non_tip(void)
/* Pick one of them (we know there at least is one) */ /* Pick one of them (we know there at least is one) */
for (i = 0; i < want_obj.nr; i++) { for (i = 0; i < want_obj.nr; i++) {
o = want_obj.objects[i].item; o = want_obj.objects[i].item;
if (!(o->flags & OUR_REF)) if (!is_our_ref(o))
die("git upload-pack: not our ref %s", die("git upload-pack: not our ref %s",
sha1_to_hex(o->sha1)); sha1_to_hex(o->sha1));
} }
...@@ -646,7 +654,7 @@ static void receive_needs(void) ...@@ -646,7 +654,7 @@ static void receive_needs(void)
sha1_to_hex(sha1_buf)); sha1_to_hex(sha1_buf));
if (!(o->flags & WANTED)) { if (!(o->flags & WANTED)) {
o->flags |= WANTED; o->flags |= WANTED;
if (!(o->flags & OUR_REF)) if (!is_our_ref(o))
has_non_tip = 1; has_non_tip = 1;
add_object_array(o, NULL, &want_obj); add_object_array(o, NULL, &want_obj);
} }
...@@ -725,8 +733,10 @@ static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag ...@@ -725,8 +733,10 @@ static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag
{ {
struct object *o = lookup_unknown_object(sha1); struct object *o = lookup_unknown_object(sha1);
if (ref_is_hidden(refname)) if (ref_is_hidden(refname)) {
o->flags |= HIDDEN_REF;
return 1; return 1;
}
if (!o) if (!o)
die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1)); die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
o->flags |= OUR_REF; o->flags |= OUR_REF;
...@@ -745,9 +755,10 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo ...@@ -745,9 +755,10 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
return 0; return 0;
if (capabilities) if (capabilities)
packet_write(1, "%s %s%c%s%s agent=%s\n", packet_write(1, "%s %s%c%s%s%s agent=%s\n",
sha1_to_hex(sha1), refname_nons, sha1_to_hex(sha1), refname_nons,
0, capabilities, 0, capabilities,
allow_tip_sha1_in_want ? " allow-tip-sha1-in-want" : "",
stateless_rpc ? " no-done" : "", stateless_rpc ? " no-done" : "",
git_user_agent_sanitized()); git_user_agent_sanitized());
else else
...@@ -781,6 +792,8 @@ static void upload_pack(void) ...@@ -781,6 +792,8 @@ static void upload_pack(void)
static int upload_pack_config(const char *var, const char *value, void *unused) static int upload_pack_config(const char *var, const char *value, void *unused)
{ {
if (!strcmp("uploadpack.allowtipsha1inwant", var))
allow_tip_sha1_in_want = git_config_bool(var, value);
return parse_hide_refs_config(var, value, "uploadpack"); return parse_hide_refs_config(var, value, "uploadpack");
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册