diff options
Diffstat (limited to 'wt-status.c')
-rw-r--r-- | wt-status.c | 115 |
1 files changed, 99 insertions, 16 deletions
diff --git a/wt-status.c b/wt-status.c index 0c8287a023..5d215f4e4f 100644 --- a/wt-status.c +++ b/wt-status.c @@ -456,7 +456,7 @@ static void wt_status_collect_changed_cb(struct diff_queue_struct *q, it = string_list_insert(&s->change, p->two->path); d = it->util; if (!d) { - d = xcalloc(1, sizeof(*d)); + CALLOC_ARRAY(d, 1); it->util = d; } if (!d->worktree_status) @@ -540,7 +540,7 @@ static void wt_status_collect_updated_cb(struct diff_queue_struct *q, it = string_list_insert(&s->change, p->two->path); d = it->util; if (!d) { - d = xcalloc(1, sizeof(*d)); + CALLOC_ARRAY(d, 1); it->util = d; } if (!d->index_status) @@ -616,6 +616,7 @@ static void wt_status_collect_changes_worktree(struct wt_status *s) 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); + clear_pathspec(&rev.prune_data); } static void wt_status_collect_changes_index(struct wt_status *s) @@ -638,7 +639,7 @@ static void wt_status_collect_changes_index(struct wt_status *s) * mode by passing a command line option we do not ignore any * changed submodule SHA-1s when comparing index and HEAD, no * matter what is configured. Otherwise the user won't be - * shown any submodules she manually added (and which are + * shown any submodules manually added (and which are * staged to be committed), which would be really confusing. */ handle_ignore_submodules_arg(&rev.diffopt, "dirty"); @@ -652,6 +653,38 @@ static void wt_status_collect_changes_index(struct wt_status *s) 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); + object_array_clear(&rev.pending); + clear_pathspec(&rev.prune_data); +} + +static int add_file_to_list(const struct object_id *oid, + struct strbuf *base, const char *path, + unsigned int mode, void *context) +{ + struct string_list_item *it; + struct wt_status_change_data *d; + struct wt_status *s = context; + struct strbuf full_name = STRBUF_INIT; + + if (S_ISDIR(mode)) + return READ_TREE_RECURSIVE; + + strbuf_add(&full_name, base->buf, base->len); + strbuf_addstr(&full_name, path); + it = string_list_insert(&s->change, full_name.buf); + d = it->util; + if (!d) { + CALLOC_ARRAY(d, 1); + it->util = d; + } + + d->index_status = DIFF_STATUS_ADDED; + /* Leave {mode,oid}_head zero for adds. */ + d->mode_index = mode; + oidcpy(&d->oid_index, oid); + s->committable = 1; + strbuf_release(&full_name); + return 0; } static void wt_status_collect_changes_initial(struct wt_status *s) @@ -668,10 +701,31 @@ static void wt_status_collect_changes_initial(struct wt_status *s) continue; if (ce_intent_to_add(ce)) continue; + if (S_ISSPARSEDIR(ce->ce_mode)) { + /* + * This is a sparse directory entry, so we want to collect all + * of the added files within the tree. This requires recursively + * expanding the trees to find the elements that are new in this + * tree and marking them with DIFF_STATUS_ADDED. + */ + struct strbuf base = STRBUF_INIT; + struct pathspec ps = { 0 }; + struct tree *tree = lookup_tree(istate->repo, &ce->oid); + + ps.recursive = 1; + ps.has_wildcard = 1; + ps.max_depth = -1; + + strbuf_add(&base, ce->name, ce->ce_namelen); + read_tree_at(istate->repo, tree, &base, &ps, + add_file_to_list, s); + continue; + } + it = string_list_insert(&s->change, ce->name); d = it->util; if (!d) { - d = xcalloc(1, sizeof(*d)); + CALLOC_ARRAY(d, 1); it->util = d; } if (ce_stage(ce)) { @@ -696,14 +750,13 @@ static void wt_status_collect_changes_initial(struct wt_status *s) static void wt_status_collect_untracked(struct wt_status *s) { int i; - struct dir_struct dir; + struct dir_struct dir = DIR_INIT; uint64_t t_begin = getnanotime(); struct index_state *istate = s->repo->index; if (!s->show_untracked_files) return; - dir_init(&dir); if (s->show_untracked_files != SHOW_ALL_UNTRACKED_FILES) dir.flags |= DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES; @@ -734,7 +787,7 @@ static void wt_status_collect_untracked(struct wt_status *s) dir_clear(&dir); - if (advice_status_u_option) + if (advice_enabled(ADVICE_STATUS_U_OPTION)) s->untracked_in_ms = (getnanotime() - t_begin) / 1000000; } @@ -895,11 +948,17 @@ static int stash_count_refs(struct object_id *ooid, struct object_id *noid, return 0; } +static int count_stash_entries(void) +{ + int n = 0; + for_each_reflog_ent("refs/stash", stash_count_refs, &n); + return n; +} + static void wt_longstatus_print_stash_summary(struct wt_status *s) { - int stash_count = 0; + int stash_count = count_stash_entries(); - for_each_reflog_ent("refs/stash", stash_count_refs, &stash_count); if (stash_count > 0) status_printf_ln(s, GIT_COLOR_NORMAL, Q_("Your stash currently has %d entry", @@ -1105,7 +1164,7 @@ static void wt_longstatus_print_tracking(struct wt_status *s) if (!format_tracking_info(branch, &sb, s->ahead_behind_flags)) return; - if (advice_status_ahead_behind_warning && + if (advice_enabled(ADVICE_STATUS_AHEAD_BEHIND_WARNING) && s->ahead_behind_flags == AHEAD_BEHIND_FULL) { uint64_t t_delta_in_ms = (getnanotime() - t_begin) / 1000000; if (t_delta_in_ms > AB_DELAY_WARNING_IN_MS) { @@ -1490,9 +1549,12 @@ static void show_sparse_checkout_in_use(struct wt_status *s, if (s->state.sparse_checkout_percentage == SPARSE_CHECKOUT_DISABLED) return; - status_printf_ln(s, color, - _("You are in a sparse checkout with %d%% of tracked files present."), - s->state.sparse_checkout_percentage); + if (s->state.sparse_checkout_percentage == SPARSE_CHECKOUT_SPARSE_INDEX) + status_printf_ln(s, color, _("You are in a sparse checkout.")); + else + status_printf_ln(s, color, + _("You are in a sparse checkout with %d%% of tracked files present."), + s->state.sparse_checkout_percentage); wt_longstatus_print_trailer(s); } @@ -1650,6 +1712,11 @@ static void wt_status_check_sparse_checkout(struct repository *r, return; } + if (r->index->sparse_index) { + state->sparse_checkout_percentage = SPARSE_CHECKOUT_SPARSE_INDEX; + return; + } + for (i = 0; i < r->index->cache_nr; i++) { struct cache_entry *ce = r->index->cache[i]; if (ce_skip_worktree(ce)) @@ -1687,10 +1754,10 @@ void wt_status_get_state(struct repository *r, if (!sequencer_get_last_command(r, &action)) { if (action == REPLAY_PICK) { state->cherry_pick_in_progress = 1; - oidcpy(&state->cherry_pick_head_oid, &null_oid); + oidcpy(&state->cherry_pick_head_oid, null_oid()); } else { state->revert_in_progress = 1; - oidcpy(&state->revert_head_oid, &null_oid); + oidcpy(&state->revert_head_oid, null_oid()); } } if (get_detached_from) @@ -1784,7 +1851,7 @@ static void wt_longstatus_print(struct wt_status *s) wt_longstatus_print_other(s, &s->untracked, _("Untracked files"), "add"); if (s->show_ignored_mode) wt_longstatus_print_other(s, &s->ignored, _("Ignored files"), "add -f"); - if (advice_status_u_option && 2000 < s->untracked_in_ms) { + if (advice_enabled(ADVICE_STATUS_U_OPTION) && 2000 < s->untracked_in_ms) { status_printf_ln(s, GIT_COLOR_NORMAL, "%s", ""); status_printf_ln(s, GIT_COLOR_NORMAL, _("It took %.2f seconds to enumerate untracked files. 'status -uno'\n" @@ -2116,6 +2183,18 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s) } /* + * Print the stash count in a porcelain-friendly format + */ +static void wt_porcelain_v2_print_stash(struct wt_status *s) +{ + int stash_count = count_stash_entries(); + char eol = s->null_termination ? '\0' : '\n'; + + if (stash_count > 0) + fprintf(s->fp, "# stash %d%c", stash_count, eol); +} + +/* * Convert various submodule status values into a * fixed-length string of characters in the buffer provided. */ @@ -2376,6 +2455,9 @@ static void wt_porcelain_v2_print(struct wt_status *s) if (s->show_branch) wt_porcelain_v2_print_tracking(s); + if (s->show_stash) + wt_porcelain_v2_print_stash(s); + for (i = 0; i < s->change.nr; i++) { it = &(s->change.items[i]); d = it->util; @@ -2480,6 +2562,7 @@ int has_uncommitted_changes(struct repository *r, diff_setup_done(&rev_info.diffopt); result = run_diff_index(&rev_info, 1); + object_array_clear(&rev_info.pending); return diff_result_code(&rev_info.diffopt, result); } |