@@ -80,6 +80,7 @@ static struct list_objects_filter_options filter_options;
8080static struct string_list server_options = STRING_LIST_INIT_DUP ;
8181static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP ;
8282static int fetch_write_commit_graph = -1 ;
83+ static int stdin_refspecs = 0 ;
8384
8485static int git_fetch_config (const char * k , const char * v , void * cb )
8586{
@@ -205,6 +206,8 @@ static struct option builtin_fetch_options[] = {
205206 N_ ("check for forced-updates on all updated branches" )),
206207 OPT_BOOL (0 , "write-commit-graph" , & fetch_write_commit_graph ,
207208 N_ ("write the commit-graph after fetching" )),
209+ OPT_BOOL (0 , "stdin" , & stdin_refspecs ,
210+ N_ ("accept refspecs from stdin" )),
208211 OPT_END ()
209212};
210213
@@ -442,6 +445,7 @@ static struct ref *get_ref_map(struct remote *remote,
442445 struct ref * orefs = NULL , * * oref_tail = & orefs ;
443446
444447 struct hashmap existing_refs ;
448+ int existing_refs_populated = 0 ;
445449
446450 if (rs -> nr ) {
447451 struct refspec * fetch_refspec ;
@@ -535,15 +539,18 @@ static struct ref *get_ref_map(struct remote *remote,
535539
536540 ref_map = ref_remove_duplicates (ref_map );
537541
538- refname_hash_init (& existing_refs );
539- for_each_ref (add_one_refname , & existing_refs );
540-
541542 for (rm = ref_map ; rm ; rm = rm -> next ) {
542543 if (rm -> peer_ref ) {
543544 const char * refname = rm -> peer_ref -> name ;
544545 struct refname_hash_entry * peer_item ;
545546 unsigned int hash = strhash (refname );
546547
548+ if (!existing_refs_populated ) {
549+ refname_hash_init (& existing_refs );
550+ for_each_ref (add_one_refname , & existing_refs );
551+ existing_refs_populated = 1 ;
552+ }
553+
547554 peer_item = hashmap_get_entry_from_hash (& existing_refs ,
548555 hash , refname ,
549556 struct refname_hash_entry , ent );
@@ -553,7 +560,8 @@ static struct ref *get_ref_map(struct remote *remote,
553560 }
554561 }
555562 }
556- hashmap_free_entries (& existing_refs , struct refname_hash_entry , ent );
563+ if (existing_refs_populated )
564+ hashmap_free_entries (& existing_refs , struct refname_hash_entry , ent );
557565
558566 return ref_map ;
559567}
@@ -1015,11 +1023,17 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
10151023 rc |= update_local_ref (ref , what , rm , & note ,
10161024 summary_width );
10171025 free (ref );
1018- } else
1026+ } else if (write_fetch_head || dry_run ) {
1027+ /*
1028+ * Display fetches written to FETCH_HEAD (or
1029+ * would be written to FETCH_HEAD, if --dry-run
1030+ * is set).
1031+ */
10191032 format_display (& note , '*' ,
10201033 * kind ? kind : "branch" , NULL ,
10211034 * what ? what : "HEAD" ,
10221035 "FETCH_HEAD" , summary_width );
1036+ }
10231037 if (note .len ) {
10241038 if (verbosity >= 0 && !shown_url ) {
10251039 fprintf (stderr , _ ("From %.*s\n" ),
@@ -1680,7 +1694,8 @@ static inline void fetch_one_setup_partial(struct remote *remote)
16801694 return ;
16811695}
16821696
1683- static int fetch_one (struct remote * remote , int argc , const char * * argv , int prune_tags_ok )
1697+ static int fetch_one (struct remote * remote , int argc , const char * * argv ,
1698+ int prune_tags_ok , int use_stdin_refspecs )
16841699{
16851700 struct refspec rs = REFSPEC_INIT_FETCH ;
16861701 int i ;
@@ -1737,6 +1752,13 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, int pru
17371752 }
17381753 }
17391754
1755+ if (use_stdin_refspecs ) {
1756+ struct strbuf line = STRBUF_INIT ;
1757+ while (strbuf_getline_lf (& line , stdin ) != EOF )
1758+ refspec_append (& rs , line .buf );
1759+ strbuf_release (& line );
1760+ }
1761+
17401762 if (server_options .nr )
17411763 gtransport -> server_options = & server_options ;
17421764
@@ -1771,12 +1793,18 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
17711793 free (anon );
17721794 }
17731795
1774- fetch_config_from_gitmodules (& submodule_fetch_jobs_config ,
1775- & recurse_submodules );
17761796 git_config (git_fetch_config , NULL );
17771797
17781798 argc = parse_options (argc , argv , prefix ,
17791799 builtin_fetch_options , builtin_fetch_usage , 0 );
1800+ if (recurse_submodules != RECURSE_SUBMODULES_OFF ) {
1801+ int * sfjc = submodule_fetch_jobs_config == -1
1802+ ? & submodule_fetch_jobs_config : NULL ;
1803+ int * rs = recurse_submodules == RECURSE_SUBMODULES_DEFAULT
1804+ ? & recurse_submodules : NULL ;
1805+
1806+ fetch_config_from_gitmodules (sfjc , rs );
1807+ }
17801808
17811809 if (deepen_relative ) {
17821810 if (deepen_relative < 0 )
@@ -1837,14 +1865,18 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
18371865 if (remote ) {
18381866 if (filter_options .choice || has_promisor_remote ())
18391867 fetch_one_setup_partial (remote );
1840- result = fetch_one (remote , argc , argv , prune_tags_ok );
1868+ result = fetch_one (remote , argc , argv , prune_tags_ok , stdin_refspecs );
18411869 } else {
18421870 int max_children = max_jobs ;
18431871
18441872 if (filter_options .choice )
18451873 die (_ ("--filter can only be used with the remote "
18461874 "configured in extensions.partialclone" ));
18471875
1876+ if (stdin_refspecs )
1877+ die (_ ("--stdin can only be used when fetching "
1878+ "from one remote" ));
1879+
18481880 if (max_children < 0 )
18491881 max_children = fetch_parallel_config ;
18501882
0 commit comments