diff options
Diffstat (limited to 'wt-status.c')
-rw-r--r-- | wt-status.c | 124 |
1 files changed, 82 insertions, 42 deletions
diff --git a/wt-status.c b/wt-status.c index ef26f07446..66f4234af1 100644 --- a/wt-status.c +++ b/wt-status.c @@ -136,6 +136,7 @@ void wt_status_prepare(struct wt_status *s) s->ignored.strdup_strings = 1; s->show_branch = -1; /* unspecified */ s->show_stash = 0; + s->ahead_behind_flags = AHEAD_BEHIND_UNSPECIFIED; s->display_comment_prefix = 0; } @@ -360,8 +361,6 @@ static void wt_longstatus_print_change_data(struct wt_status *s, switch (change_type) { case WT_STATUS_UPDATED: status = d->index_status; - if (d->head_path) - one_name = d->head_path; break; case WT_STATUS_CHANGED: if (d->new_submodule_commits || d->dirty_submodule) { @@ -382,6 +381,14 @@ static void wt_longstatus_print_change_data(struct wt_status *s, change_type); } + /* + * Only pick up the rename it's relevant. If the rename is for + * the changed section and we're printing the updated section, + * ignore it. + */ + if (d->rename_status == status) + one_name = d->rename_source; + one = quote_path(one_name, s->prefix, &onebuf); two = quote_path(two_name, s->prefix, &twobuf); @@ -391,7 +398,7 @@ static void wt_longstatus_print_change_data(struct wt_status *s, die("BUG: unhandled diff status %c", status); len = label_width - utf8_strwidth(what); assert(len >= 0); - if (status == DIFF_STATUS_COPIED || status == DIFF_STATUS_RENAMED) + if (one_name != two_name) status_printf_more(s, c, "%s%.*s%s -> %s", what, len, padding, one, two); else @@ -406,7 +413,8 @@ static void wt_longstatus_print_change_data(struct wt_status *s, strbuf_release(&twobuf); } -static char short_submodule_status(struct wt_status_change_data *d) { +static char short_submodule_status(struct wt_status_change_data *d) +{ if (d->new_submodule_commits) return 'M'; if (d->dirty_submodule & DIRTY_SUBMODULE_MODIFIED) @@ -432,7 +440,7 @@ static void wt_status_collect_changed_cb(struct diff_queue_struct *q, struct wt_status_change_data *d; p = q->queue[i]; - it = string_list_insert(&s->change, p->one->path); + it = string_list_insert(&s->change, p->two->path); d = it->util; if (!d) { d = xcalloc(1, sizeof(*d)); @@ -459,6 +467,14 @@ static void wt_status_collect_changed_cb(struct diff_queue_struct *q, /* mode_worktree is zero for a delete. */ break; + case DIFF_STATUS_COPIED: + case DIFF_STATUS_RENAMED: + if (d->rename_status) + die("BUG: multiple renames on the same target? how?"); + d->rename_source = xstrdup(p->one->path); + d->rename_score = p->score * 100 / MAX_SCORE; + d->rename_status = p->status; + /* fallthru */ case DIFF_STATUS_MODIFIED: case DIFF_STATUS_TYPE_CHANGED: case DIFF_STATUS_UNMERGED: @@ -467,8 +483,8 @@ static void wt_status_collect_changed_cb(struct diff_queue_struct *q, oidcpy(&d->oid_index, &p->one->oid); break; - case DIFF_STATUS_UNKNOWN: - die("BUG: worktree status unknown???"); + default: + die("BUG: unhandled diff-files status '%c'", p->status); break; } @@ -530,8 +546,11 @@ static void wt_status_collect_updated_cb(struct diff_queue_struct *q, case DIFF_STATUS_COPIED: case DIFF_STATUS_RENAMED: - d->head_path = xstrdup(p->one->path); - d->score = p->score * 100 / MAX_SCORE; + if (d->rename_status) + die("BUG: multiple renames on the same target? how?"); + d->rename_source = xstrdup(p->one->path); + d->rename_score = p->score * 100 / MAX_SCORE; + d->rename_status = p->status; /* fallthru */ case DIFF_STATUS_MODIFIED: case DIFF_STATUS_TYPE_CHANGED: @@ -548,6 +567,10 @@ static void wt_status_collect_updated_cb(struct diff_queue_struct *q, * values in these fields. */ break; + + default: + die("BUG: unhandled diff-index status '%c'", p->status); + break; } } } @@ -602,7 +625,7 @@ 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 = 1; + rev.diffopt.detect_rename = DIFF_DETECT_RENAME; rev.diffopt.rename_limit = 200; rev.diffopt.break_opt = 0; copy_pathspec(&rev.prune_data, &s->pathspec); @@ -962,7 +985,7 @@ 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 = 1; + rev.diffopt.detect_rename = DIFF_DETECT_RENAME; rev.diffopt.file = s->fp; rev.diffopt.close_file = 0; /* @@ -1010,7 +1033,7 @@ static void wt_longstatus_print_tracking(struct wt_status *s) if (!skip_prefix(s->branch, "refs/heads/", &branch_name)) return; branch = branch_get(branch_name); - if (!format_tracking_info(branch, &sb)) + if (!format_tracking_info(branch, &sb, s->ahead_behind_flags)) return; i = 0; @@ -1719,13 +1742,14 @@ static void wt_shortstatus_status(struct string_list_item *it, putchar(' '); if (s->null_termination) { fprintf(stdout, "%s%c", it->string, 0); - if (d->head_path) - fprintf(stdout, "%s%c", d->head_path, 0); + if (d->rename_source) + fprintf(stdout, "%s%c", d->rename_source, 0); } else { struct strbuf onebuf = STRBUF_INIT; const char *one; - if (d->head_path) { - one = quote_path(d->head_path, s->prefix, &onebuf); + + if (d->rename_source) { + one = quote_path(d->rename_source, s->prefix, &onebuf); if (*one != '"' && strchr(one, ' ') != NULL) { putchar('"'); strbuf_addch(&onebuf, '"'); @@ -1770,7 +1794,7 @@ static void wt_shortstatus_print_tracking(struct wt_status *s) const char *base; char *short_base; const char *branch_name; - int num_ours, num_theirs; + int num_ours, num_theirs, sti; int upstream_is_gone = 0; color_fprintf(s->fp, color(WT_STATUS_HEADER, s), "## "); @@ -1796,7 +1820,9 @@ static void wt_shortstatus_print_tracking(struct wt_status *s) color_fprintf(s->fp, branch_color_local, "%s", branch_name); - if (stat_tracking_info(branch, &num_ours, &num_theirs, &base) < 0) { + sti = stat_tracking_info(branch, &num_ours, &num_theirs, &base, + s->ahead_behind_flags); + if (sti < 0) { if (!base) goto conclude; @@ -1808,12 +1834,14 @@ static void wt_shortstatus_print_tracking(struct wt_status *s) color_fprintf(s->fp, branch_color_remote, "%s", short_base); free(short_base); - if (!upstream_is_gone && !num_ours && !num_theirs) + if (!upstream_is_gone && !sti) goto conclude; color_fprintf(s->fp, header_color, " ["); if (upstream_is_gone) { color_fprintf(s->fp, header_color, LABEL(N_("gone"))); + } else if (s->ahead_behind_flags == AHEAD_BEHIND_QUICK) { + color_fprintf(s->fp, header_color, LABEL(N_("different"))); } else if (!num_ours) { color_fprintf(s->fp, header_color, LABEL(N_("behind "))); color_fprintf(s->fp, branch_color_remote, "%d", num_theirs); @@ -1882,18 +1910,19 @@ static void wt_porcelain_print(struct wt_status *s) * * <upstream> ::= the upstream branch name, when set. * - * <ahead> ::= integer ahead value, when upstream set - * and the commit is present (not gone). - * - * <behind> ::= integer behind value, when upstream set - * and commit is present. + * <ahead> ::= integer ahead value or '?'. * + * <behind> ::= integer behind value or '?'. * * The end-of-line is defined by the -z flag. * * <eol> ::= NUL when -z, * LF when NOT -z. * + * When an upstream is set and present, the 'branch.ab' line will + * be printed with the ahead/behind counts for the branch and the + * upstream. When AHEAD_BEHIND_QUICK is requested and the branches + * are different, '?' will be substituted for the actual count. */ static void wt_porcelain_v2_print_tracking(struct wt_status *s) { @@ -1933,14 +1962,25 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s) /* Lookup stats on the upstream tracking branch, if set. */ branch = branch_get(branch_name); base = NULL; - ab_info = (stat_tracking_info(branch, &nr_ahead, &nr_behind, &base) == 0); + ab_info = stat_tracking_info(branch, &nr_ahead, &nr_behind, + &base, s->ahead_behind_flags); if (base) { base = shorten_unambiguous_ref(base, 0); fprintf(s->fp, "# branch.upstream %s%c", base, eol); free((char *)base); - if (ab_info) - fprintf(s->fp, "# branch.ab +%d -%d%c", nr_ahead, nr_behind, eol); + if (ab_info > 0) { + /* different */ + if (nr_ahead || nr_behind) + fprintf(s->fp, "# branch.ab +%d -%d%c", + nr_ahead, nr_behind, eol); + else + fprintf(s->fp, "# branch.ab +? -?%c", + eol); + } else if (!ab_info) { + /* same */ + fprintf(s->fp, "# branch.ab +0 -0%c", eol); + } } } @@ -2030,10 +2070,10 @@ static void wt_porcelain_v2_print_changed_entry( struct wt_status *s) { struct wt_status_change_data *d = it->util; - struct strbuf buf_index = STRBUF_INIT; - struct strbuf buf_head = STRBUF_INIT; - const char *path_index = NULL; - const char *path_head = NULL; + struct strbuf buf = STRBUF_INIT; + struct strbuf buf_from = STRBUF_INIT; + const char *path = NULL; + const char *path_from = NULL; char key[3]; char submodule_token[5]; char sep_char, eol_char; @@ -2052,8 +2092,8 @@ static void wt_porcelain_v2_print_changed_entry( */ sep_char = '\0'; eol_char = '\0'; - path_index = it->string; - path_head = d->head_path; + path = it->string; + path_from = d->rename_source; } else { /* * Path(s) are C-quoted if necessary. Current path is ALWAYS first. @@ -2063,27 +2103,27 @@ static void wt_porcelain_v2_print_changed_entry( */ sep_char = '\t'; eol_char = '\n'; - path_index = quote_path(it->string, s->prefix, &buf_index); - if (d->head_path) - path_head = quote_path(d->head_path, s->prefix, &buf_head); + path = quote_path(it->string, s->prefix, &buf); + if (d->rename_source) + path_from = quote_path(d->rename_source, s->prefix, &buf_from); } - if (path_head) + if (path_from) fprintf(s->fp, "2 %s %s %06o %06o %06o %s %s %c%d %s%c%s%c", key, submodule_token, d->mode_head, d->mode_index, d->mode_worktree, oid_to_hex(&d->oid_head), oid_to_hex(&d->oid_index), - key[0], d->score, - path_index, sep_char, path_head, eol_char); + d->rename_status, d->rename_score, + path, sep_char, path_from, eol_char); else fprintf(s->fp, "1 %s %s %06o %06o %06o %s %s %s%c", key, submodule_token, d->mode_head, d->mode_index, d->mode_worktree, oid_to_hex(&d->oid_head), oid_to_hex(&d->oid_index), - path_index, eol_char); + path, eol_char); - strbuf_release(&buf_index); - strbuf_release(&buf_head); + strbuf_release(&buf); + strbuf_release(&buf_from); } /* |