static int builtin_diff_b_f(struct rev_info *revs, int argc, const char **argv, struct blobinfo *blob) { /* Blob vs file in the working tree*/ struct stat st; const char *path; if (argc > 1) usage(builtin_diff_usage); GUARD_PATHSPEC(&revs->prune_data, PATHSPEC_FROMTOP | PATHSPEC_LITERAL); path = revs->prune_data.items[0].match; if (lstat(path, &st)) die_errno(_("failed to stat '%s'"), path); if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))) die(_("'%s': not a regular file or symlink"), path); diff_set_mnemonic_prefix(&revs->diffopt, "o/", "w/"); if (blob[0].mode == S_IFINVALID) blob[0].mode = canon_mode(st.st_mode); stuff_change(&revs->diffopt, blob[0].mode, canon_mode(st.st_mode), blob[0].sha1, null_sha1, 1, 0, path, path); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); return 0; }
static int builtin_diff_b_f(struct rev_info *revs, int argc, const char **argv, struct blobinfo *blob, const char *path) { /* Blob vs file in the working tree*/ struct stat st; if (argc > 1) usage(builtin_diff_usage); if (lstat(path, &st)) die_errno("failed to stat '%s'", path); if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))) die("'%s': not a regular file or symlink", path); diff_set_mnemonic_prefix(&revs->diffopt, "o/", "w/"); if (blob[0].mode == S_IFINVALID) blob[0].mode = canon_mode(st.st_mode); stuff_change(&revs->diffopt, blob[0].mode, canon_mode(st.st_mode), blob[0].sha1, null_sha1, path, path); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); return 0; }
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)); }
int run_diff_index(struct rev_info *revs, int cached) { struct object_array_entry *ent; if (revs->pending.nr != 1) BUG("run_diff_index must be passed exactly one tree"); trace_performance_enter(); ent = revs->pending.objects; if (diff_cache(revs, &ent->item->oid, ent->name, cached)) exit(128); diff_set_mnemonic_prefix(&revs->diffopt, "c/", cached ? "i/" : "w/"); diffcore_fix_diff_index(&revs->diffopt); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); trace_performance_leave("diff-index"); return 0; }
int run_diff_files(struct rev_info *revs, unsigned int option) { int entries, i; int diff_unmerged_stage = revs->max_count; int silent_on_removed = option & DIFF_SILENT_ON_REMOVED; unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED) ? CE_MATCH_RACY_IS_DIRTY : 0); diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/"); if (diff_unmerged_stage < 0) diff_unmerged_stage = 2; entries = active_nr; for (i = 0; i < entries; i++) { struct stat st; unsigned int oldmode, newmode; struct cache_entry *ce = active_cache[i]; int changed; if (DIFF_OPT_TST(&revs->diffopt, QUIET) && DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES)) break; if (!ce_path_match(ce, revs->prune_data)) continue; if (ce_stage(ce)) { struct combine_diff_path *dpath; int num_compare_stages = 0; size_t path_len; path_len = ce_namelen(ce); dpath = xmalloc(combine_diff_path_size(5, path_len)); dpath->path = (char *) &(dpath->parent[5]); dpath->next = NULL; dpath->len = path_len; memcpy(dpath->path, ce->name, path_len); dpath->path[path_len] = '\0'; hashclr(dpath->sha1); memset(&(dpath->parent[0]), 0, sizeof(struct combine_diff_parent)*5); changed = check_removed(ce, &st); if (!changed) dpath->mode = ce_mode_from_stat(ce, st.st_mode); else { if (changed < 0) { perror(ce->name); continue; } if (silent_on_removed) continue; } while (i < entries) { struct cache_entry *nce = active_cache[i]; int stage; if (strcmp(ce->name, nce->name)) break; /* Stage #2 (ours) is the first parent, * stage #3 (theirs) is the second. */ stage = ce_stage(nce); if (2 <= stage) { int mode = nce->ce_mode; num_compare_stages++; hashcpy(dpath->parent[stage-2].sha1, nce->sha1); dpath->parent[stage-2].mode = ce_mode_from_stat(nce, mode); dpath->parent[stage-2].status = DIFF_STATUS_MODIFIED; } /* diff against the proper unmerged stage */ if (stage == diff_unmerged_stage) ce = nce; i++; } /* * Compensate for loop update */ i--; if (revs->combine_merges && num_compare_stages == 2) { show_combined_diff(dpath, 2, revs->dense_combined_merges, revs); free(dpath); continue; } free(dpath); dpath = NULL; /* * Show the diff for the 'ce' if we found the one * from the desired stage. */ diff_unmerge(&revs->diffopt, ce->name, 0, null_sha1); if (ce_stage(ce) != diff_unmerged_stage) continue; } if (ce_uptodate(ce)) continue; changed = check_removed(ce, &st); if (changed) { if (changed < 0) { perror(ce->name); continue; } if (silent_on_removed) continue; diff_addremove(&revs->diffopt, '-', ce->ce_mode, ce->sha1, ce->name); continue; } changed = ce_match_stat(ce, &st, ce_option); if (!changed) { ce_mark_uptodate(ce); if (!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)) continue; } oldmode = ce->ce_mode; newmode = ce_mode_from_stat(ce, st.st_mode); diff_change(&revs->diffopt, oldmode, newmode, ce->sha1, (changed ? null_sha1 : ce->sha1), ce->name); } diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); return 0; }
int run_diff_files(struct rev_info *revs, unsigned int option) { int entries, i; int diff_unmerged_stage = revs->max_count; unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED) ? CE_MATCH_RACY_IS_DIRTY : 0); diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/"); if (diff_unmerged_stage < 0) diff_unmerged_stage = 2; entries = active_nr; for (i = 0; i < entries; i++) { unsigned int oldmode, newmode; struct cache_entry *ce = active_cache[i]; int changed; unsigned dirty_submodule = 0; const unsigned char *old_sha1, *new_sha1; if (diff_can_quit_early(&revs->diffopt)) break; if (!ce_path_match(ce, &revs->prune_data, NULL)) continue; if (ce_stage(ce)) { struct combine_diff_path *dpath; struct diff_filepair *pair; unsigned int wt_mode = 0; int num_compare_stages = 0; size_t path_len; struct stat st; path_len = ce_namelen(ce); dpath = xmalloc(combine_diff_path_size(5, path_len)); dpath->path = (char *) &(dpath->parent[5]); dpath->next = NULL; memcpy(dpath->path, ce->name, path_len); dpath->path[path_len] = '\0'; oidclr(&dpath->oid); memset(&(dpath->parent[0]), 0, sizeof(struct combine_diff_parent)*5); changed = check_removed(ce, &st); if (!changed) wt_mode = ce_mode_from_stat(ce, st.st_mode); else { if (changed < 0) { perror(ce->name); continue; } wt_mode = 0; } dpath->mode = wt_mode; while (i < entries) { struct cache_entry *nce = active_cache[i]; int stage; if (strcmp(ce->name, nce->name)) break; /* Stage #2 (ours) is the first parent, * stage #3 (theirs) is the second. */ stage = ce_stage(nce); if (2 <= stage) { int mode = nce->ce_mode; num_compare_stages++; hashcpy(dpath->parent[stage-2].oid.hash, nce->sha1); dpath->parent[stage-2].mode = ce_mode_from_stat(nce, mode); dpath->parent[stage-2].status = DIFF_STATUS_MODIFIED; } /* diff against the proper unmerged stage */ if (stage == diff_unmerged_stage) ce = nce; i++; } /* * Compensate for loop update */ i--; if (revs->combine_merges && num_compare_stages == 2) { show_combined_diff(dpath, 2, revs->dense_combined_merges, revs); free(dpath); continue; } free(dpath); dpath = NULL; /* * Show the diff for the 'ce' if we found the one * from the desired stage. */ pair = diff_unmerge(&revs->diffopt, ce->name); if (wt_mode) pair->two->mode = wt_mode; if (ce_stage(ce) != diff_unmerged_stage) continue; } if (ce_uptodate(ce) || ce_skip_worktree(ce)) continue; /* If CE_VALID is set, don't look at workdir for file removal */ if (ce->ce_flags & CE_VALID) { changed = 0; newmode = ce->ce_mode; } else { struct stat st; changed = check_removed(ce, &st); if (changed) { if (changed < 0) { perror(ce->name); continue; } diff_addremove(&revs->diffopt, '-', ce->ce_mode, ce->sha1, !is_null_sha1(ce->sha1), ce->name, 0); continue; } changed = match_stat_with_submodule(&revs->diffopt, ce, &st, ce_option, &dirty_submodule); newmode = ce_mode_from_stat(ce, st.st_mode); } if (!changed && !dirty_submodule) { ce_mark_uptodate(ce); if (!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)) continue; } oldmode = ce->ce_mode; old_sha1 = ce->sha1; new_sha1 = changed ? null_sha1 : ce->sha1; diff_change(&revs->diffopt, oldmode, newmode, old_sha1, new_sha1, !is_null_sha1(old_sha1), !is_null_sha1(new_sha1), ce->name, 0, dirty_submodule); } diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); 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)); }
int run_diff_files(struct rev_info *revs, unsigned int option) { int entries, i; int diff_unmerged_stage = revs->max_count; unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED) ? CE_MATCH_RACY_IS_DIRTY : 0); uint64_t start = getnanotime(); struct index_state *istate = revs->diffopt.repo->index; diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/"); if (diff_unmerged_stage < 0) diff_unmerged_stage = 2; entries = istate->cache_nr; for (i = 0; i < entries; i++) { unsigned int oldmode, newmode; struct cache_entry *ce = istate->cache[i]; int changed; unsigned dirty_submodule = 0; const struct object_id *old_oid, *new_oid; if (diff_can_quit_early(&revs->diffopt)) break; if (!ce_path_match(istate, ce, &revs->prune_data, NULL)) continue; if (ce_stage(ce)) { struct combine_diff_path *dpath; struct diff_filepair *pair; unsigned int wt_mode = 0; int num_compare_stages = 0; size_t path_len; struct stat st; path_len = ce_namelen(ce); dpath = xmalloc(combine_diff_path_size(5, path_len)); dpath->path = (char *) &(dpath->parent[5]); dpath->next = NULL; memcpy(dpath->path, ce->name, path_len); dpath->path[path_len] = '\0'; oidclr(&dpath->oid); memset(&(dpath->parent[0]), 0, sizeof(struct combine_diff_parent)*5); changed = check_removed(ce, &st); if (!changed) wt_mode = ce_mode_from_stat(ce, st.st_mode); else { if (changed < 0) { perror(ce->name); continue; } wt_mode = 0; } dpath->mode = wt_mode; while (i < entries) { struct cache_entry *nce = istate->cache[i]; int stage; if (strcmp(ce->name, nce->name)) break; /* Stage #2 (ours) is the first parent, * stage #3 (theirs) is the second. */ stage = ce_stage(nce); if (2 <= stage) { int mode = nce->ce_mode; num_compare_stages++; oidcpy(&dpath->parent[stage - 2].oid, &nce->oid); dpath->parent[stage-2].mode = ce_mode_from_stat(nce, mode); dpath->parent[stage-2].status = DIFF_STATUS_MODIFIED; } /* diff against the proper unmerged stage */ if (stage == diff_unmerged_stage) ce = nce; i++; } /* * Compensate for loop update */ i--; if (revs->combine_merges && num_compare_stages == 2) { show_combined_diff(dpath, 2, revs->dense_combined_merges, revs); free(dpath); continue; } FREE_AND_NULL(dpath); /* * Show the diff for the 'ce' if we found the one * from the desired stage. */ pair = diff_unmerge(&revs->diffopt, ce->name); if (wt_mode) pair->two->mode = wt_mode; if (ce_stage(ce) != diff_unmerged_stage) continue; } if (ce_uptodate(ce) || ce_skip_worktree(ce)) continue; /* If CE_VALID is set, don't look at workdir for file removal */ if (ce->ce_flags & CE_VALID) { changed = 0; newmode = ce->ce_mode; } else { struct stat st; changed = check_removed(ce, &st); if (changed) { if (changed < 0) { perror(ce->name); continue; } diff_addremove(&revs->diffopt, '-', ce->ce_mode, &ce->oid, !is_null_oid(&ce->oid), ce->name, 0); continue; } else if (revs->diffopt.ita_invisible_in_index && ce_intent_to_add(ce)) { diff_addremove(&revs->diffopt, '+', ce->ce_mode, the_hash_algo->empty_tree, 0, ce->name, 0); continue; } changed = match_stat_with_submodule(&revs->diffopt, ce, &st, ce_option, &dirty_submodule); newmode = ce_mode_from_stat(ce, st.st_mode); } if (!changed && !dirty_submodule) { ce_mark_uptodate(ce); mark_fsmonitor_valid(ce); if (!revs->diffopt.flags.find_copies_harder) continue; } oldmode = ce->ce_mode; old_oid = &ce->oid; new_oid = changed ? &null_oid : &ce->oid; diff_change(&revs->diffopt, oldmode, newmode, old_oid, new_oid, !is_null_oid(old_oid), !is_null_oid(new_oid), ce->name, 0, dirty_submodule); } diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); trace_performance_since(start, "diff-files"); return 0; }