14
14
15
15
static const char * const builtin_fetch_usage [] = {
16
16
"git fetch [options] [<repository> <refspec>...]" ,
17
+ "git fetch [options] <group>" ,
18
+ "git fetch --all [options]" ,
17
19
NULL
18
20
};
19
21
23
25
TAGS_SET = 2
24
26
};
25
27
26
- static int append , force , keep , update_head_ok , verbosity ;
28
+ static int all , append , force , keep , update_head_ok , verbosity ;
27
29
static int tags = TAGS_DEFAULT ;
28
30
static const char * depth ;
29
31
static const char * upload_pack ;
@@ -32,6 +34,8 @@ static struct transport *transport;
32
34
33
35
static struct option builtin_fetch_options [] = {
34
36
OPT__VERBOSITY (& verbosity ),
37
+ OPT_BOOLEAN (0 , "all" , & all ,
38
+ "fetch from all remotes" ),
35
39
OPT_BOOLEAN ('a' , "append" , & append ,
36
40
"append to .git/FETCH_HEAD instead of overwriting" ),
37
41
OPT_STRING (0 , "upload-pack" , & upload_pack , "PATH" ,
@@ -639,27 +643,89 @@ static void set_option(const char *name, const char *value)
639
643
name , transport -> url );
640
644
}
641
645
642
- int cmd_fetch (int argc , const char * * argv , const char * prefix )
646
+ static int get_one_remote_for_fetch (struct remote * remote , void * priv )
647
+ {
648
+ struct string_list * list = priv ;
649
+ string_list_append (remote -> name , list );
650
+ return 0 ;
651
+ }
652
+
653
+ struct remote_group_data {
654
+ const char * name ;
655
+ struct string_list * list ;
656
+ };
657
+
658
+ static int get_remote_group (const char * key , const char * value , void * priv )
659
+ {
660
+ struct remote_group_data * g = priv ;
661
+
662
+ if (!prefixcmp (key , "remotes." ) &&
663
+ !strcmp (key + 8 , g -> name )) {
664
+ /* split list by white space */
665
+ int space = strcspn (value , " \t\n" );
666
+ while (* value ) {
667
+ if (space > 1 ) {
668
+ string_list_append (xstrndup (value , space ),
669
+ g -> list );
670
+ }
671
+ value += space + (value [space ] != '\0' );
672
+ space = strcspn (value , " \t\n" );
673
+ }
674
+ }
675
+
676
+ return 0 ;
677
+ }
678
+
679
+ static int add_remote_or_group (const char * name , struct string_list * list )
680
+ {
681
+ int prev_nr = list -> nr ;
682
+ struct remote_group_data g = { name , list };
683
+
684
+ git_config (get_remote_group , & g );
685
+ if (list -> nr == prev_nr ) {
686
+ struct remote * remote ;
687
+ if (!remote_is_configured (name ))
688
+ return 0 ;
689
+ remote = remote_get (name );
690
+ string_list_append (remote -> name , list );
691
+ }
692
+ return 1 ;
693
+ }
694
+
695
+ static int fetch_multiple (struct string_list * list )
696
+ {
697
+ int i , result = 0 ;
698
+ const char * argv [] = { "fetch" , NULL , NULL , NULL , NULL };
699
+ int argc = 1 ;
700
+
701
+ if (verbosity >= 2 )
702
+ argv [argc ++ ] = "-v" ;
703
+ if (verbosity >= 1 )
704
+ argv [argc ++ ] = "-v" ;
705
+ else if (verbosity < 0 )
706
+ argv [argc ++ ] = "-q" ;
707
+
708
+ for (i = 0 ; i < list -> nr ; i ++ ) {
709
+ const char * name = list -> items [i ].string ;
710
+ argv [argc ] = name ;
711
+ if (verbosity >= 0 )
712
+ printf ("Fetching %s\n" , name );
713
+ if (run_command_v_opt (argv , RUN_GIT_CMD )) {
714
+ error ("Could not fetch %s" , name );
715
+ result = 1 ;
716
+ }
717
+ }
718
+
719
+ return result ;
720
+ }
721
+
722
+ static int fetch_one (struct remote * remote , int argc , const char * * argv )
643
723
{
644
- struct remote * remote ;
645
724
int i ;
646
725
static const char * * refs = NULL ;
647
726
int ref_nr = 0 ;
648
727
int exit_code ;
649
728
650
- /* Record the command line for the reflog */
651
- strbuf_addstr (& default_rla , "fetch" );
652
- for (i = 1 ; i < argc ; i ++ )
653
- strbuf_addf (& default_rla , " %s" , argv [i ]);
654
-
655
- argc = parse_options (argc , argv , prefix ,
656
- builtin_fetch_options , builtin_fetch_usage , 0 );
657
-
658
- if (argc == 0 )
659
- remote = remote_get (NULL );
660
- else
661
- remote = remote_get (argv [0 ]);
662
-
663
729
if (!remote )
664
730
die ("Where do you want to fetch from today?" );
665
731
@@ -675,10 +741,10 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
675
741
if (depth )
676
742
set_option (TRANS_OPT_DEPTH , depth );
677
743
678
- if (argc > 1 ) {
744
+ if (argc > 0 ) {
679
745
int j = 0 ;
680
746
refs = xcalloc (argc + 1 , sizeof (const char * ));
681
- for (i = 1 ; i < argc ; i ++ ) {
747
+ for (i = 0 ; i < argc ; i ++ ) {
682
748
if (!strcmp (argv [i ], "tag" )) {
683
749
char * ref ;
684
750
i ++ ;
@@ -705,3 +771,51 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
705
771
transport = NULL ;
706
772
return exit_code ;
707
773
}
774
+
775
+ int cmd_fetch (int argc , const char * * argv , const char * prefix )
776
+ {
777
+ int i ;
778
+ struct string_list list = { NULL , 0 , 0 , 0 };
779
+ struct remote * remote ;
780
+ int result = 0 ;
781
+
782
+ /* Record the command line for the reflog */
783
+ strbuf_addstr (& default_rla , "fetch" );
784
+ for (i = 1 ; i < argc ; i ++ )
785
+ strbuf_addf (& default_rla , " %s" , argv [i ]);
786
+
787
+ argc = parse_options (argc , argv , prefix ,
788
+ builtin_fetch_options , builtin_fetch_usage , 0 );
789
+
790
+ if (all ) {
791
+ if (argc == 1 )
792
+ die ("fetch --all does not take a repository argument" );
793
+ else if (argc > 1 )
794
+ die ("fetch --all does not make sense with refspecs" );
795
+ (void ) for_each_remote (get_one_remote_for_fetch , & list );
796
+ result = fetch_multiple (& list );
797
+ } else if (argc == 0 ) {
798
+ /* No arguments -- use default remote */
799
+ remote = remote_get (NULL );
800
+ result = fetch_one (remote , argc , argv );
801
+ } else {
802
+ /* Single remote or group */
803
+ (void ) add_remote_or_group (argv [0 ], & list );
804
+ if (list .nr > 1 ) {
805
+ /* More than one remote */
806
+ if (argc > 1 )
807
+ die ("Fetching a group and specifying refspecs does not make sense" );
808
+ result = fetch_multiple (& list );
809
+ } else {
810
+ /* Zero or one remotes */
811
+ remote = remote_get (argv [0 ]);
812
+ result = fetch_one (remote , argc - 1 , argv + 1 );
813
+ }
814
+ }
815
+
816
+ /* All names were strdup()ed or strndup()ed */
817
+ list .strdup_strings = 1 ;
818
+ string_list_clear (& list , 0 );
819
+
820
+ return result ;
821
+ }
0 commit comments