diff options
Diffstat (limited to 'third_party/git/combine-diff.c')
-rw-r--r-- | third_party/git/combine-diff.c | 68 |
1 files changed, 52 insertions, 16 deletions
diff --git a/third_party/git/combine-diff.c b/third_party/git/combine-diff.c index 3e49f3bda84b..9228aebc16b6 100644 --- a/third_party/git/combine-diff.c +++ b/third_party/git/combine-diff.c @@ -10,7 +10,7 @@ #include "log-tree.h" #include "refs.h" #include "userdiff.h" -#include "sha1-array.h" +#include "oid-array.h" #include "revision.h" static int compare_paths(const struct combine_diff_path *one, @@ -923,14 +923,13 @@ static void dump_quoted_path(const char *head, static void show_combined_header(struct combine_diff_path *elem, int num_parent, - int dense, struct rev_info *rev, const char *line_prefix, int mode_differs, int show_file_header) { struct diff_options *opt = &rev->diffopt; - int abbrev = opt->flags.full_index ? GIT_SHA1_HEXSZ : DEFAULT_ABBREV; + int abbrev = opt->flags.full_index ? the_hash_algo->hexsz : DEFAULT_ABBREV; const char *a_prefix = opt->a_prefix ? opt->a_prefix : "a/"; const char *b_prefix = opt->b_prefix ? opt->b_prefix : "b/"; const char *c_meta = diff_get_color_opt(opt, DIFF_METAINFO); @@ -939,6 +938,7 @@ static void show_combined_header(struct combine_diff_path *elem, int added = 0; int deleted = 0; int i; + int dense = rev->dense_combined_merges; if (rev->loginfo && !rev->no_commit_id) show_log(rev); @@ -1012,7 +1012,7 @@ static void show_combined_header(struct combine_diff_path *elem, } static void show_patch_diff(struct combine_diff_path *elem, int num_parent, - int dense, int working_tree_file, + int working_tree_file, struct rev_info *rev) { struct diff_options *opt = &rev->diffopt; @@ -1145,7 +1145,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, } } if (is_binary) { - show_combined_header(elem, num_parent, dense, rev, + show_combined_header(elem, num_parent, rev, line_prefix, mode_differs, 0); printf("Binary files differ\n"); free(result); @@ -1200,10 +1200,10 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, textconv, elem->path, opt->xdl_opts); } - show_hunks = make_hunks(sline, cnt, num_parent, dense); + show_hunks = make_hunks(sline, cnt, num_parent, rev->dense_combined_merges); if (show_hunks || mode_differs || working_tree_file) { - show_combined_header(elem, num_parent, dense, rev, + show_combined_header(elem, num_parent, rev, line_prefix, mode_differs, 1); dump_sline(sline, line_prefix, cnt, num_parent, opt->use_color, result_deleted); @@ -1284,7 +1284,6 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct re */ void show_combined_diff(struct combine_diff_path *p, int num_parent, - int dense, struct rev_info *rev) { struct diff_options *opt = &rev->diffopt; @@ -1294,7 +1293,7 @@ void show_combined_diff(struct combine_diff_path *p, DIFF_FORMAT_NAME_STATUS)) show_raw_diff(p, num_parent, rev); else if (opt->output_format & DIFF_FORMAT_PATCH) - show_patch_diff(p, num_parent, dense, 1, rev); + show_patch_diff(p, num_parent, 1, rev); } static void free_combined_pair(struct diff_filepair *pair) @@ -1451,10 +1450,45 @@ static struct combine_diff_path *find_paths_multitree( return paths_head.next; } +static int match_objfind(struct combine_diff_path *path, + int num_parent, + const struct oidset *set) +{ + int i; + if (oidset_contains(set, &path->oid)) + return 1; + for (i = 0; i < num_parent; i++) { + if (oidset_contains(set, &path->parent[i].oid)) + return 1; + } + return 0; +} + +static struct combine_diff_path *combined_objfind(struct diff_options *opt, + struct combine_diff_path *paths, + int num_parent) +{ + struct combine_diff_path *ret = NULL, **tail = &ret; + struct combine_diff_path *p = paths; + + while (p) { + struct combine_diff_path *next = p->next; + + if (match_objfind(p, num_parent, opt->objfind)) { + p->next = NULL; + *tail = p; + tail = &p->next; + } else { + free(p); + } + p = next; + } + + return ret; +} void diff_tree_combined(const struct object_id *oid, const struct oid_array *parents, - int dense, struct rev_info *rev) { struct diff_options *opt = &rev->diffopt; @@ -1506,10 +1540,10 @@ void diff_tree_combined(const struct object_id *oid, opt->flags.follow_renames || opt->break_opt != -1 || opt->detect_rename || - (opt->pickaxe_opts & DIFF_PICKAXE_KINDS_MASK) || + (opt->pickaxe_opts & + (DIFF_PICKAXE_KINDS_MASK & ~DIFF_PICKAXE_KIND_OBJFIND)) || opt->filter; - if (need_generic_pathscan) { /* * NOTE generic case also handles --stat, as it computes @@ -1523,6 +1557,9 @@ void diff_tree_combined(const struct object_id *oid, int stat_opt; paths = find_paths_multitree(oid, parents, &diffopts); + if (opt->pickaxe_opts & DIFF_PICKAXE_KIND_OBJFIND) + paths = combined_objfind(opt, paths, num_parent); + /* * show stat against the first parent even * when doing combined diff. @@ -1581,8 +1618,7 @@ void diff_tree_combined(const struct object_id *oid, printf("%s%c", diff_line_prefix(opt), opt->line_termination); for (p = paths; p; p = p->next) - show_patch_diff(p, num_parent, dense, - 0, rev); + show_patch_diff(p, num_parent, 0, rev); } } @@ -1600,7 +1636,7 @@ void diff_tree_combined(const struct object_id *oid, clear_pathspec(&diffopts.pathspec); } -void diff_tree_combined_merge(const struct commit *commit, int dense, +void diff_tree_combined_merge(const struct commit *commit, struct rev_info *rev) { struct commit_list *parent = get_saved_parents(rev, commit); @@ -1610,6 +1646,6 @@ void diff_tree_combined_merge(const struct commit *commit, int dense, oid_array_append(&parents, &parent->item->object.oid); parent = parent->next; } - diff_tree_combined(&commit->object.oid, &parents, dense, rev); + diff_tree_combined(&commit->object.oid, &parents, rev); oid_array_clear(&parents); } |