summaryrefslogtreecommitdiff
path: root/wt-status.c
diff options
context:
space:
mode:
Diffstat (limited to 'wt-status.c')
-rw-r--r--wt-status.c115
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);
}