void diff_no_index(struct rev_info *revs, int argc, const char **argv, const char *prefix) { int i, prefixlen; const char *paths[2]; diff_setup(&revs->diffopt); for (i = 1; i < argc - 2; ) { int j; if (!strcmp(argv[i], "--no-index")) i++; else if (!strcmp(argv[i], "--")) i++; else { j = diff_opt_parse(&revs->diffopt, argv + i, argc - i); if (j <= 0) die("invalid diff option/value: %s", argv[i]); i += j; } } prefixlen = prefix ? strlen(prefix) : 0; for (i = 0; i < 2; i++) { const char *p = argv[argc - 2 + i]; if (!strcmp(p, "-")) /* * stdin should be spelled as "-"; if you have * path that is "-", spell it as "./-". */ p = file_from_standard_input; else if (prefixlen) p = xstrdup(prefix_filename(prefix, prefixlen, p)); paths[i] = p; } revs->diffopt.skip_stat_unmatch = 1; if (!revs->diffopt.output_format) revs->diffopt.output_format = DIFF_FORMAT_PATCH; DIFF_OPT_SET(&revs->diffopt, NO_INDEX); revs->max_count = -2; diff_setup_done(&revs->diffopt); setup_diff_pager(&revs->diffopt); DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); if (queue_diff(&revs->diffopt, paths[0], paths[1])) exit(1); diff_set_mnemonic_prefix(&revs->diffopt, "1/", "2/"); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); /* * The return code for --no-index imitates diff(1): * 0 = no changes, 1 = changes, else error */ exit(diff_result_code(&revs->diffopt, 0)); }
static int queue_diff(struct diff_options *o, const char *name1, const char *name2) { int mode1 = 0, mode2 = 0; if (get_mode(name1, &mode1) || get_mode(name2, &mode2)) return -1; if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2)) return error("file/directory conflict: %s, %s", name1, name2); if (S_ISDIR(mode1) || S_ISDIR(mode2)) { char buffer1[PATH_MAX], buffer2[PATH_MAX]; struct string_list p1 = {NULL, 0, 0, 1}, p2 = {NULL, 0, 0, 1}; int len1 = 0, len2 = 0, i1, i2, ret = 0; if (name1 && read_directory(name1, &p1)) return -1; if (name2 && read_directory(name2, &p2)) { string_list_clear(&p1, 0); return -1; } if (name1) { len1 = strlen(name1); if (len1 > 0 && name1[len1 - 1] == '/') len1--; memcpy(buffer1, name1, len1); buffer1[len1++] = '/'; } if (name2) { len2 = strlen(name2); if (len2 > 0 && name2[len2 - 1] == '/') len2--; memcpy(buffer2, name2, len2); buffer2[len2++] = '/'; } for (i1 = i2 = 0; !ret && (i1 < p1.nr || i2 < p2.nr); ) { const char *n1, *n2; int comp; if (i1 == p1.nr) comp = 1; else if (i2 == p2.nr) comp = -1; else comp = strcmp(p1.items[i1].string, p2.items[i2].string); if (comp > 0) n1 = NULL; else { n1 = buffer1; strncpy(buffer1 + len1, p1.items[i1++].string, PATH_MAX - len1); } if (comp < 0) n2 = NULL; else { n2 = buffer2; strncpy(buffer2 + len2, p2.items[i2++].string, PATH_MAX - len2); } ret = queue_diff(o, n1, n2); } string_list_clear(&p1, 0); string_list_clear(&p2, 0); return ret; } else { struct diff_filespec *d1, *d2; if (DIFF_OPT_TST(o, REVERSE_DIFF)) { unsigned tmp; const char *tmp_c; tmp = mode1; mode1 = mode2; mode2 = tmp; tmp_c = name1; name1 = name2; name2 = tmp_c; } if (!name1) name1 = "/dev/null"; if (!name2) name2 = "/dev/null"; d1 = alloc_filespec(name1); d2 = alloc_filespec(name2); fill_filespec(d1, null_sha1, mode1); fill_filespec(d2, null_sha1, mode2); diff_queue(&diff_queued_diff, d1, d2); return 0; } }
void diff_no_index(struct rev_info *revs, int argc, const char **argv, int nongit, const char *prefix) { int i; int no_index = 0; unsigned options = 0; /* Were we asked to do --no-index explicitly? */ for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "--")) return; if (!strcmp(argv[i], "--no-index")) no_index = 1; if (argv[i][0] != '-') break; } if (!no_index && !nongit) { /* * Inside a git repository, without --no-index. Only * when a path outside the repository is given, * e.g. "git diff /var/tmp/[12]", or "git diff * Makefile /var/tmp/Makefile", allow it to be used as * a colourful "diff" replacement. */ if ((argc != i + 2) || (!path_outside_repo(argv[i]) && !path_outside_repo(argv[i+1]))) return; } if (argc != i + 2) die("git diff %s takes two paths", no_index ? "--no-index" : "[--no-index]"); /* * If the user asked for our exit code then don't start a * pager or we would end up reporting its exit code instead. */ if (!DIFF_OPT_TST(&revs->diffopt, EXIT_WITH_STATUS)) setup_pager(); diff_setup(&revs->diffopt); if (!revs->diffopt.output_format) revs->diffopt.output_format = DIFF_FORMAT_PATCH; for (i = 1; i < argc - 2; ) { int j; if (!strcmp(argv[i], "--no-index")) i++; else if (!strcmp(argv[1], "-q")) options |= DIFF_SILENT_ON_REMOVED; else { j = diff_opt_parse(&revs->diffopt, argv + i, argc - i); if (!j) die("invalid diff option/value: %s", argv[i]); i += j; } } if (prefix) { int len = strlen(prefix); revs->diffopt.paths = xcalloc(2, sizeof(char*)); for (i = 0; i < 2; i++) { const char *p = argv[argc - 2 + i]; /* * stdin should be spelled as '-'; if you have * path that is '-', spell it as ./-. */ p = (strcmp(p, "-") ? xstrdup(prefix_filename(prefix, len, p)) : p); revs->diffopt.paths[i] = p; } } else revs->diffopt.paths = argv + argc - 2; revs->diffopt.nr_paths = 2; DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); DIFF_OPT_SET(&revs->diffopt, NO_INDEX); revs->max_count = -2; if (diff_setup_done(&revs->diffopt) < 0) die("diff_setup_done failed"); if (queue_diff(&revs->diffopt, revs->diffopt.paths[0], revs->diffopt.paths[1])) exit(1); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); /* * The return code for --no-index imitates diff(1): * 0 = no changes, 1 = changes, else error */ exit(revs->diffopt.found_changes); }
static int queue_diff(struct diff_options *o, const char *name1, const char *name2) { int mode1 = 0, mode2 = 0; if (get_mode(name1, &mode1) || get_mode(name2, &mode2)) return -1; if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2)) return error("file/directory conflict: %s, %s", name1, name2); if (S_ISDIR(mode1) || S_ISDIR(mode2)) { struct strbuf buffer1 = STRBUF_INIT; struct strbuf buffer2 = STRBUF_INIT; struct string_list p1 = STRING_LIST_INIT_DUP; struct string_list p2 = STRING_LIST_INIT_DUP; int i1, i2, ret = 0; size_t len1 = 0, len2 = 0; if (name1 && read_directory_contents(name1, &p1)) return -1; if (name2 && read_directory_contents(name2, &p2)) { string_list_clear(&p1, 0); return -1; } if (name1) { strbuf_addstr(&buffer1, name1); if (buffer1.len && buffer1.buf[buffer1.len - 1] != '/') strbuf_addch(&buffer1, '/'); len1 = buffer1.len; } if (name2) { strbuf_addstr(&buffer2, name2); if (buffer2.len && buffer2.buf[buffer2.len - 1] != '/') strbuf_addch(&buffer2, '/'); len2 = buffer2.len; } for (i1 = i2 = 0; !ret && (i1 < p1.nr || i2 < p2.nr); ) { const char *n1, *n2; int comp; strbuf_setlen(&buffer1, len1); strbuf_setlen(&buffer2, len2); if (i1 == p1.nr) comp = 1; else if (i2 == p2.nr) comp = -1; else comp = strcmp(p1.items[i1].string, p2.items[i2].string); if (comp > 0) n1 = NULL; else { strbuf_addstr(&buffer1, p1.items[i1++].string); n1 = buffer1.buf; } if (comp < 0) n2 = NULL; else { strbuf_addstr(&buffer2, p2.items[i2++].string); n2 = buffer2.buf; } ret = queue_diff(o, n1, n2); } string_list_clear(&p1, 0); string_list_clear(&p2, 0); strbuf_release(&buffer1); strbuf_release(&buffer2); return ret; } else { struct diff_filespec *d1, *d2; if (DIFF_OPT_TST(o, REVERSE_DIFF)) { unsigned tmp; const char *tmp_c; tmp = mode1; mode1 = mode2; mode2 = tmp; tmp_c = name1; name1 = name2; name2 = tmp_c; } d1 = noindex_filespec(name1, mode1); d2 = noindex_filespec(name2, mode2); diff_queue(&diff_queued_diff, d1, d2); return 0; } }
static int queue_diff(struct diff_options *o, const char *name1, const char *name2) { int mode1 = 0, mode2 = 0; if (get_mode(name1, &mode1) || get_mode(name2, &mode2)) return -1; if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2)) { struct diff_filespec *d1, *d2; if (S_ISDIR(mode1)) { /* 2 is file that is created */ d1 = noindex_filespec(NULL, 0); d2 = noindex_filespec(name2, mode2); name2 = NULL; mode2 = 0; } else { /* 1 is file that is deleted */ d1 = noindex_filespec(name1, mode1); d2 = noindex_filespec(NULL, 0); name1 = NULL; mode1 = 0; } /* emit that file */ diff_queue(&diff_queued_diff, d1, d2); /* and then let the entire directory be created or deleted */ } if (S_ISDIR(mode1) || S_ISDIR(mode2)) { struct strbuf buffer1 = STRBUF_INIT; struct strbuf buffer2 = STRBUF_INIT; struct string_list p1 = STRING_LIST_INIT_DUP; struct string_list p2 = STRING_LIST_INIT_DUP; int i1, i2, ret = 0; size_t len1 = 0, len2 = 0; if (name1 && read_directory_contents(name1, &p1)) return -1; if (name2 && read_directory_contents(name2, &p2)) { string_list_clear(&p1, 0); return -1; } if (name1) { strbuf_addstr(&buffer1, name1); strbuf_complete(&buffer1, '/'); len1 = buffer1.len; } if (name2) { strbuf_addstr(&buffer2, name2); strbuf_complete(&buffer2, '/'); len2 = buffer2.len; } for (i1 = i2 = 0; !ret && (i1 < p1.nr || i2 < p2.nr); ) { const char *n1, *n2; int comp; strbuf_setlen(&buffer1, len1); strbuf_setlen(&buffer2, len2); if (i1 == p1.nr) comp = 1; else if (i2 == p2.nr) comp = -1; else comp = strcmp(p1.items[i1].string, p2.items[i2].string); if (comp > 0) n1 = NULL; else { strbuf_addstr(&buffer1, p1.items[i1++].string); n1 = buffer1.buf; } if (comp < 0) n2 = NULL; else { strbuf_addstr(&buffer2, p2.items[i2++].string); n2 = buffer2.buf; } ret = queue_diff(o, n1, n2); } string_list_clear(&p1, 0); string_list_clear(&p2, 0); strbuf_release(&buffer1); strbuf_release(&buffer2); return ret; } else { struct diff_filespec *d1, *d2; if (o->flags.reverse_diff) { SWAP(mode1, mode2); SWAP(name1, name2); } d1 = noindex_filespec(name1, mode1); d2 = noindex_filespec(name2, mode2); diff_queue(&diff_queued_diff, d1, d2); return 0; } }
void diff_no_index(struct repository *r, struct rev_info *revs, int argc, const char **argv) { int i; const char *paths[2]; struct strbuf replacement = STRBUF_INIT; const char *prefix = revs->prefix; /* * FIXME: --no-index should not look at index and we should be * able to pass NULL repo. Maybe later. */ repo_diff_setup(r, &revs->diffopt); for (i = 1; i < argc - 2; ) { int j; if (!strcmp(argv[i], "--no-index")) i++; else if (!strcmp(argv[i], "--")) i++; else { j = diff_opt_parse(&revs->diffopt, argv + i, argc - i, revs->prefix); if (j <= 0) die("invalid diff option/value: %s", argv[i]); i += j; } } for (i = 0; i < 2; i++) { const char *p = argv[argc - 2 + i]; if (!strcmp(p, "-")) /* * stdin should be spelled as "-"; if you have * path that is "-", spell it as "./-". */ p = file_from_standard_input; else if (prefix) p = prefix_filename(prefix, p); paths[i] = p; } fixup_paths(paths, &replacement); revs->diffopt.skip_stat_unmatch = 1; if (!revs->diffopt.output_format) revs->diffopt.output_format = DIFF_FORMAT_PATCH; revs->diffopt.flags.no_index = 1; revs->diffopt.flags.relative_name = 1; revs->diffopt.prefix = prefix; revs->max_count = -2; diff_setup_done(&revs->diffopt); setup_diff_pager(&revs->diffopt); revs->diffopt.flags.exit_with_status = 1; if (queue_diff(&revs->diffopt, paths[0], paths[1])) exit(1); diff_set_mnemonic_prefix(&revs->diffopt, "1/", "2/"); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); strbuf_release(&replacement); /* * The return code for --no-index imitates diff(1): * 0 = no changes, 1 = changes, else error */ exit(diff_result_code(&revs->diffopt, 0)); }
void diff_no_index(struct rev_info *revs, int argc, const char **argv, int nongit, const char *prefix) { int i, prefixlen; int no_index = 0; unsigned options = 0; const char *paths[2]; /* Were we asked to do --no-index explicitly? */ for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "--")) { i++; break; } if (!strcmp(argv[i], "--no-index")) no_index = 1; if (argv[i][0] != '-') break; } if (!no_index && !nongit) { /* * Inside a git repository, without --no-index. Only * when a path outside the repository is given, * e.g. "git diff /var/tmp/[12]", or "git diff * Makefile /var/tmp/Makefile", allow it to be used as * a colourful "diff" replacement. */ if ((argc != i + 2) || (path_inside_repo(prefix, argv[i]) && path_inside_repo(prefix, argv[i+1]))) return; } if (argc != i + 2) usagef("git diff %s <path> <path>", no_index ? "--no-index" : "[--no-index]"); diff_setup(&revs->diffopt); for (i = 1; i < argc - 2; ) { int j; if (!strcmp(argv[i], "--no-index")) i++; else if (!strcmp(argv[i], "-q")) { options |= DIFF_SILENT_ON_REMOVED; i++; } else if (!strcmp(argv[i], "--")) i++; else { j = diff_opt_parse(&revs->diffopt, argv + i, argc - i); if (!j) die("invalid diff option/value: %s", argv[i]); i += j; } } prefixlen = prefix ? strlen(prefix) : 0; for (i = 0; i < 2; i++) { const char *p = argv[argc - 2 + i]; if (!strcmp(p, "-")) /* * stdin should be spelled as "-"; if you have * path that is "-", spell it as "./-". */ p = file_from_standard_input; else if (prefixlen) p = xstrdup(prefix_filename(prefix, prefixlen, p)); paths[i] = p; } revs->diffopt.skip_stat_unmatch = 1; if (!revs->diffopt.output_format) revs->diffopt.output_format = DIFF_FORMAT_PATCH; DIFF_OPT_SET(&revs->diffopt, NO_INDEX); revs->max_count = -2; diff_setup_done(&revs->diffopt); setup_diff_pager(&revs->diffopt); DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); if (queue_diff(&revs->diffopt, paths[0], paths[1])) exit(1); diff_set_mnemonic_prefix(&revs->diffopt, "1/", "2/"); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); /* * The return code for --no-index imitates diff(1): * 0 = no changes, 1 = changes, else error */ exit(diff_result_code(&revs->diffopt, 0)); }