18
18
#include "shortlog.h"
19
19
#include "remote.h"
20
20
#include "string-list.h"
21
+ #include "parse-options.h"
21
22
22
23
/* Set a default date-time format for git log ("log.date" config variable) */
23
24
static const char * default_date_mode = NULL ;
@@ -740,27 +741,179 @@ static const char *set_outdir(const char *prefix, const char *output_directory)
740
741
output_directory ));
741
742
}
742
743
744
+ static const char * const builtin_format_patch_usage [] = {
745
+ "git format-patch [options] [<since> | <revision range>]" ,
746
+ NULL
747
+ };
748
+
749
+ static int keep_subject = 0 ;
750
+
751
+ static int keep_callback (const struct option * opt , const char * arg , int unset )
752
+ {
753
+ ((struct rev_info * )opt -> value )-> total = -1 ;
754
+ keep_subject = 1 ;
755
+ return 0 ;
756
+ }
757
+
758
+ static int subject_prefix = 0 ;
759
+
760
+ static int subject_prefix_callback (const struct option * opt , const char * arg ,
761
+ int unset )
762
+ {
763
+ subject_prefix = 1 ;
764
+ ((struct rev_info * )opt -> value )-> subject_prefix = arg ;
765
+ return 0 ;
766
+ }
767
+
768
+ static int numbered_cmdline_opt = 0 ;
769
+
770
+ static int numbered_callback (const struct option * opt , const char * arg ,
771
+ int unset )
772
+ {
773
+ * (int * )opt -> value = numbered_cmdline_opt = unset ? 0 : 1 ;
774
+ if (unset )
775
+ auto_number = 0 ;
776
+ return 0 ;
777
+ }
778
+
779
+ static int no_numbered_callback (const struct option * opt , const char * arg ,
780
+ int unset )
781
+ {
782
+ return numbered_callback (opt , arg , 1 );
783
+ }
784
+
785
+ static int output_directory_callback (const struct option * opt , const char * arg ,
786
+ int unset )
787
+ {
788
+ const char * * dir = (const char * * )opt -> value ;
789
+ if (* dir )
790
+ die ("Two output directories?" );
791
+ * dir = arg ;
792
+ return 0 ;
793
+ }
794
+
795
+ static int thread_callback (const struct option * opt , const char * arg , int unset )
796
+ {
797
+ int * thread = (int * )opt -> value ;
798
+ if (unset )
799
+ * thread = 0 ;
800
+ else if (!arg || !strcmp (arg , "shallow" ))
801
+ * thread = THREAD_SHALLOW ;
802
+ else if (!strcmp (arg , "deep" ))
803
+ * thread = THREAD_DEEP ;
804
+ else
805
+ return 1 ;
806
+ return 0 ;
807
+ }
808
+
809
+ static int attach_callback (const struct option * opt , const char * arg , int unset )
810
+ {
811
+ struct rev_info * rev = (struct rev_info * )opt -> value ;
812
+ if (unset )
813
+ rev -> mime_boundary = NULL ;
814
+ else if (arg )
815
+ rev -> mime_boundary = arg ;
816
+ else
817
+ rev -> mime_boundary = git_version_string ;
818
+ rev -> no_inline = unset ? 0 : 1 ;
819
+ return 0 ;
820
+ }
821
+
822
+ static int inline_callback (const struct option * opt , const char * arg , int unset )
823
+ {
824
+ struct rev_info * rev = (struct rev_info * )opt -> value ;
825
+ if (unset )
826
+ rev -> mime_boundary = NULL ;
827
+ else if (arg )
828
+ rev -> mime_boundary = arg ;
829
+ else
830
+ rev -> mime_boundary = git_version_string ;
831
+ rev -> no_inline = 0 ;
832
+ return 0 ;
833
+ }
834
+
835
+ static int header_callback (const struct option * opt , const char * arg , int unset )
836
+ {
837
+ add_header (arg );
838
+ return 0 ;
839
+ }
840
+
841
+ static int cc_callback (const struct option * opt , const char * arg , int unset )
842
+ {
843
+ ALLOC_GROW (extra_cc , extra_cc_nr + 1 , extra_cc_alloc );
844
+ extra_cc [extra_cc_nr ++ ] = xstrdup (arg );
845
+ return 0 ;
846
+ }
847
+
743
848
int cmd_format_patch (int argc , const char * * argv , const char * prefix )
744
849
{
745
850
struct commit * commit ;
746
851
struct commit * * list = NULL ;
747
852
struct rev_info rev ;
748
- int nr = 0 , total , i , j ;
853
+ int nr = 0 , total , i ;
749
854
int use_stdout = 0 ;
750
855
int start_number = -1 ;
751
- int keep_subject = 0 ;
752
856
int numbered_files = 0 ; /* _just_ numbers */
753
- int subject_prefix = 0 ;
754
857
int ignore_if_in_upstream = 0 ;
755
858
int cover_letter = 0 ;
756
859
int boundary_count = 0 ;
757
860
int no_binary_diff = 0 ;
758
- int numbered_cmdline_opt = 0 ;
759
861
struct commit * origin = NULL , * head = NULL ;
760
862
const char * in_reply_to = NULL ;
761
863
struct patch_ids ids ;
762
864
char * add_signoff = NULL ;
763
865
struct strbuf buf = STRBUF_INIT ;
866
+ const struct option builtin_format_patch_options [] = {
867
+ { OPTION_CALLBACK , 'n' , "numbered" , & numbered , NULL ,
868
+ "use [PATCH n/m] even with a single patch" ,
869
+ PARSE_OPT_NOARG , numbered_callback },
870
+ { OPTION_CALLBACK , 'N' , "no-numbered" , & numbered , NULL ,
871
+ "use [PATCH] even with multiple patches" ,
872
+ PARSE_OPT_NOARG , no_numbered_callback },
873
+ OPT_BOOLEAN ('s' , "signoff" , & do_signoff , "add Signed-off-by:" ),
874
+ OPT_BOOLEAN (0 , "stdout" , & use_stdout ,
875
+ "print patches to standard out" ),
876
+ OPT_BOOLEAN (0 , "cover-letter" , & cover_letter ,
877
+ "generate a cover letter" ),
878
+ OPT_BOOLEAN (0 , "numbered-files" , & numbered_files ,
879
+ "use simple number sequence for output file names" ),
880
+ OPT_STRING (0 , "suffix" , & fmt_patch_suffix , "sfx" ,
881
+ "use <sfx> instead of '.patch'" ),
882
+ OPT_INTEGER (0 , "start-number" , & start_number ,
883
+ "start numbering patches at <n> instead of 1" ),
884
+ { OPTION_CALLBACK , 0 , "subject-prefix" , & rev , "prefix" ,
885
+ "Use [<prefix>] instead of [PATCH]" ,
886
+ PARSE_OPT_NONEG , subject_prefix_callback },
887
+ { OPTION_CALLBACK , 'o' , "output-directory" , & output_directory ,
888
+ "dir" , "store resulting files in <dir>" ,
889
+ PARSE_OPT_NONEG , output_directory_callback },
890
+ { OPTION_CALLBACK , 'k' , "keep-subject" , & rev , NULL ,
891
+ "don't strip/add [PATCH]" ,
892
+ PARSE_OPT_NOARG | PARSE_OPT_NONEG , keep_callback },
893
+ OPT_BOOLEAN (0 , "no-binary" , & no_binary_diff ,
894
+ "don't output binary diffs" ),
895
+ OPT_BOOLEAN (0 , "ignore-if-in-upstream" , & ignore_if_in_upstream ,
896
+ "don't include a patch matching a commit upstream" ),
897
+ OPT_GROUP ("Messaging" ),
898
+ { OPTION_CALLBACK , 0 , "add-header" , NULL , "header" ,
899
+ "add email header" , PARSE_OPT_NONEG ,
900
+ header_callback },
901
+ { OPTION_CALLBACK , 0 , "cc" , NULL , "email" , "add Cc: header" ,
902
+ PARSE_OPT_NONEG , cc_callback },
903
+ OPT_STRING (0 , "in-reply-to" , & in_reply_to , "message-id" ,
904
+ "make first mail a reply to <message-id>" ),
905
+ { OPTION_CALLBACK , 0 , "attach" , & rev , "boundary" ,
906
+ "attach the patch" , PARSE_OPT_OPTARG ,
907
+ attach_callback },
908
+ { OPTION_CALLBACK , 0 , "inline" , & rev , "boundary" ,
909
+ "inline the patch" ,
910
+ PARSE_OPT_OPTARG | PARSE_OPT_NONEG ,
911
+ inline_callback },
912
+ { OPTION_CALLBACK , 0 , "thread" , & thread , "style" ,
913
+ "enable message threading, styles: shallow, deep" ,
914
+ PARSE_OPT_OPTARG , thread_callback },
915
+ OPT_END ()
916
+ };
764
917
765
918
git_config (git_format_config , NULL );
766
919
init_revisions (& rev , prefix );
@@ -783,102 +936,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
783
936
* like "git format-patch -o a123 HEAD^.." may fail; a123 is
784
937
* possibly a valid SHA1.
785
938
*/
786
- for (i = 1 , j = 1 ; i < argc ; i ++ ) {
787
- if (!strcmp (argv [i ], "--stdout" ))
788
- use_stdout = 1 ;
789
- else if (!strcmp (argv [i ], "-n" ) ||
790
- !strcmp (argv [i ], "--numbered" )) {
791
- numbered = 1 ;
792
- numbered_cmdline_opt = 1 ;
793
- }
794
- else if (!strcmp (argv [i ], "-N" ) ||
795
- !strcmp (argv [i ], "--no-numbered" )) {
796
- numbered = 0 ;
797
- auto_number = 0 ;
798
- }
799
- else if (!prefixcmp (argv [i ], "--start-number=" ))
800
- start_number = strtol (argv [i ] + 15 , NULL , 10 );
801
- else if (!strcmp (argv [i ], "--numbered-files" ))
802
- numbered_files = 1 ;
803
- else if (!strcmp (argv [i ], "--start-number" )) {
804
- i ++ ;
805
- if (i == argc )
806
- die ("Need a number for --start-number" );
807
- start_number = strtol (argv [i ], NULL , 10 );
808
- }
809
- else if (!prefixcmp (argv [i ], "--cc=" )) {
810
- ALLOC_GROW (extra_cc , extra_cc_nr + 1 , extra_cc_alloc );
811
- extra_cc [extra_cc_nr ++ ] = xstrdup (argv [i ] + 5 );
812
- }
813
- else if (!strcmp (argv [i ], "-k" ) ||
814
- !strcmp (argv [i ], "--keep-subject" )) {
815
- keep_subject = 1 ;
816
- rev .total = -1 ;
817
- }
818
- else if (!strcmp (argv [i ], "--output-directory" ) ||
819
- !strcmp (argv [i ], "-o" )) {
820
- i ++ ;
821
- if (argc <= i )
822
- die ("Which directory?" );
823
- if (output_directory )
824
- die ("Two output directories?" );
825
- output_directory = argv [i ];
826
- }
827
- else if (!strcmp (argv [i ], "--signoff" ) ||
828
- !strcmp (argv [i ], "-s" )) {
829
- do_signoff = 1 ;
830
- }
831
- else if (!strcmp (argv [i ], "--attach" )) {
832
- rev .mime_boundary = git_version_string ;
833
- rev .no_inline = 1 ;
834
- }
835
- else if (!prefixcmp (argv [i ], "--attach=" )) {
836
- rev .mime_boundary = argv [i ] + 9 ;
837
- rev .no_inline = 1 ;
838
- }
839
- else if (!strcmp (argv [i ], "--no-attach" )) {
840
- rev .mime_boundary = NULL ;
841
- rev .no_inline = 0 ;
842
- }
843
- else if (!strcmp (argv [i ], "--inline" )) {
844
- rev .mime_boundary = git_version_string ;
845
- rev .no_inline = 0 ;
846
- }
847
- else if (!prefixcmp (argv [i ], "--inline=" )) {
848
- rev .mime_boundary = argv [i ] + 9 ;
849
- rev .no_inline = 0 ;
850
- }
851
- else if (!strcmp (argv [i ], "--ignore-if-in-upstream" ))
852
- ignore_if_in_upstream = 1 ;
853
- else if (!strcmp (argv [i ], "--thread" )
854
- || !strcmp (argv [i ], "--thread=shallow" ))
855
- thread = THREAD_SHALLOW ;
856
- else if (!strcmp (argv [i ], "--thread=deep" ))
857
- thread = THREAD_DEEP ;
858
- else if (!strcmp (argv [i ], "--no-thread" ))
859
- thread = 0 ;
860
- else if (!prefixcmp (argv [i ], "--in-reply-to=" ))
861
- in_reply_to = argv [i ] + 14 ;
862
- else if (!strcmp (argv [i ], "--in-reply-to" )) {
863
- i ++ ;
864
- if (i == argc )
865
- die ("Need a Message-Id for --in-reply-to" );
866
- in_reply_to = argv [i ];
867
- } else if (!prefixcmp (argv [i ], "--subject-prefix=" )) {
868
- subject_prefix = 1 ;
869
- rev .subject_prefix = argv [i ] + 17 ;
870
- } else if (!prefixcmp (argv [i ], "--suffix=" ))
871
- fmt_patch_suffix = argv [i ] + 9 ;
872
- else if (!strcmp (argv [i ], "--cover-letter" ))
873
- cover_letter = 1 ;
874
- else if (!strcmp (argv [i ], "--no-binary" ))
875
- no_binary_diff = 1 ;
876
- else if (!prefixcmp (argv [i ], "--add-header=" ))
877
- add_header (argv [i ] + 13 );
878
- else
879
- argv [j ++ ] = argv [i ];
880
- }
881
- argc = j ;
939
+ argc = parse_options (argc , argv , builtin_format_patch_options ,
940
+ builtin_format_patch_usage ,
941
+ PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN );
882
942
883
943
if (do_signoff ) {
884
944
const char * committer ;
0 commit comments