@@ -967,6 +967,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
967
967
int dummy ;
968
968
int use_index = 1 ;
969
969
int pattern_type_arg = GREP_PATTERN_TYPE_UNSPECIFIED ;
970
+ int allow_revs ;
970
971
971
972
struct option options [] = {
972
973
OPT_BOOL (0 , "cached" , & cached ,
@@ -1149,26 +1150,69 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
1149
1150
1150
1151
compile_grep_patterns (& opt );
1151
1152
1152
- /* Check revs and then paths */
1153
+ /*
1154
+ * We have to find "--" in a separate pass, because its presence
1155
+ * influences how we will parse arguments that come before it.
1156
+ */
1157
+ for (i = 0 ; i < argc ; i ++ ) {
1158
+ if (!strcmp (argv [i ], "--" )) {
1159
+ seen_dashdash = 1 ;
1160
+ break ;
1161
+ }
1162
+ }
1163
+
1164
+ /*
1165
+ * Resolve any rev arguments. If we have a dashdash, then everything up
1166
+ * to it must resolve as a rev. If not, then we stop at the first
1167
+ * non-rev and assume everything else is a path.
1168
+ */
1169
+ allow_revs = use_index && !untracked ;
1153
1170
for (i = 0 ; i < argc ; i ++ ) {
1154
1171
const char * arg = argv [i ];
1155
1172
unsigned char sha1 [20 ];
1156
1173
struct object_context oc ;
1157
- /* Is it a rev? */
1158
- if (!get_sha1_with_context (arg , 0 , sha1 , & oc )) {
1159
- struct object * object = parse_object_or_die (sha1 , arg );
1160
- if (!seen_dashdash )
1161
- verify_non_filename (prefix , arg );
1162
- add_object_array_with_path (object , arg , & list , oc .mode , oc .path );
1163
- continue ;
1164
- }
1174
+ struct object * object ;
1175
+
1165
1176
if (!strcmp (arg , "--" )) {
1166
1177
i ++ ;
1167
- seen_dashdash = 1 ;
1178
+ break ;
1168
1179
}
1169
- break ;
1180
+
1181
+ if (!allow_revs ) {
1182
+ if (seen_dashdash )
1183
+ die (_ ("--no-index or --untracked cannot be used with revs" ));
1184
+ break ;
1185
+ }
1186
+
1187
+ if (get_sha1_with_context (arg , 0 , sha1 , & oc )) {
1188
+ if (seen_dashdash )
1189
+ die (_ ("unable to resolve revision: %s" ), arg );
1190
+ break ;
1191
+ }
1192
+
1193
+ object = parse_object_or_die (sha1 , arg );
1194
+ if (!seen_dashdash )
1195
+ verify_non_filename (prefix , arg );
1196
+ add_object_array_with_path (object , arg , & list , oc .mode , oc .path );
1170
1197
}
1171
1198
1199
+ /*
1200
+ * Anything left over is presumed to be a path. But in the non-dashdash
1201
+ * "do what I mean" case, we verify and complain when that isn't true.
1202
+ */
1203
+ if (!seen_dashdash ) {
1204
+ int j ;
1205
+ for (j = i ; j < argc ; j ++ )
1206
+ verify_filename (prefix , argv [j ], j == i && allow_revs );
1207
+ }
1208
+
1209
+ parse_pathspec (& pathspec , 0 ,
1210
+ PATHSPEC_PREFER_CWD |
1211
+ (opt .max_depth != -1 ? PATHSPEC_MAXDEPTH_VALID : 0 ),
1212
+ prefix , argv + i );
1213
+ pathspec .max_depth = opt .max_depth ;
1214
+ pathspec .recursive = 1 ;
1215
+
1172
1216
#ifndef NO_PTHREADS
1173
1217
if (list .nr || cached || show_in_pager )
1174
1218
num_threads = 0 ;
@@ -1190,20 +1234,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
1190
1234
}
1191
1235
#endif
1192
1236
1193
- /* The rest are paths */
1194
- if (!seen_dashdash ) {
1195
- int j ;
1196
- for (j = i ; j < argc ; j ++ )
1197
- verify_filename (prefix , argv [j ], j == i );
1198
- }
1199
-
1200
- parse_pathspec (& pathspec , 0 ,
1201
- PATHSPEC_PREFER_CWD |
1202
- (opt .max_depth != -1 ? PATHSPEC_MAXDEPTH_VALID : 0 ),
1203
- prefix , argv + i );
1204
- pathspec .max_depth = opt .max_depth ;
1205
- pathspec .recursive = 1 ;
1206
-
1207
1237
if (recurse_submodules ) {
1208
1238
gitmodules_config ();
1209
1239
compile_submodule_options (& opt , & pathspec , cached , untracked ,
@@ -1245,8 +1275,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
1245
1275
1246
1276
if (!use_index || untracked ) {
1247
1277
int use_exclude = (opt_exclude < 0 ) ? use_index : !!opt_exclude ;
1248
- if (list .nr )
1249
- die (_ ("--no-index or --untracked cannot be used with revs." ));
1250
1278
hit = grep_directory (& opt , & pathspec , use_exclude , use_index );
1251
1279
} else if (0 <= opt_exclude ) {
1252
1280
die (_ ("--[no-]exclude-standard cannot be used for tracked contents." ));
0 commit comments