@matheusbsbs / matheus-bagliano / commits / 0569e9b8ce
Fork 0

"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>

Junio C Hamano committed May 23, 2008 at 22:28 UTC 0569e9b8cea20d5eedfec66730a9711a0907ab0d
8 files changed +283 -338
Makefile
+1
@@ -405,6 +405,7 @@ LIB_OBJS += diffcore-order.o
405 LIB_OBJS += diffcore-pickaxe.o
406 LIB_OBJS += diffcore-rename.o
407 LIB_OBJS += diff-delta.o
408 +LIB_OBJS += diff-no-index.o
409 LIB_OBJS += diff-lib.o
410 LIB_OBJS += diff.o
411 LIB_OBJS += dir.o
builtin-diff.c
+45 -10
@@ -202,6 +202,37 @@ static void refresh_index_quietly(void)
202 rollback_lock_file(lock_file);
203 }
204
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 +
236 int cmd_diff(int argc, const char **argv, const char *prefix)
237 {
238 int i;
@@ -230,6 +261,9 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
261 * N=2, M=0:
262 * tree vs tree (diff-tree)
263 *
264 + * N=0, M=0, P=2:
265 + * compare two filesystem entities (aka --no-index).
266 + *
267 * Other cases are errors.
268 */
269
@@ -240,21 +274,21 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
274 diff_use_color_default = git_use_color_default;
275
276 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 */
282 rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index;
283
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);
287 if (!rev.diffopt.output_format) {
288 rev.diffopt.output_format = DIFF_FORMAT_PATCH;
289 if (diff_setup_done(&rev.diffopt) < 0)
290 die("diff_setup_done failed");
291 }
254 - if (rev.diffopt.prefix && nongit) {
255 - rev.diffopt.prefix = NULL;
256 - rev.diffopt.prefix_length = 0;
257 - }
292 DIFF_OPT_SET(&rev.diffopt, ALLOW_EXTERNAL);
293 DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
294
@@ -265,7 +299,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
299 if (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
300 setup_pager();
301
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
304 * default to HEAD by hand. Eek.
305 */
306 if (!rev.pending.nr) {
@@ -333,7 +368,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
368 if (!ents) {
369 switch (blobs) {
370 case 0:
336 - result = run_diff_files_cmd(&rev, argc, argv);
371 + result = builtin_diff_files(&rev, argc, argv);
372 break;
373 case 1:
374 if (paths != 1)
diff-lib.c
-323
@@ -8,7 +8,6 @@
8 #include "diffcore.h"
9 #include "revision.h"
10 #include "cache-tree.h"
11 -#include "path-list.h"
11 #include "unpack-trees.h"
12 #include "refs.h"
13
@@ -16,328 +15,6 @@
15 * diff-files
16 */
17
19 -static int read_directory(const char *path, struct path_list *list)
20 -{
21 - DIR *dir;
22 - struct dirent *e;
23 -
24 - if (!(dir = opendir(path)))
25 - return error("Could not open directory %s", path);
26 -
27 - while ((e = readdir(dir)))
28 - if (strcmp(".", e->d_name) && strcmp("..", e->d_name))
29 - path_list_insert(e->d_name, list);
30 -
31 - closedir(dir);
32 - return 0;
33 -}
34 -
35 -static int get_mode(const char *path, int *mode)
36 -{
37 - struct stat st;
38 -
39 - if (!path || !strcmp(path, "/dev/null"))
40 - *mode = 0;
41 - else if (!strcmp(path, "-"))
42 - *mode = create_ce_mode(0666);
43 - else if (stat(path, &st))
44 - return error("Could not access '%s'", path);
45 - else
46 - *mode = st.st_mode;
47 - return 0;
48 -}
49 -
50 -static int queue_diff(struct diff_options *o,
51 - const char *name1, const char *name2)
52 -{
53 - int mode1 = 0, mode2 = 0;
54 -
55 - if (get_mode(name1, &mode1) || get_mode(name2, &mode2))
56 - return -1;
57 -
58 - if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2))
59 - return error("file/directory conflict: %s, %s", name1, name2);
60 -
61 - if (S_ISDIR(mode1) || S_ISDIR(mode2)) {
62 - char buffer1[PATH_MAX], buffer2[PATH_MAX];
63 - struct path_list p1 = {NULL, 0, 0, 1}, p2 = {NULL, 0, 0, 1};
64 - int len1 = 0, len2 = 0, i1, i2, ret = 0;
65 -
66 - if (name1 && read_directory(name1, &p1))
67 - return -1;
68 - if (name2 && read_directory(name2, &p2)) {
69 - path_list_clear(&p1, 0);
70 - return -1;
71 - }
72 -
73 - if (name1) {
74 - len1 = strlen(name1);
75 - if (len1 > 0 && name1[len1 - 1] == '/')
76 - len1--;
77 - memcpy(buffer1, name1, len1);
78 - buffer1[len1++] = '/';
79 - }
80 -
81 - if (name2) {
82 - len2 = strlen(name2);
83 - if (len2 > 0 && name2[len2 - 1] == '/')
84 - len2--;
85 - memcpy(buffer2, name2, len2);
86 - buffer2[len2++] = '/';
87 - }
88 -
89 - for (i1 = i2 = 0; !ret && (i1 < p1.nr || i2 < p2.nr); ) {
90 - const char *n1, *n2;
91 - int comp;
92 -
93 - if (i1 == p1.nr)
94 - comp = 1;
95 - else if (i2 == p2.nr)
96 - comp = -1;
97 - else
98 - comp = strcmp(p1.items[i1].path,
99 - p2.items[i2].path);
100 -
101 - if (comp > 0)
102 - n1 = NULL;
103 - else {
104 - n1 = buffer1;
105 - strncpy(buffer1 + len1, p1.items[i1++].path,
106 - PATH_MAX - len1);
107 - }
108 -
109 - if (comp < 0)
110 - n2 = NULL;
111 - else {
112 - n2 = buffer2;
113 - strncpy(buffer2 + len2, p2.items[i2++].path,
114 - PATH_MAX - len2);
115 - }
116 -
117 - ret = queue_diff(o, n1, n2);
118 - }
119 - path_list_clear(&p1, 0);
120 - path_list_clear(&p2, 0);
121 -
122 - return ret;
123 - } else {
124 - struct diff_filespec *d1, *d2;
125 -
126 - if (DIFF_OPT_TST(o, REVERSE_DIFF)) {
127 - unsigned tmp;
128 - const char *tmp_c;
129 - tmp = mode1; mode1 = mode2; mode2 = tmp;
130 - tmp_c = name1; name1 = name2; name2 = tmp_c;
131 - }
132 -
133 - if (!name1)
134 - name1 = "/dev/null";
135 - if (!name2)
136 - name2 = "/dev/null";
137 - d1 = alloc_filespec(name1);
138 - d2 = alloc_filespec(name2);
139 - fill_filespec(d1, null_sha1, mode1);
140 - fill_filespec(d2, null_sha1, mode2);
141 -
142 - diff_queue(&diff_queued_diff, d1, d2);
143 - return 0;
144 - }
145 -}
146 -
147 -/*
148 - * Does the path name a blob in the working tree, or a directory
149 - * in the working tree?
150 - */
151 -static int is_in_index(const char *path)
152 -{
153 - int len, pos;
154 - struct cache_entry *ce;
155 -
156 - len = strlen(path);
157 - while (path[len-1] == '/')
158 - len--;
159 - if (!len)
160 - return 1; /* "." */
161 - pos = cache_name_pos(path, len);
162 - if (0 <= pos)
163 - return 1;
164 - pos = -1 - pos;
165 - while (pos < active_nr) {
166 - ce = active_cache[pos++];
167 - if (ce_namelen(ce) <= len ||
168 - strncmp(ce->name, path, len) ||
169 - (ce->name[len] > '/'))
170 - break; /* path cannot be a prefix */
171 - if (ce->name[len] == '/')
172 - return 1;
173 - }
174 - return 0;
175 -}
176 -
177 -static int handle_diff_files_args(struct rev_info *revs,
178 - int argc, const char **argv,
179 - unsigned int *options)
180 -{
181 - *options = 0;
182 -
183 - /* revs->max_count == -2 means --no-index */
184 - while (1 < argc && argv[1][0] == '-') {
185 - if (!strcmp(argv[1], "--base"))
186 - revs->max_count = 1;
187 - else if (!strcmp(argv[1], "--ours"))
188 - revs->max_count = 2;
189 - else if (!strcmp(argv[1], "--theirs"))
190 - revs->max_count = 3;
191 - else if (!strcmp(argv[1], "-n") ||
192 - !strcmp(argv[1], "--no-index")) {
193 - revs->max_count = -2;
194 - DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
195 - DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
196 - }
197 - else if (!strcmp(argv[1], "-q"))
198 - *options |= DIFF_SILENT_ON_REMOVED;
199 - else
200 - return error("invalid option: %s", argv[1]);
201 - argv++; argc--;
202 - }
203 -
204 - if (revs->max_count == -1 && revs->diffopt.nr_paths == 2) {
205 - /*
206 - * If two files are specified, and at least one is untracked,
207 - * default to no-index.
208 - */
209 - read_cache();
210 - if (!is_in_index(revs->diffopt.paths[0]) ||
211 - !is_in_index(revs->diffopt.paths[1])) {
212 - revs->max_count = -2;
213 - DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
214 - }
215 - }
216 -
217 - /*
218 - * Make sure there are NO revision (i.e. pending object) parameter,
219 - * rev.max_count is reasonable (0 <= n <= 3),
220 - * there is no other revision filtering parameters.
221 - */
222 - if (revs->pending.nr || revs->max_count > 3 ||
223 - revs->min_age != -1 || revs->max_age != -1)
224 - return error("no revision allowed with diff-files");
225 -
226 - if (revs->max_count == -1 &&
227 - (revs->diffopt.output_format & DIFF_FORMAT_PATCH))
228 - revs->combine_merges = revs->dense_combined_merges = 1;
229 -
230 - return 0;
231 -}
232 -
233 -static int is_outside_repo(const char *path, int nongit, const char *prefix)
234 -{
235 - int i;
236 - if (nongit || !strcmp(path, "-") || is_absolute_path(path))
237 - return 1;
238 - if (prefixcmp(path, "../"))
239 - return 0;
240 - if (!prefix)
241 - return 1;
242 - for (i = strlen(prefix); !prefixcmp(path, "../"); ) {
243 - while (i > 0 && prefix[i - 1] != '/')
244 - i--;
245 - if (--i < 0)
246 - return 1;
247 - path += 3;
248 - }
249 - return 0;
250 -}
251 -
252 -int setup_diff_no_index(struct rev_info *revs,
253 - int argc, const char ** argv, int nongit, const char *prefix)
254 -{
255 - int i;
256 - for (i = 1; i < argc; i++)
257 - if (argv[i][0] != '-' || argv[i][1] == '\0')
258 - break;
259 - else if (!strcmp(argv[i], "--")) {
260 - i++;
261 - break;
262 - } else if (i < argc - 3 && !strcmp(argv[i], "--no-index")) {
263 - i = argc - 3;
264 - DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
265 - break;
266 - }
267 - if (nongit && argc != i + 2)
268 - die("git diff [--no-index] takes two paths");
269 -
270 - if (argc != i + 2 || (!is_outside_repo(argv[i + 1], nongit, prefix) &&
271 - !is_outside_repo(argv[i], nongit, prefix)))
272 - return -1;
273 -
274 - diff_setup(&revs->diffopt);
275 - for (i = 1; i < argc - 2; )
276 - if (!strcmp(argv[i], "--no-index"))
277 - i++;
278 - else {
279 - int j = diff_opt_parse(&revs->diffopt,
280 - argv + i, argc - i);
281 - if (!j)
282 - die("invalid diff option/value: %s", argv[i]);
283 - i += j;
284 - }
285 -
286 - if (prefix) {
287 - int len = strlen(prefix);
288 -
289 - revs->diffopt.paths = xcalloc(2, sizeof(char*));
290 - for (i = 0; i < 2; i++) {
291 - const char *p = argv[argc - 2 + i];
292 - /*
293 - * stdin should be spelled as '-'; if you have
294 - * path that is '-', spell it as ./-.
295 - */
296 - p = (strcmp(p, "-")
297 - ? xstrdup(prefix_filename(prefix, len, p))
298 - : p);
299 - revs->diffopt.paths[i] = p;
300 - }
301 - }
302 - else
303 - revs->diffopt.paths = argv + argc - 2;
304 - revs->diffopt.nr_paths = 2;
305 - DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
306 - revs->max_count = -2;
307 - if (diff_setup_done(&revs->diffopt) < 0)
308 - die("diff_setup_done failed");
309 - return 0;
310 -}
311 -
312 -int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv)
313 -{
314 - unsigned int options;
315 -
316 - if (handle_diff_files_args(revs, argc, argv, &options))
317 - return -1;
318 -
319 - if (DIFF_OPT_TST(&revs->diffopt, NO_INDEX)) {
320 - if (revs->diffopt.nr_paths != 2)
321 - return error("need two files/directories with --no-index");
322 - if (queue_diff(&revs->diffopt, revs->diffopt.paths[0],
323 - revs->diffopt.paths[1]))
324 - return -1;
325 - diffcore_std(&revs->diffopt);
326 - diff_flush(&revs->diffopt);
327 - /*
328 - * The return code for --no-index imitates diff(1):
329 - * 0 = no changes, 1 = changes, else error
330 - */
331 - return revs->diffopt.found_changes;
332 - }
333 -
334 - if (read_cache() < 0) {
335 - perror("read_cache");
336 - return -1;
337 - }
338 - return run_diff_files(revs, options);
339 -}
340 -
18 /*
19 * Has the work tree entity been removed?
20 *
diff-no-index.c new
+231
@@ -0,0 +1,231 @@
1 +/*
2 + * "diff --no-index" support
3 + * Copyright (c) 2007 by Johannes Schindelin
4 + * Copyright (c) 2008 by Junio C Hamano
5 + */
6 +
7 +#include "cache.h"
8 +#include "color.h"
9 +#include "commit.h"
10 +#include "blob.h"
11 +#include "tag.h"
12 +#include "diff.h"
13 +#include "diffcore.h"
14 +#include "revision.h"
15 +#include "log-tree.h"
16 +#include "builtin.h"
17 +#include "path-list.h"
18 +
19 +static int read_directory(const char *path, struct path_list *list)
20 +{
21 + DIR *dir;
22 + struct dirent *e;
23 +
24 + if (!(dir = opendir(path)))
25 + return error("Could not open directory %s", path);
26 +
27 + while ((e = readdir(dir)))
28 + if (strcmp(".", e->d_name) && strcmp("..", e->d_name))
29 + path_list_insert(e->d_name, list);
30 +
31 + closedir(dir);
32 + return 0;
33 +}
34 +
35 +static int get_mode(const char *path, int *mode)
36 +{
37 + struct stat st;
38 +
39 + if (!path || !strcmp(path, "/dev/null"))
40 + *mode = 0;
41 + else if (!strcmp(path, "-"))
42 + *mode = create_ce_mode(0666);
43 + else if (stat(path, &st))
44 + return error("Could not access '%s'", path);
45 + else
46 + *mode = st.st_mode;
47 + return 0;
48 +}
49 +
50 +static int queue_diff(struct diff_options *o,
51 + const char *name1, const char *name2)
52 +{
53 + int mode1 = 0, mode2 = 0;
54 +
55 + if (get_mode(name1, &mode1) || get_mode(name2, &mode2))
56 + return -1;
57 +
58 + if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2))
59 + return error("file/directory conflict: %s, %s", name1, name2);
60 +
61 + if (S_ISDIR(mode1) || S_ISDIR(mode2)) {
62 + char buffer1[PATH_MAX], buffer2[PATH_MAX];
63 + struct path_list p1 = {NULL, 0, 0, 1}, p2 = {NULL, 0, 0, 1};
64 + int len1 = 0, len2 = 0, i1, i2, ret = 0;
65 +
66 + if (name1 && read_directory(name1, &p1))
67 + return -1;
68 + if (name2 && read_directory(name2, &p2)) {
69 + path_list_clear(&p1, 0);
70 + return -1;
71 + }
72 +
73 + if (name1) {
74 + len1 = strlen(name1);
75 + if (len1 > 0 && name1[len1 - 1] == '/')
76 + len1--;
77 + memcpy(buffer1, name1, len1);
78 + buffer1[len1++] = '/';
79 + }
80 +
81 + if (name2) {
82 + len2 = strlen(name2);
83 + if (len2 > 0 && name2[len2 - 1] == '/')
84 + len2--;
85 + memcpy(buffer2, name2, len2);
86 + buffer2[len2++] = '/';
87 + }
88 +
89 + for (i1 = i2 = 0; !ret && (i1 < p1.nr || i2 < p2.nr); ) {
90 + const char *n1, *n2;
91 + int comp;
92 +
93 + if (i1 == p1.nr)
94 + comp = 1;
95 + else if (i2 == p2.nr)
96 + comp = -1;
97 + else
98 + comp = strcmp(p1.items[i1].path,
99 + p2.items[i2].path);
100 +
101 + if (comp > 0)
102 + n1 = NULL;
103 + else {
104 + n1 = buffer1;
105 + strncpy(buffer1 + len1, p1.items[i1++].path,
106 + PATH_MAX - len1);
107 + }
108 +
109 + if (comp < 0)
110 + n2 = NULL;
111 + else {
112 + n2 = buffer2;
113 + strncpy(buffer2 + len2, p2.items[i2++].path,
114 + PATH_MAX - len2);
115 + }
116 +
117 + ret = queue_diff(o, n1, n2);
118 + }
119 + path_list_clear(&p1, 0);
120 + path_list_clear(&p2, 0);
121 +
122 + return ret;
123 + } else {
124 + struct diff_filespec *d1, *d2;
125 +
126 + if (DIFF_OPT_TST(o, REVERSE_DIFF)) {
127 + unsigned tmp;
128 + const char *tmp_c;
129 + tmp = mode1; mode1 = mode2; mode2 = tmp;
130 + tmp_c = name1; name1 = name2; name2 = tmp_c;
131 + }
132 +
133 + if (!name1)
134 + name1 = "/dev/null";
135 + if (!name2)
136 + name2 = "/dev/null";
137 + d1 = alloc_filespec(name1);
138 + d2 = alloc_filespec(name2);
139 + fill_filespec(d1, null_sha1, mode1);
140 + fill_filespec(d2, null_sha1, mode2);
141 +
142 + diff_queue(&diff_queued_diff, d1, d2);
143 + return 0;
144 + }
145 +}
146 +
147 +void diff_no_index(struct rev_info *revs,
148 + int argc, const char **argv,
149 + int nongit, const char *prefix)
150 +{
151 + int i;
152 + int no_index = 0;
153 + unsigned options = 0;
154 +
155 + /* Were we asked to do --no-index explicitly? */
156 + for (i = 1; i < argc; i++) {
157 + if (!strcmp(argv[i], "--"))
158 + return;
159 + if (!strcmp(argv[i], "--no-index"))
160 + no_index = 1;
161 + if (argv[i][0] != '-')
162 + break;
163 + }
164 +
165 + /*
166 + * No explicit --no-index, but "git diff --opts A B" outside
167 + * a git repository is a cute hack to support.
168 + */
169 + if (!no_index && !nongit)
170 + return;
171 +
172 + if (argc != i + 2)
173 + die("git diff %s takes two paths",
174 + no_index ? "--no-index" : "[--no-index]");
175 +
176 + diff_setup(&revs->diffopt);
177 + if (!revs->diffopt.output_format)
178 + revs->diffopt.output_format = DIFF_FORMAT_PATCH;
179 + for (i = 1; i < argc - 2; ) {
180 + int j;
181 + if (!strcmp(argv[i], "--no-index"))
182 + i++;
183 + else if (!strcmp(argv[1], "-q"))
184 + options |= DIFF_SILENT_ON_REMOVED;
185 + else {
186 + j = diff_opt_parse(&revs->diffopt, argv + i, argc - i);
187 + if (!j)
188 + die("invalid diff option/value: %s", argv[i]);
189 + i += j;
190 + }
191 + }
192 +
193 + if (prefix) {
194 + int len = strlen(prefix);
195 +
196 + revs->diffopt.paths = xcalloc(2, sizeof(char*));
197 + for (i = 0; i < 2; i++) {
198 + const char *p = argv[argc - 2 + i];
199 + /*
200 + * stdin should be spelled as '-'; if you have
201 + * path that is '-', spell it as ./-.
202 + */
203 + p = (strcmp(p, "-")
204 + ? xstrdup(prefix_filename(prefix, len, p))
205 + : p);
206 + revs->diffopt.paths[i] = p;
207 + }
208 + }
209 + else
210 + revs->diffopt.paths = argv + argc - 2;
211 + revs->diffopt.nr_paths = 2;
212 +
213 + DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
214 + DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
215 +
216 + revs->max_count = -2;
217 + if (diff_setup_done(&revs->diffopt) < 0)
218 + die("diff_setup_done failed");
219 +
220 + if (queue_diff(&revs->diffopt, revs->diffopt.paths[0],
221 + revs->diffopt.paths[1]))
222 + exit(1);
223 + diffcore_std(&revs->diffopt);
224 + diff_flush(&revs->diffopt);
225 +
226 + /*
227 + * The return code for --no-index imitates diff(1):
228 + * 0 = no changes, 1 = changes, else error
229 + */
230 + exit(revs->diffopt.found_changes);
231 +}
diff.h
+2 -4
@@ -250,10 +250,6 @@ extern const char *diff_unique_abbrev(const unsigned char *, int);
250 /* report racily-clean paths as modified */
251 #define DIFF_RACY_IS_MODIFIED 02
252 extern int run_diff_files(struct rev_info *revs, unsigned int option);
253 -extern int setup_diff_no_index(struct rev_info *revs,
254 - int argc, const char ** argv, int nongit, const char *prefix);
255 -extern int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv);
256 -
253 extern int run_diff_index(struct rev_info *revs, int cached);
254
255 extern int do_diff_cache(const unsigned char *, struct diff_options *);
@@ -261,4 +257,6 @@ extern int diff_flush_patch_id(struct diff_options *, unsigned char *);
257
258 extern int diff_result_code(struct diff_options *, int);
259
260 +extern void diff_no_index(struct rev_info *, int, const char **, int, const char *);
261 +
262 #endif /* DIFF_H */
t/t4013-diff-various.sh
+1
@@ -257,6 +257,7 @@ diff --patch-with-raw initial..side
257 diff --patch-with-stat -r initial..side
258 diff --patch-with-raw -r initial..side
259 diff --name-status dir2 dir
260 +diff --no-index --name-status dir2 dir
261 EOF
262
263 test_done
t/t4013/diff.diff_--name-status_dir2_dir
-1
@@ -1,3 +1,2 @@
1 $ git diff --name-status dir2 dir
2 -A dir/sub
2 $
t/t4013/diff.diff_--no-index_--name-status_dir2_dir new
+3
@@ -0,0 +1,3 @@
1 +$ git diff --no-index --name-status dir2 dir
2 +A dir/sub
3 +$