@@ -38,57 +38,110 @@ int cmd_range_diff(int argc, const char **argv, const char *prefix)
3838 OPT_END ()
3939 };
4040 struct option * options ;
41- int res = 0 ;
41+ int i , dash_dash = -1 , res = 0 ;
4242 struct strbuf range1 = STRBUF_INIT , range2 = STRBUF_INIT ;
43+ struct object_id oid ;
44+ const char * three_dots = NULL ;
4345
4446 git_config (git_diff_ui_config , NULL );
4547
4648 repo_diff_setup (the_repository , & diffopt );
4749
4850 options = parse_options_concat (range_diff_options , diffopt .parseopts );
4951 argc = parse_options (argc , argv , prefix , options ,
50- builtin_range_diff_usage , 0 );
52+ builtin_range_diff_usage , PARSE_OPT_KEEP_DASHDASH );
5153
5254 diff_setup_done (& diffopt );
5355
5456 /* force color when --dual-color was used */
5557 if (!simple_color )
5658 diffopt .use_color = 1 ;
5759
58- if (argc == 2 ) {
59- if (!is_range_diff_range (argv [0 ]))
60- die (_ ("not a commit range: '%s'" ), argv [0 ]);
61- strbuf_addstr (& range1 , argv [0 ]);
60+ for (i = 0 ; i < argc ; i ++ )
61+ if (!strcmp (argv [i ], "--" )) {
62+ dash_dash = i ;
63+ break ;
64+ }
65+
66+ if (dash_dash == 3 ||
67+ (dash_dash < 0 && argc > 2 &&
68+ !get_oid_committish (argv [0 ], & oid ) &&
69+ !get_oid_committish (argv [1 ], & oid ) &&
70+ !get_oid_committish (argv [2 ], & oid ))) {
71+ if (dash_dash < 0 )
72+ ; /* already validated arguments */
73+ else if (get_oid_committish (argv [0 ], & oid ))
74+ usage_msg_optf (_ ("not a revision: '%s'" ),
75+ builtin_range_diff_usage , options ,
76+ argv [0 ]);
77+ else if (get_oid_committish (argv [1 ], & oid ))
78+ usage_msg_optf (_ ("not a revision: '%s'" ),
79+ builtin_range_diff_usage , options ,
80+ argv [1 ]);
81+ else if (get_oid_committish (argv [2 ], & oid ))
82+ usage_msg_optf (_ ("not a revision: '%s'" ),
83+ builtin_range_diff_usage , options ,
84+ argv [2 ]);
6285
63- if (!is_range_diff_range (argv [1 ]))
64- die (_ ("not a commit range: '%s'" ), argv [1 ]);
65- strbuf_addstr (& range2 , argv [1 ]);
66- } else if (argc == 3 ) {
6786 strbuf_addf (& range1 , "%s..%s" , argv [0 ], argv [1 ]);
6887 strbuf_addf (& range2 , "%s..%s" , argv [0 ], argv [2 ]);
69- } else if (argc == 1 ) {
70- const char * b = strstr (argv [0 ], "..." ), * a = argv [0 ];
88+
89+ strvec_pushv (& other_arg , argv +
90+ (dash_dash < 0 ? 3 : dash_dash ));
91+ } else if (dash_dash == 2 ||
92+ (dash_dash < 0 && argc > 1 &&
93+ is_range_diff_range (argv [0 ]) &&
94+ is_range_diff_range (argv [1 ]))) {
95+ if (dash_dash < 0 )
96+ ; /* already validated arguments */
97+ else if (!is_range_diff_range (argv [0 ]))
98+ usage_msg_optf (_ ("not a commit range: '%s'" ),
99+ builtin_range_diff_usage , options ,
100+ argv [0 ]);
101+ else if (!is_range_diff_range (argv [1 ]))
102+ usage_msg_optf (_ ("not a commit range: '%s'" ),
103+ builtin_range_diff_usage , options ,
104+ argv [1 ]);
105+
106+ strbuf_addstr (& range1 , argv [0 ]);
107+ strbuf_addstr (& range2 , argv [1 ]);
108+
109+ strvec_pushv (& other_arg , argv +
110+ (dash_dash < 0 ? 2 : dash_dash ));
111+ } else if (dash_dash == 1 ||
112+ (dash_dash < 0 && argc > 0 &&
113+ (three_dots = strstr (argv [0 ], "..." )))) {
114+ const char * a , * b ;
71115 int a_len ;
72116
73- if (!b ) {
74- error (_ ("single arg format must be symmetric range" ));
75- usage_with_options (builtin_range_diff_usage , options );
76- }
117+ if (dash_dash < 0 )
118+ ; /* already validated arguments */
119+ else if (!(three_dots = strstr (argv [0 ], "..." )))
120+ usage_msg_optf (_ ("not a symmetric range: '%s'" ),
121+ builtin_range_diff_usage , options ,
122+ argv [0 ]);
77123
78- a_len = (int )(b - a );
79- if (!a_len ) {
124+ if (three_dots == argv [0 ]) {
80125 a = "HEAD" ;
81126 a_len = strlen (a );
127+ } else {
128+ a = argv [0 ];
129+ a_len = (int )(three_dots - a );
82130 }
83- b += 3 ;
84- if (!* b )
131+
132+ if (three_dots [3 ])
133+ b = three_dots + 3 ;
134+ else
85135 b = "HEAD" ;
136+
86137 strbuf_addf (& range1 , "%s..%.*s" , b , a_len , a );
87138 strbuf_addf (& range2 , "%.*s..%s" , a_len , a , b );
88- } else {
89- error (_ ("need two commit ranges" ));
90- usage_with_options (builtin_range_diff_usage , options );
91- }
139+
140+ strvec_pushv (& other_arg , argv +
141+ (dash_dash < 0 ? 1 : dash_dash ));
142+ } else
143+ usage_msg_opt (_ ("need two commit ranges" ),
144+ builtin_range_diff_usage , options );
92145 FREE_AND_NULL (options );
93146
94147 range_diff_opts .dual_color = simple_color < 1 ;
0 commit comments