提交 5da4847d 编写于 作者: J Junio C Hamano

Merge branch 'bp/status-rename-config'

"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
......@@ -3179,6 +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.
......
......@@ -135,6 +135,16 @@ ignored, then the directory is not shown, but all contents are shown.
Display or do not display detailed ahead/behind counts for the
branch relative to its upstream branch. Defaults to true.
--renames::
--no-renames::
Turn on/off rename detection regardless of user configuration.
See also linkgit:git-diff[1] `--no-renames`.
--find-renames[=<n>]::
Turn on rename detection, optionally setting the similarity
threshold.
See also linkgit:git-diff[1] `--find-renames`.
<pathspec>...::
See the 'pathspec' entry in linkgit:gitglossary[7].
......
......@@ -143,6 +143,16 @@ static int opt_parse_m(const struct option *opt, const char *arg, int unset)
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()))
......@@ -1259,11 +1269,31 @@ static int git_status_config(const char *k, const char *v, void *cb)
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;
......@@ -1297,6 +1327,10 @@ int cmd_status(int argc, const char **argv, const char *prefix)
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(),
};
......@@ -1336,6 +1370,14 @@ int cmd_status(int argc, const char **argv, const char *prefix)
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);
......
#!/bin/sh
test_description='git status rename detection options'
. ./test-lib.sh
test_expect_success 'setup' '
echo 1 >original &&
git add . &&
git commit -m"Adding original file." &&
mv original renamed &&
echo 2 >> renamed &&
git add . &&
cat >.gitignore <<-\EOF
.gitignore
expect*
actual*
EOF
'
test_expect_success 'status no-options' '
git status >actual &&
test_i18ngrep "renamed:" actual
'
test_expect_success 'status --no-renames' '
git status --no-renames >actual &&
test_i18ngrep "deleted:" actual &&
test_i18ngrep "new file:" actual
'
test_expect_success 'status.renames inherits from diff.renames false' '
git -c diff.renames=false status >actual &&
test_i18ngrep "deleted:" actual &&
test_i18ngrep "new file:" actual
'
test_expect_success 'status.renames inherits from diff.renames true' '
git -c diff.renames=true status >actual &&
test_i18ngrep "renamed:" actual
'
test_expect_success 'status.renames overrides diff.renames false' '
git -c diff.renames=true -c status.renames=false status >actual &&
test_i18ngrep "deleted:" actual &&
test_i18ngrep "new file:" actual
'
test_expect_success 'status.renames overrides from diff.renames true' '
git -c diff.renames=false -c status.renames=true status >actual &&
test_i18ngrep "renamed:" actual
'
test_expect_success 'status status.renames=false' '
git -c status.renames=false status >actual &&
test_i18ngrep "deleted:" actual &&
test_i18ngrep "new file:" actual
'
test_expect_success 'status status.renames=true' '
git -c status.renames=true status >actual &&
test_i18ngrep "renamed:" actual
'
test_expect_success 'commit honors status.renames=false' '
git -c status.renames=false commit --dry-run >actual &&
test_i18ngrep "deleted:" actual &&
test_i18ngrep "new file:" actual
'
test_expect_success 'commit honors status.renames=true' '
git -c status.renames=true commit --dry-run >actual &&
test_i18ngrep "renamed:" actual
'
test_expect_success 'status config overridden' '
git -c status.renames=true status --no-renames >actual &&
test_i18ngrep "deleted:" actual &&
test_i18ngrep "new file:" actual
'
test_expect_success 'status score=100%' '
git status -M=100% >actual &&
test_i18ngrep "deleted:" actual &&
test_i18ngrep "new file:" actual &&
git status --find-rename=100% >actual &&
test_i18ngrep "deleted:" actual &&
test_i18ngrep "new file:" actual
'
test_expect_success 'status score=01%' '
git status -M=01% >actual &&
test_i18ngrep "renamed:" actual &&
git status --find-rename=01% >actual &&
test_i18ngrep "renamed:" actual
'
test_expect_success 'copies not overridden by find-rename' '
cp renamed copy &&
git add copy &&
git -c status.renames=copies status -M=01% >actual &&
test_i18ngrep "copied:" actual &&
test_i18ngrep "renamed:" actual &&
git -c status.renames=copies status --find-rename=01% >actual &&
test_i18ngrep "copied:" actual &&
test_i18ngrep "renamed:" actual
'
test_done
......@@ -138,6 +138,9 @@ void wt_status_prepare(struct wt_status *s)
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)
......@@ -592,6 +595,9 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)
}
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 @@ static void wt_status_collect_changes_index(struct wt_status *s)
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 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
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;
/*
......
......@@ -89,7 +89,9 @@ struct wt_status {
int show_stash;
int hints;
enum ahead_behind_flags ahead_behind_flags;
int detect_rename;
int rename_score;
int rename_limit;
enum wt_status_format status_format;
unsigned char sha1_commit[GIT_MAX_RAWSZ]; /* when not Initial */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册