]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'so/log-diff-merges-opt'
authorJunio C Hamano <gitster@pobox.com>
Tue, 18 Aug 2020 00:02:49 +0000 (17:02 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 18 Aug 2020 00:02:50 +0000 (17:02 -0700)
Earlier, to countermand the implicit "-m" option when the
"--first-parent" option is used with "git log", we added the
"--[no-]diff-merges" option in the jk/log-fp-implies-m topic.  To
leave the door open to allow the "--diff-merges" option to take
values that instructs how patches for merge commits should be
computed (e.g. "cc"? "-p against first parent?"), redefine
"--diff-merges" to take non-optional value, and implement "off"
that means the same thing as "--no-diff-merges".

* so/log-diff-merges-opt:
  t/t4013: add test for --diff-merges=off
  doc/git-log: describe --diff-merges=off
  revision: change "--diff-merges" option to require parameter

1  2 
Documentation/git-log.txt
revision.c
t/t4013-diff-various.sh
t/t4013/diff.log_--diff-merges=off_-p_--first-parent_master
t/t4013/diff.log_--first-parent_--diff-merges=off_-p_master

index 27fa0ea26deed036981108d1bf1bb8a02b6a9f97,f3727c78645346d1e78d2aafba8691f20af5f629..2b8ac5ff882ae84d52d08458c2439f314d2a0370
@@@ -15,12 -15,9 +15,12 @@@ DESCRIPTIO
  -----------
  Shows the commit logs.
  
 -The command takes options applicable to the `git rev-list`
 +:git-log: 1
 +include::rev-list-description.txt[]
 +
 +The command takes options applicable to the linkgit:git-rev-list[1]
  command to control what is shown and how, and options applicable to
 -the `git diff-*` commands to control how the changes
 +the linkgit:git-diff[1] command to control how the changes
  each commit introduces are shown.
  
  
@@@ -148,7 -145,6 +148,6 @@@ combined-diff option or with `--no-diff
        rename or copy detection have been requested).
  
  -m::
- --diff-merges::
        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
        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[]
  
diff --combined revision.c
index 97ae8f16a8865642868a9c8346223c30d7811cb9,417659cfcb100be4a9e0646ceabacd5ae1d2e57d..96630e31867dd6987b8d5447bcaedb777303679d
@@@ -23,7 -23,7 +23,7 @@@
  #include "bisect.h"
  #include "packfile.h"
  #include "worktree.h"
 -#include "argv-array.h"
 +#include "strvec.h"
  #include "commit-reach.h"
  #include "commit-graph.h"
  #include "prio-queue.h"
@@@ -633,6 -633,7 +633,6 @@@ static unsigned int count_bloom_filter_
  static unsigned int count_bloom_filter_definitely_not;
  static unsigned int count_bloom_filter_false_positive;
  static unsigned int count_bloom_filter_not_present;
 -static unsigned int count_bloom_filter_length_zero;
  
  static void trace2_bloom_filter_statistics_atexit(void)
  {
  
        jw_object_begin(&jw, 0);
        jw_object_intmax(&jw, "filter_not_present", count_bloom_filter_not_present);
 -      jw_object_intmax(&jw, "zero_length_filter", count_bloom_filter_length_zero);
        jw_object_intmax(&jw, "maybe", count_bloom_filter_maybe);
        jw_object_intmax(&jw, "definitely_not", count_bloom_filter_definitely_not);
        jw_object_intmax(&jw, "false_positive", count_bloom_filter_false_positive);
@@@ -668,9 -670,9 +668,9 @@@ static void prepare_to_use_bloom_filter
  {
        struct pathspec_item *pi;
        char *path_alloc = NULL;
 -      const char *path;
 -      int last_index;
 -      int len;
 +      const char *path, *p;
 +      size_t len;
 +      int path_component_nr = 1;
  
        if (!revs->commits)
                return;
                return;
  
        pi = &revs->pruning.pathspec.items[0];
 -      last_index = pi->len - 1;
  
        /* remove single trailing slash from path, if needed */
 -      if (pi->match[last_index] == '/') {
 -          path_alloc = xstrdup(pi->match);
 -          path_alloc[last_index] = '\0';
 -          path = path_alloc;
 +      if (pi->len > 0 && pi->match[pi->len - 1] == '/') {
 +              path_alloc = xmemdupz(pi->match, pi->len - 1);
 +              path = path_alloc;
        } else
 -          path = pi->match;
 +              path = pi->match;
  
        len = strlen(path);
 +      if (!len) {
 +              revs->bloom_filter_settings = NULL;
 +              free(path_alloc);
 +              return;
 +      }
 +
 +      p = path;
 +      while (*p) {
 +              /*
 +               * At this point, the path is normalized to use Unix-style
 +               * path separators. This is required due to how the
 +               * changed-path Bloom filters store the paths.
 +               */
 +              if (*p == '/')
 +                      path_component_nr++;
 +              p++;
 +      }
 +
 +      revs->bloom_keys_nr = path_component_nr;
 +      ALLOC_ARRAY(revs->bloom_keys, revs->bloom_keys_nr);
  
 -      revs->bloom_key = xmalloc(sizeof(struct bloom_key));
 -      fill_bloom_key(path, len, revs->bloom_key, revs->bloom_filter_settings);
 +      fill_bloom_key(path, len, &revs->bloom_keys[0],
 +                     revs->bloom_filter_settings);
 +      path_component_nr = 1;
 +
 +      p = path + len - 1;
 +      while (p > path) {
 +              if (*p == '/')
 +                      fill_bloom_key(path, p - path,
 +                                     &revs->bloom_keys[path_component_nr++],
 +                                     revs->bloom_filter_settings);
 +              p--;
 +      }
  
        if (trace2_is_enabled() && !bloom_filter_atexit_registered) {
                atexit(trace2_bloom_filter_statistics_atexit);
@@@ -746,7 -720,7 +746,7 @@@ static int check_maybe_different_in_blo
                                                 struct commit *commit)
  {
        struct bloom_filter *filter;
 -      int result;
 +      int result = 1, j;
  
        if (!revs->repo->objects->commit_graph)
                return -1;
                return -1;
        }
  
 -      if (!filter->len) {
 -              count_bloom_filter_length_zero++;
 -              return -1;
 +      for (j = 0; result && j < revs->bloom_keys_nr; j++) {
 +              result = bloom_filter_contains(filter,
 +                                             &revs->bloom_keys[j],
 +                                             revs->bloom_filter_settings);
        }
  
 -      result = bloom_filter_contains(filter,
 -                                     revs->bloom_key,
 -                                     revs->bloom_filter_settings);
 -
        if (result)
                count_bloom_filter_maybe++;
        else
@@@ -805,7 -782,7 +805,7 @@@ static int rev_compare_tree(struct rev_
                        return REV_TREE_SAME;
        }
  
 -      if (revs->bloom_key && !nth_parent) {
 +      if (revs->bloom_keys_nr && !nth_parent) {
                bloom_ret = check_maybe_different_in_bloom_filter(revs, commit);
  
                if (bloom_ret == 0)
  
        tree_difference = REV_TREE_SAME;
        revs->pruning.flags.has_changes = 0;
 -      if (diff_tree_oid(&t1->object.oid, &t2->object.oid, "",
 -                         &revs->pruning) < 0)
 -              return REV_TREE_DIFFERENT;
 +      diff_tree_oid(&t1->object.oid, &t2->object.oid, "", &revs->pruning);
  
        if (!nth_parent)
                if (bloom_ret == 1 && tree_difference == REV_TREE_SAME)
  
  static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit)
  {
 -      int retval;
        struct tree *t1 = get_commit_tree(commit);
  
        if (!t1)
  
        tree_difference = REV_TREE_SAME;
        revs->pruning.flags.has_changes = 0;
 -      retval = diff_tree_oid(NULL, &t1->object.oid, "", &revs->pruning);
 +      diff_tree_oid(NULL, &t1->object.oid, "", &revs->pruning);
  
 -      return retval >= 0 && (tree_difference == REV_TREE_SAME);
 +      return tree_difference == REV_TREE_SAME;
  }
  
  struct treesame_state {
@@@ -2093,14 -2073,14 +2093,14 @@@ int handle_revision_arg(const char *arg
  }
  
  static void read_pathspec_from_stdin(struct strbuf *sb,
 -                                   struct argv_array *prune)
 +                                   struct strvec *prune)
  {
        while (strbuf_getline(sb, stdin) != EOF)
 -              argv_array_push(prune, sb->buf);
 +              strvec_push(prune, sb->buf);
  }
  
  static void read_revisions_from_stdin(struct rev_info *revs,
 -                                    struct argv_array *prune)
 +                                    struct strvec *prune)
  {
        struct strbuf sb;
        int seen_dashdash = 0;
@@@ -2335,7 -2315,7 +2335,7 @@@ static int handle_revision_opt(struct r
        } else if (!strcmp(arg, "--unpacked")) {
                revs->unpacked = 1;
        } else if (starts_with(arg, "--unpacked=")) {
 -              die("--unpacked=<packfile> no longer supported.");
 +              die(_("--unpacked=<packfile> no longer supported"));
        } else if (!strcmp(arg, "-r")) {
                revs->diff = 1;
                revs->diffopt.flags.recursive = 1;
                revs->diff = 1;
                revs->diffopt.flags.recursive = 1;
                revs->diffopt.flags.tree_in_recursive = 1;
-       } else if (!strcmp(arg, "-m") || !strcmp(arg, "--diff-merges")) {
+       } else if (!strcmp(arg, "-m")) {
                revs->ignore_merges = 0;
+       } 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);
+               }
+               return argcount;
        } else if (!strcmp(arg, "--no-diff-merges")) {
                revs->ignore_merges = 1;
        } else if (!strcmp(arg, "-c")) {
@@@ -2697,7 -2684,7 +2704,7 @@@ static void NORETURN diagnose_missing_d
  int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct setup_revision_opt *opt)
  {
        int i, flags, left, seen_dashdash, got_rev_arg = 0, revarg_opt;
 -      struct argv_array prune_data = ARGV_ARRAY_INIT;
 +      struct strvec prune_data = STRVEC_INIT;
        const char *submodule = NULL;
        int seen_end_of_options = 0;
  
                        argv[i] = NULL;
                        argc = i;
                        if (argv[i + 1])
 -                              argv_array_pushv(&prune_data, argv + i + 1);
 +                              strvec_pushv(&prune_data, argv + i + 1);
                        seen_dashdash = 1;
                        break;
                }
                        for (j = i; j < argc; j++)
                                verify_filename(revs->prefix, argv[j], j == i);
  
 -                      argv_array_pushv(&prune_data, argv + i);
 +                      strvec_pushv(&prune_data, argv + i);
                        break;
                }
                else
                        got_rev_arg = 1;
        }
  
 -      if (prune_data.argc) {
 +      if (prune_data.nr) {
                /*
                 * If we need to introduce the magic "a lone ':' means no
                 * pathspec whatsoever", here is the place to do so.
                 * }
                 */
                parse_pathspec(&revs->prune_data, 0, 0,
 -                             revs->prefix, prune_data.argv);
 +                             revs->prefix, prune_data.v);
        }
 -      argv_array_clear(&prune_data);
 +      strvec_clear(&prune_data);
  
        if (revs->def == NULL)
                revs->def = opt ? opt->def : NULL;
        if (!revs->reflog_info && revs->grep_filter.use_reflog_filter)
                die("cannot use --grep-reflog without --walk-reflogs");
  
 -      if (revs->first_parent_only && revs->bisect)
 -              die(_("--first-parent is incompatible with --bisect"));
 -
        if (revs->line_level_traverse &&
            (revs->diffopt.output_format & ~(DIFF_FORMAT_PATCH | DIFF_FORMAT_NO_OUTPUT)))
                die(_("-L does not yet support diff formats besides -p and -s"));
diff --combined t/t4013-diff-various.sh
index 2a57f9033e8c8a50e5a29ad09b677b9dfa468019,7f7f1058cb86b6d4f00e71b7227b72f7e0926efb..5f97dd6d6565c45d6afe4262d82d6750d756ec3d
@@@ -117,12 -117,12 +117,12 @@@ test_expect_success setup 
  
  : <<\EOF
  ! [initial] Initial
 - * [master] Merge branch 'side' into master
 + * [master] Merge branch 'side'
    ! [rearrange] Rearranged lines in dir/sub
     ! [side] Side
  ----
    +  [rearrange] Rearranged lines in dir/sub
 - -   [master] Merge branch 'side' into master
 + -   [master] Merge branch 'side'
   * + [side] Side
   *   [master^] Third
   *   [master~2] Second
@@@ -298,6 -298,8 +298,8 @@@ log --root -c --patch-with-stat --summa
  # improved by Timo's patch
  log --root --cc --patch-with-stat --summary master
  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 -m -p --first-parent master
  log -m -p master
index 0000000000000000000000000000000000000000,c878f13c95194a2f49762c3744f97ba5a4c3c193..194e893c94f861080558e9cec4f0de6a021abd5f
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,78 +1,78 @@@
 -    Merge branch 'side' into master
+ $ git log --diff-merges=off -p --first-parent master
+ commit 59d314ad6f356dd08601a4cd5e530381da3e3c64
+ Merge: 9a6d494 c7a2ab9
+ Author: A U Thor <author@example.com>
+ Date:   Mon Jun 26 00:04:00 2006 +0000
++    Merge branch 'side'
+ commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0
+ Author: A U Thor <author@example.com>
+ 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 <author@example.com>
+ 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 <author@example.com>
+ Date:   Mon Jun 26 00:00:00 2006 +0000
+     Initial
+ $
index 0000000000000000000000000000000000000000,ad2e6d3be22cca4383d4adc1be04aa578d1eeee5..5d7461a167ee1662b4b133105e2e3c81e4f1b7d5
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,78 +1,78 @@@
 -    Merge branch 'side' into master
+ $ git log --first-parent --diff-merges=off -p master
+ commit 80e25ffa65bcdbe82ef654b4d06dbbde7945c37f
+ Merge: 9a6d494 c7a2ab9
+ Author: A U Thor <author@example.com>
+ Date:   Mon Jun 26 00:04:00 2006 +0000
++    Merge branch 'side'
+ commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0
+ Author: A U Thor <author@example.com>
+ 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 <author@example.com>
+ 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 <author@example.com>
+ Date:   Mon Jun 26 00:00:00 2006 +0000
+     Initial
+ $