@@ -99,6 +99,7 @@ static struct transport *gsecondary;
9999static struct refspec refmap = REFSPEC_INIT_FETCH ;
100100static struct string_list server_options = STRING_LIST_INIT_DUP ;
101101static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP ;
102+ static struct string_list negotiation_require = STRING_LIST_INIT_NODUP ;
102103
103104struct fetch_config {
104105 enum display_format display_format ;
@@ -1534,7 +1535,7 @@ static int add_oid(const struct reference *ref, void *cb_data)
15341535 return 0 ;
15351536}
15361537
1537- static void add_negotiation_tips (struct git_transport_options * smart_options )
1538+ static void add_negotiation_restrict_tips (struct git_transport_options * smart_options )
15381539{
15391540 struct oid_array * oids = xcalloc (1 , sizeof (* oids ));
15401541 int i ;
@@ -1558,10 +1559,10 @@ static void add_negotiation_tips(struct git_transport_options *smart_options)
15581559 refs_for_each_ref_ext (get_main_ref_store (the_repository ),
15591560 add_oid , oids , & opts );
15601561 if (old_nr == oids -> nr )
1561- warning ("ignoring --negotiation-tip =%s because it does not match any refs" ,
1562- s );
1562+ warning (_ ( "ignoring %s =%s because it does not match any refs" ) ,
1563+ "--negotiation-restrict" , s );
15631564 }
1564- smart_options -> negotiation_tips = oids ;
1565+ smart_options -> negotiation_restrict_tips = oids ;
15651566}
15661567
15671568static struct transport * prepare_transport (struct remote * remote , int deepen ,
@@ -1597,9 +1598,40 @@ static struct transport *prepare_transport(struct remote *remote, int deepen,
15971598 }
15981599 if (negotiation_tip .nr ) {
15991600 if (transport -> smart_options )
1600- add_negotiation_tips (transport -> smart_options );
1601+ add_negotiation_restrict_tips (transport -> smart_options );
16011602 else
1602- warning ("ignoring --negotiation-tip because the protocol does not support it" );
1603+ warning (_ ("ignoring %s because the protocol does not support it" ),
1604+ "--negotiation-restrict" );
1605+ } else if (remote -> negotiation_restrict .nr ) {
1606+ struct string_list_item * item ;
1607+ for_each_string_list_item (item , & remote -> negotiation_restrict )
1608+ string_list_append (& negotiation_tip , item -> string );
1609+ if (transport -> smart_options )
1610+ add_negotiation_restrict_tips (transport -> smart_options );
1611+ else {
1612+ struct strbuf config_name = STRBUF_INIT ;
1613+ strbuf_addf (& config_name , "remote.%s.negotiationRestrict" , remote -> name );
1614+ warning (_ ("ignoring %s because the protocol does not support it" ),
1615+ config_name .buf );
1616+ strbuf_release (& config_name );
1617+ }
1618+ }
1619+ if (negotiation_require .nr ) {
1620+ if (transport -> smart_options )
1621+ transport -> smart_options -> negotiation_require = & negotiation_require ;
1622+ else
1623+ warning (_ ("ignoring %s because the protocol does not support it" ),
1624+ "--negotiation-require" );
1625+ } else if (remote -> negotiation_require .nr ) {
1626+ if (transport -> smart_options ) {
1627+ transport -> smart_options -> negotiation_require = & remote -> negotiation_require ;
1628+ } else {
1629+ struct strbuf config_name = STRBUF_INIT ;
1630+ strbuf_addf (& config_name , "remote.%s.negotiationRequire" , remote -> name );
1631+ warning (_ ("ignoring %s because the protocol does not support it" ),
1632+ config_name .buf );
1633+ strbuf_release (& config_name );
1634+ }
16031635 }
16041636 return transport ;
16051637}
@@ -2525,6 +2557,10 @@ int cmd_fetch(int argc,
25252557 OPT_IPVERSION (& family ),
25262558 OPT_STRING_LIST (0 , "negotiation-tip" , & negotiation_tip , N_ ("revision" ),
25272559 N_ ("report that we have only objects reachable from this object" )),
2560+ OPT_STRING_LIST (0 , "negotiation-restrict" , & negotiation_tip , N_ ("revision" ),
2561+ N_ ("report that we have only objects reachable from this object" )),
2562+ OPT_STRING_LIST (0 , "negotiation-require" , & negotiation_require , N_ ("revision" ),
2563+ N_ ("ensure this ref is always sent as a negotiation have" )),
25282564 OPT_BOOL (0 , "negotiate-only" , & negotiate_only ,
25292565 N_ ("do not fetch a packfile; instead, print ancestors of negotiation tips" )),
25302566 OPT_PARSE_LIST_OBJECTS_FILTER (& filter_options ),
@@ -2614,8 +2650,12 @@ int cmd_fetch(int argc,
26142650 config .display_format = DISPLAY_FORMAT_PORCELAIN ;
26152651 }
26162652
2617- if (negotiate_only && !negotiation_tip .nr )
2618- die (_ ("--negotiate-only needs one or more --negotiation-tip=*" ));
2653+ if (negotiate_only && !negotiation_tip .nr ) {
2654+ /*
2655+ * Defer this check: remote.<name>.negotiationRestrict may
2656+ * provide defaults in prepare_transport().
2657+ */
2658+ }
26192659
26202660 if (deepen_relative ) {
26212661 if (deepen_relative < 0 )
@@ -2704,6 +2744,9 @@ int cmd_fetch(int argc,
27042744 if (!remote )
27052745 die (_ ("must supply remote when using --negotiate-only" ));
27062746 gtransport = prepare_transport (remote , 1 , & filter_options );
2747+ if (!gtransport -> smart_options ||
2748+ !gtransport -> smart_options -> negotiation_restrict_tips )
2749+ die (_ ("--negotiate-only needs one or more --negotiation-restrict=*" ));
27072750 if (gtransport -> smart_options ) {
27082751 gtransport -> smart_options -> acked_commits = & acked_commits ;
27092752 } else {
0 commit comments