@@ -2262,8 +2262,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
22622262 struct scoreboard sb ;
22632263 struct origin * o ;
22642264 struct blame_entry * ent ;
2265- int i , seen_dashdash , unk ;
2266- long bottom , top , lno ;
2265+ long dashdash_pos , bottom , top , lno ;
22672266 const char * final_commit_name = NULL ;
22682267 enum object_type type ;
22692268
@@ -2301,6 +2300,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
23012300 git_config (git_blame_config , NULL );
23022301 init_revisions (& revs , NULL );
23032302 save_commit_buffer = 0 ;
2303+ dashdash_pos = 0 ;
23042304
23052305 parse_options_start (& ctx , argc , argv , PARSE_OPT_KEEP_DASHDASH |
23062306 PARSE_OPT_KEEP_ARGV0 );
@@ -2311,6 +2311,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
23112311 case PARSE_OPT_HELP :
23122312 exit (129 );
23132313 case PARSE_OPT_DONE :
2314+ if (ctx .argv [0 ])
2315+ dashdash_pos = ctx .cpidx ;
23142316 goto parse_done ;
23152317 }
23162318
@@ -2330,20 +2332,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
23302332parse_done :
23312333 argc = parse_options_end (& ctx );
23322334
2333- seen_dashdash = 0 ;
2334- for (unk = i = 1 ; i < argc ; i ++ ) {
2335- const char * arg = argv [i ];
2336- if (* arg != '-' )
2337- break ;
2338- else if (!strcmp ("--" , arg )) {
2339- seen_dashdash = 1 ;
2340- i ++ ;
2341- break ;
2342- }
2343- else
2344- argv [unk ++ ] = arg ;
2345- }
2346-
23472335 if (!blame_move_score )
23482336 blame_move_score = BLAME_DEFAULT_MOVE_SCORE ;
23492337 if (!blame_copy_score )
@@ -2356,92 +2344,50 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
23562344 *
23572345 * The remaining are:
23582346 *
2359- * (1) if seen_dashdash, its either
2360- * "-options -- <path>" or
2361- * "-options -- <path> <rev>".
2362- * but the latter is allowed only if there is no
2363- * options that we passed to revision machinery.
2347+ * (1) if dashdash_pos != 0, its either
2348+ * "blame [revisions] -- <path>" or
2349+ * "blame -- <path> <rev>"
23642350 *
2365- * (2) otherwise, we may have "--" somewhere later and
2366- * might be looking at the first one of multiple 'rev'
2367- * parameters (e.g. " master ^next ^maint -- path").
2368- * See if there is a dashdash first, and give the
2369- * arguments before that to revision machinery.
2370- * After that there must be one 'path'.
2351+ * (2) otherwise, its one of the two:
2352+ * "blame [revisions] <path>"
2353+ * "blame <path> <rev>"
23712354 *
2372- * (3) otherwise, its one of the three:
2373- * "-options <path> <rev>"
2374- * "-options <rev> <path>"
2375- * "-options <path>"
2376- * but again the first one is allowed only if
2377- * there is no options that we passed to revision
2378- * machinery.
2355+ * Note that we must strip out <path> from the arguments: we do not
2356+ * want the path pruning but we may want "bottom" processing.
23792357 */
2380-
2381- if (seen_dashdash ) {
2382- /* (1) */
2383- if (argc <= i )
2384- usage_with_options (blame_opt_usage , options );
2385- path = add_prefix (prefix , argv [i ]);
2386- if (i + 1 == argc - 1 ) {
2387- if (unk != 1 )
2358+ if (dashdash_pos ) {
2359+ switch (argc - dashdash_pos - 1 ) {
2360+ case 2 : /* (1b) */
2361+ if (argc != 4 )
23882362 usage_with_options (blame_opt_usage , options );
2389- argv [unk ++ ] = argv [i + 1 ];
2363+ /* reorder for the new way: <rev> -- <path> */
2364+ argv [1 ] = argv [3 ];
2365+ argv [3 ] = argv [2 ];
2366+ argv [2 ] = "--" ;
2367+ /* FALLTHROUGH */
2368+ case 1 : /* (1a) */
2369+ path = add_prefix (prefix , argv [-- argc ]);
2370+ argv [argc ] = NULL ;
2371+ break ;
2372+ default :
2373+ usage_with_options (blame_opt_usage , options );
23902374 }
2391- else if ( i + 1 != argc )
2392- /* garbage at end */
2375+ } else {
2376+ if ( argc < 2 )
23932377 usage_with_options (blame_opt_usage , options );
2394- }
2395- else {
2396- int j ;
2397- for (j = i ; !seen_dashdash && j < argc ; j ++ )
2398- if (!strcmp (argv [j ], "--" ))
2399- seen_dashdash = j ;
2400- if (seen_dashdash ) {
2401- /* (2) */
2402- if (seen_dashdash + 1 != argc - 1 )
2403- usage_with_options (blame_opt_usage , options );
2404- path = add_prefix (prefix , argv [seen_dashdash + 1 ]);
2405- for (j = i ; j < seen_dashdash ; j ++ )
2406- argv [unk ++ ] = argv [j ];
2378+ path = add_prefix (prefix , argv [argc - 1 ]);
2379+ if (argc == 3 && !has_path_in_work_tree (path )) { /* (2b) */
2380+ path = add_prefix (prefix , argv [1 ]);
2381+ argv [1 ] = argv [2 ];
24072382 }
2408- else {
2409- /* (3) */
2410- if (argc <= i )
2411- usage_with_options (blame_opt_usage , options );
2412- path = add_prefix (prefix , argv [i ]);
2413- if (i + 1 == argc - 1 ) {
2414- final_commit_name = argv [i + 1 ];
2415-
2416- /* if (unk == 1) we could be getting
2417- * old-style
2418- */
2419- if (unk == 1 && !has_path_in_work_tree (path )) {
2420- path = add_prefix (prefix , argv [i + 1 ]);
2421- final_commit_name = argv [i ];
2422- }
2423- }
2424- else if (i != argc - 1 )
2425- usage_with_options (blame_opt_usage , options );
2383+ argv [argc - 1 ] = "--" ;
24262384
2427- setup_work_tree ();
2428- if (!has_path_in_work_tree (path ))
2429- die ("cannot stat path %s: %s" ,
2430- path , strerror (errno ));
2431- }
2385+ setup_work_tree ();
2386+ if (!has_path_in_work_tree (path ))
2387+ die ("cannot stat path %s: %s" , path , strerror (errno ));
24322388 }
24332389
2434- if (final_commit_name )
2435- argv [unk ++ ] = final_commit_name ;
2436-
2437- /*
2438- * Now we got rev and path. We do not want the path pruning
2439- * but we may want "bottom" processing.
2440- */
2441- argv [unk ++ ] = "--" ; /* terminate the rev name */
2442- argv [unk ] = NULL ;
2443-
2444- setup_revisions (unk , argv , & revs , NULL );
2390+ setup_revisions (argc , argv , & revs , NULL );
24452391 memset (& sb , 0 , sizeof (sb ));
24462392
24472393 sb .revs = & revs ;
0 commit comments