@@ -35,7 +35,11 @@ static int multi_ack;
3535static int no_done ;
3636static int use_thin_pack , use_ofs_delta , use_include_tag ;
3737static int no_progress , daemon_mode ;
38- static int allow_tip_sha1_in_want ;
38+ /* Allow specifying sha1 if it is a ref tip. */
39+ #define ALLOW_TIP_SHA1 01
40+ /* Allow request of a sha1 if it is reachable from a ref (possibly hidden ref). */
41+ #define ALLOW_REACHABLE_SHA1 02
42+ static unsigned int allow_unadvertised_object_request ;
3943static int shallow_nr ;
4044static struct object_array have_obj ;
4145static struct object_array want_obj ;
@@ -442,8 +446,9 @@ static int get_common_commits(void)
442446
443447static int is_our_ref (struct object * o )
444448{
445- return o -> flags &
446- ((allow_tip_sha1_in_want ? HIDDEN_REF : 0 ) | OUR_REF );
449+ int allow_hidden_ref = (allow_unadvertised_object_request &
450+ (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1 ));
451+ return o -> flags & ((allow_hidden_ref ? HIDDEN_REF : 0 ) | OUR_REF );
447452}
448453
449454static void check_non_tip (void )
@@ -456,8 +461,12 @@ static void check_non_tip(void)
456461 char namebuf [42 ]; /* ^ + SHA-1 + LF */
457462 int i ;
458463
459- /* In the normal in-process case non-tip request can never happen */
460- if (!stateless_rpc )
464+ /*
465+ * In the normal in-process case without
466+ * uploadpack.allowReachableSHA1InWant,
467+ * non-tip requests can never happen.
468+ */
469+ if (!stateless_rpc && !(allow_unadvertised_object_request & ALLOW_REACHABLE_SHA1 ))
461470 goto error ;
462471
463472 cmd .argv = argv ;
@@ -724,10 +733,13 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
724733 struct strbuf symref_info = STRBUF_INIT ;
725734
726735 format_symref_info (& symref_info , cb_data );
727- packet_write (1 , "%s %s%c%s%s%s%s agent=%s\n" ,
736+ packet_write (1 , "%s %s%c%s%s%s%s%s agent=%s\n" ,
728737 sha1_to_hex (sha1 ), refname_nons ,
729738 0 , capabilities ,
730- allow_tip_sha1_in_want ? " allow-tip-sha1-in-want" : "" ,
739+ (allow_unadvertised_object_request & ALLOW_TIP_SHA1 ) ?
740+ " allow-tip-sha1-in-want" : "" ,
741+ (allow_unadvertised_object_request & ALLOW_REACHABLE_SHA1 ) ?
742+ " allow-reachable-sha1-in-want" : "" ,
731743 stateless_rpc ? " no-done" : "" ,
732744 symref_info .buf ,
733745 git_user_agent_sanitized ());
@@ -787,9 +799,17 @@ static void upload_pack(void)
787799
788800static int upload_pack_config (const char * var , const char * value , void * unused )
789801{
790- if (!strcmp ("uploadpack.allowtipsha1inwant" , var ))
791- allow_tip_sha1_in_want = git_config_bool (var , value );
792- else if (!strcmp ("uploadpack.keepalive" , var )) {
802+ if (!strcmp ("uploadpack.allowtipsha1inwant" , var )) {
803+ if (git_config_bool (var , value ))
804+ allow_unadvertised_object_request |= ALLOW_TIP_SHA1 ;
805+ else
806+ allow_unadvertised_object_request &= ~ALLOW_TIP_SHA1 ;
807+ } else if (!strcmp ("uploadpack.allowreachablesha1inwant" , var )) {
808+ if (git_config_bool (var , value ))
809+ allow_unadvertised_object_request |= ALLOW_REACHABLE_SHA1 ;
810+ else
811+ allow_unadvertised_object_request &= ~ALLOW_REACHABLE_SHA1 ;
812+ } else if (!strcmp ("uploadpack.keepalive" , var )) {
793813 keepalive = git_config_int (var , value );
794814 if (!keepalive )
795815 keepalive = -1 ;
0 commit comments