wt-status.c: remove implicit dependency on the_index

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nguyễn Thái Ngọc Duy 2018-11-10 06:48:49 +01:00 committed by Junio C Hamano
parent 8858448bb4
commit 5b02ca38a3
6 changed files with 66 additions and 47 deletions

View file

@ -185,7 +185,7 @@ static void determine_whence(struct wt_status *s)
static void status_init_config(struct wt_status *s, config_fn_t fn) static void status_init_config(struct wt_status *s, config_fn_t fn)
{ {
wt_status_prepare(s); wt_status_prepare(the_repository, s);
init_diff_ui_defaults(); init_diff_ui_defaults();
git_config(fn, s); git_config(fn, s);
determine_whence(s); determine_whence(s);

View file

@ -888,7 +888,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
die(_("Updating an unborn branch with changes added to the index.")); die(_("Updating an unborn branch with changes added to the index."));
if (!autostash) if (!autostash)
require_clean_work_tree(N_("pull with rebase"), require_clean_work_tree(the_repository,
N_("pull with rebase"),
_("please commit or stash them."), 1, 0); _("please commit or stash them."), 1, 0);
if (get_rebase_fork_point(&rebase_fork_point, repo, *refspecs)) if (get_rebase_fork_point(&rebase_fork_point, repo, *refspecs))

View file

@ -983,7 +983,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
&lock_file); &lock_file);
rollback_lock_file(&lock_file); rollback_lock_file(&lock_file);
if (has_unstaged_changes(1)) { if (has_unstaged_changes(the_repository, 1)) {
puts(_("You must edit all merge conflicts and then\n" puts(_("You must edit all merge conflicts and then\n"
"mark them as resolved using git add")); "mark them as resolved using git add"));
exit(1); exit(1);
@ -1351,7 +1351,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
update_index_if_able(&the_index, &lock_file); update_index_if_able(&the_index, &lock_file);
rollback_lock_file(&lock_file); rollback_lock_file(&lock_file);
if (has_unstaged_changes(1) || has_uncommitted_changes(1)) { if (has_unstaged_changes(the_repository, 1) ||
has_uncommitted_changes(the_repository, 1)) {
const char *autostash = const char *autostash =
state_dir_path("autostash", &options); state_dir_path("autostash", &options);
struct child_process stash = CHILD_PROCESS_INIT; struct child_process stash = CHILD_PROCESS_INIT;
@ -1397,7 +1398,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
} }
} }
if (require_clean_work_tree("rebase", if (require_clean_work_tree(the_repository, "rebase",
_("Please commit or stash them."), 1, 1)) { _("Please commit or stash them."), 1, 1)) {
ret = 1; ret = 1;
goto cleanup; goto cleanup;

View file

@ -2773,7 +2773,7 @@ static int do_exec(const char *command_line)
if (discard_cache() < 0 || read_cache() < 0) if (discard_cache() < 0 || read_cache() < 0)
return error(_("could not read index")); return error(_("could not read index"));
dirty = require_clean_work_tree("rebase", NULL, 1, 1); dirty = require_clean_work_tree(the_repository, "rebase", NULL, 1, 1);
if (status) { if (status) {
warning(_("execution failed: %s\n%s" warning(_("execution failed: %s\n%s"
@ -3714,10 +3714,10 @@ static int commit_staged_changes(struct replay_opts *opts,
unsigned int flags = ALLOW_EMPTY | EDIT_MSG; unsigned int flags = ALLOW_EMPTY | EDIT_MSG;
unsigned int final_fixup = 0, is_clean; unsigned int final_fixup = 0, is_clean;
if (has_unstaged_changes(1)) if (has_unstaged_changes(the_repository, 1))
return error(_("cannot rebase: You have unstaged changes.")); return error(_("cannot rebase: You have unstaged changes."));
is_clean = !has_uncommitted_changes(0); is_clean = !has_uncommitted_changes(the_repository, 0);
if (file_exists(rebase_path_amend())) { if (file_exists(rebase_path_amend())) {
struct strbuf rev = STRBUF_INIT; struct strbuf rev = STRBUF_INIT;
@ -4847,7 +4847,7 @@ int complete_action(struct replay_opts *opts, unsigned flags,
if (checkout_onto(opts, onto_name, oid_to_hex(&oid), orig_head)) if (checkout_onto(opts, onto_name, oid_to_hex(&oid), orig_head))
return -1; return -1;
; ;
if (require_clean_work_tree("rebase", "", 1, 1)) if (require_clean_work_tree(the_repository, "rebase", "", 1, 1))
return -1; return -1;
return sequencer_continue(opts); return sequencer_continue(opts);

View file

@ -119,9 +119,10 @@ static void status_printf_more(struct wt_status *s, const char *color,
va_end(ap); va_end(ap);
} }
void wt_status_prepare(struct wt_status *s) void wt_status_prepare(struct repository *r, struct wt_status *s)
{ {
memset(s, 0, sizeof(*s)); memset(s, 0, sizeof(*s));
s->repo = r;
memcpy(s->color_palette, default_wt_status_colors, memcpy(s->color_palette, default_wt_status_colors,
sizeof(default_wt_status_colors)); sizeof(default_wt_status_colors));
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES; s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
@ -494,19 +495,19 @@ static void wt_status_collect_changed_cb(struct diff_queue_struct *q,
} }
} }
static int unmerged_mask(const char *path) static int unmerged_mask(struct index_state *istate, const char *path)
{ {
int pos, mask; int pos, mask;
const struct cache_entry *ce; const struct cache_entry *ce;
pos = cache_name_pos(path, strlen(path)); pos = index_name_pos(istate, path, strlen(path));
if (0 <= pos) if (0 <= pos)
return 0; return 0;
mask = 0; mask = 0;
pos = -pos-1; pos = -pos-1;
while (pos < active_nr) { while (pos < istate->cache_nr) {
ce = active_cache[pos++]; ce = istate->cache[pos++];
if (strcmp(ce->name, path) || !ce_stage(ce)) if (strcmp(ce->name, path) || !ce_stage(ce))
break; break;
mask |= (1 << (ce_stage(ce) - 1)); mask |= (1 << (ce_stage(ce) - 1));
@ -566,7 +567,8 @@ static void wt_status_collect_updated_cb(struct diff_queue_struct *q,
s->committable = 1; s->committable = 1;
break; break;
case DIFF_STATUS_UNMERGED: case DIFF_STATUS_UNMERGED:
d->stagemask = unmerged_mask(p->two->path); d->stagemask = unmerged_mask(s->repo->index,
p->two->path);
/* /*
* Don't bother setting {mode,oid}_{head,index} since the print * Don't bother setting {mode,oid}_{head,index} since the print
* code will output the stage values directly and not use the * code will output the stage values directly and not use the
@ -585,7 +587,7 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)
{ {
struct rev_info rev; struct rev_info rev;
repo_init_revisions(the_repository, &rev, NULL); repo_init_revisions(s->repo, &rev, NULL);
setup_revisions(0, NULL, &rev, NULL); setup_revisions(0, NULL, &rev, NULL);
rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK; rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
rev.diffopt.flags.dirty_submodules = 1; rev.diffopt.flags.dirty_submodules = 1;
@ -610,7 +612,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)
struct rev_info rev; struct rev_info rev;
struct setup_revision_opt opt; struct setup_revision_opt opt;
repo_init_revisions(the_repository, &rev, NULL); repo_init_revisions(s->repo, &rev, NULL);
memset(&opt, 0, sizeof(opt)); memset(&opt, 0, sizeof(opt));
opt.def = s->is_initial ? empty_tree_oid_hex() : s->reference; opt.def = s->is_initial ? empty_tree_oid_hex() : s->reference;
setup_revisions(0, NULL, &rev, &opt); setup_revisions(0, NULL, &rev, &opt);
@ -643,14 +645,15 @@ static void wt_status_collect_changes_index(struct wt_status *s)
static void wt_status_collect_changes_initial(struct wt_status *s) static void wt_status_collect_changes_initial(struct wt_status *s)
{ {
struct index_state *istate = s->repo->index;
int i; int i;
for (i = 0; i < active_nr; i++) { for (i = 0; i < istate->cache_nr; i++) {
struct string_list_item *it; struct string_list_item *it;
struct wt_status_change_data *d; struct wt_status_change_data *d;
const struct cache_entry *ce = active_cache[i]; const struct cache_entry *ce = istate->cache[i];
if (!ce_path_match(&the_index, ce, &s->pathspec, NULL)) if (!ce_path_match(istate, ce, &s->pathspec, NULL))
continue; continue;
if (ce_intent_to_add(ce)) if (ce_intent_to_add(ce))
continue; continue;
@ -684,6 +687,7 @@ static void wt_status_collect_untracked(struct wt_status *s)
int i; int i;
struct dir_struct dir; struct dir_struct dir;
uint64_t t_begin = getnanotime(); uint64_t t_begin = getnanotime();
struct index_state *istate = s->repo->index;
if (!s->show_untracked_files) if (!s->show_untracked_files)
return; return;
@ -698,25 +702,25 @@ static void wt_status_collect_untracked(struct wt_status *s)
if (s->show_ignored_mode == SHOW_MATCHING_IGNORED) if (s->show_ignored_mode == SHOW_MATCHING_IGNORED)
dir.flags |= DIR_SHOW_IGNORED_TOO_MODE_MATCHING; dir.flags |= DIR_SHOW_IGNORED_TOO_MODE_MATCHING;
} else { } else {
dir.untracked = the_index.untracked; dir.untracked = istate->untracked;
} }
setup_standard_excludes(&dir); setup_standard_excludes(&dir);
fill_directory(&dir, &the_index, &s->pathspec); fill_directory(&dir, istate, &s->pathspec);
for (i = 0; i < dir.nr; i++) { for (i = 0; i < dir.nr; i++) {
struct dir_entry *ent = dir.entries[i]; struct dir_entry *ent = dir.entries[i];
if (cache_name_is_other(ent->name, ent->len) && if (index_name_is_other(istate, ent->name, ent->len) &&
dir_path_match(&the_index, ent, &s->pathspec, 0, NULL)) dir_path_match(istate, ent, &s->pathspec, 0, NULL))
string_list_insert(&s->untracked, ent->name); string_list_insert(&s->untracked, ent->name);
free(ent); free(ent);
} }
for (i = 0; i < dir.ignored_nr; i++) { for (i = 0; i < dir.ignored_nr; i++) {
struct dir_entry *ent = dir.ignored[i]; struct dir_entry *ent = dir.ignored[i];
if (cache_name_is_other(ent->name, ent->len) && if (index_name_is_other(istate, ent->name, ent->len) &&
dir_path_match(&the_index, ent, &s->pathspec, 0, NULL)) dir_path_match(istate, ent, &s->pathspec, 0, NULL))
string_list_insert(&s->ignored, ent->name); string_list_insert(&s->ignored, ent->name);
free(ent); free(ent);
} }
@ -1009,7 +1013,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
int dirty_submodules; int dirty_submodules;
const char *c = color(WT_STATUS_HEADER, s); const char *c = color(WT_STATUS_HEADER, s);
repo_init_revisions(the_repository, &rev, NULL); repo_init_revisions(s->repo, &rev, NULL);
rev.diffopt.flags.allow_textconv = 1; rev.diffopt.flags.allow_textconv = 1;
rev.diffopt.ita_invisible_in_index = 1; rev.diffopt.ita_invisible_in_index = 1;
@ -1326,7 +1330,7 @@ static void show_rebase_in_progress(struct wt_status *s,
_(" (use \"git rebase --abort\" to check out the original branch)")); _(" (use \"git rebase --abort\" to check out the original branch)"));
} }
} else if (s->state.rebase_in_progress || } else if (s->state.rebase_in_progress ||
!stat(git_path_merge_msg(the_repository), &st)) { !stat(git_path_merge_msg(s->repo), &st)) {
print_rebase_state(s, color); print_rebase_state(s, color);
if (s->hints) if (s->hints)
status_printf_ln(s, color, status_printf_ln(s, color,
@ -2135,6 +2139,7 @@ static void wt_porcelain_v2_print_unmerged_entry(
struct wt_status *s) struct wt_status *s)
{ {
struct wt_status_change_data *d = it->util; struct wt_status_change_data *d = it->util;
struct index_state *istate = s->repo->index;
const struct cache_entry *ce; const struct cache_entry *ce;
struct strbuf buf_index = STRBUF_INIT; struct strbuf buf_index = STRBUF_INIT;
const char *path_index = NULL; const char *path_index = NULL;
@ -2173,11 +2178,11 @@ static void wt_porcelain_v2_print_unmerged_entry(
*/ */
memset(stages, 0, sizeof(stages)); memset(stages, 0, sizeof(stages));
sum = 0; sum = 0;
pos = cache_name_pos(it->string, strlen(it->string)); pos = index_name_pos(istate, it->string, strlen(it->string));
assert(pos < 0); assert(pos < 0);
pos = -pos-1; pos = -pos-1;
while (pos < active_nr) { while (pos < istate->cache_nr) {
ce = active_cache[pos++]; ce = istate->cache[pos++];
stage = ce_stage(ce); stage = ce_stage(ce);
if (strcmp(ce->name, it->string) || !stage) if (strcmp(ce->name, it->string) || !stage)
break; break;
@ -2302,12 +2307,12 @@ void wt_status_print(struct wt_status *s)
/** /**
* Returns 1 if there are unstaged changes, 0 otherwise. * Returns 1 if there are unstaged changes, 0 otherwise.
*/ */
int has_unstaged_changes(int ignore_submodules) int has_unstaged_changes(struct repository *r, int ignore_submodules)
{ {
struct rev_info rev_info; struct rev_info rev_info;
int result; int result;
repo_init_revisions(the_repository, &rev_info, NULL); repo_init_revisions(r, &rev_info, NULL);
if (ignore_submodules) { if (ignore_submodules) {
rev_info.diffopt.flags.ignore_submodules = 1; rev_info.diffopt.flags.ignore_submodules = 1;
rev_info.diffopt.flags.override_submodule_config = 1; rev_info.diffopt.flags.override_submodule_config = 1;
@ -2321,15 +2326,16 @@ int has_unstaged_changes(int ignore_submodules)
/** /**
* Returns 1 if there are uncommitted changes, 0 otherwise. * Returns 1 if there are uncommitted changes, 0 otherwise.
*/ */
int has_uncommitted_changes(int ignore_submodules) int has_uncommitted_changes(struct repository *r,
int ignore_submodules)
{ {
struct rev_info rev_info; struct rev_info rev_info;
int result; int result;
if (is_cache_unborn()) if (is_index_unborn(r->index))
return 0; return 0;
repo_init_revisions(the_repository, &rev_info, NULL); repo_init_revisions(r, &rev_info, NULL);
if (ignore_submodules) if (ignore_submodules)
rev_info.diffopt.flags.ignore_submodules = 1; rev_info.diffopt.flags.ignore_submodules = 1;
rev_info.diffopt.flags.quick = 1; rev_info.diffopt.flags.quick = 1;
@ -2340,7 +2346,7 @@ int has_uncommitted_changes(int ignore_submodules)
* We have no head (or it's corrupt); use the empty tree, * We have no head (or it's corrupt); use the empty tree,
* which will complain if the index is non-empty. * which will complain if the index is non-empty.
*/ */
struct tree *tree = lookup_tree(the_repository, the_hash_algo->empty_tree); struct tree *tree = lookup_tree(r, the_hash_algo->empty_tree);
add_pending_object(&rev_info, &tree->object, ""); add_pending_object(&rev_info, &tree->object, "");
} }
@ -2353,24 +2359,28 @@ int has_uncommitted_changes(int ignore_submodules)
* If the work tree has unstaged or uncommitted changes, dies with the * If the work tree has unstaged or uncommitted changes, dies with the
* appropriate message. * appropriate message.
*/ */
int require_clean_work_tree(const char *action, const char *hint, int ignore_submodules, int gently) int require_clean_work_tree(struct repository *r,
const char *action,
const char *hint,
int ignore_submodules,
int gently)
{ {
struct lock_file lock_file = LOCK_INIT; struct lock_file lock_file = LOCK_INIT;
int err = 0, fd; int err = 0, fd;
fd = hold_locked_index(&lock_file, 0); fd = hold_locked_index(&lock_file, 0);
refresh_cache(REFRESH_QUIET); refresh_index(r->index, REFRESH_QUIET, NULL, NULL, NULL);
if (0 <= fd) if (0 <= fd)
update_index_if_able(&the_index, &lock_file); update_index_if_able(r->index, &lock_file);
rollback_lock_file(&lock_file); rollback_lock_file(&lock_file);
if (has_unstaged_changes(ignore_submodules)) { if (has_unstaged_changes(r, ignore_submodules)) {
/* TRANSLATORS: the action is e.g. "pull with rebase" */ /* TRANSLATORS: the action is e.g. "pull with rebase" */
error(_("cannot %s: You have unstaged changes."), _(action)); error(_("cannot %s: You have unstaged changes."), _(action));
err = 1; err = 1;
} }
if (has_uncommitted_changes(ignore_submodules)) { if (has_uncommitted_changes(r, ignore_submodules)) {
if (err) if (err)
error(_("additionally, your index contains uncommitted changes.")); error(_("additionally, your index contains uncommitted changes."));
else else

View file

@ -7,6 +7,7 @@
#include "pathspec.h" #include "pathspec.h"
#include "remote.h" #include "remote.h"
struct repository;
struct worktree; struct worktree;
enum color_wt_status { enum color_wt_status {
@ -83,6 +84,7 @@ struct wt_status_state {
}; };
struct wt_status { struct wt_status {
struct repository *repo;
int is_initial; int is_initial;
char *branch; char *branch;
const char *reference; const char *reference;
@ -128,7 +130,7 @@ struct wt_status {
size_t wt_status_locate_end(const char *s, size_t len); size_t wt_status_locate_end(const char *s, size_t len);
void wt_status_add_cut_line(FILE *fp); void wt_status_add_cut_line(FILE *fp);
void wt_status_prepare(struct wt_status *s); void wt_status_prepare(struct repository *r, struct wt_status *s);
void wt_status_print(struct wt_status *s); void wt_status_print(struct wt_status *s);
void wt_status_collect(struct wt_status *s); void wt_status_collect(struct wt_status *s);
void wt_status_collect_free_buffers(struct wt_status *s); void wt_status_collect_free_buffers(struct wt_status *s);
@ -144,9 +146,14 @@ __attribute__((format (printf, 3, 4)))
void status_printf(struct wt_status *s, const char *color, const char *fmt, ...); void status_printf(struct wt_status *s, const char *color, const char *fmt, ...);
/* The following functions expect that the caller took care of reading the index. */ /* The following functions expect that the caller took care of reading the index. */
int has_unstaged_changes(int ignore_submodules); int has_unstaged_changes(struct repository *repo,
int has_uncommitted_changes(int ignore_submodules); int ignore_submodules);
int require_clean_work_tree(const char *action, const char *hint, int has_uncommitted_changes(struct repository *repo,
int ignore_submodules, int gently); int ignore_submodules);
int require_clean_work_tree(struct repository *repo,
const char *action,
const char *hint,
int ignore_submodules,
int gently);
#endif /* STATUS_H */ #endif /* STATUS_H */