From 41f43b8243f42b9df2e98be8460646d4c0100ad3 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 6 Dec 2024 11:27:19 +0100 Subject: global: mark code units that generate warnings with `-Wsign-compare` Mark code units that generate warnings with `-Wsign-compare`. This allows for a structured approach to get rid of all such warnings over time in a way that can be easily measured. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/range-diff.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'builtin/range-diff.c') diff --git a/builtin/range-diff.c b/builtin/range-diff.c index 1b33ab66a7..aa88a46d9e 100644 --- a/builtin/range-diff.c +++ b/builtin/range-diff.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "gettext.h" #include "object-name.h" -- cgit v1.3 From 47d72a74a737f06791c282a75baf2c573cdf42f6 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 6 Dec 2024 11:27:21 +0100 Subject: diff.h: fix index used to loop through unsigned integer The `struct diff_flags` structure is essentially an array of flags, all of which have the same type. We can thus use `sizeof()` to iterate through all of the flags, which we do in `diff_flags_or()`. But while the statement returns an unsigned integer, we used a signed integer to iterate through the flags, which generates a warning. Fix this by using `size_t` for the index instead. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/am.c | 1 - builtin/diff-tree.c | 1 - builtin/merge-ours.c | 1 - builtin/pack-refs.c | 1 - builtin/range-diff.c | 1 - builtin/reflog.c | 1 - builtin/reset.c | 1 - builtin/revert.c | 1 - builtin/shortlog.c | 1 - diff-merges.c | 2 -- diff.h | 3 +-- diffcore-order.c | 2 -- diffcore-rotate.c | 2 -- list-objects-filter.c | 1 - patch-ids.c | 2 -- reachable.c | 1 - reflog-walk.c | 1 - t/helper/test-revision-walking.c | 1 - 18 files changed, 1 insertion(+), 23 deletions(-) (limited to 'builtin/range-diff.c') diff --git a/builtin/am.c b/builtin/am.c index f3b6546b30..1338b606fe 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -5,7 +5,6 @@ */ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "builtin.h" #include "abspath.h" diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index a4df2d0c13..40804e7b48 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -1,5 +1,4 @@ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "builtin.h" #include "config.h" diff --git a/builtin/merge-ours.c b/builtin/merge-ours.c index 3672c6353f..3ecd9172f1 100644 --- a/builtin/merge-ours.c +++ b/builtin/merge-ours.c @@ -9,7 +9,6 @@ */ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "builtin.h" diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c index 71175a713a..4fdd68880e 100644 --- a/builtin/pack-refs.c +++ b/builtin/pack-refs.c @@ -1,5 +1,4 @@ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "builtin.h" #include "config.h" diff --git a/builtin/range-diff.c b/builtin/range-diff.c index aa88a46d9e..433c305fc5 100644 --- a/builtin/range-diff.c +++ b/builtin/range-diff.c @@ -1,5 +1,4 @@ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "builtin.h" #include "gettext.h" diff --git a/builtin/reflog.c b/builtin/reflog.c index 08e99a22b0..95f264989b 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -1,5 +1,4 @@ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "builtin.h" #include "config.h" diff --git a/builtin/reset.c b/builtin/reset.c index f34d22190f..73b4537a9a 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -9,7 +9,6 @@ */ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "builtin.h" #include "advice.h" diff --git a/builtin/revert.c b/builtin/revert.c index 4b57c2c383..aca6c293cd 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -1,5 +1,4 @@ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "builtin.h" diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 1c46f13a16..30075b67be 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -1,5 +1,4 @@ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "builtin.h" #include "config.h" diff --git a/diff-merges.c b/diff-merges.c index 0adfe7f5c0..45507588a2 100644 --- a/diff-merges.c +++ b/diff-merges.c @@ -1,5 +1,3 @@ -#define DISABLE_SIGN_COMPARE_WARNINGS - #include "git-compat-util.h" #include "diff-merges.h" diff --git a/diff.h b/diff.h index 5c8de79535..6e6007c17b 100644 --- a/diff.h +++ b/diff.h @@ -205,9 +205,8 @@ static inline void diff_flags_or(struct diff_flags *a, { char *tmp_a = (char *)a; const char *tmp_b = (const char *)b; - int i; - for (i = 0; i < sizeof(struct diff_flags); i++) + for (size_t i = 0; i < sizeof(struct diff_flags); i++) tmp_a[i] |= tmp_b[i]; } diff --git a/diffcore-order.c b/diffcore-order.c index ec59d3d9bc..f91ef22471 100644 --- a/diffcore-order.c +++ b/diffcore-order.c @@ -2,8 +2,6 @@ * Copyright (C) 2005 Junio C Hamano */ -#define DISABLE_SIGN_COMPARE_WARNINGS - #include "git-compat-util.h" #include "gettext.h" #include "diff.h" diff --git a/diffcore-rotate.c b/diffcore-rotate.c index 941a022d5e..67b591261a 100644 --- a/diffcore-rotate.c +++ b/diffcore-rotate.c @@ -3,8 +3,6 @@ * Based on diffcore-order.c, which is Copyright (C) 2005, Junio C Hamano */ -#define DISABLE_SIGN_COMPARE_WARNINGS - #include "git-compat-util.h" #include "gettext.h" #include "diff.h" diff --git a/list-objects-filter.c b/list-objects-filter.c index 4afa3029dc..dc598a081b 100644 --- a/list-objects-filter.c +++ b/list-objects-filter.c @@ -1,5 +1,4 @@ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "dir.h" diff --git a/patch-ids.c b/patch-ids.c index 8b89198073..a5683b462c 100644 --- a/patch-ids.c +++ b/patch-ids.c @@ -1,5 +1,3 @@ -#define DISABLE_SIGN_COMPARE_WARNINGS - #include "git-compat-util.h" #include "diff.h" #include "commit.h" diff --git a/reachable.c b/reachable.c index 34079e1ae9..3e9b3dd0a4 100644 --- a/reachable.c +++ b/reachable.c @@ -1,5 +1,4 @@ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "gettext.h" diff --git a/reflog-walk.c b/reflog-walk.c index b53628ed53..c7070b13b0 100644 --- a/reflog-walk.c +++ b/reflog-walk.c @@ -1,5 +1,4 @@ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "commit.h" diff --git a/t/helper/test-revision-walking.c b/t/helper/test-revision-walking.c index 3b931a34a2..071f5bd1e2 100644 --- a/t/helper/test-revision-walking.c +++ b/t/helper/test-revision-walking.c @@ -9,7 +9,6 @@ */ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "test-tool.h" #include "commit.h" -- cgit v1.3 From f8043236c6c9cb9e943a87ab2e55e8e394796727 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 16 Dec 2024 14:11:21 +0000 Subject: range-diff: optionally include merge commits' diffs in the analysis The `git log` command already offers support for including diffs for merges, via the `--diff-merges=` option. Let's add corresponding support for `git range-diff`, too. This makes it more convenient to spot differences between commit ranges that contain merges. This is especially true in scenarios with non-trivial merges, i.e. merges introducing changes other than, or in addition to, what merge ORT would have produced. Merging a topic branch that changes a function signature into a branch that added a caller of that function, for example, would require the merge commit itself to adjust that caller to the modified signature. In my code reviews, I found the `--diff-merges=remerge` option particularly useful. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git-range-diff.txt | 13 ++++++++++++- builtin/range-diff.c | 10 ++++++++++ range-diff.c | 15 +++++++++++---- range-diff.h | 1 + t/t3206-range-diff.sh | 16 ++++++++++++++++ 5 files changed, 50 insertions(+), 5 deletions(-) (limited to 'builtin/range-diff.c') diff --git a/Documentation/git-range-diff.txt b/Documentation/git-range-diff.txt index fbdbe0befe..00c649b140 100644 --- a/Documentation/git-range-diff.txt +++ b/Documentation/git-range-diff.txt @@ -10,7 +10,7 @@ SYNOPSIS [verse] 'git range-diff' [--color=[]] [--no-color] [] [--no-dual-color] [--creation-factor=] - [--left-only | --right-only] + [--left-only | --right-only] [--diff-merges=] ( | ... | ) [[--] ...] @@ -81,6 +81,17 @@ to revert to color all lines according to the outer diff markers Suppress commits that are missing from the second specified range (or the "right range" when using the `...` format). +--diff-merges=:: + Instead of ignoring merge commits, generate diffs for them using the + corresponding `--diff-merges=` option of linkgit:git-log[1], + and include them in the comparison. ++ +Note: In the common case, the `remerge` mode will be the most natural one +to use, as it shows only the diff on top of what Git's merge machinery would +have produced. In other words, if a merge commit is the result of a +non-conflicting `git merge`, the `remerge` mode will represent it with an empty +diff. + --[no-]notes[=]:: This flag is passed to the `git log` program (see linkgit:git-log[1]) that generates the patches. diff --git a/builtin/range-diff.c b/builtin/range-diff.c index 1b33ab66a7..901de5d133 100644 --- a/builtin/range-diff.c +++ b/builtin/range-diff.c @@ -21,6 +21,7 @@ int cmd_range_diff(int argc, { struct diff_options diffopt = { NULL }; struct strvec other_arg = STRVEC_INIT; + struct strvec diff_merges_arg = STRVEC_INIT; struct range_diff_options range_diff_opts = { .creation_factor = RANGE_DIFF_CREATION_FACTOR_DEFAULT, .diffopt = &diffopt, @@ -36,6 +37,8 @@ int cmd_range_diff(int argc, OPT_PASSTHRU_ARGV(0, "notes", &other_arg, N_("notes"), N_("passed to 'git log'"), PARSE_OPT_OPTARG), + OPT_PASSTHRU_ARGV(0, "diff-merges", &diff_merges_arg, + N_("style"), N_("passed to 'git log'"), 0), OPT_BOOL(0, "left-only", &left_only, N_("only emit output related to the first range")), OPT_BOOL(0, "right-only", &right_only, @@ -62,6 +65,12 @@ int cmd_range_diff(int argc, if (!simple_color) diffopt.use_color = 1; + /* If `--diff-merges` was specified, imply `--merges` */ + if (diff_merges_arg.nr) { + range_diff_opts.include_merges = 1; + strvec_pushv(&other_arg, diff_merges_arg.v); + } + for (i = 0; i < argc; i++) if (!strcmp(argv[i], "--")) { dash_dash = i; @@ -155,6 +164,7 @@ int cmd_range_diff(int argc, res = show_range_diff(range1.buf, range2.buf, &range_diff_opts); strvec_clear(&other_arg); + strvec_clear(&diff_merges_arg); strbuf_release(&range1); strbuf_release(&range2); diff --git a/range-diff.c b/range-diff.c index 10885ba301..19673d47d9 100644 --- a/range-diff.c +++ b/range-diff.c @@ -38,7 +38,8 @@ struct patch_util { * as struct object_id (will need to be free()d). */ static int read_patches(const char *range, struct string_list *list, - const struct strvec *other_arg) + const struct strvec *other_arg, + unsigned int include_merges) { struct child_process cp = CHILD_PROCESS_INIT; struct strbuf buf = STRBUF_INIT, contents = STRBUF_INIT; @@ -49,7 +50,7 @@ static int read_patches(const char *range, struct string_list *list, size_t size; int ret = -1; - strvec_pushl(&cp.args, "log", "--no-color", "-p", "--no-merges", + strvec_pushl(&cp.args, "log", "--no-color", "-p", "--reverse", "--date-order", "--decorate=no", "--no-prefix", "--submodule=short", /* @@ -64,6 +65,8 @@ static int read_patches(const char *range, struct string_list *list, "--pretty=medium", "--show-notes-by-default", NULL); + if (!include_merges) + strvec_push(&cp.args, "--no-merges"); strvec_push(&cp.args, range); if (other_arg) strvec_pushv(&cp.args, other_arg->v); @@ -96,11 +99,14 @@ static int read_patches(const char *range, struct string_list *list, } if (skip_prefix(line, "commit ", &p)) { + char *q; if (util) { string_list_append(list, buf.buf)->util = util; strbuf_reset(&buf); } CALLOC_ARRAY(util, 1); + if (include_merges && (q = strstr(p, " (from "))) + *q = '\0'; if (repo_get_oid(the_repository, p, &util->oid)) { error(_("could not parse commit '%s'"), p); FREE_AND_NULL(util); @@ -571,13 +577,14 @@ int show_range_diff(const char *range1, const char *range2, struct string_list branch1 = STRING_LIST_INIT_DUP; struct string_list branch2 = STRING_LIST_INIT_DUP; + unsigned int include_merges = range_diff_opts->include_merges; if (range_diff_opts->left_only && range_diff_opts->right_only) res = error(_("options '%s' and '%s' cannot be used together"), "--left-only", "--right-only"); - if (!res && read_patches(range1, &branch1, range_diff_opts->other_arg)) + if (!res && read_patches(range1, &branch1, range_diff_opts->other_arg, include_merges)) res = error(_("could not parse log for '%s'"), range1); - if (!res && read_patches(range2, &branch2, range_diff_opts->other_arg)) + if (!res && read_patches(range2, &branch2, range_diff_opts->other_arg, include_merges)) res = error(_("could not parse log for '%s'"), range2); if (!res) { diff --git a/range-diff.h b/range-diff.h index 2f69f6a434..cd85000b5a 100644 --- a/range-diff.h +++ b/range-diff.h @@ -16,6 +16,7 @@ struct range_diff_options { int creation_factor; unsigned dual_color:1; unsigned left_only:1, right_only:1; + unsigned include_merges:1; const struct diff_options *diffopt; /* may be NULL */ const struct strvec *other_arg; /* may be NULL */ }; diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh index 86010931ab..c18a3fdab8 100755 --- a/t/t3206-range-diff.sh +++ b/t/t3206-range-diff.sh @@ -909,4 +909,20 @@ test_expect_success 'submodule changes are shown irrespective of diff.submodule' test_cmp expect actual ' +test_expect_success '--diff-merges' ' + renamed_oid=$(git rev-parse --short renamed-file) && + tree=$(git merge-tree unmodified renamed-file) && + clean=$(git commit-tree -m merge -p unmodified -p renamed-file $tree) && + clean_oid=$(git rev-parse --short $clean) && + conflict=$(git commit-tree -m merge -p unmodified -p renamed-file^ $tree) && + conflict_oid=$(git rev-parse --short $conflict) && + + git range-diff --diff-merges=1 $clean...$conflict >actual && + cat >expect <<-EOF && + 1: $renamed_oid < -: ------- s/12/B/ + 2: $clean_oid = 1: $conflict_oid merge + EOF + test_cmp expect actual +' + test_done -- cgit v1.3 From 4538338c7edb13a5e818abcfa5739f16ad3dda0c Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 16 Dec 2024 14:11:22 +0000 Subject: range-diff: introduce the convenience option `--remerge-diff` Just like `git log`, now also `git range-diff` has that option as a shortcut for the common operation that would otherwise require the quite unwieldy (if theoretically "more correct") `--diff-mode=remerge` option. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git-range-diff.txt | 4 ++++ builtin/range-diff.c | 2 ++ 2 files changed, 6 insertions(+) (limited to 'builtin/range-diff.c') diff --git a/Documentation/git-range-diff.txt b/Documentation/git-range-diff.txt index 00c649b140..db0e4279b5 100644 --- a/Documentation/git-range-diff.txt +++ b/Documentation/git-range-diff.txt @@ -11,6 +11,7 @@ SYNOPSIS 'git range-diff' [--color=[]] [--no-color] [] [--no-dual-color] [--creation-factor=] [--left-only | --right-only] [--diff-merges=] + [--remerge-diff] ( | ... | ) [[--] ...] @@ -92,6 +93,9 @@ have produced. In other words, if a merge commit is the result of a non-conflicting `git merge`, the `remerge` mode will represent it with an empty diff. +--remerge-diff:: + Convenience option, equivalent to `--diff-merges=remerge`. + --[no-]notes[=]:: This flag is passed to the `git log` program (see linkgit:git-log[1]) that generates the patches. diff --git a/builtin/range-diff.c b/builtin/range-diff.c index 901de5d133..2452654347 100644 --- a/builtin/range-diff.c +++ b/builtin/range-diff.c @@ -39,6 +39,8 @@ int cmd_range_diff(int argc, PARSE_OPT_OPTARG), OPT_PASSTHRU_ARGV(0, "diff-merges", &diff_merges_arg, N_("style"), N_("passed to 'git log'"), 0), + OPT_PASSTHRU_ARGV(0, "remerge-diff", &diff_merges_arg, NULL, + N_("passed to 'git log'"), PARSE_OPT_NOARG), OPT_BOOL(0, "left-only", &left_only, N_("only emit output related to the first range")), OPT_BOOL(0, "right-only", &right_only, -- cgit v1.3