1212#include "builtin.h"
1313#include "utf8.h"
1414#include "gpg-interface.h"
15+ #include "parse-options.h"
1516
16- static const char commit_tree_usage [] = "git commit-tree [(-p <sha1>)...] [-S[<keyid>]] [-m <message>] [-F <file>] <sha1>" ;
17+ static const char * const commit_tree_usage [] = {
18+ N_ ("git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] "
19+ "[(-F <file>)...] <tree>" ),
20+ NULL
21+ };
1722
1823static const char * sign_commit ;
1924
@@ -23,7 +28,7 @@ static void new_parent(struct commit *parent, struct commit_list **parents_p)
2328 struct commit_list * parents ;
2429 for (parents = * parents_p ; parents ; parents = parents -> next ) {
2530 if (parents -> item == parent ) {
26- error ("duplicate parent %s ignored" , oid_to_hex (oid ));
31+ error (_ ( "duplicate parent %s ignored" ) , oid_to_hex (oid ));
2732 return ;
2833 }
2934 parents_p = & parents -> next ;
@@ -39,91 +44,100 @@ static int commit_tree_config(const char *var, const char *value, void *cb)
3944 return git_default_config (var , value , cb );
4045}
4146
47+ static int parse_parent_arg_callback (const struct option * opt ,
48+ const char * arg , int unset )
49+ {
50+ struct object_id oid ;
51+ struct commit_list * * parents = opt -> value ;
52+
53+ BUG_ON_OPT_NEG_NOARG (unset , arg );
54+
55+ if (get_oid_commit (arg , & oid ))
56+ die (_ ("not a valid object name %s" ), arg );
57+
58+ assert_oid_type (& oid , OBJ_COMMIT );
59+ new_parent (lookup_commit (the_repository , & oid ), parents );
60+ return 0 ;
61+ }
62+
63+ static int parse_message_arg_callback (const struct option * opt ,
64+ const char * arg , int unset )
65+ {
66+ struct strbuf * buf = opt -> value ;
67+
68+ BUG_ON_OPT_NEG_NOARG (unset , arg );
69+
70+ if (buf -> len )
71+ strbuf_addch (buf , '\n' );
72+ strbuf_addstr (buf , arg );
73+ strbuf_complete_line (buf );
74+
75+ return 0 ;
76+ }
77+
78+ static int parse_file_arg_callback (const struct option * opt ,
79+ const char * arg , int unset )
80+ {
81+ int fd ;
82+ struct strbuf * buf = opt -> value ;
83+
84+ BUG_ON_OPT_NEG_NOARG (unset , arg );
85+
86+ if (buf -> len )
87+ strbuf_addch (buf , '\n' );
88+ if (!strcmp (arg , "-" ))
89+ fd = 0 ;
90+ else {
91+ fd = open (arg , O_RDONLY );
92+ if (fd < 0 )
93+ die_errno (_ ("git commit-tree: failed to open '%s'" ), arg );
94+ }
95+ if (strbuf_read (buf , fd , 0 ) < 0 )
96+ die_errno (_ ("git commit-tree: failed to read '%s'" ), arg );
97+ if (fd && close (fd ))
98+ die_errno (_ ("git commit-tree: failed to close '%s'" ), arg );
99+
100+ return 0 ;
101+ }
102+
42103int cmd_commit_tree (int argc , const char * * argv , const char * prefix )
43104{
44- int i , got_tree = 0 ;
105+ static struct strbuf buffer = STRBUF_INIT ;
45106 struct commit_list * parents = NULL ;
46107 struct object_id tree_oid ;
47108 struct object_id commit_oid ;
48- struct strbuf buffer = STRBUF_INIT ;
109+
110+ struct option options [] = {
111+ { OPTION_CALLBACK , 'p' , NULL , & parents , N_ ("parent" ),
112+ N_ ("id of a parent commit object" ), PARSE_OPT_NONEG ,
113+ parse_parent_arg_callback },
114+ { OPTION_CALLBACK , 'm' , NULL , & buffer , N_ ("message" ),
115+ N_ ("commit message" ), PARSE_OPT_NONEG ,
116+ parse_message_arg_callback },
117+ { OPTION_CALLBACK , 'F' , NULL , & buffer , N_ ("file" ),
118+ N_ ("read commit log message from file" ), PARSE_OPT_NONEG ,
119+ parse_file_arg_callback },
120+ { OPTION_STRING , 'S' , "gpg-sign" , & sign_commit , N_ ("key-id" ),
121+ N_ ("GPG sign commit" ), PARSE_OPT_OPTARG , NULL , (intptr_t ) "" },
122+ OPT_END ()
123+ };
49124
50125 git_config (commit_tree_config , NULL );
51126
52127 if (argc < 2 || !strcmp (argv [1 ], "-h" ))
53- usage (commit_tree_usage );
54-
55- for (i = 1 ; i < argc ; i ++ ) {
56- const char * arg = argv [i ];
57- if (!strcmp (arg , "-p" )) {
58- struct object_id oid ;
59- if (argc <= ++ i )
60- usage (commit_tree_usage );
61- if (get_oid_commit (argv [i ], & oid ))
62- die ("Not a valid object name %s" , argv [i ]);
63- assert_oid_type (& oid , OBJ_COMMIT );
64- new_parent (lookup_commit (the_repository , & oid ),
65- & parents );
66- continue ;
67- }
128+ usage_with_options (commit_tree_usage , options );
68129
69- if (!strcmp (arg , "--gpg-sign" )) {
70- sign_commit = "" ;
71- continue ;
72- }
130+ argc = parse_options (argc , argv , prefix , options , commit_tree_usage , 0 );
73131
74- if (skip_prefix (arg , "-S" , & sign_commit ) ||
75- skip_prefix (arg , "--gpg-sign=" , & sign_commit ))
76- continue ;
132+ if (argc != 1 )
133+ die (_ ("must give exactly one tree" ));
77134
78- if (!strcmp (arg , "--no-gpg-sign" )) {
79- sign_commit = NULL ;
80- continue ;
81- }
82-
83- if (!strcmp (arg , "-m" )) {
84- if (argc <= ++ i )
85- usage (commit_tree_usage );
86- if (buffer .len )
87- strbuf_addch (& buffer , '\n' );
88- strbuf_addstr (& buffer , argv [i ]);
89- strbuf_complete_line (& buffer );
90- continue ;
91- }
92-
93- if (!strcmp (arg , "-F" )) {
94- int fd ;
95-
96- if (argc <= ++ i )
97- usage (commit_tree_usage );
98- if (buffer .len )
99- strbuf_addch (& buffer , '\n' );
100- if (!strcmp (argv [i ], "-" ))
101- fd = 0 ;
102- else {
103- fd = open (argv [i ], O_RDONLY );
104- if (fd < 0 )
105- die_errno ("git commit-tree: failed to open '%s'" ,
106- argv [i ]);
107- }
108- if (strbuf_read (& buffer , fd , 0 ) < 0 )
109- die_errno ("git commit-tree: failed to read '%s'" ,
110- argv [i ]);
111- if (fd && close (fd ))
112- die_errno ("git commit-tree: failed to close '%s'" ,
113- argv [i ]);
114- continue ;
115- }
116-
117- if (get_oid_tree (arg , & tree_oid ))
118- die ("Not a valid object name %s" , arg );
119- if (got_tree )
120- die ("Cannot give more than one trees" );
121- got_tree = 1 ;
122- }
135+ if (get_oid_tree (argv [0 ], & tree_oid ))
136+ die (_ ("not a valid object name %s" ), argv [0 ]);
123137
124138 if (!buffer .len ) {
125139 if (strbuf_read (& buffer , 0 , 0 ) < 0 )
126- die_errno ("git commit-tree: failed to read" );
140+ die_errno (_ ( "git commit-tree: failed to read" ) );
127141 }
128142
129143 if (commit_tree (buffer .buf , buffer .len , & tree_oid , parents , & commit_oid ,
0 commit comments