@@ -19,8 +19,7 @@ static const char * const show_ref_usage[] = {
19
19
};
20
20
21
21
static int deref_tags , show_head , tags_only , heads_only , found_match , verify ,
22
- quiet , hash_only , abbrev , exclude_arg ;
23
- static const char * exclude_existing_arg ;
22
+ quiet , hash_only , abbrev ;
24
23
25
24
static void show_one (const char * refname , const struct object_id * oid )
26
25
{
@@ -95,6 +94,15 @@ static int add_existing(const char *refname,
95
94
return 0 ;
96
95
}
97
96
97
+ struct exclude_existing_options {
98
+ /*
99
+ * We need an explicit `enabled` field because it is perfectly valid
100
+ * for `pattern` to be `NULL` even if `--exclude-existing` was given.
101
+ */
102
+ int enabled ;
103
+ const char * pattern ;
104
+ };
105
+
98
106
/*
99
107
* read "^(?:<anything>\s)?<refname>(?:\^\{\})?$" from the standard input,
100
108
* and
@@ -104,11 +112,11 @@ static int add_existing(const char *refname,
104
112
* (4) ignore if refname is a ref that exists in the local repository;
105
113
* (5) otherwise output the line.
106
114
*/
107
- static int cmd_show_ref__exclude_existing (const char * match )
115
+ static int cmd_show_ref__exclude_existing (const struct exclude_existing_options * opts )
108
116
{
109
117
struct string_list existing_refs = STRING_LIST_INIT_DUP ;
110
118
char buf [1024 ];
111
- int matchlen = match ? strlen (match ) : 0 ;
119
+ int patternlen = opts -> pattern ? strlen (opts -> pattern ) : 0 ;
112
120
113
121
for_each_ref (add_existing , & existing_refs );
114
122
while (fgets (buf , sizeof (buf ), stdin )) {
@@ -124,11 +132,11 @@ static int cmd_show_ref__exclude_existing(const char *match)
124
132
for (ref = buf + len ; buf < ref ; ref -- )
125
133
if (isspace (ref [-1 ]))
126
134
break ;
127
- if (match ) {
135
+ if (opts -> pattern ) {
128
136
int reflen = buf + len - ref ;
129
- if (reflen < matchlen )
137
+ if (reflen < patternlen )
130
138
continue ;
131
- if (strncmp (ref , match , matchlen ))
139
+ if (strncmp (ref , opts -> pattern , patternlen ))
132
140
continue ;
133
141
}
134
142
if (check_refname_format (ref , 0 )) {
@@ -201,44 +209,46 @@ static int hash_callback(const struct option *opt, const char *arg, int unset)
201
209
static int exclude_existing_callback (const struct option * opt , const char * arg ,
202
210
int unset )
203
211
{
212
+ struct exclude_existing_options * opts = opt -> value ;
204
213
BUG_ON_OPT_NEG (unset );
205
- exclude_arg = 1 ;
206
- * ( const char * * ) opt -> value = arg ;
214
+ opts -> enabled = 1 ;
215
+ opts -> pattern = arg ;
207
216
return 0 ;
208
217
}
209
218
210
- static const struct option show_ref_options [] = {
211
- OPT_BOOL (0 , "tags" , & tags_only , N_ ("only show tags (can be combined with heads)" )),
212
- OPT_BOOL (0 , "heads" , & heads_only , N_ ("only show heads (can be combined with tags)" )),
213
- OPT_BOOL (0 , "verify" , & verify , N_ ("stricter reference checking, "
214
- "requires exact ref path" )),
215
- OPT_HIDDEN_BOOL ('h' , NULL , & show_head ,
216
- N_ ("show the HEAD reference, even if it would be filtered out" )),
217
- OPT_BOOL (0 , "head" , & show_head ,
218
- N_ ("show the HEAD reference, even if it would be filtered out" )),
219
- OPT_BOOL ('d' , "dereference" , & deref_tags ,
220
- N_ ("dereference tags into object IDs" )),
221
- OPT_CALLBACK_F ('s' , "hash" , & abbrev , N_ ("n" ),
222
- N_ ("only show SHA1 hash using <n> digits" ),
223
- PARSE_OPT_OPTARG , & hash_callback ),
224
- OPT__ABBREV (& abbrev ),
225
- OPT__QUIET (& quiet ,
226
- N_ ("do not print results to stdout (useful with --verify)" )),
227
- OPT_CALLBACK_F (0 , "exclude-existing" , & exclude_existing_arg ,
228
- N_ ("pattern" ), N_ ("show refs from stdin that aren't in local repository" ),
229
- PARSE_OPT_OPTARG | PARSE_OPT_NONEG , exclude_existing_callback ),
230
- OPT_END ()
231
- };
232
-
233
219
int cmd_show_ref (int argc , const char * * argv , const char * prefix )
234
220
{
221
+ struct exclude_existing_options exclude_existing_opts = {0 };
222
+ const struct option show_ref_options [] = {
223
+ OPT_BOOL (0 , "tags" , & tags_only , N_ ("only show tags (can be combined with heads)" )),
224
+ OPT_BOOL (0 , "heads" , & heads_only , N_ ("only show heads (can be combined with tags)" )),
225
+ OPT_BOOL (0 , "verify" , & verify , N_ ("stricter reference checking, "
226
+ "requires exact ref path" )),
227
+ OPT_HIDDEN_BOOL ('h' , NULL , & show_head ,
228
+ N_ ("show the HEAD reference, even if it would be filtered out" )),
229
+ OPT_BOOL (0 , "head" , & show_head ,
230
+ N_ ("show the HEAD reference, even if it would be filtered out" )),
231
+ OPT_BOOL ('d' , "dereference" , & deref_tags ,
232
+ N_ ("dereference tags into object IDs" )),
233
+ OPT_CALLBACK_F ('s' , "hash" , & abbrev , N_ ("n" ),
234
+ N_ ("only show SHA1 hash using <n> digits" ),
235
+ PARSE_OPT_OPTARG , & hash_callback ),
236
+ OPT__ABBREV (& abbrev ),
237
+ OPT__QUIET (& quiet ,
238
+ N_ ("do not print results to stdout (useful with --verify)" )),
239
+ OPT_CALLBACK_F (0 , "exclude-existing" , & exclude_existing_opts ,
240
+ N_ ("pattern" ), N_ ("show refs from stdin that aren't in local repository" ),
241
+ PARSE_OPT_OPTARG | PARSE_OPT_NONEG , exclude_existing_callback ),
242
+ OPT_END ()
243
+ };
244
+
235
245
git_config (git_default_config , NULL );
236
246
237
247
argc = parse_options (argc , argv , prefix , show_ref_options ,
238
248
show_ref_usage , 0 );
239
249
240
- if (exclude_arg )
241
- return cmd_show_ref__exclude_existing (exclude_existing_arg );
250
+ if (exclude_existing_opts . enabled )
251
+ return cmd_show_ref__exclude_existing (& exclude_existing_opts );
242
252
else if (verify )
243
253
return cmd_show_ref__verify (argv );
244
254
else
0 commit comments