12
12
#include "unpack-trees.h"
13
13
#include "dir.h"
14
14
#include "builtin.h"
15
+ #include "parse-options.h"
15
16
16
17
static int nr_trees ;
17
18
static struct tree * trees [MAX_UNPACK_TREES ];
@@ -29,7 +30,39 @@ static int list_tree(unsigned char *sha1)
29
30
return 0 ;
30
31
}
31
32
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
+ }
33
66
34
67
static struct lock_file lock_file ;
35
68
@@ -39,6 +72,34 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
39
72
unsigned char sha1 [20 ];
40
73
struct tree_desc t [MAX_UNPACK_TREES ];
41
74
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
+ };
42
103
43
104
memset (& opts , 0 , sizeof (opts ));
44
105
opts .head_idx = -1 ;
@@ -49,114 +110,31 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
49
110
50
111
newfd = hold_locked_index (& lock_file , 1 );
51
112
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 );
119
115
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" );
130
118
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 );
147
123
148
- /* using -u and -i at the same time makes no sense */
149
- if (1 < opts .index_only + opts .update )
150
- usage (read_tree_usage );
124
+ for (i = 0 ; i < argc ; i ++ ) {
125
+ const char * arg = argv [i ];
151
126
152
127
if (get_sha1 (arg , sha1 ))
153
128
die ("Not a valid object name %s" , arg );
154
129
if (list_tree (sha1 ) < 0 )
155
130
die ("failed to unpack tree object %s" , arg );
156
131
stage ++ ;
157
132
}
133
+ if (1 < opts .index_only + opts .update )
134
+ die ("-u and -i at the same time makes no sense" );
158
135
if ((opts .update || opts .index_only ) && !opts .merge )
159
- usage (read_tree_usage );
136
+ die ("%s is meaningless without -m, --reset, or --prefix" ,
137
+ opts .update ? "-u" : "-i" );
160
138
if ((opts .dir && !opts .update ))
161
139
die ("--exclude-per-directory is meaningless unless -u" );
162
140
if (opts .merge && !opts .index_only )
0 commit comments