1212#include "unpack-trees.h"
1313#include "dir.h"
1414#include "builtin.h"
15+ #include "parse-options.h"
1516
1617static int nr_trees ;
1718static struct tree * trees [MAX_UNPACK_TREES ];
@@ -29,7 +30,39 @@ static int list_tree(unsigned char *sha1)
2930 return 0 ;
3031}
3132
32- static const char read_tree_usage [] = "git read-tree (<sha> | [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] [--index-output=<file>] <sha1> [<sha2> [<sha3>]])" ;
33+ static const char * const read_tree_usage [] = {
34+ "git read-tree [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>] [-u [--exclude-per-directory=<gitignore>] | -i]] [--index-output=<file>] <tree-ish1> [<tree-ish2> [<tree-ish3>]]" ,
35+ NULL
36+ };
37+
38+ static int index_output_cb (const struct option * opt , const char * arg ,
39+ int unset )
40+ {
41+ set_alternate_index_output (arg );
42+ return 0 ;
43+ }
44+
45+ static int exclude_per_directory_cb (const struct option * opt , const char * arg ,
46+ int unset )
47+ {
48+ struct dir_struct * dir ;
49+ struct unpack_trees_options * opts ;
50+
51+ opts = (struct unpack_trees_options * )opt -> value ;
52+
53+ if (opts -> dir )
54+ die ("more than one --exclude-per-directory given." );
55+
56+ dir = xcalloc (1 , sizeof (* opts -> dir ));
57+ dir -> flags |= DIR_SHOW_IGNORED ;
58+ dir -> exclude_per_dir = arg ;
59+ opts -> dir = dir ;
60+ /* We do not need to nor want to do read-directory
61+ * here; we are merely interested in reusing the
62+ * per directory ignore stack mechanism.
63+ */
64+ return 0 ;
65+ }
3366
3467static struct lock_file lock_file ;
3568
@@ -39,6 +72,34 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
3972 unsigned char sha1 [20 ];
4073 struct tree_desc t [MAX_UNPACK_TREES ];
4174 struct unpack_trees_options opts ;
75+ int prefix_set = 0 ;
76+ const struct option read_tree_options [] = {
77+ { OPTION_CALLBACK , 0 , "index-output" , NULL , "FILE" ,
78+ "write resulting index to <FILE>" ,
79+ PARSE_OPT_NONEG , index_output_cb },
80+ OPT__VERBOSE (& opts .verbose_update ),
81+ OPT_GROUP ("Merging" ),
82+ OPT_SET_INT ('m' , NULL , & opts .merge ,
83+ "perform a merge in addition to a read" , 1 ),
84+ OPT_SET_INT (0 , "trivial" , & opts .trivial_merges_only ,
85+ "3-way merge if no file level merging required" , 1 ),
86+ OPT_SET_INT (0 , "aggressive" , & opts .aggressive ,
87+ "3-way merge in presence of adds and removes" , 1 ),
88+ OPT_SET_INT (0 , "reset" , & opts .reset ,
89+ "same as -m, but discard unmerged entries" , 1 ),
90+ { OPTION_STRING , 0 , "prefix" , & opts .prefix , "<subdirectory>/" ,
91+ "read the tree into the index under <subdirectory>/" ,
92+ PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP },
93+ OPT_SET_INT ('u' , NULL , & opts .update ,
94+ "update working tree with merge result" , 1 ),
95+ { OPTION_CALLBACK , 0 , "exclude-per-directory" , & opts ,
96+ "gitignore" ,
97+ "allow explicitly ignored files to be overwritten" ,
98+ PARSE_OPT_NONEG , exclude_per_directory_cb },
99+ OPT_SET_INT ('i' , NULL , & opts .index_only ,
100+ "don't check the working tree after merging" , 1 ),
101+ OPT_END ()
102+ };
42103
43104 memset (& opts , 0 , sizeof (opts ));
44105 opts .head_idx = -1 ;
@@ -49,111 +110,28 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
49110
50111 newfd = hold_locked_index (& lock_file , 1 );
51112
52- for (i = 1 ; i < argc ; i ++ ) {
53- const char * arg = argv [i ];
54-
55- /* "-u" means "update", meaning that a merge will update
56- * the working tree.
57- */
58- if (!strcmp (arg , "-u" )) {
59- opts .update = 1 ;
60- continue ;
61- }
62-
63- if (!strcmp (arg , "-v" )) {
64- opts .verbose_update = 1 ;
65- continue ;
66- }
67-
68- /* "-i" means "index only", meaning that a merge will
69- * not even look at the working tree.
70- */
71- if (!strcmp (arg , "-i" )) {
72- opts .index_only = 1 ;
73- continue ;
74- }
75-
76- if (!prefixcmp (arg , "--index-output=" )) {
77- set_alternate_index_output (arg + 15 );
78- continue ;
79- }
80-
81- /* "--prefix=<subdirectory>/" means keep the current index
82- * entries and put the entries from the tree under the
83- * given subdirectory.
84- */
85- if (!prefixcmp (arg , "--prefix=" )) {
86- if (stage || opts .merge || opts .prefix )
87- usage (read_tree_usage );
88- opts .prefix = arg + 9 ;
89- opts .merge = 1 ;
90- stage = 1 ;
91- if (read_cache_unmerged ())
92- die ("you need to resolve your current index first" );
93- continue ;
94- }
95-
96- /* This differs from "-m" in that we'll silently ignore
97- * unmerged entries and overwrite working tree files that
98- * correspond to them.
99- */
100- if (!strcmp (arg , "--reset" )) {
101- if (stage || opts .merge || opts .prefix )
102- usage (read_tree_usage );
103- opts .reset = 1 ;
104- opts .merge = 1 ;
105- stage = 1 ;
106- read_cache_unmerged ();
107- continue ;
108- }
109-
110- if (!strcmp (arg , "--trivial" )) {
111- opts .trivial_merges_only = 1 ;
112- continue ;
113- }
114-
115- if (!strcmp (arg , "--aggressive" )) {
116- opts .aggressive = 1 ;
117- continue ;
118- }
113+ argc = parse_options (argc , argv , unused_prefix , read_tree_options ,
114+ read_tree_usage , 0 );
119115
120- /* "-m" stands for "merge", meaning we start in stage 1 */
121- if (!strcmp (arg , "-m" )) {
122- if (stage || opts .merge || opts .prefix )
123- usage (read_tree_usage );
124- if (read_cache_unmerged ())
125- die ("you need to resolve your current index first" );
126- stage = 1 ;
127- opts .merge = 1 ;
128- continue ;
129- }
116+ if (read_cache_unmerged () && (opts .prefix || opts .merge ))
117+ die ("You need to resolve your current index first" );
130118
131- if (!prefixcmp (arg , "--exclude-per-directory=" )) {
132- struct dir_struct * dir ;
133-
134- if (opts .dir )
135- die ("more than one --exclude-per-directory are given." );
136-
137- dir = xcalloc (1 , sizeof (* opts .dir ));
138- dir -> flags |= DIR_SHOW_IGNORED ;
139- dir -> exclude_per_dir = arg + 24 ;
140- opts .dir = dir ;
141- /* We do not need to nor want to do read-directory
142- * here; we are merely interested in reusing the
143- * per directory ignore stack mechanism.
144- */
145- continue ;
146- }
119+ prefix_set = opts .prefix ? 1 : 0 ;
120+ if (1 < opts .merge + opts .reset + prefix_set )
121+ die ("Which one? -m, --reset, or --prefix?" );
122+ stage = opts .merge = (opts .reset || opts .merge || prefix_set );
147123
148- if ( 1 < opts . index_only + opts . update )
149- die ( "-u and -i at the same time makes no sense" ) ;
124+ for ( i = 0 ; i < argc ; i ++ ) {
125+ const char * arg = argv [ i ] ;
150126
151127 if (get_sha1 (arg , sha1 ))
152128 die ("Not a valid object name %s" , arg );
153129 if (list_tree (sha1 ) < 0 )
154130 die ("failed to unpack tree object %s" , arg );
155131 stage ++ ;
156132 }
133+ if (1 < opts .index_only + opts .update )
134+ die ("-u and -i at the same time makes no sense" );
157135 if ((opts .update || opts .index_only ) && !opts .merge )
158136 die ("%s is meaningless without -m, --reset, or --prefix" ,
159137 opts .update ? "-u" : "-i" );
0 commit comments