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