static int check_changes_tracked_files(struct pathspec ps) { int result; struct rev_info rev; struct object_id dummy; /* No initial commit. */ if (get_oid("HEAD", &dummy)) return -1; if (read_cache() < 0) return -1; init_revisions(&rev, NULL); rev.prune_data = ps; rev.diffopt.flags.quick = 1; rev.diffopt.flags.ignore_submodules = 1; rev.abbrev = 0; add_head_to_pending(&rev); diff_setup_done(&rev.diffopt); result = run_diff_index(&rev, 1); if (diff_result_code(&rev.diffopt, result)) return 1; object_array_clear(&rev.pending); result = run_diff_files(&rev, 0); if (diff_result_code(&rev.diffopt, result)) return 1; return 0; }
static int evaluate_result(void) { int cnt = 0; struct rev_info rev; if (read_cache() < 0) die("failed to read the cache"); /* Check how many files differ. */ init_revisions(&rev, ""); setup_revisions(0, NULL, &rev, NULL); rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK; rev.diffopt.format_callback = count_diff_files; rev.diffopt.format_callback_data = &cnt; run_diff_files(&rev, 0); /* * Check how many unmerged entries are * there. */ cnt += count_unmerged_entries(); return cnt; }
int cmd_diff_files(int argc, const char **argv, const char *prefix) { struct rev_info rev; int result; unsigned options = 0; if (argc == 2 && !strcmp(argv[1], "-h")) usage(diff_files_usage); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ init_revisions(&rev, prefix); rev.abbrev = 0; precompose_argv(argc, argv); argc = setup_revisions(argc, argv, &rev, NULL); while (1 < argc && argv[1][0] == '-') { if (!strcmp(argv[1], "--base")) rev.max_count = 1; else if (!strcmp(argv[1], "--ours")) rev.max_count = 2; else if (!strcmp(argv[1], "--theirs")) rev.max_count = 3; else if (!strcmp(argv[1], "-q")) options |= DIFF_SILENT_ON_REMOVED; else usage(diff_files_usage); argv++; argc--; } if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_RAW; /* * Make sure there are NO revision (i.e. pending object) parameter, * rev.max_count is reasonable (0 <= n <= 3), and * there is no other revision filtering parameters. */ if (rev.pending.nr || rev.min_age != -1 || rev.max_age != -1 || 3 < rev.max_count) usage(diff_files_usage); /* * "diff-files --base -p" should not combine merges because it * was not asked to. "diff-files -c -p" should not densify * (the user should ask with "diff-files --cc" explicitly). */ if (rev.max_count == -1 && !rev.combine_merges && (rev.diffopt.output_format & DIFF_FORMAT_PATCH)) rev.combine_merges = rev.dense_combined_merges = 1; if (read_cache_preload(&rev.diffopt.pathspec) < 0) { perror("read_cache_preload"); return -1; } result = run_diff_files(&rev, options); return diff_result_code(&rev.diffopt, result); }
static void wt_status_print_changed(struct wt_status *s) { struct rev_info rev; init_revisions(&rev, ""); setup_revisions(0, NULL, &rev, NULL); rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK; rev.diffopt.format_callback = wt_status_print_changed_cb; rev.diffopt.format_callback_data = s; run_diff_files(&rev, 0); }
/** * Returns 1 if there are unstaged changes, 0 otherwise. */ static int has_unstaged_changes(const char *prefix) { struct rev_info rev_info; int result; init_revisions(&rev_info, prefix); DIFF_OPT_SET(&rev_info.diffopt, IGNORE_SUBMODULES); DIFF_OPT_SET(&rev_info.diffopt, QUICK); diff_setup_done(&rev_info.diffopt); result = run_diff_files(&rev_info, 0); return diff_result_code(&rev_info.diffopt, result); }
static void wt_status_print_verbose(struct wt_status *s) { struct rev_info rev; struct setup_revision_opt opt; int dirty_submodules; const char *c = color(WT_STATUS_HEADER, s); init_revisions(&rev, NULL); DIFF_OPT_SET(&rev.diffopt, ALLOW_TEXTCONV); memset(&opt, 0, sizeof(opt)); opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference; setup_revisions(0, NULL, &rev, &opt); rev.diffopt.output_format |= DIFF_FORMAT_PATCH; rev.diffopt.detect_rename = 1; rev.diffopt.file = s->fp; rev.diffopt.close_file = 0; /* * If we're not going to stdout, then we definitely don't * want color, since we are going to the commit message * file (and even the "auto" setting won't work, since it * will have checked isatty on stdout). But we then do want * to insert the scissor line here to reliably remove the * diff before committing. */ if (s->fp != stdout) { rev.diffopt.use_color = 0; wt_status_add_cut_line(s->fp); } if (s->verbose > 1 && s->commitable) { /* print_updated() printed a header, so do we */ if (s->fp != stdout) wt_status_print_trailer(s); status_printf_ln(s, c, _("Changes to be committed:")); rev.diffopt.a_prefix = "c/"; rev.diffopt.b_prefix = "i/"; } /* else use prefix as per user config */ run_diff_index(&rev, 1); if (s->verbose > 1 && wt_status_check_worktree_changes(s, &dirty_submodules)) { status_printf_ln(s, c, "--------------------------------------------------"); status_printf_ln(s, c, _("Changes not staged for commit:")); setup_work_tree(); rev.diffopt.a_prefix = "i/"; rev.diffopt.b_prefix = "w/"; run_diff_files(&rev, 0); } }
static int edit_patch(int argc, const char **argv, const char *prefix) { char *file = git_pathdup("ADD_EDIT.patch"); const char *apply_argv[] = { "apply", "--recount", "--cached", NULL, NULL }; struct child_process child = CHILD_PROCESS_INIT; struct rev_info rev; int out; struct stat st; apply_argv[3] = file; git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ if (read_cache() < 0) die(_("Could not read the index")); repo_init_revisions(the_repository, &rev, prefix); rev.diffopt.context = 7; argc = setup_revisions(argc, argv, &rev, NULL); rev.diffopt.output_format = DIFF_FORMAT_PATCH; rev.diffopt.use_color = 0; rev.diffopt.flags.ignore_dirty_submodules = 1; out = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0666); if (out < 0) die(_("Could not open '%s' for writing."), file); rev.diffopt.file = xfdopen(out, "w"); rev.diffopt.close_file = 1; if (run_diff_files(&rev, 0)) die(_("Could not write patch")); if (launch_editor(file, NULL, NULL)) die(_("editing patch failed")); if (stat(file, &st)) die_errno(_("Could not stat '%s'"), file); if (!st.st_size) die(_("Empty patch. Aborted.")); child.git_cmd = 1; child.argv = apply_argv; if (run_command(&child)) die(_("Could not apply '%s'"), file); unlink(file); free(file); return 0; }
static int edit_patch(int argc, const char **argv, const char *prefix) { char *file = git_pathdup("ADD_EDIT.patch"); const char *apply_argv[] = { "apply", "--recount", "--cached", NULL, NULL }; struct child_process child; struct rev_info rev; int out; struct stat st; apply_argv[3] = file; git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ if (read_cache() < 0) die(_("Could not read the index")); init_revisions(&rev, prefix); rev.diffopt.context = 7; argc = setup_revisions(argc, argv, &rev, NULL); rev.diffopt.output_format = DIFF_FORMAT_PATCH; rev.diffopt.use_color = 0; DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES); out = open(file, O_CREAT | O_WRONLY, 0666); if (out < 0) die(_("Could not open '%s' for writing."), file); rev.diffopt.file = xfdopen(out, "w"); rev.diffopt.close_file = 1; if (run_diff_files(&rev, 0)) die(_("Could not write patch")); launch_editor(file, NULL, NULL); if (stat(file, &st)) die_errno(_("Could not stat '%s'"), file); if (!st.st_size) die(_("Empty patch. Aborted.")); memset(&child, 0, sizeof(child)); child.git_cmd = 1; child.argv = apply_argv; if (run_command(&child)) die(_("Could not apply '%s'"), file); unlink(file); free(file); return 0; }
int add_files_to_cache(const char *prefix, const char **pathspec, int flags) { struct update_callback_data data; struct rev_info rev; init_revisions(&rev, prefix); setup_revisions(0, NULL, &rev, NULL); rev.prune_data = pathspec; rev.diffopt.output_format = DIFF_FORMAT_CALLBACK; rev.diffopt.format_callback = update_callback; data.flags = flags; data.add_errors = 0; rev.diffopt.format_callback_data = &data; run_diff_files(&rev, DIFF_RACY_IS_MODIFIED); return !!data.add_errors; }
static void update_files_in_cache(const char *prefix, const struct pathspec *pathspec, struct update_callback_data *data) { struct rev_info rev; init_revisions(&rev, prefix); setup_revisions(0, NULL, &rev, NULL); if (pathspec) copy_pathspec(&rev.prune_data, pathspec); rev.diffopt.output_format = DIFF_FORMAT_CALLBACK; rev.diffopt.format_callback = update_callback; rev.diffopt.format_callback_data = data; rev.max_count = 0; /* do not compare unmerged paths with stage #2 */ run_diff_files(&rev, DIFF_RACY_IS_MODIFIED); }
static void wt_status_collect_changes_worktree(struct wt_status *s) { struct rev_info rev; init_revisions(&rev, NULL); setup_revisions(0, NULL, &rev, NULL); rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK; DIFF_OPT_SET(&rev.diffopt, DIRTY_SUBMODULES); if (!s->show_untracked_files) DIFF_OPT_SET(&rev.diffopt, IGNORE_UNTRACKED_IN_SUBMODULES); if (s->ignore_submodule_arg) handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg); rev.diffopt.format_callback = wt_status_collect_changed_cb; rev.diffopt.format_callback_data = s; rev.prune_data = s->pathspec; run_diff_files(&rev, 0); }
int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags) { struct update_callback_data data; struct rev_info rev; memset(&data, 0, sizeof(data)); data.flags = flags; init_revisions(&rev, prefix); setup_revisions(0, NULL, &rev, NULL); if (pathspec) copy_pathspec(&rev.prune_data, pathspec); rev.diffopt.output_format = DIFF_FORMAT_CALLBACK; rev.diffopt.format_callback = update_callback; rev.diffopt.format_callback_data = &data; rev.max_count = 0; /* do not compare unmerged paths with stage #2 */ run_diff_files(&rev, DIFF_RACY_IS_MODIFIED); return !!data.add_errors; }
static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv) { int result; unsigned int options = 0; while (1 < argc && argv[1][0] == '-') { if (!strcmp(argv[1], "--base")) revs->max_count = 1; else if (!strcmp(argv[1], "--ours")) revs->max_count = 2; else if (!strcmp(argv[1], "--theirs")) revs->max_count = 3; else if (!strcmp(argv[1], "-q")) options |= DIFF_SILENT_ON_REMOVED; else if (!strcmp(argv[1], "-h")) usage(builtin_diff_usage); else return error("invalid option: %s", argv[1]); argv++; argc--; } /* * "diff --base" should not combine merges because it was not * asked to. "diff -c" should not densify (if the user wants * dense one, --cc can be explicitly asked for, or just rely * on the default). */ if (revs->max_count == -1 && !revs->combine_merges && (revs->diffopt.output_format & DIFF_FORMAT_PATCH)) revs->combine_merges = revs->dense_combined_merges = 1; setup_work_tree(); if (read_cache_preload(revs->diffopt.paths) < 0) { perror("read_cache_preload"); return -1; } result = run_diff_files(revs, options); return diff_result_code(&revs->diffopt, result); }