@@ -202,6 +202,37 @@ static void refresh_index_quietly(void)
202202 rollback_lock_file (lock_file );
203203}
204204
205+ static int builtin_diff_files (struct rev_info * revs , int argc , const char * * argv )
206+ {
207+ int result ;
208+ unsigned int options = 0 ;
209+
210+ while (1 < argc && argv [1 ][0 ] == '-' ) {
211+ if (!strcmp (argv [1 ], "--base" ))
212+ revs -> max_count = 1 ;
213+ else if (!strcmp (argv [1 ], "--ours" ))
214+ revs -> max_count = 2 ;
215+ else if (!strcmp (argv [1 ], "--theirs" ))
216+ revs -> max_count = 3 ;
217+ else if (!strcmp (argv [1 ], "-q" ))
218+ options |= DIFF_SILENT_ON_REMOVED ;
219+ else
220+ return error ("invalid option: %s" , argv [1 ]);
221+ argv ++ ; argc -- ;
222+ }
223+
224+ if (revs -> max_count == -1 &&
225+ (revs -> diffopt .output_format & DIFF_FORMAT_PATCH ))
226+ revs -> combine_merges = revs -> dense_combined_merges = 1 ;
227+
228+ if (read_cache () < 0 ) {
229+ perror ("read_cache" );
230+ return -1 ;
231+ }
232+ result = run_diff_files (revs , options );
233+ return diff_result_code (& revs -> diffopt , result );
234+ }
235+
205236int cmd_diff (int argc , const char * * argv , const char * prefix )
206237{
207238 int i ;
@@ -230,6 +261,9 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
230261 * N=2, M=0:
231262 * tree vs tree (diff-tree)
232263 *
264+ * N=0, M=0, P=2:
265+ * compare two filesystem entities (aka --no-index).
266+ *
233267 * Other cases are errors.
234268 */
235269
@@ -240,21 +274,21 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
240274 diff_use_color_default = git_use_color_default ;
241275
242276 init_revisions (& rev , prefix );
277+
278+ /* If this is a no-index diff, just run it and exit there. */
279+ diff_no_index (& rev , argc , argv , nongit , prefix );
280+
281+ /* Otherwise, we are doing the usual "git" diff */
243282 rev .diffopt .skip_stat_unmatch = !!diff_auto_refresh_index ;
244283
245- if (!setup_diff_no_index (& rev , argc , argv , nongit , prefix ))
246- argc = 0 ;
247- else
248- argc = setup_revisions (argc , argv , & rev , NULL );
284+ if (nongit )
285+ die ("Not a git repository" );
286+ argc = setup_revisions (argc , argv , & rev , NULL );
249287 if (!rev .diffopt .output_format ) {
250288 rev .diffopt .output_format = DIFF_FORMAT_PATCH ;
251289 if (diff_setup_done (& rev .diffopt ) < 0 )
252290 die ("diff_setup_done failed" );
253291 }
254- if (rev .diffopt .prefix && nongit ) {
255- rev .diffopt .prefix = NULL ;
256- rev .diffopt .prefix_length = 0 ;
257- }
258292 DIFF_OPT_SET (& rev .diffopt , ALLOW_EXTERNAL );
259293 DIFF_OPT_SET (& rev .diffopt , RECURSIVE );
260294
@@ -265,7 +299,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
265299 if (!DIFF_OPT_TST (& rev .diffopt , EXIT_WITH_STATUS ))
266300 setup_pager ();
267301
268- /* Do we have --cached and not have a pending object, then
302+ /*
303+ * Do we have --cached and not have a pending object, then
269304 * default to HEAD by hand. Eek.
270305 */
271306 if (!rev .pending .nr ) {
@@ -333,7 +368,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
333368 if (!ents ) {
334369 switch (blobs ) {
335370 case 0 :
336- result = run_diff_files_cmd (& rev , argc , argv );
371+ result = builtin_diff_files (& rev , argc , argv );
337372 break ;
338373 case 1 :
339374 if (paths != 1 )
0 commit comments