From 891e417cbc70495efca4f1333a8bb3c587fb69cb Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:29 +0300 Subject: [PATCH 01/32] revision: factor out parsing of diff-merge related options Move all the parsing code related to diffing merges into new parse_diff_merge_opts() function. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- revision.c | 67 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/revision.c b/revision.c index aa62212040..8b17cfd754 100644 --- a/revision.c +++ b/revision.c @@ -2153,6 +2153,45 @@ static void add_message_grep(struct rev_info *revs, const char *pattern) add_grep(revs, pattern, GREP_PATTERN_BODY); } +static int parse_diff_merge_opts(struct rev_info *revs, const char **argv) +{ + int argcount = 1; + const char *optarg; + const char *arg = argv[0]; + + if (!strcmp(arg, "-m")) { + /* + * To "diff-index", "-m" means "match missing", and to the "log" + * family of commands, it means "show full diff for merges". Set + * both fields appropriately. + */ + revs->ignore_merges = 0; + revs->match_missing = 1; + } else if (!strcmp(arg, "-c")) { + revs->diff = 1; + revs->dense_combined_merges = 0; + revs->combine_merges = 1; + } else if (!strcmp(arg, "--cc")) { + revs->diff = 1; + revs->dense_combined_merges = 1; + revs->combine_merges = 1; + } else if (!strcmp(arg, "--no-diff-merges")) { + revs->ignore_merges = 1; + } else if (!strcmp(arg, "--combined-all-paths")) { + revs->diff = 1; + revs->combined_all_paths = 1; + } else if ((argcount = parse_long_opt("diff-merges", argv, &optarg))) { + if (!strcmp(optarg, "off")) { + revs->ignore_merges = 1; + } else { + die(_("unknown value for --diff-merges: %s"), optarg); + } + } else + argcount = 0; + + return argcount; +} + static int handle_revision_opt(struct rev_info *revs, int argc, const char **argv, int *unkc, const char **unkv, const struct setup_revision_opt* opt) @@ -2349,34 +2388,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->diff = 1; revs->diffopt.flags.recursive = 1; revs->diffopt.flags.tree_in_recursive = 1; - } else if (!strcmp(arg, "-m")) { - /* - * To "diff-index", "-m" means "match missing", and to the "log" - * family of commands, it means "show full diff for merges". Set - * both fields appropriately. - */ - revs->ignore_merges = 0; - revs->match_missing = 1; - } else if ((argcount = parse_long_opt("diff-merges", argv, &optarg))) { - if (!strcmp(optarg, "off")) { - revs->ignore_merges = 1; - } else { - die(_("unknown value for --diff-merges: %s"), optarg); - } + } else if ((argcount = parse_diff_merge_opts(revs, argv))) { return argcount; - } else if (!strcmp(arg, "--no-diff-merges")) { - revs->ignore_merges = 1; - } else if (!strcmp(arg, "-c")) { - revs->diff = 1; - revs->dense_combined_merges = 0; - revs->combine_merges = 1; - } else if (!strcmp(arg, "--combined-all-paths")) { - revs->diff = 1; - revs->combined_all_paths = 1; - } else if (!strcmp(arg, "--cc")) { - revs->diff = 1; - revs->dense_combined_merges = 1; - revs->combine_merges = 1; } else if (!strcmp(arg, "-v")) { revs->verbose_header = 1; } else if (!strcmp(arg, "--pretty")) { From 299a66344065583162518cd8b65e2b91132eb1ac Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:30 +0300 Subject: [PATCH 02/32] revision: factor out setup of diff-merge related settings Move all the setting code related to diffing merges into new setup_diff_merge_revs() function. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- revision.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/revision.c b/revision.c index 8b17cfd754..d818e0b18b 100644 --- a/revision.c +++ b/revision.c @@ -2192,6 +2192,16 @@ static int parse_diff_merge_opts(struct rev_info *revs, const char **argv) return argcount; } +static void setup_diff_merges_revs(struct rev_info *revs) +{ + if (revs->combine_merges && revs->ignore_merges < 0) + revs->ignore_merges = 0; + if (revs->ignore_merges < 0) + revs->ignore_merges = 1; + if (revs->combined_all_paths && !revs->combine_merges) + die("--combined-all-paths makes no sense without -c or --cc"); +} + static int handle_revision_opt(struct rev_info *revs, int argc, const char **argv, int *unkc, const char **unkv, const struct setup_revision_opt* opt) @@ -2886,12 +2896,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s copy_pathspec(&revs->diffopt.pathspec, &revs->prune_data); } - if (revs->combine_merges && revs->ignore_merges < 0) - revs->ignore_merges = 0; - if (revs->ignore_merges < 0) - revs->ignore_merges = 1; - if (revs->combined_all_paths && !revs->combine_merges) - die("--combined-all-paths makes no sense without -c or --cc"); + + setup_diff_merges_revs(revs); revs->diffopt.abbrev = revs->abbrev; From 027c4783d73bbaff0a3c494b886cd8fa20ba8372 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:31 +0300 Subject: [PATCH 03/32] revision: factor out initialization of diff-merge related settings Move initialization code related to diffing merges into new init_diff_merge_revs() function. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- revision.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/revision.c b/revision.c index d818e0b18b..3250b2d7e1 100644 --- a/revision.c +++ b/revision.c @@ -1805,6 +1805,8 @@ static int add_parents_only(struct rev_info *revs, const char *arg_, int flags, return 1; } +static void init_diff_merge_revs(struct rev_info *revs); + void repo_init_revisions(struct repository *r, struct rev_info *revs, const char *prefix) @@ -1813,7 +1815,7 @@ void repo_init_revisions(struct repository *r, revs->repo = r; revs->abbrev = DEFAULT_ABBREV; - revs->ignore_merges = -1; + init_diff_merge_revs(revs); revs->simplify_history = 1; revs->pruning.repo = r; revs->pruning.flags.recursive = 1; @@ -2153,6 +2155,11 @@ static void add_message_grep(struct rev_info *revs, const char *pattern) add_grep(revs, pattern, GREP_PATTERN_BODY); } +static void init_diff_merge_revs(struct rev_info *revs) +{ + revs->ignore_merges = -1; +} + static int parse_diff_merge_opts(struct rev_info *revs, const char **argv) { int argcount = 1; From 3d4fd9436337d1688e7e2c2b2da4f7b7e3e8591e Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:32 +0300 Subject: [PATCH 04/32] revision: provide implementation for diff merges tweaks Use these implementations from show_setup_revisions_tweak() and log_setup_revisions_tweak() in builtin/log.c. This completes moving of management of diff merges parameters to a single place, where we can finally observe them simultaneously. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- builtin/log.c | 13 ++----------- revision.c | 19 +++++++++++++++++++ revision.h | 3 +++ 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/builtin/log.c b/builtin/log.c index 0a7ed4bef9..717855a49e 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -598,15 +598,7 @@ static int show_tree_object(const struct object_id *oid, static void show_setup_revisions_tweak(struct rev_info *rev, struct setup_revision_opt *opt) { - if (rev->ignore_merges < 0) { - /* There was no "-m" variant on the command line */ - rev->ignore_merges = 0; - if (!rev->first_parent_only && !rev->combine_merges) { - /* No "--first-parent", "-c", or "--cc" */ - rev->combine_merges = 1; - rev->dense_combined_merges = 1; - } - } + rev_diff_merges_default_to_dense_combined(rev); if (!rev->diffopt.output_format) rev->diffopt.output_format = DIFF_FORMAT_PATCH; } @@ -731,8 +723,7 @@ static void log_setup_revisions_tweak(struct rev_info *rev, if (!rev->diffopt.output_format && rev->combine_merges) rev->diffopt.output_format = DIFF_FORMAT_PATCH; - if (rev->first_parent_only && rev->ignore_merges < 0) - rev->ignore_merges = 0; + rev_diff_merges_first_parent_defaults_to_enable(rev); } int cmd_log(int argc, const char **argv, const char *prefix) diff --git a/revision.c b/revision.c index 3250b2d7e1..1c224d2764 100644 --- a/revision.c +++ b/revision.c @@ -2209,6 +2209,25 @@ static void setup_diff_merges_revs(struct rev_info *revs) die("--combined-all-paths makes no sense without -c or --cc"); } +void rev_diff_merges_first_parent_defaults_to_enable(struct rev_info *revs) +{ + if (revs->first_parent_only && revs->ignore_merges < 0) + revs->ignore_merges = 0; +} + +void rev_diff_merges_default_to_dense_combined(struct rev_info *revs) +{ + if (revs->ignore_merges < 0) { + /* There was no "-m" variant on the command line */ + revs->ignore_merges = 0; + if (!revs->first_parent_only && !revs->combine_merges) { + /* No "--first-parent", "-c", or "--cc" */ + revs->combine_merges = 1; + revs->dense_combined_merges = 1; + } + } +} + static int handle_revision_opt(struct rev_info *revs, int argc, const char **argv, int *unkc, const char **unkv, const struct setup_revision_opt* opt) diff --git a/revision.h b/revision.h index f6bf860d19..3dd0229f4e 100644 --- a/revision.h +++ b/revision.h @@ -456,4 +456,7 @@ int rewrite_parents(struct rev_info *revs, */ struct commit_list *get_saved_parents(struct rev_info *revs, const struct commit *commit); +void rev_diff_merges_default_to_dense_combined(struct rev_info *revs); +void rev_diff_merges_first_parent_defaults_to_enable(struct rev_info *revs); + #endif From a37eec6333db6f38edd21e74812d6c5f215b6e6c Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:33 +0300 Subject: [PATCH 05/32] revision: move diff merges functions to its own diff-merges.c Create separate diff-merges.c and diff-merges.h files, and move all the code related to handling of diff merges there. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- Makefile | 1 + builtin/log.c | 1 + diff-merges.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ diff-merges.h | 18 ++++++++++++ revision.c | 76 +-------------------------------------------------- revision.h | 3 -- 6 files changed, 97 insertions(+), 78 deletions(-) create mode 100644 diff-merges.c create mode 100644 diff-merges.h diff --git a/Makefile b/Makefile index b84e182688..efcd63fe6e 100644 --- a/Makefile +++ b/Makefile @@ -872,6 +872,7 @@ LIB_OBJS += date.o LIB_OBJS += decorate.o LIB_OBJS += delta-islands.o LIB_OBJS += diff-delta.o +LIB_OBJS += diff-merges.o LIB_OBJS += diff-lib.o LIB_OBJS += diff-no-index.o LIB_OBJS += diff.o diff --git a/builtin/log.c b/builtin/log.c index 717855a49e..ad3092fdd8 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -12,6 +12,7 @@ #include "color.h" #include "commit.h" #include "diff.h" +#include "diff-merges.h" #include "revision.h" #include "log-tree.h" #include "builtin.h" diff --git a/diff-merges.c b/diff-merges.c new file mode 100644 index 0000000000..0204292aa9 --- /dev/null +++ b/diff-merges.c @@ -0,0 +1,76 @@ +#include "diff-merges.h" + +#include "revision.h" + +void init_diff_merge_revs(struct rev_info *revs) +{ + revs->ignore_merges = -1; +} + +int parse_diff_merge_opts(struct rev_info *revs, const char **argv) +{ + int argcount = 1; + const char *optarg; + const char *arg = argv[0]; + + if (!strcmp(arg, "-m")) { + /* + * To "diff-index", "-m" means "match missing", and to the "log" + * family of commands, it means "show full diff for merges". Set + * both fields appropriately. + */ + revs->ignore_merges = 0; + revs->match_missing = 1; + } else if (!strcmp(arg, "-c")) { + revs->diff = 1; + revs->dense_combined_merges = 0; + revs->combine_merges = 1; + } else if (!strcmp(arg, "--cc")) { + revs->diff = 1; + revs->dense_combined_merges = 1; + revs->combine_merges = 1; + } else if (!strcmp(arg, "--no-diff-merges")) { + revs->ignore_merges = 1; + } else if (!strcmp(arg, "--combined-all-paths")) { + revs->diff = 1; + revs->combined_all_paths = 1; + } else if ((argcount = parse_long_opt("diff-merges", argv, &optarg))) { + if (!strcmp(optarg, "off")) { + revs->ignore_merges = 1; + } else { + die(_("unknown value for --diff-merges: %s"), optarg); + } + } else + argcount = 0; + + return argcount; +} + +void setup_diff_merges_revs(struct rev_info *revs) +{ + if (revs->combine_merges && revs->ignore_merges < 0) + revs->ignore_merges = 0; + if (revs->ignore_merges < 0) + revs->ignore_merges = 1; + if (revs->combined_all_paths && !revs->combine_merges) + die("--combined-all-paths makes no sense without -c or --cc"); +} + +void rev_diff_merges_first_parent_defaults_to_enable(struct rev_info *revs) +{ + if (revs->first_parent_only && revs->ignore_merges < 0) + revs->ignore_merges = 0; +} + +void rev_diff_merges_default_to_dense_combined(struct rev_info *revs) +{ + if (revs->ignore_merges < 0) { + /* There was no "-m" variant on the command line */ + revs->ignore_merges = 0; + if (!revs->first_parent_only && !revs->combine_merges) { + /* No "--first-parent", "-c", or "--cc" */ + revs->combine_merges = 1; + revs->dense_combined_merges = 1; + } + } +} diff --git a/diff-merges.h b/diff-merges.h new file mode 100644 index 0000000000..7e970b266c --- /dev/null +++ b/diff-merges.h @@ -0,0 +1,18 @@ +#ifndef DIFF_MERGES_H +#define DIFF_MERGES_H + +/* + * diff-merges - utility module to handle command-line options for + * selection of particular diff format of merge commits + * representation. + */ + +struct rev_info; + +void init_diff_merge_revs(struct rev_info *revs); +int parse_diff_merge_opts(struct rev_info *revs, const char **argv); +void setup_diff_merges_revs(struct rev_info *revs); +void rev_diff_merges_default_to_dense_combined(struct rev_info *revs); +void rev_diff_merges_first_parent_defaults_to_enable(struct rev_info *revs); + +#endif diff --git a/revision.c b/revision.c index 1c224d2764..4bc14a08a6 100644 --- a/revision.c +++ b/revision.c @@ -5,6 +5,7 @@ #include "tree.h" #include "commit.h" #include "diff.h" +#include "diff-merges.h" #include "refs.h" #include "revision.h" #include "repository.h" @@ -1805,8 +1806,6 @@ static int add_parents_only(struct rev_info *revs, const char *arg_, int flags, return 1; } -static void init_diff_merge_revs(struct rev_info *revs); - void repo_init_revisions(struct repository *r, struct rev_info *revs, const char *prefix) @@ -2155,79 +2154,6 @@ static void add_message_grep(struct rev_info *revs, const char *pattern) add_grep(revs, pattern, GREP_PATTERN_BODY); } -static void init_diff_merge_revs(struct rev_info *revs) -{ - revs->ignore_merges = -1; -} - -static int parse_diff_merge_opts(struct rev_info *revs, const char **argv) -{ - int argcount = 1; - const char *optarg; - const char *arg = argv[0]; - - if (!strcmp(arg, "-m")) { - /* - * To "diff-index", "-m" means "match missing", and to the "log" - * family of commands, it means "show full diff for merges". Set - * both fields appropriately. - */ - revs->ignore_merges = 0; - revs->match_missing = 1; - } else if (!strcmp(arg, "-c")) { - revs->diff = 1; - revs->dense_combined_merges = 0; - revs->combine_merges = 1; - } else if (!strcmp(arg, "--cc")) { - revs->diff = 1; - revs->dense_combined_merges = 1; - revs->combine_merges = 1; - } else if (!strcmp(arg, "--no-diff-merges")) { - revs->ignore_merges = 1; - } else if (!strcmp(arg, "--combined-all-paths")) { - revs->diff = 1; - revs->combined_all_paths = 1; - } else if ((argcount = parse_long_opt("diff-merges", argv, &optarg))) { - if (!strcmp(optarg, "off")) { - revs->ignore_merges = 1; - } else { - die(_("unknown value for --diff-merges: %s"), optarg); - } - } else - argcount = 0; - - return argcount; -} - -static void setup_diff_merges_revs(struct rev_info *revs) -{ - if (revs->combine_merges && revs->ignore_merges < 0) - revs->ignore_merges = 0; - if (revs->ignore_merges < 0) - revs->ignore_merges = 1; - if (revs->combined_all_paths && !revs->combine_merges) - die("--combined-all-paths makes no sense without -c or --cc"); -} - -void rev_diff_merges_first_parent_defaults_to_enable(struct rev_info *revs) -{ - if (revs->first_parent_only && revs->ignore_merges < 0) - revs->ignore_merges = 0; -} - -void rev_diff_merges_default_to_dense_combined(struct rev_info *revs) -{ - if (revs->ignore_merges < 0) { - /* There was no "-m" variant on the command line */ - revs->ignore_merges = 0; - if (!revs->first_parent_only && !revs->combine_merges) { - /* No "--first-parent", "-c", or "--cc" */ - revs->combine_merges = 1; - revs->dense_combined_merges = 1; - } - } -} - static int handle_revision_opt(struct rev_info *revs, int argc, const char **argv, int *unkc, const char **unkv, const struct setup_revision_opt* opt) diff --git a/revision.h b/revision.h index 3dd0229f4e..f6bf860d19 100644 --- a/revision.h +++ b/revision.h @@ -456,7 +456,4 @@ int rewrite_parents(struct rev_info *revs, */ struct commit_list *get_saved_parents(struct rev_info *revs, const struct commit *commit); -void rev_diff_merges_default_to_dense_combined(struct rev_info *revs); -void rev_diff_merges_first_parent_defaults_to_enable(struct rev_info *revs); - #endif From 18f09473bf8685a1f8db254cff915d4c31e86406 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:34 +0300 Subject: [PATCH 06/32] diff-merges: rename all functions to have common prefix Use the same "diff_merges" prefix for all the diff merges function names. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- builtin/log.c | 4 ++-- diff-merges.c | 10 +++++----- diff-merges.h | 15 ++++++++++----- revision.c | 6 +++--- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/builtin/log.c b/builtin/log.c index ad3092fdd8..77a7bba543 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -599,7 +599,7 @@ static int show_tree_object(const struct object_id *oid, static void show_setup_revisions_tweak(struct rev_info *rev, struct setup_revision_opt *opt) { - rev_diff_merges_default_to_dense_combined(rev); + diff_merges_default_to_dense_combined(rev); if (!rev->diffopt.output_format) rev->diffopt.output_format = DIFF_FORMAT_PATCH; } @@ -724,7 +724,7 @@ static void log_setup_revisions_tweak(struct rev_info *rev, if (!rev->diffopt.output_format && rev->combine_merges) rev->diffopt.output_format = DIFF_FORMAT_PATCH; - rev_diff_merges_first_parent_defaults_to_enable(rev); + diff_merges_first_parent_defaults_to_enable(rev); } int cmd_log(int argc, const char **argv, const char *prefix) diff --git a/diff-merges.c b/diff-merges.c index 0204292aa9..9286dbbd4d 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -2,12 +2,12 @@ #include "revision.h" -void init_diff_merge_revs(struct rev_info *revs) +void diff_merges_init_revs(struct rev_info *revs) { revs->ignore_merges = -1; } -int parse_diff_merge_opts(struct rev_info *revs, const char **argv) +int diff_merges_parse_opts(struct rev_info *revs, const char **argv) { int argcount = 1; const char *optarg; @@ -46,7 +46,7 @@ int parse_diff_merge_opts(struct rev_info *revs, const char **argv) return argcount; } -void setup_diff_merges_revs(struct rev_info *revs) +void diff_merges_setup_revs(struct rev_info *revs) { if (revs->combine_merges && revs->ignore_merges < 0) revs->ignore_merges = 0; @@ -56,13 +56,13 @@ void setup_diff_merges_revs(struct rev_info *revs) die("--combined-all-paths makes no sense without -c or --cc"); } -void rev_diff_merges_first_parent_defaults_to_enable(struct rev_info *revs) +void diff_merges_first_parent_defaults_to_enable(struct rev_info *revs) { if (revs->first_parent_only && revs->ignore_merges < 0) revs->ignore_merges = 0; } -void rev_diff_merges_default_to_dense_combined(struct rev_info *revs) +void diff_merges_default_to_dense_combined(struct rev_info *revs) { if (revs->ignore_merges < 0) { /* There was no "-m" variant on the command line */ diff --git a/diff-merges.h b/diff-merges.h index 7e970b266c..4ced909b79 100644 --- a/diff-merges.h +++ b/diff-merges.h @@ -9,10 +9,15 @@ struct rev_info; -void init_diff_merge_revs(struct rev_info *revs); -int parse_diff_merge_opts(struct rev_info *revs, const char **argv); -void setup_diff_merges_revs(struct rev_info *revs); -void rev_diff_merges_default_to_dense_combined(struct rev_info *revs); -void rev_diff_merges_first_parent_defaults_to_enable(struct rev_info *revs); +void diff_merges_init_revs(struct rev_info *revs); + +int diff_merges_parse_opts(struct rev_info *revs, const char **argv); + +void diff_merges_setup_revs(struct rev_info *revs); + +void diff_merges_default_to_dense_combined(struct rev_info *revs); + +void diff_merges_first_parent_defaults_to_enable(struct rev_info *revs); + #endif diff --git a/revision.c b/revision.c index 4bc14a08a6..5a0e3d6ad5 100644 --- a/revision.c +++ b/revision.c @@ -1814,7 +1814,7 @@ void repo_init_revisions(struct repository *r, revs->repo = r; revs->abbrev = DEFAULT_ABBREV; - init_diff_merge_revs(revs); + diff_merges_init_revs(revs); revs->simplify_history = 1; revs->pruning.repo = r; revs->pruning.flags.recursive = 1; @@ -2350,7 +2350,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->diff = 1; revs->diffopt.flags.recursive = 1; revs->diffopt.flags.tree_in_recursive = 1; - } else if ((argcount = parse_diff_merge_opts(revs, argv))) { + } else if ((argcount = diff_merges_parse_opts(revs, argv))) { return argcount; } else if (!strcmp(arg, "-v")) { revs->verbose_header = 1; @@ -2849,7 +2849,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s &revs->prune_data); } - setup_diff_merges_revs(revs); + diff_merges_setup_revs(revs); revs->diffopt.abbrev = revs->abbrev; From 7acf0d06f54043b3b79d5d388ed1c8fb66e2db5a Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:35 +0300 Subject: [PATCH 07/32] diff-merges: move checks for first_parent_only out of the module The checks for first_parent_only don't in fact belong to this module, as the primary purpose of this flag is history traversal limiting, so get it out of this module and rename the diff_merges_first_parent_defaults_to_enable() to diff_merges_default_to_enable() to match new semantics. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- builtin/log.c | 8 ++++++-- diff-merges.c | 10 ++++------ diff-merges.h | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/builtin/log.c b/builtin/log.c index 77a7bba543..a7791c003c 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -599,7 +599,10 @@ static int show_tree_object(const struct object_id *oid, static void show_setup_revisions_tweak(struct rev_info *rev, struct setup_revision_opt *opt) { - diff_merges_default_to_dense_combined(rev); + if (rev->first_parent_only) + diff_merges_default_to_enable(rev); + else + diff_merges_default_to_dense_combined(rev); if (!rev->diffopt.output_format) rev->diffopt.output_format = DIFF_FORMAT_PATCH; } @@ -724,7 +727,8 @@ static void log_setup_revisions_tweak(struct rev_info *rev, if (!rev->diffopt.output_format && rev->combine_merges) rev->diffopt.output_format = DIFF_FORMAT_PATCH; - diff_merges_first_parent_defaults_to_enable(rev); + if (rev->first_parent_only) + diff_merges_default_to_enable(rev); } int cmd_log(int argc, const char **argv, const char *prefix) diff --git a/diff-merges.c b/diff-merges.c index 9286dbbd4d..a3bafa92f3 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -56,19 +56,17 @@ void diff_merges_setup_revs(struct rev_info *revs) die("--combined-all-paths makes no sense without -c or --cc"); } -void diff_merges_first_parent_defaults_to_enable(struct rev_info *revs) +void diff_merges_default_to_enable(struct rev_info *revs) { - if (revs->first_parent_only && revs->ignore_merges < 0) + if (revs->ignore_merges < 0) /* No -m */ revs->ignore_merges = 0; } void diff_merges_default_to_dense_combined(struct rev_info *revs) { - if (revs->ignore_merges < 0) { - /* There was no "-m" variant on the command line */ + if (revs->ignore_merges < 0) { /* No -m */ revs->ignore_merges = 0; - if (!revs->first_parent_only && !revs->combine_merges) { - /* No "--first-parent", "-c", or "--cc" */ + if (!revs->combine_merges) { /* No -c/--cc" */ revs->combine_merges = 1; revs->dense_combined_merges = 1; } diff --git a/diff-merges.h b/diff-merges.h index 4ced909b79..6937d46219 100644 --- a/diff-merges.h +++ b/diff-merges.h @@ -17,7 +17,7 @@ void diff_merges_setup_revs(struct rev_info *revs); void diff_merges_default_to_dense_combined(struct rev_info *revs); -void diff_merges_first_parent_defaults_to_enable(struct rev_info *revs); +void diff_merges_default_to_enable(struct rev_info *revs); #endif From 4f54544d736e286538ebef0d3120c164f80f04c1 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:36 +0300 Subject: [PATCH 08/32] diff-merges: rename diff_merges_default_to_enable() to match semantics Rename diff_merges_default_to_enable() to diff_merges_default_to_first_parent() to match its semantics. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- builtin/log.c | 4 ++-- diff-merges.c | 2 +- diff-merges.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/builtin/log.c b/builtin/log.c index a7791c003c..63875c3aee 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -600,7 +600,7 @@ static void show_setup_revisions_tweak(struct rev_info *rev, struct setup_revision_opt *opt) { if (rev->first_parent_only) - diff_merges_default_to_enable(rev); + diff_merges_default_to_first_parent(rev); else diff_merges_default_to_dense_combined(rev); if (!rev->diffopt.output_format) @@ -728,7 +728,7 @@ static void log_setup_revisions_tweak(struct rev_info *rev, rev->diffopt.output_format = DIFF_FORMAT_PATCH; if (rev->first_parent_only) - diff_merges_default_to_enable(rev); + diff_merges_default_to_first_parent(rev); } int cmd_log(int argc, const char **argv, const char *prefix) diff --git a/diff-merges.c b/diff-merges.c index a3bafa92f3..76c8045797 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -56,7 +56,7 @@ void diff_merges_setup_revs(struct rev_info *revs) die("--combined-all-paths makes no sense without -c or --cc"); } -void diff_merges_default_to_enable(struct rev_info *revs) +void diff_merges_default_to_first_parent(struct rev_info *revs) { if (revs->ignore_merges < 0) /* No -m */ revs->ignore_merges = 0; diff --git a/diff-merges.h b/diff-merges.h index 6937d46219..18861dc548 100644 --- a/diff-merges.h +++ b/diff-merges.h @@ -17,7 +17,7 @@ void diff_merges_setup_revs(struct rev_info *revs); void diff_merges_default_to_dense_combined(struct rev_info *revs); -void diff_merges_default_to_enable(struct rev_info *revs); +void diff_merges_default_to_first_parent(struct rev_info *revs); #endif From 564a4fc8471b41fc05bda16e4bbb02a99b515cbf Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:37 +0300 Subject: [PATCH 09/32] diff-merges: re-arrange functions to match the order they are called in For clarity, define public functions in the order they are called, to make logic inter-dependencies easier to grok. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- diff-merges.c | 24 ++++++++++++++---------- diff-merges.h | 5 ++--- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/diff-merges.c b/diff-merges.c index 76c8045797..8325ab8801 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -2,6 +2,10 @@ #include "revision.h" +/* + * Public functions. They are in the order they are called. + */ + void diff_merges_init_revs(struct rev_info *revs) { revs->ignore_merges = -1; @@ -46,16 +50,6 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv) return argcount; } -void diff_merges_setup_revs(struct rev_info *revs) -{ - if (revs->combine_merges && revs->ignore_merges < 0) - revs->ignore_merges = 0; - if (revs->ignore_merges < 0) - revs->ignore_merges = 1; - if (revs->combined_all_paths && !revs->combine_merges) - die("--combined-all-paths makes no sense without -c or --cc"); -} - void diff_merges_default_to_first_parent(struct rev_info *revs) { if (revs->ignore_merges < 0) /* No -m */ @@ -72,3 +66,13 @@ void diff_merges_default_to_dense_combined(struct rev_info *revs) } } } + +void diff_merges_setup_revs(struct rev_info *revs) +{ + if (revs->combine_merges && revs->ignore_merges < 0) + revs->ignore_merges = 0; + if (revs->ignore_merges < 0) + revs->ignore_merges = 1; + if (revs->combined_all_paths && !revs->combine_merges) + die("--combined-all-paths makes no sense without -c or --cc"); +} diff --git a/diff-merges.h b/diff-merges.h index 18861dc548..243ef915c4 100644 --- a/diff-merges.h +++ b/diff-merges.h @@ -13,11 +13,10 @@ void diff_merges_init_revs(struct rev_info *revs); int diff_merges_parse_opts(struct rev_info *revs, const char **argv); -void diff_merges_setup_revs(struct rev_info *revs); +void diff_merges_default_to_first_parent(struct rev_info *revs); void diff_merges_default_to_dense_combined(struct rev_info *revs); -void diff_merges_default_to_first_parent(struct rev_info *revs); - +void diff_merges_setup_revs(struct rev_info *revs); #endif From 09322b1da92fd32204c8b4b07cf12decccfe47f3 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:38 +0300 Subject: [PATCH 10/32] diff-merges: new function diff_merges_suppress() This function sets all the relevant flags to disabled state, so that no code that checks only one of them get it wrong. Then we call this new function everywhere where diff merges output suppression is needed. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- builtin/merge.c | 3 ++- diff-merges.c | 17 +++++++++++++++-- diff-merges.h | 2 ++ fmt-merge-msg.c | 3 ++- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/builtin/merge.c b/builtin/merge.c index 9d5359edc2..1f7b69982b 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -14,6 +14,7 @@ #include "lockfile.h" #include "run-command.h" #include "diff.h" +#include "diff-merges.h" #include "refs.h" #include "refspec.h" #include "commit.h" @@ -400,7 +401,7 @@ static void squash_message(struct commit *commit, struct commit_list *remotehead printf(_("Squash commit -- not updating HEAD\n")); repo_init_revisions(the_repository, &rev, NULL); - rev.ignore_merges = 1; + diff_merges_suppress(&rev); rev.commit_format = CMIT_FMT_MEDIUM; commit->object.flags |= UNINTERESTING; diff --git a/diff-merges.c b/diff-merges.c index 8325ab8801..23e6cb11d1 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -2,6 +2,14 @@ #include "revision.h" +static void suppress(struct rev_info *revs) +{ + revs->ignore_merges = 1; + revs->first_parent_merges = 0; + revs->combine_merges = 0; + revs->dense_combined_merges = 0; +} + /* * Public functions. They are in the order they are called. */ @@ -34,13 +42,13 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv) revs->dense_combined_merges = 1; revs->combine_merges = 1; } else if (!strcmp(arg, "--no-diff-merges")) { - revs->ignore_merges = 1; + suppress(revs); } else if (!strcmp(arg, "--combined-all-paths")) { revs->diff = 1; revs->combined_all_paths = 1; } else if ((argcount = parse_long_opt("diff-merges", argv, &optarg))) { if (!strcmp(optarg, "off")) { - revs->ignore_merges = 1; + suppress(revs); } else { die(_("unknown value for --diff-merges: %s"), optarg); } @@ -50,6 +58,11 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv) return argcount; } +void diff_merges_suppress(struct rev_info *revs) +{ + suppress(revs); +} + void diff_merges_default_to_first_parent(struct rev_info *revs) { if (revs->ignore_merges < 0) /* No -m */ diff --git a/diff-merges.h b/diff-merges.h index 243ef915c4..a031240576 100644 --- a/diff-merges.h +++ b/diff-merges.h @@ -13,6 +13,8 @@ void diff_merges_init_revs(struct rev_info *revs); int diff_merges_parse_opts(struct rev_info *revs, const char **argv); +void diff_merges_suppress(struct rev_info *revs); + void diff_merges_default_to_first_parent(struct rev_info *revs); void diff_merges_default_to_dense_combined(struct rev_info *revs); diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c index bd22e1ea88..abc3403fb8 100644 --- a/fmt-merge-msg.c +++ b/fmt-merge-msg.c @@ -2,6 +2,7 @@ #include "refs.h" #include "object-store.h" #include "diff.h" +#include "diff-merges.h" #include "revision.h" #include "tag.h" #include "string-list.h" @@ -668,7 +669,7 @@ int fmt_merge_msg(struct strbuf *in, struct strbuf *out, head = lookup_commit_or_die(&head_oid, "HEAD"); repo_init_revisions(the_repository, &rev, NULL); rev.commit_format = CMIT_FMT_ONELINE; - rev.ignore_merges = 1; + diff_merges_suppress(&rev); rev.limited = 1; strbuf_complete_line(out); From 3b6c17b5c0bd126e3c712f5de909a033d99f1e3a Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:39 +0300 Subject: [PATCH 11/32] diff-merges: new function diff_merges_set_dense_combined_if_unset() Call it where given functionality is needed instead of direct checking/tweaking of diff merges related fields. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- builtin/diff-files.c | 5 +++-- builtin/diff.c | 9 +++++---- diff-merges.c | 16 ++++++++++++++-- diff-merges.h | 2 ++ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/builtin/diff-files.c b/builtin/diff-files.c index 1e352dd8f7..4742a4559b 100644 --- a/builtin/diff-files.c +++ b/builtin/diff-files.c @@ -7,6 +7,7 @@ #include "cache.h" #include "config.h" #include "diff.h" +#include "diff-merges.h" #include "commit.h" #include "revision.h" #include "builtin.h" @@ -69,9 +70,9 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix) * 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 && + if (rev.max_count == -1 && (rev.diffopt.output_format & DIFF_FORMAT_PATCH)) - rev.combine_merges = rev.dense_combined_merges = 1; + diff_merges_set_dense_combined_if_unset(&rev); if (read_cache_preload(&rev.diffopt.pathspec) < 0) { perror("read_cache_preload"); diff --git a/builtin/diff.c b/builtin/diff.c index cd4083fed9..2f570a3131 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -13,6 +13,7 @@ #include "blob.h" #include "tag.h" #include "diff.h" +#include "diff-merges.h" #include "diffcore.h" #include "revision.h" #include "log-tree.h" @@ -199,8 +200,8 @@ static int builtin_diff_combined(struct rev_info *revs, if (argc > 1) usage(builtin_diff_usage); - if (!revs->dense_combined_merges && !revs->combine_merges) - revs->dense_combined_merges = revs->combine_merges = 1; + diff_merges_set_dense_combined_if_unset(revs); + for (i = 1; i < ents; i++) oid_array_append(&parents, &ent[i].item->oid); diff_tree_combined(&ent[0].item->oid, &parents, revs); @@ -248,9 +249,9 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv * dense one, --cc can be explicitly asked for, or just rely * on the default). */ - if (revs->max_count == -1 && !revs->combine_merges && + if (revs->max_count == -1 && (revs->diffopt.output_format & DIFF_FORMAT_PATCH)) - revs->combine_merges = revs->dense_combined_merges = 1; + diff_merges_set_dense_combined_if_unset(revs); setup_work_tree(); if (read_cache_preload(&revs->diffopt.pathspec) < 0) { diff --git a/diff-merges.c b/diff-merges.c index 23e6cb11d1..24f922cf8a 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -10,6 +10,13 @@ static void suppress(struct rev_info *revs) revs->dense_combined_merges = 0; } +static void set_dense_combined(struct rev_info *revs) +{ + revs->combine_merges = 1; + revs->dense_combined_merges = 1; +} + + /* * Public functions. They are in the order they are called. */ @@ -39,8 +46,7 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv) revs->combine_merges = 1; } else if (!strcmp(arg, "--cc")) { revs->diff = 1; - revs->dense_combined_merges = 1; - revs->combine_merges = 1; + set_dense_combined(revs); } else if (!strcmp(arg, "--no-diff-merges")) { suppress(revs); } else if (!strcmp(arg, "--combined-all-paths")) { @@ -80,6 +86,12 @@ void diff_merges_default_to_dense_combined(struct rev_info *revs) } } +void diff_merges_set_dense_combined_if_unset(struct rev_info *revs) +{ + if (!revs->combine_merges) + set_dense_combined(revs); +} + void diff_merges_setup_revs(struct rev_info *revs) { if (revs->combine_merges && revs->ignore_merges < 0) diff --git a/diff-merges.h b/diff-merges.h index a031240576..f92de137d3 100644 --- a/diff-merges.h +++ b/diff-merges.h @@ -19,6 +19,8 @@ void diff_merges_default_to_first_parent(struct rev_info *revs); void diff_merges_default_to_dense_combined(struct rev_info *revs); +void diff_merges_set_dense_combined_if_unset(struct rev_info *revs); + void diff_merges_setup_revs(struct rev_info *revs); #endif From 3291eea3104e1a1aa64181671da3f9551ec3d59f Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:40 +0300 Subject: [PATCH 12/32] diff-merges: introduce revs->first_parent_merges flag This new field allows us to separate format of diff for merges from 'first_parent_only' flag which primary purpose is limiting history traversal. This change further localizes diff format selection logic into the diff-merges.c file. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- diff-merges.c | 2 ++ log-tree.c | 4 ++-- revision.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/diff-merges.c b/diff-merges.c index 24f922cf8a..fb591a9339 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -73,6 +73,8 @@ void diff_merges_default_to_first_parent(struct rev_info *revs) { if (revs->ignore_merges < 0) /* No -m */ revs->ignore_merges = 0; + if (!revs->combine_merges) /* No -c/--cc" */ + revs->first_parent_merges = 1; } void diff_merges_default_to_dense_combined(struct rev_info *revs) diff --git a/log-tree.c b/log-tree.c index 1927f917ce..3fdc0fc64b 100644 --- a/log-tree.c +++ b/log-tree.c @@ -922,7 +922,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log return 0; else if (opt->combine_merges) return do_diff_combined(opt, commit); - else if (!opt->first_parent_only) { + else if (!opt->first_parent_merges) { /* If we show multiple diffs, show the parent info */ log->parent = parents->item; } @@ -941,7 +941,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log /* Set up the log info for the next parent, if any.. */ parents = parents->next; - if (!parents || opt->first_parent_only) + if (!parents || opt->first_parent_merges) break; log->parent = parents->item; opt->loginfo = log; diff --git a/revision.h b/revision.h index f6bf860d19..ba2aef7921 100644 --- a/revision.h +++ b/revision.h @@ -194,6 +194,7 @@ struct rev_info { combine_merges:1, combined_all_paths:1, dense_combined_merges:1, + first_parent_merges:1, always_show_header:1; int ignore_merges:2; From 0c627f5d3cbcb7d85219d9a4cfc195f7d4230b3d Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:41 +0300 Subject: [PATCH 13/32] diff-merges: handle imply -p on -c/--cc logic for log.c Move logic that handles implying -p on -c/--cc from log_setup_revisions_tweak() to diff_merges_setup_revs(), where it belongs. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- builtin/log.c | 4 ---- diff-merges.c | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/builtin/log.c b/builtin/log.c index 63875c3aee..c3caf0955b 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -723,10 +723,6 @@ static void log_setup_revisions_tweak(struct rev_info *rev, rev->prune_data.nr == 1) rev->diffopt.flags.follow_renames = 1; - /* Turn --cc/-c into -p --cc/-c when -p was not given */ - if (!rev->diffopt.output_format && rev->combine_merges) - rev->diffopt.output_format = DIFF_FORMAT_PATCH; - if (rev->first_parent_only) diff_merges_default_to_first_parent(rev); } diff --git a/diff-merges.c b/diff-merges.c index fb591a9339..c48a65f8de 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -102,4 +102,9 @@ void diff_merges_setup_revs(struct rev_info *revs) revs->ignore_merges = 1; if (revs->combined_all_paths && !revs->combine_merges) die("--combined-all-paths makes no sense without -c or --cc"); + if (revs->combine_merges) { + /* Turn --cc/-c into -p --cc/-c when -p was not given */ + if (!revs->diffopt.output_format) + revs->diffopt.output_format = DIFF_FORMAT_PATCH; + } } From e121b4b822765336cd4710ec9f8aed77d25de3fe Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:42 +0300 Subject: [PATCH 14/32] diff-merges: revise revs->diff flag handling Do not set revs->diff when we encounter an option that needs it, as it'd be impossible to undo later. Besides, some other options than what we handle here set this flag as well, and we'd interfere with them trying to clear this flag later. Rather set revs->diff, if finally needed, in diff_merges_setup_revs(). As an additional bonus, this also makes our code shorter. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- diff-merges.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/diff-merges.c b/diff-merges.c index c48a65f8de..225edd293b 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -41,16 +41,13 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv) revs->ignore_merges = 0; revs->match_missing = 1; } else if (!strcmp(arg, "-c")) { - revs->diff = 1; revs->dense_combined_merges = 0; revs->combine_merges = 1; } else if (!strcmp(arg, "--cc")) { - revs->diff = 1; set_dense_combined(revs); } else if (!strcmp(arg, "--no-diff-merges")) { suppress(revs); } else if (!strcmp(arg, "--combined-all-paths")) { - revs->diff = 1; revs->combined_all_paths = 1; } else if ((argcount = parse_long_opt("diff-merges", argv, &optarg))) { if (!strcmp(optarg, "off")) { @@ -103,6 +100,7 @@ void diff_merges_setup_revs(struct rev_info *revs) if (revs->combined_all_paths && !revs->combine_merges) die("--combined-all-paths makes no sense without -c or --cc"); if (revs->combine_merges) { + revs->diff = 1; /* Turn --cc/-c into -p --cc/-c when -p was not given */ if (!revs->diffopt.output_format) revs->diffopt.output_format = DIFF_FORMAT_PATCH; From 14c14b44e47bc8c420e5161abc8fe283121f3e31 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:43 +0300 Subject: [PATCH 15/32] t4013: support test_expect_failure through ':failure' magic Add support to be able to specify expected failure, through :failure magic, like this: :failure cmd args Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- t/t4013-diff-various.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 5c7b0122b4..935d10ac05 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -174,6 +174,7 @@ process_diffs () { V=$(git version | sed -e 's/^git version //' -e 's/\./\\./g') while read magic cmd do + status=success case "$magic" in '' | '#'*) continue ;; @@ -182,6 +183,10 @@ do label="$magic-$cmd" case "$magic" in noellipses) ;; + failure) + status=failure + magic= + label="$cmd" ;; *) BUG "unknown magic $magic" ;; esac ;; @@ -194,7 +199,7 @@ do expect="$TEST_DIRECTORY/t4013/diff.$test" actual="$pfx-diff.$test" - test_expect_success "git $cmd # magic is ${magic:-(not used)}" ' + test_expect_$status "git $cmd # magic is ${magic:-(not used)}" ' { echo "$ git $cmd" case "$magic" in From ec315c66bb73e26542b7b3de8abaffa310c4380e Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:44 +0300 Subject: [PATCH 16/32] t4013: add tests for -m failing to override -c/--cc Logically, -m, -c, --cc specify 3 different formats for representing merge commits, yet -m doesn't in fact override -c or --cc, that makes no sense. Add 2 expected to fail tests that demonstrate the problem. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- t/t4013-diff-various.sh | 2 + t/t4013/diff.log_--cc_-m_-p_master | 200 +++++++++++++++++++++++++++++ t/t4013/diff.log_-c_-m_-p_master | 200 +++++++++++++++++++++++++++++ 3 files changed, 402 insertions(+) create mode 100644 t/t4013/diff.log_--cc_-m_-p_master create mode 100644 t/t4013/diff.log_-c_-m_-p_master diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 935d10ac05..64d9fce446 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -329,6 +329,8 @@ log --first-parent --diff-merges=off -p master log -p --first-parent master log -m -p --first-parent master log -m -p master +:failure log --cc -m -p master +:failure log -c -m -p master log -SF master log -S F master log -SF -p master diff --git a/t/t4013/diff.log_--cc_-m_-p_master b/t/t4013/diff.log_--cc_-m_-p_master new file mode 100644 index 0000000000..7c217cf348 --- /dev/null +++ b/t/t4013/diff.log_--cc_-m_-p_master @@ -0,0 +1,200 @@ +$ git log --cc -m -p master +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (from 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0) +Merge: 9a6d494 c7a2ab9 +Author: A U Thor +Date: Mon Jun 26 00:04:00 2006 +0000 + + Merge branch 'side' + +diff --git a/dir/sub b/dir/sub +index cead32e..992913c 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -4,3 +4,5 @@ C + D + E + F ++1 ++2 +diff --git a/file0 b/file0 +index b414108..10a8a9f 100644 +--- a/file0 ++++ b/file0 +@@ -4,3 +4,6 @@ + 4 + 5 + 6 ++A ++B ++C + +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (from c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a) +Merge: 9a6d494 c7a2ab9 +Author: A U Thor +Date: Mon Jun 26 00:04:00 2006 +0000 + + Merge branch 'side' + +diff --git a/dir/sub b/dir/sub +index 7289e35..992913c 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -1,4 +1,8 @@ + A + B ++C ++D ++E ++F + 1 + 2 +diff --git a/file0 b/file0 +index f4615da..10a8a9f 100644 +--- a/file0 ++++ b/file0 +@@ -1,6 +1,9 @@ + 1 + 2 + 3 ++4 ++5 ++6 + A + B + C +diff --git a/file1 b/file1 +new file mode 100644 +index 0000000..b1e6722 +--- /dev/null ++++ b/file1 +@@ -0,0 +1,3 @@ ++A ++B ++C +diff --git a/file2 b/file2 +deleted file mode 100644 +index 01e79c3..0000000 +--- a/file2 ++++ /dev/null +@@ -1,3 +0,0 @@ +-1 +-2 +-3 +diff --git a/file3 b/file3 +deleted file mode 100644 +index 7289e35..0000000 +--- a/file3 ++++ /dev/null +@@ -1,4 +0,0 @@ +-A +-B +-1 +-2 + +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side + +diff --git a/dir/sub b/dir/sub +index 35d242b..7289e35 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -1,2 +1,4 @@ + A + B ++1 ++2 +diff --git a/file0 b/file0 +index 01e79c3..f4615da 100644 +--- a/file0 ++++ b/file0 +@@ -1,3 +1,6 @@ + 1 + 2 + 3 ++A ++B ++C +diff --git a/file3 b/file3 +new file mode 100644 +index 0000000..7289e35 +--- /dev/null ++++ b/file3 +@@ -0,0 +1,4 @@ ++A ++B ++1 ++2 + +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third + +diff --git a/dir/sub b/dir/sub +index 8422d40..cead32e 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -2,3 +2,5 @@ A + B + C + D ++E ++F +diff --git a/file1 b/file1 +new file mode 100644 +index 0000000..b1e6722 +--- /dev/null ++++ b/file1 +@@ -0,0 +1,3 @@ ++A ++B ++C + +commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 +Author: A U Thor +Date: Mon Jun 26 00:01:00 2006 +0000 + + Second + + This is the second commit. + +diff --git a/dir/sub b/dir/sub +index 35d242b..8422d40 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -1,2 +1,4 @@ + A + B ++C ++D +diff --git a/file0 b/file0 +index 01e79c3..b414108 100644 +--- a/file0 ++++ b/file0 +@@ -1,3 +1,6 @@ + 1 + 2 + 3 ++4 ++5 ++6 +diff --git a/file2 b/file2 +deleted file mode 100644 +index 01e79c3..0000000 +--- a/file2 ++++ /dev/null +@@ -1,3 +0,0 @@ +-1 +-2 +-3 + +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial +$ diff --git a/t/t4013/diff.log_-c_-m_-p_master b/t/t4013/diff.log_-c_-m_-p_master new file mode 100644 index 0000000000..b660f3d5f2 --- /dev/null +++ b/t/t4013/diff.log_-c_-m_-p_master @@ -0,0 +1,200 @@ +$ git log -c -m -p master +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (from 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0) +Merge: 9a6d494 c7a2ab9 +Author: A U Thor +Date: Mon Jun 26 00:04:00 2006 +0000 + + Merge branch 'side' + +diff --git a/dir/sub b/dir/sub +index cead32e..992913c 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -4,3 +4,5 @@ C + D + E + F ++1 ++2 +diff --git a/file0 b/file0 +index b414108..10a8a9f 100644 +--- a/file0 ++++ b/file0 +@@ -4,3 +4,6 @@ + 4 + 5 + 6 ++A ++B ++C + +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (from c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a) +Merge: 9a6d494 c7a2ab9 +Author: A U Thor +Date: Mon Jun 26 00:04:00 2006 +0000 + + Merge branch 'side' + +diff --git a/dir/sub b/dir/sub +index 7289e35..992913c 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -1,4 +1,8 @@ + A + B ++C ++D ++E ++F + 1 + 2 +diff --git a/file0 b/file0 +index f4615da..10a8a9f 100644 +--- a/file0 ++++ b/file0 +@@ -1,6 +1,9 @@ + 1 + 2 + 3 ++4 ++5 ++6 + A + B + C +diff --git a/file1 b/file1 +new file mode 100644 +index 0000000..b1e6722 +--- /dev/null ++++ b/file1 +@@ -0,0 +1,3 @@ ++A ++B ++C +diff --git a/file2 b/file2 +deleted file mode 100644 +index 01e79c3..0000000 +--- a/file2 ++++ /dev/null +@@ -1,3 +0,0 @@ +-1 +-2 +-3 +diff --git a/file3 b/file3 +deleted file mode 100644 +index 7289e35..0000000 +--- a/file3 ++++ /dev/null +@@ -1,4 +0,0 @@ +-A +-B +-1 +-2 + +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side + +diff --git a/dir/sub b/dir/sub +index 35d242b..7289e35 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -1,2 +1,4 @@ + A + B ++1 ++2 +diff --git a/file0 b/file0 +index 01e79c3..f4615da 100644 +--- a/file0 ++++ b/file0 +@@ -1,3 +1,6 @@ + 1 + 2 + 3 ++A ++B ++C +diff --git a/file3 b/file3 +new file mode 100644 +index 0000000..7289e35 +--- /dev/null ++++ b/file3 +@@ -0,0 +1,4 @@ ++A ++B ++1 ++2 + +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third + +diff --git a/dir/sub b/dir/sub +index 8422d40..cead32e 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -2,3 +2,5 @@ A + B + C + D ++E ++F +diff --git a/file1 b/file1 +new file mode 100644 +index 0000000..b1e6722 +--- /dev/null ++++ b/file1 +@@ -0,0 +1,3 @@ ++A ++B ++C + +commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 +Author: A U Thor +Date: Mon Jun 26 00:01:00 2006 +0000 + + Second + + This is the second commit. + +diff --git a/dir/sub b/dir/sub +index 35d242b..8422d40 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -1,2 +1,4 @@ + A + B ++C ++D +diff --git a/file0 b/file0 +index 01e79c3..b414108 100644 +--- a/file0 ++++ b/file0 +@@ -1,3 +1,6 @@ + 1 + 2 + 3 ++4 ++5 ++6 +diff --git a/file2 b/file2 +deleted file mode 100644 +index 01e79c3..0000000 +--- a/file2 ++++ /dev/null +@@ -1,3 +0,0 @@ +-1 +-2 +-3 + +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial +$ From 6fc944d8956bf75bf2e52a871c02b71b4f9dfcba Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:45 +0300 Subject: [PATCH 17/32] diff-merges: fix -m to properly override -c/--cc Logically, -m, -c, --cc specify 3 different formats for representing merge commits, yet -m doesn't in fact override -c or --cc, that makes no sense. Fix -m to properly override -c/--cc, and change the tests accordingly. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- diff-merges.c | 1 + t/t4013-diff-various.sh | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/diff-merges.c b/diff-merges.c index 225edd293b..047bf81e67 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -33,6 +33,7 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv) const char *arg = argv[0]; if (!strcmp(arg, "-m")) { + suppress(revs); /* * To "diff-index", "-m" means "match missing", and to the "log" * family of commands, it means "show full diff for merges". Set diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 64d9fce446..8d8178a8a6 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -329,8 +329,8 @@ log --first-parent --diff-merges=off -p master log -p --first-parent master log -m -p --first-parent master log -m -p master -:failure log --cc -m -p master -:failure log -c -m -p master +log --cc -m -p master +log -c -m -p master log -SF master log -S F master log -SF -p master From 1a2c4d80501c50fbe96cc0be096273703a5c0d16 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:46 +0300 Subject: [PATCH 18/32] diff-merges: split 'ignore_merges' field 'ignore_merges' was 3-way field that served two distinct purposes that we now assign to 2 new independent flags: 'separate_merges', and 'explicit_diff_merges'. 'separate_merges' tells that we need to output diff format containing separate diff for every parent (as opposed to 'combine_merges'). 'explicit_diff_merges' tells that at least one of diff-merges options has been explicitly specified on the command line, so no defaults should apply. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- diff-merges.c | 31 +++++++++++++------------------ log-tree.c | 15 ++++++++------- revision.h | 3 ++- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/diff-merges.c b/diff-merges.c index 047bf81e67..eff54cca82 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -4,7 +4,7 @@ static void suppress(struct rev_info *revs) { - revs->ignore_merges = 1; + revs->separate_merges = 0; revs->first_parent_merges = 0; revs->combine_merges = 0; revs->dense_combined_merges = 0; @@ -23,7 +23,6 @@ static void set_dense_combined(struct rev_info *revs) void diff_merges_init_revs(struct rev_info *revs) { - revs->ignore_merges = -1; } int diff_merges_parse_opts(struct rev_info *revs, const char **argv) @@ -39,7 +38,7 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv) * family of commands, it means "show full diff for merges". Set * both fields appropriately. */ - revs->ignore_merges = 0; + revs->separate_merges = 1; revs->match_missing = 1; } else if (!strcmp(arg, "-c")) { revs->dense_combined_merges = 0; @@ -57,8 +56,9 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv) die(_("unknown value for --diff-merges: %s"), optarg); } } else - argcount = 0; + return 0; + revs->explicit_diff_merges = 1; return argcount; } @@ -69,21 +69,16 @@ void diff_merges_suppress(struct rev_info *revs) void diff_merges_default_to_first_parent(struct rev_info *revs) { - if (revs->ignore_merges < 0) /* No -m */ - revs->ignore_merges = 0; - if (!revs->combine_merges) /* No -c/--cc" */ + if (!revs->explicit_diff_merges) + revs->separate_merges = 1; + if (revs->separate_merges) revs->first_parent_merges = 1; } void diff_merges_default_to_dense_combined(struct rev_info *revs) { - if (revs->ignore_merges < 0) { /* No -m */ - revs->ignore_merges = 0; - if (!revs->combine_merges) { /* No -c/--cc" */ - revs->combine_merges = 1; - revs->dense_combined_merges = 1; - } - } + if (!revs->explicit_diff_merges) + set_dense_combined(revs); } void diff_merges_set_dense_combined_if_unset(struct rev_info *revs) @@ -94,10 +89,10 @@ void diff_merges_set_dense_combined_if_unset(struct rev_info *revs) void diff_merges_setup_revs(struct rev_info *revs) { - if (revs->combine_merges && revs->ignore_merges < 0) - revs->ignore_merges = 0; - if (revs->ignore_merges < 0) - revs->ignore_merges = 1; + if (revs->combine_merges == 0) + revs->dense_combined_merges = 0; + if (revs->separate_merges == 0) + revs->first_parent_merges = 0; if (revs->combined_all_paths && !revs->combine_merges) die("--combined-all-paths makes no sense without -c or --cc"); if (revs->combine_merges) { diff --git a/log-tree.c b/log-tree.c index 3fdc0fc64b..f9385b1dae 100644 --- a/log-tree.c +++ b/log-tree.c @@ -918,14 +918,15 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log /* More than one parent? */ if (parents->next) { - if (opt->ignore_merges) - return 0; - else if (opt->combine_merges) + if (opt->combine_merges) return do_diff_combined(opt, commit); - else if (!opt->first_parent_merges) { - /* If we show multiple diffs, show the parent info */ - log->parent = parents->item; - } + if (opt->separate_merges) { + if (!opt->first_parent_merges) { + /* Show parent info for multiple diffs */ + log->parent = parents->item; + } + } else + return 0; } showed_log = 0; diff --git a/revision.h b/revision.h index ba2aef7921..fcc532c873 100644 --- a/revision.h +++ b/revision.h @@ -191,12 +191,13 @@ struct rev_info { match_missing:1, no_commit_id:1, verbose_header:1, + explicit_diff_merges: 1, + separate_merges: 1, combine_merges:1, combined_all_paths:1, dense_combined_merges:1, first_parent_merges:1, always_show_header:1; - int ignore_merges:2; /* Format info */ int show_notes; From d9b1bc6d13f6581f1e91f21d20b50b7312c60e62 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:47 +0300 Subject: [PATCH 19/32] diff-merges: group diff-merge flags next to each other inside 'rev_info' The relevant flags were somewhat scattered over definition of 'struct rev_info'. Rearrange them to group them together. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- revision.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/revision.h b/revision.h index fcc532c873..dcfa14454a 100644 --- a/revision.h +++ b/revision.h @@ -191,13 +191,14 @@ struct rev_info { match_missing:1, no_commit_id:1, verbose_header:1, + always_show_header:1, + /* Diff-merge flags */ explicit_diff_merges: 1, separate_merges: 1, combine_merges:1, combined_all_paths:1, dense_combined_merges:1, - first_parent_merges:1, - always_show_header:1; + first_parent_merges:1; /* Format info */ int show_notes; From a6e66af923d54f44bc7d0a404109e900a6a1cb60 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:48 +0300 Subject: [PATCH 20/32] diff-merges: get rid of now empty diff_merges_init_revs() After getting rid of 'ignore_merges' field, the diff_merges_init_revs() function became empty. Get rid of it. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- diff-merges.c | 4 ---- diff-merges.h | 2 -- revision.c | 1 - 3 files changed, 7 deletions(-) diff --git a/diff-merges.c b/diff-merges.c index eff54cca82..34d7ed7c70 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -21,10 +21,6 @@ static void set_dense_combined(struct rev_info *revs) * Public functions. They are in the order they are called. */ -void diff_merges_init_revs(struct rev_info *revs) -{ -} - int diff_merges_parse_opts(struct rev_info *revs, const char **argv) { int argcount = 1; diff --git a/diff-merges.h b/diff-merges.h index f92de137d3..659467c99a 100644 --- a/diff-merges.h +++ b/diff-merges.h @@ -9,8 +9,6 @@ struct rev_info; -void diff_merges_init_revs(struct rev_info *revs); - int diff_merges_parse_opts(struct rev_info *revs, const char **argv); void diff_merges_suppress(struct rev_info *revs); diff --git a/revision.c b/revision.c index 5a0e3d6ad5..46645ca0b6 100644 --- a/revision.c +++ b/revision.c @@ -1814,7 +1814,6 @@ void repo_init_revisions(struct repository *r, revs->repo = r; revs->abbrev = DEFAULT_ABBREV; - diff_merges_init_revs(revs); revs->simplify_history = 1; revs->pruning.repo = r; revs->pruning.flags.recursive = 1; From 3d2b5f2f496b9868f982b614f9c2232efa7505df Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:49 +0300 Subject: [PATCH 21/32] diff-merges: refactor opt settings into separate functions To prepare introduction of new options some of which will be synonyms to existing options, let every option handling code just call corresponding function. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- diff-merges.c | 63 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/diff-merges.c b/diff-merges.c index 34d7ed7c70..b8fd92adcf 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -10,12 +10,43 @@ static void suppress(struct rev_info *revs) revs->dense_combined_merges = 0; } +static void set_separate(struct rev_info *revs) +{ + suppress(revs); + revs->separate_merges = 1; +} + +static void set_m(struct rev_info *revs) +{ + /* + * To "diff-index", "-m" means "match missing", and to the "log" + * family of commands, it means "show full diff for merges". Set + * both fields appropriately. + */ + set_separate(revs); + revs->match_missing = 1; +} + +static void set_combined(struct rev_info *revs) +{ + revs->combine_merges = 1; + revs->dense_combined_merges = 0; +} + static void set_dense_combined(struct rev_info *revs) { revs->combine_merges = 1; revs->dense_combined_merges = 1; } +static void set_diff_merges(struct rev_info *revs, const char *optarg) +{ + if (!strcmp(optarg, "off")) { + suppress(revs); + } else { + die(_("unknown value for --diff-merges: %s"), optarg); + } +} /* * Public functions. They are in the order they are called. @@ -27,31 +58,19 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv) const char *optarg; const char *arg = argv[0]; - if (!strcmp(arg, "-m")) { - suppress(revs); - /* - * To "diff-index", "-m" means "match missing", and to the "log" - * family of commands, it means "show full diff for merges". Set - * both fields appropriately. - */ - revs->separate_merges = 1; - revs->match_missing = 1; - } else if (!strcmp(arg, "-c")) { - revs->dense_combined_merges = 0; - revs->combine_merges = 1; - } else if (!strcmp(arg, "--cc")) { + if (!strcmp(arg, "-m")) + set_m(revs); + else if (!strcmp(arg, "-c")) + set_combined(revs); + else if (!strcmp(arg, "--cc")) set_dense_combined(revs); - } else if (!strcmp(arg, "--no-diff-merges")) { + else if (!strcmp(arg, "--no-diff-merges")) suppress(revs); - } else if (!strcmp(arg, "--combined-all-paths")) { + else if (!strcmp(arg, "--combined-all-paths")) revs->combined_all_paths = 1; - } else if ((argcount = parse_long_opt("diff-merges", argv, &optarg))) { - if (!strcmp(optarg, "off")) { - suppress(revs); - } else { - die(_("unknown value for --diff-merges: %s"), optarg); - } - } else + else if ((argcount = parse_long_opt("diff-merges", argv, &optarg))) + set_diff_merges(revs, optarg); + else return 0; revs->explicit_diff_merges = 1; From 255a4dacc59f4f4f62cc61743f40a078b4b38647 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:50 +0300 Subject: [PATCH 22/32] diff-merges: make -m/-c/--cc explicitly mutually exclusive -c/--cc got precedence over -m only because of external logic where corresponding flags are checked before that for -m. This is too error-prone, so add code that explicitly makes these 3 options mutually exclusive, so that the last option specified on the command-line gets precedence. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- diff-merges.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/diff-merges.c b/diff-merges.c index b8fd92adcf..e3c0190ebd 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -8,6 +8,7 @@ static void suppress(struct rev_info *revs) revs->first_parent_merges = 0; revs->combine_merges = 0; revs->dense_combined_merges = 0; + revs->combined_all_paths = 0; } static void set_separate(struct rev_info *revs) @@ -29,12 +30,14 @@ static void set_m(struct rev_info *revs) static void set_combined(struct rev_info *revs) { + suppress(revs); revs->combine_merges = 1; revs->dense_combined_merges = 0; } static void set_dense_combined(struct rev_info *revs) { + suppress(revs); revs->combine_merges = 1; revs->dense_combined_merges = 1; } From 8c0ba528bc3c61f4582bf68d3f0cc2a72f5f3792 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:51 +0300 Subject: [PATCH 23/32] diff-merges: implement new values for --diff-merges We first implement new options as exact synonyms for their original counterparts, to get all the infrastructure right, and keep functional improvements for later commits. The following values are implemented: --diff-merges= old equivalent first|first-parent = --first-parent (only format implications) sep|separate = -m comb|combined = -c dense| dense-combined = --cc Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- diff-merges.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/diff-merges.c b/diff-merges.c index e3c0190ebd..4d22da1795 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -17,6 +17,12 @@ static void set_separate(struct rev_info *revs) revs->separate_merges = 1; } +static void set_first_parent(struct rev_info *revs) +{ + set_separate(revs); + revs->first_parent_merges = 1; +} + static void set_m(struct rev_info *revs) { /* @@ -44,11 +50,18 @@ static void set_dense_combined(struct rev_info *revs) static void set_diff_merges(struct rev_info *revs, const char *optarg) { - if (!strcmp(optarg, "off")) { + if (!strcmp(optarg, "off") || !strcmp(optarg, "none")) suppress(revs); - } else { + else if (!strcmp(optarg, "first-parent")) + set_first_parent(revs); + else if (!strcmp(optarg, "separate")) + set_separate(revs); + else if (!strcmp(optarg, "combined")) + set_combined(revs); + else if (!strcmp(optarg, "dense-combined")) + set_dense_combined(revs); + else die(_("unknown value for --diff-merges: %s"), optarg); - } } /* From 5733b20f41ac0fecdacdf34a11acef2d03fac829 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:52 +0300 Subject: [PATCH 24/32] diff-merges: do not imply -p for new options Add 'combined_imply_patch' field and set it only for old --cc/-c options, then imply -p if this flag is set instead of implying -p whenever 'combined_merge' flag is set. We don't want new --diff-merge options to imply -p, to make it possible to enable output of diffs for merges independently from non-merge commits. At the same time we want to preserve behavior of old --c/-c/-m options and their interactions with --first-parent, to stay backward-compatible. This patch is first step in this direction: it separates old "--cc/-c imply -p" logic from the rest of the options. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- diff-merges.c | 20 ++++++++++++-------- revision.h | 1 + 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/diff-merges.c b/diff-merges.c index 4d22da1795..6d48ac5ab9 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -9,6 +9,7 @@ static void suppress(struct rev_info *revs) revs->combine_merges = 0; revs->dense_combined_merges = 0; revs->combined_all_paths = 0; + revs->combined_imply_patch = 0; } static void set_separate(struct rev_info *revs) @@ -74,19 +75,21 @@ int diff_merges_parse_opts(struct rev_info *revs, const char **argv) const char *optarg; const char *arg = argv[0]; - if (!strcmp(arg, "-m")) + if (!strcmp(arg, "-m")) { set_m(revs); - else if (!strcmp(arg, "-c")) + } else if (!strcmp(arg, "-c")) { set_combined(revs); - else if (!strcmp(arg, "--cc")) + revs->combined_imply_patch = 1; + } else if (!strcmp(arg, "--cc")) { set_dense_combined(revs); - else if (!strcmp(arg, "--no-diff-merges")) + revs->combined_imply_patch = 1; + } else if (!strcmp(arg, "--no-diff-merges")) { suppress(revs); - else if (!strcmp(arg, "--combined-all-paths")) + } else if (!strcmp(arg, "--combined-all-paths")) { revs->combined_all_paths = 1; - else if ((argcount = parse_long_opt("diff-merges", argv, &optarg))) + } else if ((argcount = parse_long_opt("diff-merges", argv, &optarg))) { set_diff_merges(revs, optarg); - else + } else return 0; revs->explicit_diff_merges = 1; @@ -126,8 +129,9 @@ void diff_merges_setup_revs(struct rev_info *revs) revs->first_parent_merges = 0; if (revs->combined_all_paths && !revs->combine_merges) die("--combined-all-paths makes no sense without -c or --cc"); - if (revs->combine_merges) { + if (revs->combine_merges) revs->diff = 1; + if (revs->combined_imply_patch) { /* Turn --cc/-c into -p --cc/-c when -p was not given */ if (!revs->diffopt.output_format) revs->diffopt.output_format = DIFF_FORMAT_PATCH; diff --git a/revision.h b/revision.h index dcfa14454a..bfbae526ad 100644 --- a/revision.h +++ b/revision.h @@ -197,6 +197,7 @@ struct rev_info { separate_merges: 1, combine_merges:1, combined_all_paths:1, + combined_imply_patch:1, dense_combined_merges:1, first_parent_merges:1; From a6d19ecc6b7715b50b0dced7e3d2923a8797df64 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:53 +0300 Subject: [PATCH 25/32] diff-merges: let new options enable diff without -p New options don't have any visible effect unless -p is either given or implied, as unlike -c/-cc we don't imply -p with --diff-merges. To fix this, this patch adds new functionality by letting new options enable output of diffs for merge commits only. Add 'merges_need_diff' field and set it whenever diff output for merges is enabled by any of the new options. Extend diff output logic accordingly, to output diffs for merges when 'merges_need_diff' is set even when no -p has been provided. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- diff-merges.c | 17 ++++++++++++----- log-tree.c | 13 +++++++++---- revision.h | 1 + 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/diff-merges.c b/diff-merges.c index 6d48ac5ab9..ee91ed0db4 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -10,6 +10,7 @@ static void suppress(struct rev_info *revs) revs->dense_combined_merges = 0; revs->combined_all_paths = 0; revs->combined_imply_patch = 0; + revs->merges_need_diff = 0; } static void set_separate(struct rev_info *revs) @@ -51,9 +52,13 @@ static void set_dense_combined(struct rev_info *revs) static void set_diff_merges(struct rev_info *revs, const char *optarg) { - if (!strcmp(optarg, "off") || !strcmp(optarg, "none")) + if (!strcmp(optarg, "off") || !strcmp(optarg, "none")) { suppress(revs); - else if (!strcmp(optarg, "first-parent")) + /* Return early to leave revs->merges_need_diff unset */ + return; + } + + if (!strcmp(optarg, "first-parent")) set_first_parent(revs); else if (!strcmp(optarg, "separate")) set_separate(revs); @@ -63,6 +68,9 @@ static void set_diff_merges(struct rev_info *revs, const char *optarg) set_dense_combined(revs); else die(_("unknown value for --diff-merges: %s"), optarg); + + /* The flag is cleared by set_xxx() functions, so don't move this up */ + revs->merges_need_diff = 1; } /* @@ -129,10 +137,9 @@ void diff_merges_setup_revs(struct rev_info *revs) revs->first_parent_merges = 0; if (revs->combined_all_paths && !revs->combine_merges) die("--combined-all-paths makes no sense without -c or --cc"); - if (revs->combine_merges) + if (revs->combined_imply_patch) revs->diff = 1; - if (revs->combined_imply_patch) { - /* Turn --cc/-c into -p --cc/-c when -p was not given */ + if (revs->combined_imply_patch || revs->merges_need_diff) { if (!revs->diffopt.output_format) revs->diffopt.output_format = DIFF_FORMAT_PATCH; } diff --git a/log-tree.c b/log-tree.c index f9385b1dae..9f50a81e53 100644 --- a/log-tree.c +++ b/log-tree.c @@ -899,15 +899,21 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log int showed_log; struct commit_list *parents; struct object_id *oid; + int is_merge; + int all_need_diff = opt->diff || opt->diffopt.flags.exit_with_status; - if (!opt->diff && !opt->diffopt.flags.exit_with_status) + if (!all_need_diff && !opt->merges_need_diff) return 0; parse_commit_or_die(commit); oid = get_commit_tree_oid(commit); - /* Root commit? */ parents = get_saved_parents(opt, commit); + is_merge = parents && parents->next; + if (!is_merge && !all_need_diff) + return 0; + + /* Root commit? */ if (!parents) { if (opt->show_root_diff) { diff_root_tree_oid(oid, "", &opt->diffopt); @@ -916,8 +922,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log return !opt->loginfo; } - /* More than one parent? */ - if (parents->next) { + if (is_merge) { if (opt->combine_merges) return do_diff_combined(opt, commit); if (opt->separate_merges) { diff --git a/revision.h b/revision.h index bfbae526ad..494d861424 100644 --- a/revision.h +++ b/revision.h @@ -194,6 +194,7 @@ struct rev_info { always_show_header:1, /* Diff-merge flags */ explicit_diff_merges: 1, + merges_need_diff: 1, separate_merges: 1, combine_merges:1, combined_all_paths:1, From 5071c7531692f53cdfec43542f1cbaee573fd2be Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:54 +0300 Subject: [PATCH 26/32] diff-merges: add old mnemonic counterparts to --diff-merges This adds --diff-merges={m|c|cc} values that match mnemonics of old options, for those who are used to them. Note that, say, --diff-meres=cc behaves differently than --cc, as the latter implies -p and therefore enables diffs for all the commits, while the former enables output of diffs for merge commits only. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- diff-merges.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/diff-merges.c b/diff-merges.c index ee91ed0db4..011bfff1f1 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -60,11 +60,11 @@ static void set_diff_merges(struct rev_info *revs, const char *optarg) if (!strcmp(optarg, "first-parent")) set_first_parent(revs); - else if (!strcmp(optarg, "separate")) + else if (!strcmp(optarg, "m") || !strcmp(optarg, "separate")) set_separate(revs); - else if (!strcmp(optarg, "combined")) + else if (!strcmp(optarg, "c") || !strcmp(optarg, "combined")) set_combined(revs); - else if (!strcmp(optarg, "dense-combined")) + else if (!strcmp(optarg, "cc") || !strcmp(optarg, "dense-combined")) set_dense_combined(revs); else die(_("unknown value for --diff-merges: %s"), optarg); From 388091fe4d9e06475f491c195e84e1996aad3f42 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:55 +0300 Subject: [PATCH 27/32] diff-merges: add '--diff-merges=1' as synonym for 'first-parent' As we now have --diff-merges={m|c|cc}, add --diff-merges=1 as synonym for --diff-merges=first-parent, to have shorter mnemonics for it as well. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- diff-merges.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diff-merges.c b/diff-merges.c index 011bfff1f1..146bb50316 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -58,7 +58,7 @@ static void set_diff_merges(struct rev_info *revs, const char *optarg) return; } - if (!strcmp(optarg, "first-parent")) + if (!strcmp(optarg, "1") || !strcmp(optarg, "first-parent")) set_first_parent(revs); else if (!strcmp(optarg, "m") || !strcmp(optarg, "separate")) set_separate(revs); From b5ffa9ec10a3b82a1530d6f7628bd3ef9e8dd037 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:56 +0300 Subject: [PATCH 28/32] doc/git-log: describe new --diff-merges options Describe all the new --diff-merges options in the git-log.txt and adopt description of originals accordingly. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- Documentation/git-log.txt | 83 +++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index 2b8ac5ff88..ff83dff14d 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -120,45 +120,62 @@ DIFF FORMATTING By default, `git log` does not generate any diff output. The options below can be used to show the changes made by each commit. -Note that unless one of `-c`, `--cc`, or `-m` is given, merge commits -will never show a diff, even if a diff format like `--patch` is -selected, nor will they match search options like `-S`. The exception is -when `--first-parent` is in use, in which merges are treated like normal -single-parent commits (this can be overridden by providing a -combined-diff option or with `--no-diff-merges`). +Note that unless one of `--diff-merges` variants (including short +`-m`, `-c`, and `--cc` options) is explicitly given, merge commits +will not show a diff, even if a diff format like `--patch` is +selected, nor will they match search options like `-S`. The exception +is when `--first-parent` is in use, in which case `first-parent` is +the default format. --c:: - With this option, diff output for a merge commit - shows the differences from each of the parents to the merge result - simultaneously instead of showing pairwise diff between a parent - and the result one at a time. Furthermore, it lists only files - which were modified from all parents. - ---cc:: - This flag implies the `-c` option and further compresses the - patch output by omitting uninteresting hunks whose contents in - the parents have only two variants and the merge result picks - one of them without modification. +--diff-merges=(off|none|first-parent|1|separate|m|combined|c|dense-combined|cc):: +--no-diff-merges:: + Specify diff format to be used for merge commits. Default is + `off` unless `--first-parent` is in use, in which case + `first-parent` is the default. ++ +--diff-merges=(off|none)::: +--no-diff-merges::: + Disable output of diffs for merge commits. Useful to override + implied value. ++ +--diff-merges=first-parent::: +--diff-merges=1::: + This option makes merge commits show the full diff with + respect to the first parent only. ++ +--diff-merges=separate::: +--diff-merges=m::: +-m::: + This makes merge commits show the full diff with respect to + each of the parents. Separate log entry and diff is generated + for each parent. `-m` doesn't produce any output without `-p`. ++ +--diff-merges=combined::: +--diff-merges=c::: +-c::: + With this option, diff output for a merge commit shows the + differences from each of the parents to the merge result + simultaneously instead of showing pairwise diff between a + parent and the result one at a time. Furthermore, it lists + only files which were modified from all parents. `-c` implies + `-p`. ++ +--diff-merges=dense-combined::: +--diff-merges=cc::: +--cc::: + With this option the output produced by + `--diff-merges=combined` is further compressed by omitting + uninteresting hunks whose contents in the parents have only + two variants and the merge result picks one of them without + modification. `--cc` implies `-p`. --combined-all-paths:: This flag causes combined diffs (used for merge commits) to list the name of the file from all parents. It thus only has - effect when -c or --cc are specified, and is likely only - useful if filename changes are detected (i.e. when either - rename or copy detection have been requested). + effect when `--diff-merges=[dense-]combined` is in use, and + is likely only useful if filename changes are detected (i.e. + when either rename or copy detection have been requested). --m:: - This flag makes the merge commits show the full diff like - regular commits; for each merge parent, a separate log entry - and diff is generated. An exception is that only diff against - the first parent is shown when `--first-parent` option is given; - in that case, the output represents the changes the merge - brought _into_ the then-current branch. - ---diff-merges=off:: ---no-diff-merges:: - Disable output of diffs for merge commits (default). Useful to - override `-m`, `-c`, or `--cc`. :git-log: 1 include::diff-options.txt[] From 8efd2efc32c41c7dcc2bf86a11fa89377f1c8d94 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:57 +0300 Subject: [PATCH 29/32] doc/diff-generate-patch: mention new --diff-merges option Mention --diff-merges instead of -m in a note to merge formats to aid discoverability, as -m is now described among --diff-merges options anyway. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- Documentation/diff-generate-patch.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/diff-generate-patch.txt b/Documentation/diff-generate-patch.txt index b10ff4caa6..2db8eacc3e 100644 --- a/Documentation/diff-generate-patch.txt +++ b/Documentation/diff-generate-patch.txt @@ -81,9 +81,9 @@ Combined diff format Any diff-generating command can take the `-c` or `--cc` option to produce a 'combined diff' when showing a merge. This is the default format when showing merges with linkgit:git-diff[1] or -linkgit:git-show[1]. Note also that you can give the `-m` option to any -of these commands to force generation of diffs with individual parents -of a merge. +linkgit:git-show[1]. Note also that you can give suitable +`--diff-merges` option to any of these commands to force generation of +diffs in specific format. A "combined diff" format looks like this: From e58142add40e0db354eaed9554d1b0c871e23f7d Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:58 +0300 Subject: [PATCH 30/32] doc/rev-list-options: document --first-parent changes merges format After introduction of the --diff-merges=first-parent, the --first-parent sets the default format for merges to the same value as this new option. Document this behavior and add corresponding reference to --diff-merges. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- Documentation/rev-list-options.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 002379056a..96cc89d157 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -130,6 +130,11 @@ parents) and `--max-parents=-1` (negative numbers denote no upper limit). this option allows you to ignore the individual commits brought in to your history by such a merge. +ifdef::git-log[] + This option also changes default diff format for merge commits + to `first-parent`, see `--diff-merges=first-parent` for details. +endif::git-log[] + --not:: Reverses the meaning of the '{caret}' prefix (or lack thereof) for all following revision specifiers, up to the next `--not`. From 1d24509b7b865115836982267a5e54b2f7d77c42 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:19:59 +0300 Subject: [PATCH 31/32] doc/git-show: include --diff-merges description Move description of --diff-merges option from git-log.txt to diff-options.txt so that it is included in the git-show help. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- Documentation/diff-options.txt | 51 ++++++++++++++++++++++++++++++++++ Documentation/git-log.txt | 51 +--------------------------------- Documentation/git-show.txt | 7 +++-- 3 files changed, 57 insertions(+), 52 deletions(-) diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 573fb9bb71..c995e82584 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -33,6 +33,57 @@ endif::git-diff[] show the patch by default, or to cancel the effect of `--patch`. endif::git-format-patch[] +ifdef::git-log[] +--diff-merges=(off|none|first-parent|1|separate|m|combined|c|dense-combined|cc):: +--no-diff-merges:: + Specify diff format to be used for merge commits. Default is + {diff-merges-default} unless `--first-parent` is in use, in which case + `first-parent` is the default. ++ +--diff-merges=(off|none)::: +--no-diff-merges::: + Disable output of diffs for merge commits. Useful to override + implied value. ++ +--diff-merges=first-parent::: +--diff-merges=1::: + This option makes merge commits show the full diff with + respect to the first parent only. ++ +--diff-merges=separate::: +--diff-merges=m::: +-m::: + This makes merge commits show the full diff with respect to + each of the parents. Separate log entry and diff is generated + for each parent. `-m` doesn't produce any output without `-p`. ++ +--diff-merges=combined::: +--diff-merges=c::: +-c::: + With this option, diff output for a merge commit shows the + differences from each of the parents to the merge result + simultaneously instead of showing pairwise diff between a + parent and the result one at a time. Furthermore, it lists + only files which were modified from all parents. `-c` implies + `-p`. ++ +--diff-merges=dense-combined::: +--diff-merges=cc::: +--cc::: + With this option the output produced by + `--diff-merges=combined` is further compressed by omitting + uninteresting hunks whose contents in the parents have only + two variants and the merge result picks one of them without + modification. `--cc` implies `-p`. + +--combined-all-paths:: + This flag causes combined diffs (used for merge commits) to + list the name of the file from all parents. It thus only has + effect when `--diff-merges=[dense-]combined` is in use, and + is likely only useful if filename changes are detected (i.e. + when either rename or copy detection have been requested). +endif::git-log[] + -U:: --unified=:: Generate diffs with lines of context instead of diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index ff83dff14d..727d20e1a2 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -127,57 +127,8 @@ selected, nor will they match search options like `-S`. The exception is when `--first-parent` is in use, in which case `first-parent` is the default format. ---diff-merges=(off|none|first-parent|1|separate|m|combined|c|dense-combined|cc):: ---no-diff-merges:: - Specify diff format to be used for merge commits. Default is - `off` unless `--first-parent` is in use, in which case - `first-parent` is the default. -+ ---diff-merges=(off|none)::: ---no-diff-merges::: - Disable output of diffs for merge commits. Useful to override - implied value. -+ ---diff-merges=first-parent::: ---diff-merges=1::: - This option makes merge commits show the full diff with - respect to the first parent only. -+ ---diff-merges=separate::: ---diff-merges=m::: --m::: - This makes merge commits show the full diff with respect to - each of the parents. Separate log entry and diff is generated - for each parent. `-m` doesn't produce any output without `-p`. -+ ---diff-merges=combined::: ---diff-merges=c::: --c::: - With this option, diff output for a merge commit shows the - differences from each of the parents to the merge result - simultaneously instead of showing pairwise diff between a - parent and the result one at a time. Furthermore, it lists - only files which were modified from all parents. `-c` implies - `-p`. -+ ---diff-merges=dense-combined::: ---diff-merges=cc::: ---cc::: - With this option the output produced by - `--diff-merges=combined` is further compressed by omitting - uninteresting hunks whose contents in the parents have only - two variants and the merge result picks one of them without - modification. `--cc` implies `-p`. - ---combined-all-paths:: - This flag causes combined diffs (used for merge commits) to - list the name of the file from all parents. It thus only has - effect when `--diff-merges=[dense-]combined` is in use, and - is likely only useful if filename changes are detected (i.e. - when either rename or copy detection have been requested). - - :git-log: 1 +:diff-merges-default: `off` include::diff-options.txt[] include::diff-generate-patch.txt[] diff --git a/Documentation/git-show.txt b/Documentation/git-show.txt index fcf528c1b3..2b1bc7288d 100644 --- a/Documentation/git-show.txt +++ b/Documentation/git-show.txt @@ -45,10 +45,13 @@ include::pretty-options.txt[] include::pretty-formats.txt[] -COMMON DIFF OPTIONS -------------------- +DIFF FORMATTING +--------------- +The options below can be used to change the way `git show` generates +diff output. :git-log: 1 +:diff-merges-default: `dense-combined` include::diff-options.txt[] include::diff-generate-patch.txt[] From af04d8f1a5a38373fba762071824bc85da7cc050 Mon Sep 17 00:00:00 2001 From: Sergey Organov Date: Mon, 21 Dec 2020 18:20:00 +0300 Subject: [PATCH 32/32] t4013: add tests for --diff-merges=first-parent This new option provides essential new functionality, changing diff output to first parent only, without changing history traversal mode, so it deserves its own test. As we do it, add additional test that --diff-merges=first-parent by itself doesn't imply -p and only outputs diffs for merge commits. Signed-off-by: Sergey Organov Signed-off-by: Junio C Hamano --- t/t4013-diff-various.sh | 2 + ...diff.log_--diff-merges=first-parent_master | 56 +++++++ ...f.log_-p_--diff-merges=first-parent_master | 137 ++++++++++++++++++ 3 files changed, 195 insertions(+) create mode 100644 t/t4013/diff.log_--diff-merges=first-parent_master create mode 100644 t/t4013/diff.log_-p_--diff-merges=first-parent_master diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 8d8178a8a6..fa82b5a8ee 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -327,6 +327,8 @@ log --no-diff-merges -p --first-parent master log --diff-merges=off -p --first-parent master log --first-parent --diff-merges=off -p master log -p --first-parent master +log -p --diff-merges=first-parent master +log --diff-merges=first-parent master log -m -p --first-parent master log -m -p master log --cc -m -p master diff --git a/t/t4013/diff.log_--diff-merges=first-parent_master b/t/t4013/diff.log_--diff-merges=first-parent_master new file mode 100644 index 0000000000..fa63a557dd --- /dev/null +++ b/t/t4013/diff.log_--diff-merges=first-parent_master @@ -0,0 +1,56 @@ +$ git log --diff-merges=first-parent master +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 +Merge: 9a6d494 c7a2ab9 +Author: A U Thor +Date: Mon Jun 26 00:04:00 2006 +0000 + + Merge branch 'side' + +diff --git a/dir/sub b/dir/sub +index cead32e..992913c 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -4,3 +4,5 @@ C + D + E + F ++1 ++2 +diff --git a/file0 b/file0 +index b414108..10a8a9f 100644 +--- a/file0 ++++ b/file0 +@@ -4,3 +4,6 @@ + 4 + 5 + 6 ++A ++B ++C + +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side + +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third + +commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 +Author: A U Thor +Date: Mon Jun 26 00:01:00 2006 +0000 + + Second + + This is the second commit. + +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial +$ diff --git a/t/t4013/diff.log_-p_--diff-merges=first-parent_master b/t/t4013/diff.log_-p_--diff-merges=first-parent_master new file mode 100644 index 0000000000..9538a27511 --- /dev/null +++ b/t/t4013/diff.log_-p_--diff-merges=first-parent_master @@ -0,0 +1,137 @@ +$ git log -p --diff-merges=first-parent master +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 +Merge: 9a6d494 c7a2ab9 +Author: A U Thor +Date: Mon Jun 26 00:04:00 2006 +0000 + + Merge branch 'side' + +diff --git a/dir/sub b/dir/sub +index cead32e..992913c 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -4,3 +4,5 @@ C + D + E + F ++1 ++2 +diff --git a/file0 b/file0 +index b414108..10a8a9f 100644 +--- a/file0 ++++ b/file0 +@@ -4,3 +4,6 @@ + 4 + 5 + 6 ++A ++B ++C + +commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a +Author: A U Thor +Date: Mon Jun 26 00:03:00 2006 +0000 + + Side + +diff --git a/dir/sub b/dir/sub +index 35d242b..7289e35 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -1,2 +1,4 @@ + A + B ++1 ++2 +diff --git a/file0 b/file0 +index 01e79c3..f4615da 100644 +--- a/file0 ++++ b/file0 +@@ -1,3 +1,6 @@ + 1 + 2 + 3 ++A ++B ++C +diff --git a/file3 b/file3 +new file mode 100644 +index 0000000..7289e35 +--- /dev/null ++++ b/file3 +@@ -0,0 +1,4 @@ ++A ++B ++1 ++2 + +commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 +Author: A U Thor +Date: Mon Jun 26 00:02:00 2006 +0000 + + Third + +diff --git a/dir/sub b/dir/sub +index 8422d40..cead32e 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -2,3 +2,5 @@ A + B + C + D ++E ++F +diff --git a/file1 b/file1 +new file mode 100644 +index 0000000..b1e6722 +--- /dev/null ++++ b/file1 +@@ -0,0 +1,3 @@ ++A ++B ++C + +commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44 +Author: A U Thor +Date: Mon Jun 26 00:01:00 2006 +0000 + + Second + + This is the second commit. + +diff --git a/dir/sub b/dir/sub +index 35d242b..8422d40 100644 +--- a/dir/sub ++++ b/dir/sub +@@ -1,2 +1,4 @@ + A + B ++C ++D +diff --git a/file0 b/file0 +index 01e79c3..b414108 100644 +--- a/file0 ++++ b/file0 +@@ -1,3 +1,6 @@ + 1 + 2 + 3 ++4 ++5 ++6 +diff --git a/file2 b/file2 +deleted file mode 100644 +index 01e79c3..0000000 +--- a/file2 ++++ /dev/null +@@ -1,3 +0,0 @@ +-1 +-2 +-3 + +commit 444ac553ac7612cc88969031b02b3767fb8a353a +Author: A U Thor +Date: Mon Jun 26 00:00:00 2006 +0000 + + Initial +$