Merge branch 'bp/status-rename-config'
authorJunio C Hamano <gitster@pobox.com>
Wed, 30 May 2018 05:04:07 +0000 (14:04 +0900)
committerJunio C Hamano <gitster@pobox.com>
Wed, 30 May 2018 05:04:07 +0000 (14:04 +0900)
"git status" learned to honor a new status.renames configuration to
skip rename detection, which could be useful for those who want to
do so without disabling the default rename detection done by the
"git diff" command.

* bp/status-rename-config:
add status config and command line options for rename detection

1  2 
Documentation/config.txt
builtin/commit.c
wt-status.c
diff --combined Documentation/config.txt
index 84e2891aed156e367a38692ee34998c8e06261d3,88884f1eadef1b9b2bec40d020fc998b66e75a21..460c14f0476f0c1c2c85fbbb37b00875c38f3548
@@@ -530,12 -530,6 +530,12 @@@ core.autocrlf:
        This variable can be set to 'input',
        in which case no output conversion is performed.
  
 +core.checkRoundtripEncoding::
 +      A comma and/or whitespace separated list of encodings that Git
 +      performs UTF-8 round trip checks on if they are used in an
 +      `working-tree-encoding` attribute (see linkgit:gitattributes[5]).
 +      The default value is `SHIFT-JIS`.
 +
  core.symlinks::
        If false, symbolic links are checked out as small plain files that
        contain the link text. linkgit:git-update-index[1] and
@@@ -904,10 -898,6 +904,10 @@@ core.notesRef:
  This setting defaults to "refs/notes/commits", and it can be overridden by
  the `GIT_NOTES_REF` environment variable.  See linkgit:git-notes[1].
  
 +core.commitGraph::
 +      Enable git commit graph feature. Allows reading from the
 +      commit-graph file.
 +
  core.sparseCheckout::
        Enable "sparse checkout" feature. See section "Sparse checkout" in
        linkgit:git-read-tree[1] for more information.
@@@ -1068,10 -1058,6 +1068,10 @@@ branch.<name>.rebase:
        "git pull" is run. See "pull.rebase" for doing this in a non
        branch-specific manner.
  +
 +When `merges`, pass the `--rebase-merges` option to 'git rebase'
 +so that the local merge commits are included in the rebase (see
 +linkgit:git-rebase[1] for details).
 ++
  When preserve, also pass `--preserve-merges` along to 'git rebase'
  so that locally committed merge commits will not be flattened
  by running 'git pull'.
@@@ -1102,16 -1088,6 +1102,16 @@@ clean.requireForce:
        A boolean to make git-clean do nothing unless given -f,
        -i or -n.   Defaults to true.
  
 +color.advice::
 +      A boolean to enable/disable color in hints (e.g. when a push
 +      failed, see `advice.*` for a list).  May be set to `always`,
 +      `false` (or `never`) or `auto` (or `true`), in which case colors
 +      are used only when the error output goes to a terminal. If
 +      unset, then the value of `color.ui` is used (`auto` by default).
 +
 +color.advice.hint::
 +      Use customized color for hints.
 +
  color.branch::
        A boolean to enable/disable color in the output of
        linkgit:git-branch[1]. May be set to `always`,
@@@ -1214,15 -1190,6 +1214,15 @@@ color.pager:
        A boolean to enable/disable colored output when the pager is in
        use (default is true).
  
 +color.push::
 +      A boolean to enable/disable color in push errors. May be set to
 +      `always`, `false` (or `never`) or `auto` (or `true`), in which
 +      case colors are used only when the error output goes to a terminal.
 +      If unset, then the value of `color.ui` is used (`auto` by default).
 +
 +color.push.error::
 +      Use customized color for push errors.
 +
  color.showBranch::
        A boolean to enable/disable color in the output of
        linkgit:git-show-branch[1]. May be set to `always`,
@@@ -1251,15 -1218,6 +1251,15 @@@ color.status.<slot>:
        status short-format), or
        `unmerged` (files which have unmerged changes).
  
 +color.transport::
 +      A boolean to enable/disable color when pushes are rejected. May be
 +      set to `always`, `false` (or `never`) or `auto` (or `true`), in which
 +      case colors are used only when the error output goes to a terminal.
 +      If unset, then the value of `color.ui` is used (`auto` by default).
 +
 +color.transport.rejected::
 +      Use customized color when a push was rejected.
 +
  color.ui::
        This variable determines the default value for variables such
        as `color.diff` and `color.grep` that control the use of color
@@@ -1600,18 -1558,6 +1600,18 @@@ gc.autoDetach:
        Make `git gc --auto` return immediately and run in background
        if the system supports it. Default is true.
  
 +gc.bigPackThreshold::
 +      If non-zero, all packs larger than this limit are kept when
 +      `git gc` is run. This is very similar to `--keep-base-pack`
 +      except that all packs that meet the threshold are kept, not
 +      just the base pack. Defaults to zero. Common unit suffixes of
 +      'k', 'm', or 'g' are supported.
 ++
 +Note that if the number of kept packs is more than gc.autoPackLimit,
 +this configuration variable is ignored, all packs except the base pack
 +will be repacked. After this the number of packs should go below
 +gc.autoPackLimit and gc.bigPackThreshold should be respected again.
 +
  gc.logExpiry::
        If the file gc.log exists, then `git gc --auto` won't run
        unless that file is more than 'gc.logExpiry' old.  Default is
@@@ -2476,7 -2422,6 +2476,7 @@@ pack.window:
  pack.depth::
        The maximum delta depth used by linkgit:git-pack-objects[1] when no
        maximum depth is given on the command line. Defaults to 50.
 +      Maximum value is 4095.
  
  pack.windowMemory::
        The maximum size of memory that is consumed by each thread
@@@ -2513,8 -2458,7 +2513,8 @@@ pack.deltaCacheLimit:
        The maximum size of a delta, that is cached in
        linkgit:git-pack-objects[1]. This cache is used to speed up the
        writing object phase by not having to recompute the final delta
 -      result once the best match for all objects is found. Defaults to 1000.
 +      result once the best match for all objects is found.
 +      Defaults to 1000. Maximum value is 65535.
  
  pack.threads::
        Specifies the number of threads to spawn when searching for best
@@@ -2673,10 -2617,6 +2673,10 @@@ pull.rebase:
        pull" is run. See "branch.<name>.rebase" for setting this on a
        per-branch basis.
  +
 +When `merges`, pass the `--rebase-merges` option to 'git rebase'
 +so that the local merge commits are included in the rebase (see
 +linkgit:git-rebase[1] for details).
 ++
  When preserve, also pass `--preserve-merges` along to 'git rebase'
  so that locally committed merge commits will not be flattened
  by running 'git pull'.
@@@ -3179,6 -3119,18 +3179,18 @@@ status.displayCommentPrefix:
        behavior of linkgit:git-status[1] in Git 1.8.4 and previous.
        Defaults to false.
  
+ status.renameLimit::
+       The number of files to consider when performing rename detection
+       in linkgit:git-status[1] and linkgit:git-commit[1]. Defaults to
+       the value of diff.renameLimit.
+ status.renames::
+       Whether and how Git detects renames in linkgit:git-status[1] and
+       linkgit:git-commit[1] .  If set to "false", rename detection is
+       disabled. If set to "true", basic rename detection is enabled.
+       If set to "copies" or "copy", Git will detect copies, as well.
+       Defaults to the value of diff.renames.
  status.showStash::
        If set to true, linkgit:git-status[1] will display the number of
        entries currently stashed away.
diff --combined builtin/commit.c
index 5205d3a4085e99dcc296429106fcc9145a69233d,b50e33ef483a612f8b4d83ccc152a7fe279c20b7..a842fea666a33bb2191d10cf452a255754bb44e6
@@@ -143,6 -143,16 +143,16 @@@ static int opt_parse_m(const struct opt
        return 0;
  }
  
+ static int opt_parse_rename_score(const struct option *opt, const char *arg, int unset)
+ {
+       const char **value = opt->value;
+       if (arg != NULL && *arg == '=')
+               arg = arg + 1;
+       *value = arg;
+       return 0;
+ }
  static void determine_whence(struct wt_status *s)
  {
        if (file_exists(git_path_merge_head()))
@@@ -495,7 -505,7 +505,7 @@@ static int is_a_merge(const struct comm
  static void assert_split_ident(struct ident_split *id, const struct strbuf *buf)
  {
        if (split_ident_line(id, buf->buf, buf->len) || !id->date_begin)
 -              die("BUG: unable to parse our own ident: %s", buf->buf);
 +              BUG("unable to parse our own ident: %s", buf->buf);
  }
  
  static void export_one(const char *var, const char *s, const char *e, int hack)
@@@ -1259,11 -1269,31 +1269,31 @@@ static int git_status_config(const cha
                        return error(_("Invalid untracked files mode '%s'"), v);
                return 0;
        }
+       if (!strcmp(k, "diff.renamelimit")) {
+               if (s->rename_limit == -1)
+                       s->rename_limit = git_config_int(k, v);
+               return 0;
+       }
+       if (!strcmp(k, "status.renamelimit")) {
+               s->rename_limit = git_config_int(k, v);
+               return 0;
+       }
+       if (!strcmp(k, "diff.renames")) {
+               if (s->detect_rename == -1)
+                       s->detect_rename = git_config_rename(k, v);
+               return 0;
+       }
+       if (!strcmp(k, "status.renames")) {
+               s->detect_rename = git_config_rename(k, v);
+               return 0;
+       }
        return git_diff_ui_config(k, v, NULL);
  }
  
  int cmd_status(int argc, const char **argv, const char *prefix)
  {
+       static int no_renames = -1;
+       static const char *rename_score_arg = (const char *)-1;
        static struct wt_status s;
        int fd;
        struct object_id oid;
                  N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"),
                  PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
                OPT_COLUMN(0, "column", &s.colopts, N_("list untracked files in columns")),
+               OPT_BOOL(0, "no-renames", &no_renames, N_("do not detect renames")),
+               { OPTION_CALLBACK, 'M', "find-renames", &rename_score_arg,
+                 N_("n"), N_("detect renames, optionally set similarity index"),
+                 PARSE_OPT_OPTARG, opt_parse_rename_score },
                OPT_END(),
        };
  
        s.ignore_submodule_arg = ignore_submodule_arg;
        s.status_format = status_format;
        s.verbose = verbose;
+       if (no_renames != -1)
+               s.detect_rename = !no_renames;
+       if ((intptr_t)rename_score_arg != -1) {
+               if (s.detect_rename < DIFF_DETECT_RENAME)
+                       s.detect_rename = DIFF_DETECT_RENAME;
+               if (rename_score_arg)
+                       s.rename_score = parse_rename_score(&rename_score_arg);
+       }
  
        wt_status_collect(&s);
  
diff --combined wt-status.c
index 0cf1bed995581c3b15100414f044c2acf7d04c15,172f07cbb09395826a2df7b0d8934081e4be88d7..11f64deefc1e909d06a4b71b336ff3878d1da2bd
@@@ -138,6 -138,9 +138,9 @@@ void wt_status_prepare(struct wt_statu
        s->show_stash = 0;
        s->ahead_behind_flags = AHEAD_BEHIND_UNSPECIFIED;
        s->display_comment_prefix = 0;
+       s->detect_rename = -1;
+       s->rename_score = -1;
+       s->rename_limit = -1;
  }
  
  static void wt_longstatus_print_unmerged_header(struct wt_status *s)
@@@ -264,7 -267,7 +267,7 @@@ static const char *wt_status_unmerged_s
        case 7:
                return _("both modified:");
        default:
 -              die("BUG: unhandled unmerged status %x", stagemask);
 +              BUG("unhandled unmerged status %x", stagemask);
        }
  }
  
@@@ -377,7 -380,7 +380,7 @@@ static void wt_longstatus_print_change_
                status = d->worktree_status;
                break;
        default:
 -              die("BUG: unhandled change_type %d in wt_longstatus_print_change_data",
 +              BUG("unhandled change_type %d in wt_longstatus_print_change_data",
                    change_type);
        }
  
        status_printf(s, color(WT_STATUS_HEADER, s), "\t");
        what = wt_status_diff_status_string(status);
        if (!what)
 -              die("BUG: unhandled diff status %c", status);
 +              BUG("unhandled diff status %c", status);
        len = label_width - utf8_strwidth(what);
        assert(len >= 0);
        if (one_name != two_name)
@@@ -470,7 -473,7 +473,7 @@@ static void wt_status_collect_changed_c
                case DIFF_STATUS_COPIED:
                case DIFF_STATUS_RENAMED:
                        if (d->rename_status)
 -                              die("BUG: multiple renames on the same target? how?");
 +                              BUG("multiple renames on the same target? how?");
                        d->rename_source = xstrdup(p->one->path);
                        d->rename_score = p->score * 100 / MAX_SCORE;
                        d->rename_status = p->status;
                        break;
  
                default:
 -                      die("BUG: unhandled diff-files status '%c'", p->status);
 +                      BUG("unhandled diff-files status '%c'", p->status);
                        break;
                }
  
@@@ -547,7 -550,7 +550,7 @@@ static void wt_status_collect_updated_c
                case DIFF_STATUS_COPIED:
                case DIFF_STATUS_RENAMED:
                        if (d->rename_status)
 -                              die("BUG: multiple renames on the same target? how?");
 +                              BUG("multiple renames on the same target? how?");
                        d->rename_source = xstrdup(p->one->path);
                        d->rename_score = p->score * 100 / MAX_SCORE;
                        d->rename_status = p->status;
                        break;
  
                default:
 -                      die("BUG: unhandled diff-index status '%c'", p->status);
 +                      BUG("unhandled diff-index status '%c'", p->status);
                        break;
                }
        }
@@@ -592,6 -595,9 +595,9 @@@ static void wt_status_collect_changes_w
        }
        rev.diffopt.format_callback = wt_status_collect_changed_cb;
        rev.diffopt.format_callback_data = s;
+       rev.diffopt.detect_rename = s->detect_rename >= 0 ? s->detect_rename : rev.diffopt.detect_rename;
+       rev.diffopt.rename_limit = s->rename_limit >= 0 ? s->rename_limit : rev.diffopt.rename_limit;
+       rev.diffopt.rename_score = s->rename_score >= 0 ? s->rename_score : rev.diffopt.rename_score;
        copy_pathspec(&rev.prune_data, &s->pathspec);
        run_diff_files(&rev, 0);
  }
@@@ -625,6 -631,9 +631,9 @@@ static void wt_status_collect_changes_i
        rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
        rev.diffopt.format_callback = wt_status_collect_updated_cb;
        rev.diffopt.format_callback_data = s;
+       rev.diffopt.detect_rename = s->detect_rename >= 0 ? s->detect_rename : rev.diffopt.detect_rename;
+       rev.diffopt.rename_limit = s->rename_limit >= 0 ? s->rename_limit : rev.diffopt.rename_limit;
+       rev.diffopt.rename_score = s->rename_score >= 0 ? s->rename_score : rev.diffopt.rename_score;
        copy_pathspec(&rev.prune_data, &s->pathspec);
        run_diff_index(&rev, 1);
  }
@@@ -982,6 -991,9 +991,9 @@@ static void wt_longstatus_print_verbose
        setup_revisions(0, NULL, &rev, &opt);
  
        rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
+       rev.diffopt.detect_rename = s->detect_rename >= 0 ? s->detect_rename : rev.diffopt.detect_rename;
+       rev.diffopt.rename_limit = s->rename_limit >= 0 ? s->rename_limit : rev.diffopt.rename_limit;
+       rev.diffopt.rename_score = s->rename_score >= 0 ? s->rename_score : rev.diffopt.rename_score;
        rev.diffopt.file = s->fp;
        rev.diffopt.close_file = 0;
        /*
@@@ -2154,7 -2166,7 +2166,7 @@@ static void wt_porcelain_v2_print_unmer
        case 6: key = "AA"; break; /* both added */
        case 7: key = "UU"; break; /* both modified */
        default:
 -              die("BUG: unhandled unmerged status %x", d->stagemask);
 +              BUG("unhandled unmerged status %x", d->stagemask);
        }
  
        /*
                sum |= (1 << (stage - 1));
        }
        if (sum != d->stagemask)
 -              die("BUG: observed stagemask 0x%x != expected stagemask 0x%x", sum, d->stagemask);
 +              BUG("observed stagemask 0x%x != expected stagemask 0x%x", sum, d->stagemask);
  
        if (s->null_termination)
                path_index = it->string;
@@@ -2285,7 -2297,7 +2297,7 @@@ void wt_status_print(struct wt_status *
                wt_porcelain_v2_print(s);
                break;
        case STATUS_FORMAT_UNSPECIFIED:
 -              die("BUG: finalize_deferred_config() should have been called");
 +              BUG("finalize_deferred_config() should have been called");
                break;
        case STATUS_FORMAT_NONE:
        case STATUS_FORMAT_LONG: