#include "column.h"
#include "sequencer.h"
#include "mailmap.h"
+#include "help.h"
+#include "commit-reach.h"
+#include "commit-graph.h"
static const char * const builtin_commit_usage[] = {
N_("git commit [<options>] [--] <pathspec>..."),
"Then \"git cherry-pick --continue\" will resume cherry-picking\n"
"the remaining commits.\n");
+static const char *color_status_slots[] = {
+ [WT_STATUS_HEADER] = "header",
+ [WT_STATUS_UPDATED] = "updated",
+ [WT_STATUS_CHANGED] = "changed",
+ [WT_STATUS_UNTRACKED] = "untracked",
+ [WT_STATUS_NOBRANCH] = "noBranch",
+ [WT_STATUS_UNMERGED] = "unmerged",
+ [WT_STATUS_LOCAL_BRANCH] = "localBranch",
+ [WT_STATUS_REMOTE_BRANCH] = "remoteBranch",
+ [WT_STATUS_ONBRANCH] = "branch",
+};
+
static const char *use_message_buffer;
static struct lock_file index_lock; /* real index */
static struct lock_file false_lock; /* used only for partial commits */
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()))
+ if (file_exists(git_path_merge_head(the_repository)))
whence = FROM_MERGE;
- else if (file_exists(git_path_cherry_pick_head())) {
+ else if (file_exists(git_path_cherry_pick_head(the_repository))) {
whence = FROM_CHERRY_PICK;
if (file_exists(git_path_seq_dir()))
sequencer_in_use = 1;
static void status_init_config(struct wt_status *s, config_fn_t fn)
{
wt_status_prepare(s);
+ init_diff_ui_defaults();
git_config(fn, s);
determine_whence(s);
- init_diff_ui_defaults();
s->hints = advice_status_hints; /* must come after git_config() */
}
if (with_tree) {
char *max_prefix = common_prefix(pattern);
- overlay_tree_on_index(&the_index, with_tree,
- max_prefix ? max_prefix : prefix);
+ overlay_tree_on_index(&the_index, with_tree, max_prefix);
free(max_prefix);
}
if (ce->ce_flags & CE_UPDATE)
continue;
- if (!ce_path_match(ce, pattern, m))
+ if (!ce_path_match(&the_index, ce, pattern, m))
continue;
item = string_list_insert(list, ce->name);
if (ce_skip_worktree(ce))
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)
if (have_option_m)
strbuf_addbuf(&sb, &message);
hook_arg1 = "message";
- } else if (!stat(git_path_merge_msg(), &statbuf)) {
+ } else if (!stat(git_path_merge_msg(the_repository), &statbuf)) {
/*
* prepend SQUASH_MSG here if it exists and a
* "merge --squash" was originally performed
*/
- if (!stat(git_path_squash_msg(), &statbuf)) {
- if (strbuf_read_file(&sb, git_path_squash_msg(), 0) < 0)
+ if (!stat(git_path_squash_msg(the_repository), &statbuf)) {
+ if (strbuf_read_file(&sb, git_path_squash_msg(the_repository), 0) < 0)
die_errno(_("could not read SQUASH_MSG"));
hook_arg1 = "squash";
} else
hook_arg1 = "merge";
- if (strbuf_read_file(&sb, git_path_merge_msg(), 0) < 0)
+ if (strbuf_read_file(&sb, git_path_merge_msg(the_repository), 0) < 0)
die_errno(_("could not read MERGE_MSG"));
- } else if (!stat(git_path_squash_msg(), &statbuf)) {
- if (strbuf_read_file(&sb, git_path_squash_msg(), 0) < 0)
+ } else if (!stat(git_path_squash_msg(the_repository), &statbuf)) {
+ if (strbuf_read_file(&sb, git_path_squash_msg(the_repository), 0) < 0)
die_errno(_("could not read SQUASH_MSG"));
hook_arg1 = "squash";
} else if (template_file) {
" %s\n"
"and try again.\n"),
whence == FROM_MERGE ?
- git_path_merge_head() :
- git_path_cherry_pick_head());
+ git_path_merge_head(the_repository) :
+ git_path_cherry_pick_head(the_repository));
}
fprintf(s->fp, "\n");
s->use_color = 0;
commitable = run_status(s->fp, index_file, prefix, 1, s);
s->use_color = saved_color_setting;
+ string_list_clear(&s->change, 1);
} else {
struct object_id oid;
const char *parent = "HEAD";
return commitable ? 0 : 1;
}
+define_list_config_array_extra(color_status_slots, {"added"});
+
static int parse_status_slot(const char *slot)
{
- if (!strcasecmp(slot, "header"))
- return WT_STATUS_HEADER;
- if (!strcasecmp(slot, "branch"))
- return WT_STATUS_ONBRANCH;
- if (!strcasecmp(slot, "updated") || !strcasecmp(slot, "added"))
+ if (!strcasecmp(slot, "added"))
return WT_STATUS_UPDATED;
- if (!strcasecmp(slot, "changed"))
- return WT_STATUS_CHANGED;
- if (!strcasecmp(slot, "untracked"))
- return WT_STATUS_UNTRACKED;
- if (!strcasecmp(slot, "nobranch"))
- return WT_STATUS_NOBRANCH;
- if (!strcasecmp(slot, "unmerged"))
- return WT_STATUS_UNMERGED;
- if (!strcasecmp(slot, "localBranch"))
- return WT_STATUS_LOCAL_BRANCH;
- if (!strcasecmp(slot, "remoteBranch"))
- return WT_STATUS_REMOTE_BRANCH;
- return -1;
+
+ return LOOKUP_CONFIG(color_status_slots, slot);
}
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;
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);
if (!reflog_msg)
reflog_msg = "commit (merge)";
pptr = commit_list_append(current_head, pptr);
- fp = xfopen(git_path_merge_head(), "r");
+ fp = xfopen(git_path_merge_head(the_repository), "r");
while (strbuf_getline_lf(&m, fp) != EOF) {
struct commit *parent;
}
fclose(fp);
strbuf_release(&m);
- if (!stat(git_path_merge_mode(), &statbuf)) {
- if (strbuf_read_file(&sb, git_path_merge_mode(), 0) < 0)
+ if (!stat(git_path_merge_mode(the_repository), &statbuf)) {
+ if (strbuf_read_file(&sb, git_path_merge_mode(the_repository), 0) < 0)
die_errno(_("could not read MERGE_MODE"));
if (!strcmp(sb.buf, "no-ff"))
allow_fast_forward = 0;
die("%s", err.buf);
}
- unlink(git_path_cherry_pick_head());
- unlink(git_path_revert_head());
- unlink(git_path_merge_head());
- unlink(git_path_merge_msg());
- unlink(git_path_merge_mode());
- unlink(git_path_squash_msg());
+ unlink(git_path_cherry_pick_head(the_repository));
+ unlink(git_path_revert_head(the_repository));
+ unlink(git_path_merge_head(the_repository));
+ unlink(git_path_merge_msg(the_repository));
+ unlink(git_path_merge_mode(the_repository));
+ unlink(git_path_squash_msg(the_repository));
if (commit_index_files())
- die (_("Repository has been updated, but unable to write\n"
- "new_index file. Check that disk is not full and quota is\n"
- "not exceeded, and then \"git reset HEAD\" to recover."));
+ die(_("repository has been updated, but unable to write\n"
+ "new_index file. Check that disk is not full and quota is\n"
+ "not exceeded, and then \"git reset HEAD\" to recover."));
+
+ if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0))
+ write_commit_graph_reachable(get_object_directory(), 0, 0);
rerere(0);
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);