Skip to content

Commit 0569e9b

Browse files
committed
"git diff": do not ignore index without --no-index
Even if "foo" and/or "bar" does not exist in index, "git diff foo bar" should not change behaviour drastically from "git diff foo bar baz" or "git diff foo". A feature that "sometimes works and is handy" is an unreliable cute hack. "git diff foo bar" outside a git repository continues to work as a more colourful alternative to "diff -u" as before. Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 6304c29 commit 0569e9b

File tree

8 files changed

+283
-338
lines changed

8 files changed

+283
-338
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ LIB_OBJS += diffcore-order.o
405405
LIB_OBJS += diffcore-pickaxe.o
406406
LIB_OBJS += diffcore-rename.o
407407
LIB_OBJS += diff-delta.o
408+
LIB_OBJS += diff-no-index.o
408409
LIB_OBJS += diff-lib.o
409410
LIB_OBJS += diff.o
410411
LIB_OBJS += dir.o

builtin-diff.c

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
205236
int 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

Comments
 (0)