From patchwork Fri Oct 20 18:39:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Stopak X-Patchwork-Id: 13431023 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B5E486111 for ; Fri, 20 Oct 2023 18:39:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=initialcommit-io.20230601.gappssmtp.com header.i=@initialcommit-io.20230601.gappssmtp.com header.b="f33AxDZ3" Received: from mail-pl1-x641.google.com (mail-pl1-x641.google.com [IPv6:2607:f8b0:4864:20::641]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 867ABD4C for ; Fri, 20 Oct 2023 11:39:54 -0700 (PDT) Received: by mail-pl1-x641.google.com with SMTP id d9443c01a7336-1c9b7c234a7so9408515ad.3 for ; Fri, 20 Oct 2023 11:39:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=initialcommit-io.20230601.gappssmtp.com; s=20230601; t=1697827194; x=1698431994; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ilbzUpAXCRHFu13+dCsU/z6RaJA/e8bJeUA+rWbVMZE=; b=f33AxDZ3K3AGebhJu1I4OoYLD9Qklylq/dnS5Hqwx7wSpc7RtJ6MgZ378o2Llv3GgW rh/+8GOyeAiesPbE2mCsaI6McWYj/PIP+SwJTJch9yGBYq+gWejGm5kpbZXj7Hfv4g9z /jBMrDmuCGjRBml7w/C2ad/sCE3q2uNXHEHhWGi9q6Gml0kHev9Z32vrBnZqorsi7dpK fHylvI++1r4+rjX5yfJ5bbomFFyK+YKS4+6fME1UEXwyFxbG5OdygF0O987OkrTJvoCx 8hx+urkZqVLPUWlfmRMf7beryDEubH+vblEF4O1zAQeIbbVhyvpvTv6C4+rdkqX66Kov GiVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697827194; x=1698431994; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ilbzUpAXCRHFu13+dCsU/z6RaJA/e8bJeUA+rWbVMZE=; b=SEQd0NlzvQ8YdkHFOnrnuAQradlnzjKB/FXUXIHAER9r/VV38wytp+ksYsTHukLw0y qClxPLZWN3ACKzCg7lShMoP8FsN37N1zDYM+d5qeg6AhUvRO3TmxU6sAp54i2SPQz+ty 9O28i17hNiMeFB/IEh1fHIcU06f6zeDZClmnCkgbKXdcgbd1OQEWDLsVO+W5sFwe6UA+ qIXWTFDsumMHlYQ/P+y5z2q1VZJTgGXk5TL0JQI7Hp/CbgskCc87RnMwjGv+PdDAthyZ aWPYvscT/+9tliivnydbuidOn4wFnokZUIp11y+Ry1rBzVb5M11TFlVlm6ufzWWYGlS4 cnKw== X-Gm-Message-State: AOJu0YyRB7bWaEEMhm7F0f71xjBsgUNHiZITgs+xeP7uVsTxJhJ1+xHB x0LuYGmDV2q6FNodNOylEqdNmcw93ynvO3IB05MQ8gY7AgK33Q== X-Google-Smtp-Source: AGHT+IHNoq4KOwWPjwbIXfKuk/WispiP4CmdnIsp91yEDHWNHakz/fNbWqbK8O1L0N3v0AiPuiDa/Q== X-Received: by 2002:a17:90a:53c5:b0:27d:8d0:713e with SMTP id y63-20020a17090a53c500b0027d08d0713emr2964271pjh.10.1697827193797; Fri, 20 Oct 2023 11:39:53 -0700 (PDT) Received: from localhost.localdomain (mobile-166-170-46-176.mycingular.net. [166.170.46.176]) by smtp.gmail.com with ESMTPSA id s15-20020a17090a5d0f00b0027e022bd62fsm2994353pji.5.2023.10.20.11.39.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 11:39:53 -0700 (PDT) From: Jacob Stopak To: git@vger.kernel.org Cc: Jacob Stopak Subject: [RFC PATCH 1/5] status: introduce -t, --table flag Date: Fri, 20 Oct 2023 11:39:43 -0700 Message-ID: <20231020183947.463882-2-jacob@initialcommit.io> X-Mailer: git-send-email 2.42.0.402.gbe8243af7b.dirty In-Reply-To: <20231020183947.463882-1-jacob@initialcommit.io> References: <20231020183947.463882-1-jacob@initialcommit.io> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Signed-off-by: Jacob Stopak --- Makefile | 1 + builtin/commit.c | 2 + table.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++ table.h | 6 +++ wt-status.c | 72 +++++++++++++++++++---------- wt-status.h | 1 + 6 files changed, 174 insertions(+), 25 deletions(-) create mode 100644 table.c create mode 100644 table.h diff --git a/Makefile b/Makefile index 9c6a2f125f..a7399ca8f0 100644 --- a/Makefile +++ b/Makefile @@ -1155,6 +1155,7 @@ LIB_OBJS += submodule-config.o LIB_OBJS += submodule.o LIB_OBJS += symlinks.o LIB_OBJS += tag.o +LIB_OBJS += table.o LIB_OBJS += tempfile.o LIB_OBJS += thread-utils.o LIB_OBJS += tmp-objdir.o diff --git a/builtin/commit.c b/builtin/commit.c index 7da5f92448..4338896dbf 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1539,6 +1539,8 @@ int cmd_status(int argc, const char **argv, const char *prefix) OPT_CALLBACK_F('M', "find-renames", &rename_score_arg, N_("n"), N_("detect renames, optionally set similarity index"), PARSE_OPT_OPTARG | PARSE_OPT_NONEG, opt_parse_rename_score), + OPT_SET_INT('t', "table", &status_format, + N_("show status in table format"), STATUS_FORMAT_TABLE), OPT_END(), }; diff --git a/table.c b/table.c new file mode 100644 index 0000000000..54cf9e4d07 --- /dev/null +++ b/table.c @@ -0,0 +1,117 @@ +#define USE_THE_INDEX_VARIABLE +#include "builtin.h" +#include "gettext.h" +#include "strbuf.h" +#include "wt-status.h" +#include "config.h" +#include "string-list.h" +#include "sys/ioctl.h" + +static const char *color(int slot, struct wt_status *s) +{ + const char *c = ""; + if (want_color(s->use_color)) + c = s->color_palette[slot]; + if (slot == WT_STATUS_ONBRANCH && color_is_nil(c)) + c = s->color_palette[WT_STATUS_HEADER]; + return c; +} + +static void build_table_border(struct strbuf *buf, int cols) +{ + strbuf_reset(buf); + strbuf_addchars(buf, '-', cols); +} + +static void build_table_entry(struct strbuf *buf, char *entry, int cols) +{ + strbuf_reset(buf); + strbuf_addchars(buf, ' ', (cols / 3 - 1 - strlen(entry)) / 2); + strbuf_addstr(buf, entry); + + /* Bump right padding if entry length is odd */ + if (!(strlen(entry) % 2)) + strbuf_addchars(buf, ' ', (cols / 3 - 1 - strlen(entry)) / 2 + 1); + else + strbuf_addchars(buf, ' ', (cols / 3 - 1 - strlen(entry)) / 2); +} + +static void print_table_body_line(struct strbuf *buf1, struct strbuf *buf2, struct strbuf *buf3, struct wt_status *s) +{ + printf(_("|")); + color_fprintf(s->fp, color(WT_STATUS_UNTRACKED, s), "%s", buf1->buf); + printf(_("|")); + color_fprintf(s->fp, color(WT_STATUS_CHANGED, s), "%s", buf2->buf); + printf(_("|")); + color_fprintf(s->fp, color(WT_STATUS_UPDATED, s), "%s", buf3->buf); + printf(_("|\n")); +} + +void build_and_draw_status_table(struct wt_status *s) +{ + struct winsize w; + int cols; + struct strbuf table_border = STRBUF_INIT; + struct strbuf table_col_entry_1 = STRBUF_INIT; + struct strbuf table_col_entry_2 = STRBUF_INIT; + struct strbuf table_col_entry_3 = STRBUF_INIT; + struct string_list_item *item; + + /* Get terminal width */ + ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); + cols = w.ws_col; + + /* Ensure table is divisible into 3 even columns */ + while (((cols - 1) % 3) > 0 || !(cols % 2)) { + cols -= 1; + } + + build_table_border(&table_border, cols); + build_table_entry(&table_col_entry_1, "Untracked files", cols); + build_table_entry(&table_col_entry_2, "Changes not staged for commit", cols); + build_table_entry(&table_col_entry_3, "Changes to be committed", cols); + + /* Draw table header */ + printf(_("%s\n"), table_border.buf); + printf(_("|%s|%s|%s|\n"), table_col_entry_1.buf, table_col_entry_2.buf, table_col_entry_3.buf); + printf(_("%s\n"), table_border.buf); + + /* Draw table body */ + for_each_string_list_item(item, &s->untracked) { + build_table_entry(&table_col_entry_1, item->string, cols); + build_table_entry(&table_col_entry_2, "", cols); + build_table_entry(&table_col_entry_3, "", cols); + print_table_body_line(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, s); + } + + for_each_string_list_item(item, &s->change) { + struct wt_status_change_data *d = item->util; + if (d->worktree_status && d->index_status) { + build_table_entry(&table_col_entry_1, "", cols); + build_table_entry(&table_col_entry_2, item->string, cols); + build_table_entry(&table_col_entry_3, item->string, cols); + } else if (d->worktree_status) { + build_table_entry(&table_col_entry_1, "", cols); + build_table_entry(&table_col_entry_2, item->string, cols); + build_table_entry(&table_col_entry_3, "", cols); + } else if (d->index_status) { + build_table_entry(&table_col_entry_1, "", cols); + build_table_entry(&table_col_entry_2, "", cols); + build_table_entry(&table_col_entry_3, item->string, cols); + } + print_table_body_line(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, s); + } + + if (!s->untracked.nr && !s->change.nr) { + build_table_entry(&table_col_entry_1, "-", cols); + build_table_entry(&table_col_entry_2, "-", cols); + build_table_entry(&table_col_entry_3, "-", cols); + printf(_("|%s|%s|%s|\n"), table_col_entry_1.buf, table_col_entry_2.buf, table_col_entry_3.buf); + } + + printf(_("%s\n"), table_border.buf); + strbuf_release(&table_border); + strbuf_release(&table_col_entry_1); + strbuf_release(&table_col_entry_2); + strbuf_release(&table_col_entry_3); +} diff --git a/table.h b/table.h new file mode 100644 index 0000000000..30e0d5509b --- /dev/null +++ b/table.h @@ -0,0 +1,6 @@ +#ifndef TABLE_H +#define TABLE_H + +void build_and_draw_status_table(struct wt_status *s); + +#endif /* TABLE_H */ diff --git a/wt-status.c b/wt-status.c index 9f45bf6949..24b56ea559 100644 --- a/wt-status.c +++ b/wt-status.c @@ -31,6 +31,7 @@ #include "lockfile.h" #include "sequencer.h" #include "fsmonitor-settings.h" +#include "table.h" #define AB_DELAY_WARNING_IN_MS (2 * 1000) #define UF_DELAY_WARNING_IN_MS (2 * 1000) @@ -1833,39 +1834,46 @@ static void wt_longstatus_print_state(struct wt_status *s) show_sparse_checkout_in_use(s, state_color); } -static void wt_longstatus_print(struct wt_status *s) +static void wt_longstatus_print_onwhat(struct wt_status *s, const char *branch_name) { + const char *on_what = _("On branch "); const char *branch_color = color(WT_STATUS_ONBRANCH, s); const char *branch_status_color = color(WT_STATUS_HEADER, s); + + if (!strcmp(branch_name, "HEAD")) { + branch_status_color = color(WT_STATUS_NOBRANCH, s); + if (s->state.rebase_in_progress || + s->state.rebase_interactive_in_progress) { + if (s->state.rebase_interactive_in_progress) + on_what = _("interactive rebase in progress; onto "); + else + on_what = _("rebase in progress; onto "); + branch_name = s->state.onto; + } else if (s->state.detached_from) { + branch_name = s->state.detached_from; + if (s->state.detached_at) + on_what = _("HEAD detached at "); + else + on_what = _("HEAD detached from "); + } else { + branch_name = ""; + on_what = _("Not currently on any branch."); + } + } else + skip_prefix(branch_name, "refs/heads/", &branch_name); + + status_printf_more(s, branch_status_color, "%s", on_what); + status_printf_more(s, branch_color, "%s\n", branch_name); +} + +static void wt_longstatus_print(struct wt_status *s) +{ enum fsmonitor_mode fsm_mode = fsm_settings__get_mode(s->repo); if (s->branch) { - const char *on_what = _("On branch "); const char *branch_name = s->branch; - if (!strcmp(branch_name, "HEAD")) { - branch_status_color = color(WT_STATUS_NOBRANCH, s); - if (s->state.rebase_in_progress || - s->state.rebase_interactive_in_progress) { - if (s->state.rebase_interactive_in_progress) - on_what = _("interactive rebase in progress; onto "); - else - on_what = _("rebase in progress; onto "); - branch_name = s->state.onto; - } else if (s->state.detached_from) { - branch_name = s->state.detached_from; - if (s->state.detached_at) - on_what = _("HEAD detached at "); - else - on_what = _("HEAD detached from "); - } else { - branch_name = ""; - on_what = _("Not currently on any branch."); - } - } else - skip_prefix(branch_name, "refs/heads/", &branch_name); status_printf(s, color(WT_STATUS_HEADER, s), "%s", ""); - status_printf_more(s, branch_status_color, "%s", on_what); - status_printf_more(s, branch_color, "%s\n", branch_name); + wt_longstatus_print_onwhat(s, branch_name); if (!s->is_initial) wt_longstatus_print_tracking(s); } @@ -2133,6 +2141,17 @@ static void wt_shortstatus_print(struct wt_status *s) wt_shortstatus_other(it, s, "!!"); } +static void wt_tablestatus_print(struct wt_status *s) +{ + if (s->show_branch) { + const char *branch_name = s->branch; + wt_longstatus_print_onwhat(s, branch_name); + wt_longstatus_print_tracking(s); + } + + build_and_draw_status_table(s); +} + static void wt_porcelain_print(struct wt_status *s) { s->use_color = 0; @@ -2560,6 +2579,9 @@ void wt_status_print(struct wt_status *s) case STATUS_FORMAT_LONG: wt_longstatus_print(s); break; + case STATUS_FORMAT_TABLE: + wt_tablestatus_print(s); + break; } trace2_region_leave("status", "print", s->repo); diff --git a/wt-status.h b/wt-status.h index ab9cc9d8f0..70a3b7a2e4 100644 --- a/wt-status.h +++ b/wt-status.h @@ -73,6 +73,7 @@ enum wt_status_format { STATUS_FORMAT_SHORT, STATUS_FORMAT_PORCELAIN, STATUS_FORMAT_PORCELAIN_V2, + STATUS_FORMAT_TABLE, STATUS_FORMAT_UNSPECIFIED }; From patchwork Fri Oct 20 18:39:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Stopak X-Patchwork-Id: 13431024 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 24FAD8F74 for ; Fri, 20 Oct 2023 18:39:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=initialcommit-io.20230601.gappssmtp.com header.i=@initialcommit-io.20230601.gappssmtp.com header.b="R8AwjxCV" Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 66AE8D5F for ; Fri, 20 Oct 2023 11:39:55 -0700 (PDT) Received: by mail-pj1-x102b.google.com with SMTP id 98e67ed59e1d1-27d104fa285so965507a91.2 for ; Fri, 20 Oct 2023 11:39:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=initialcommit-io.20230601.gappssmtp.com; s=20230601; t=1697827194; x=1698431994; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=6nNhvW8l9ieWflD01LAdyFAexuLSlkB+F28Sdzp57fA=; b=R8AwjxCVs1t8HCiTUAa5fxJkVHbnYbmyX+Ov6wh+JOFB0WyQwkRquEThwhPUGS9vqy +YUL9IrGrbIYmueLwWVr+FCCZxk3A+UURBvtPn29WQTCSjDdUoTS4w7wR1Nmi9f3o6HO HOcbgMYiZmUI9FrXsWQ0O29e9gM0ifOIjZa3fnodKFIeho6UU4yrcGIgJfG9HKfzFTGT wTR+DiJvRAkLJ+Pc+Kh2G7fP5KQbHQKXK3RrlZuBL6ISd5wEknMBlVcojzPyOoa0yeot FKYa+VCn86xA0ZnFtTsRBH6XfeGDO9S8a/X3JPpHQ3Y/Z/abAAquwE/Gvcgvn81o2tQF 9w3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697827195; x=1698431995; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6nNhvW8l9ieWflD01LAdyFAexuLSlkB+F28Sdzp57fA=; b=st8SSRlYzNZPqFAKflwfIRtHE2Vfu0UXeprekKGL/Cv+iHioXS0D08U8ow1/dymDva 0oohxwcONaQMFlmkmOQMkLVXPV7DBx04f3RT0hEx+W7p2uS4bw8xyWHENNAS4c6XuHna 09leIyjX8WsKfcuH0UIKyQYTVEfUi4DLyUdTxwQwStPkHH9kR/RGlwGTJl12fp/fUreg f4+MYRM495CERIE0TH18Tgvxy3pmLse6/ucy+VZg+35cxZ7+dutlQF9qZ7paELTbUxzt Kp4EvaSICOD8CT7Nv3zk9mybtTNhdCdjvkcjdM9XBJrSrwX2ubkIkvkxGtvl7AR1EQwf HTVQ== X-Gm-Message-State: AOJu0YyqSjOrR4KPF9HKieKQtS8VjffLTxoUVN8xFQ6LvZM81PpMsx1z WLSLmwF8Im0ltVcEDa5OQWXrUliO41K6WP8oMsCJ939e5aM= X-Google-Smtp-Source: AGHT+IGKNwjgJ7ZIG+2M+UquAYCv5ri3is4YGfYIWW26LWA+yYlEZRv5/KhOUARUm+LlF2oOvkOpnQ== X-Received: by 2002:a17:90a:41:b0:27d:d9d:c54d with SMTP id 1-20020a17090a004100b0027d0d9dc54dmr2645530pjb.34.1697827194693; Fri, 20 Oct 2023 11:39:54 -0700 (PDT) Received: from localhost.localdomain (mobile-166-170-46-176.mycingular.net. [166.170.46.176]) by smtp.gmail.com with ESMTPSA id s15-20020a17090a5d0f00b0027e022bd62fsm2994353pji.5.2023.10.20.11.39.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 11:39:54 -0700 (PDT) From: Jacob Stopak To: git@vger.kernel.org Cc: Jacob Stopak Subject: [RFC PATCH 2/5] status: handle long paths with -t, --table flag Date: Fri, 20 Oct 2023 11:39:44 -0700 Message-ID: <20231020183947.463882-3-jacob@initialcommit.io> X-Mailer: git-send-email 2.42.0.402.gbe8243af7b.dirty In-Reply-To: <20231020183947.463882-1-jacob@initialcommit.io> References: <20231020183947.463882-1-jacob@initialcommit.io> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Signed-off-by: Jacob Stopak --- table.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/table.c b/table.c index 54cf9e4d07..87b6df8c66 100644 --- a/table.c +++ b/table.c @@ -25,15 +25,44 @@ static void build_table_border(struct strbuf *buf, int cols) static void build_table_entry(struct strbuf *buf, char *entry, int cols) { + int len = strlen(entry); + size_t col_width = (cols / 3) - 5; /* subtract for padding */ + strbuf_reset(buf); - strbuf_addchars(buf, ' ', (cols / 3 - 1 - strlen(entry)) / 2); + + /* Trim equally from both sides if it doesn't fit in column */ + if (len > col_width) { + struct strbuf start_buf = STRBUF_INIT; + struct strbuf end_buf = STRBUF_INIT; + struct strbuf entry_buf = STRBUF_INIT; + + strbuf_addstr(&start_buf, entry); + strbuf_addstr(&end_buf, entry); + + strbuf_remove(&start_buf, col_width / 2, len - col_width / 2); + strbuf_remove(&end_buf, 0, len - col_width / 2); + + strbuf_addstr(&entry_buf, start_buf.buf); + strbuf_addstr(&entry_buf, "..."); + strbuf_addstr(&entry_buf, end_buf.buf); + + entry = strbuf_detach(&entry_buf, &col_width); + len = strlen(entry); + + strbuf_release(&start_buf); + strbuf_release(&end_buf); + strbuf_release(&entry_buf); + } + + strbuf_addchars(buf, ' ', (cols / 3 - len - 1) / 2); /* left padding */ strbuf_addstr(buf, entry); - /* Bump right padding if entry length is odd */ - if (!(strlen(entry) % 2)) - strbuf_addchars(buf, ' ', (cols / 3 - 1 - strlen(entry)) / 2 + 1); + /* right padding */ + if (!(len % 2)) + /* Bump right padding if entry length is odd */ + strbuf_addchars(buf, ' ', (cols / 3 - len - 1) / 2 + 1); else - strbuf_addchars(buf, ' ', (cols / 3 - 1 - strlen(entry)) / 2); + strbuf_addchars(buf, ' ', (cols / 3 - len - 1) / 2); } static void print_table_body_line(struct strbuf *buf1, struct strbuf *buf2, struct strbuf *buf3, struct wt_status *s) From patchwork Fri Oct 20 18:39:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Stopak X-Patchwork-Id: 13431025 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C2CAF1DA4F for ; Fri, 20 Oct 2023 18:39:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=initialcommit-io.20230601.gappssmtp.com header.i=@initialcommit-io.20230601.gappssmtp.com header.b="rfz3Az0Z" Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6B48CD63 for ; Fri, 20 Oct 2023 11:39:56 -0700 (PDT) Received: by mail-pj1-x1032.google.com with SMTP id 98e67ed59e1d1-27d3ede72f6so989392a91.1 for ; Fri, 20 Oct 2023 11:39:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=initialcommit-io.20230601.gappssmtp.com; s=20230601; t=1697827195; x=1698431995; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=dfp2jpXzcwpQzfwsObm+2FqmG2xIpjyIXGdvyhBV93c=; b=rfz3Az0ZbmHZIvFTFBI+l5UKRX05N9U7gn4AUIWpyJZrrQuZalmdR0NqpO9nU8yxhS tdIk1khDXC+oyQWeHyGqCJ2zV2xtr8pmcCGXwViZGjw9zG+oPcuN3lm/xUtqaY+Rlh7D kS6YOAv128spsw08v9TU3ldD1cKRd0iklpojQ3rEvCx6QhLP+JUfZG8Yb6uhMqmEn+A9 nU3pHVbVUTUWRtaYCXDSEnL3h+c8kQoKTjJTgNPFI/PyHejsx55M2Nbh+Y16EEeSfRtQ rG1LWOyZhmU/Aq7jlr78Lo00DZO59PPevBn2AjmEtNnsz06IkcUQw4RaeknTOG1ZSDAJ MHgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697827195; x=1698431995; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dfp2jpXzcwpQzfwsObm+2FqmG2xIpjyIXGdvyhBV93c=; b=uCqWAq2TEV1ss1fjCscEOTary2aZWe10Zpsquvo3fr56uGIIiuWD6klFsuifcuHvbD rXI7t56tDul6FH9yUOK/lfuDXsIF7M0XodBsgf1sEQTsSvwiPnX4CNSGAH1JQ6PKcqRj 1Z8TllduKIQUCKoS72ywGv9GHKlOw/csngFlWJ8TV7NRm3H6oj1XQJkofEYXetzPL9/T wwtYlt+E3Np7nrXr+penfk+7Bur++txsgOCL8y+y9rpns3WZfgsBfENPitPZ5NPkJ/yo 7POAWdGpe61wuhdwGPZpqdD4maJairqKcFDftOEXDZqAmIAtK0DgC+Bm7sgTfwL2FsWS +91A== X-Gm-Message-State: AOJu0YxWTjrM8V2c44cB5P8s/nGaLniycY6ZxVdMxpqy3obdElpjbkPd 11/7//tVSrvjAIDkDWxuW3kvg87E3Ya2/Qax1FRarENjZ2M= X-Google-Smtp-Source: AGHT+IGbi6JCj0I/W1pDZgZpWdGdoIzTyViSgjdtEFHwcIZnvQQ7zPV6Yctcb6FZelqVHSNhSm/KFg== X-Received: by 2002:a17:90a:d181:b0:27d:46c5:5e20 with SMTP id fu1-20020a17090ad18100b0027d46c55e20mr2593427pjb.39.1697827195609; Fri, 20 Oct 2023 11:39:55 -0700 (PDT) Received: from localhost.localdomain (mobile-166-170-46-176.mycingular.net. [166.170.46.176]) by smtp.gmail.com with ESMTPSA id s15-20020a17090a5d0f00b0027e022bd62fsm2994353pji.5.2023.10.20.11.39.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 11:39:55 -0700 (PDT) From: Jacob Stopak To: git@vger.kernel.org Cc: Jacob Stopak Subject: [RFC PATCH 3/5] status: add advice arg for -t, --table flag Date: Fri, 20 Oct 2023 11:39:45 -0700 Message-ID: <20231020183947.463882-4-jacob@initialcommit.io> X-Mailer: git-send-email 2.42.0.402.gbe8243af7b.dirty In-Reply-To: <20231020183947.463882-1-jacob@initialcommit.io> References: <20231020183947.463882-1-jacob@initialcommit.io> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Signed-off-by: Jacob Stopak --- table.c | 19 +++++++++++++++++-- table.h | 2 +- wt-status.c | 2 +- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/table.c b/table.c index 87b6df8c66..73751339da 100644 --- a/table.c +++ b/table.c @@ -76,7 +76,7 @@ static void print_table_body_line(struct strbuf *buf1, struct strbuf *buf2, stru printf(_("|\n")); } -void build_and_draw_status_table(struct wt_status *s) +void build_and_draw_status_table(struct wt_status *s, int add_advice) { struct winsize w; int cols; @@ -95,14 +95,29 @@ void build_and_draw_status_table(struct wt_status *s) cols -= 1; } + /* Draw table header */ build_table_border(&table_border, cols); build_table_entry(&table_col_entry_1, "Untracked files", cols); build_table_entry(&table_col_entry_2, "Changes not staged for commit", cols); build_table_entry(&table_col_entry_3, "Changes to be committed", cols); - /* Draw table header */ printf(_("%s\n"), table_border.buf); printf(_("|%s|%s|%s|\n"), table_col_entry_1.buf, table_col_entry_2.buf, table_col_entry_3.buf); + + if (add_advice) { + build_table_entry(&table_col_entry_1, "(stage: git add )", cols); + build_table_entry(&table_col_entry_2, "(stage: git add )", cols); + build_table_entry(&table_col_entry_3, "(unstage: git restore --staged )", cols); + + printf(_("|%s|%s|%s|\n"), table_col_entry_1.buf, table_col_entry_2.buf, table_col_entry_3.buf); + + build_table_entry(&table_col_entry_1, "", cols); + build_table_entry(&table_col_entry_2, "(discard: git restore --staged )", cols); + build_table_entry(&table_col_entry_3, "", cols); + + printf(_("|%s|%s|%s|\n"), table_col_entry_1.buf, table_col_entry_2.buf, table_col_entry_3.buf); + } + printf(_("%s\n"), table_border.buf); /* Draw table body */ diff --git a/table.h b/table.h index 30e0d5509b..6017923bf9 100644 --- a/table.h +++ b/table.h @@ -1,6 +1,6 @@ #ifndef TABLE_H #define TABLE_H -void build_and_draw_status_table(struct wt_status *s); +void build_and_draw_status_table(struct wt_status *s, int i); #endif /* TABLE_H */ diff --git a/wt-status.c b/wt-status.c index 24b56ea559..62731859fe 100644 --- a/wt-status.c +++ b/wt-status.c @@ -2149,7 +2149,7 @@ static void wt_tablestatus_print(struct wt_status *s) wt_longstatus_print_tracking(s); } - build_and_draw_status_table(s); + build_and_draw_status_table(s, 0); } static void wt_porcelain_print(struct wt_status *s) From patchwork Fri Oct 20 18:39:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Stopak X-Patchwork-Id: 13431027 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CCF832230A for ; Fri, 20 Oct 2023 18:39:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=initialcommit-io.20230601.gappssmtp.com header.i=@initialcommit-io.20230601.gappssmtp.com header.b="T13vx0bl" Received: from mail-pj1-x1042.google.com (mail-pj1-x1042.google.com [IPv6:2607:f8b0:4864:20::1042]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 695DC112 for ; Fri, 20 Oct 2023 11:39:57 -0700 (PDT) Received: by mail-pj1-x1042.google.com with SMTP id 98e67ed59e1d1-27d0acd0903so848068a91.1 for ; Fri, 20 Oct 2023 11:39:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=initialcommit-io.20230601.gappssmtp.com; s=20230601; t=1697827197; x=1698431997; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Sod9M6iu41DhYV1VjaGV23OczvduFxd20PUI5amSiXU=; b=T13vx0bl2hxxC0Q5Pt6t9aeQXjXJmhHMU/mV16IGEHMjnuWbJAoPbwLR92srAi58Ap 6CPjvg9uR1+YxQ28mJbR7QA8/V5bQThuJkBCvGUzTEOJT9iTJr4zrkvv4YTbLEXR1MoC YBS9aCBJ61tBpprP04uA6w6d+PkcMLl9OQpjvlrIpuod+xXgNbxwpF0xKv4U5LKCgNmA Nb1EaSDGrA5+a2vtlR+f6VKK3Agjw+9QSM9GA3ZU7Yqz0C6VhriiB9omJQnP/6OUBWSy poyKajy2+ahUcEH9/dJHAmY33D4++VOgK9yp9ZIyV0nY6cExBluXmjUC5GkXevHdCaH9 yjwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697827197; x=1698431997; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Sod9M6iu41DhYV1VjaGV23OczvduFxd20PUI5amSiXU=; b=bn9ivFhyfor9AdnCA/KdBs31ZDp9H3Ar57rUrXBE6UXm35L1nPJ6cSAo7gHkm59xUV SX6oTh1Uk2wGol5cBERCqAfirz2FqGVpiH1hB64p9vahie9nrWkCzP0ebBET8kx6OoK+ MZgdI5TePFMehkeiaidFD+zNqtS9aVcnG83prrmiGUZnovvvFxp8d+XjRYKOcjp60/Xu nJcwG4oZ6rDwGn1PsK3Wxrw45D5JOiPM9MmPOnZoyNtNjzl82mcqDmmGdT9OLdLkAaxa wUNKedFpC/+aJIK5PYjM3wHwDVUH3+naqRD0CzieXMEBX+LZXT7uIvy3/ljNrFdDc+UB OG3Q== X-Gm-Message-State: AOJu0YwzZOdETCCDzCoukIFXK12ybss6bAsdaXgI34Joij+gU+Fepfs/ WZviaeW+D0TxPbb8LRHw8kWK4Ray6gum3FgQrKXT6DVyh5fGBg== X-Google-Smtp-Source: AGHT+IH/N0NVd+3LdF8U+39Gk/0Ek+Xx9L4tY9ioQwiJU1k1ujla0U7jOynkzmkoke3wWwQ/zVjO3A== X-Received: by 2002:a17:90b:4cd0:b0:27d:2054:27b1 with SMTP id nd16-20020a17090b4cd000b0027d205427b1mr2601829pjb.32.1697827196576; Fri, 20 Oct 2023 11:39:56 -0700 (PDT) Received: from localhost.localdomain (mobile-166-170-46-176.mycingular.net. [166.170.46.176]) by smtp.gmail.com with ESMTPSA id s15-20020a17090a5d0f00b0027e022bd62fsm2994353pji.5.2023.10.20.11.39.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 11:39:56 -0700 (PDT) From: Jacob Stopak To: git@vger.kernel.org Cc: Jacob Stopak Subject: [RFC PATCH 4/5] add: add -t, --table flag for visual dry runs Date: Fri, 20 Oct 2023 11:39:46 -0700 Message-ID: <20231020183947.463882-5-jacob@initialcommit.io> X-Mailer: git-send-email 2.42.0.402.gbe8243af7b.dirty In-Reply-To: <20231020183947.463882-1-jacob@initialcommit.io> References: <20231020183947.463882-1-jacob@initialcommit.io> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Signed-off-by: Jacob Stopak --- builtin/add.c | 46 ++++++++++++++++++------ builtin/commit.c | 2 +- read-cache-ll.h | 9 ++++- read-cache.c | 32 ++++++++++++++--- table.c | 92 +++++++++++++++++++++++++++++++++++++++++++----- wt-status.c | 1 + wt-status.h | 1 + 7 files changed, 157 insertions(+), 26 deletions(-) diff --git a/builtin/add.c b/builtin/add.c index c27254a5cd..35ea1deda5 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -27,6 +27,7 @@ #include "strvec.h" #include "submodule.h" #include "add-interactive.h" +#include "wt-status.h" static const char * const builtin_add_usage[] = { N_("git add [] [--] ..."), @@ -221,7 +222,7 @@ N_("The following paths are ignored by one of your .gitignore files:\n"); static int verbose, show_only, ignored_too, refresh_only; static int ignore_add_errors, intent_to_add, ignore_missing; -static int warn_on_embedded_repo = 1; +static int table_format, warn_on_embedded_repo = 1; #define ADDREMOVE_DEFAULT 1 static int addremove = ADDREMOVE_DEFAULT; @@ -264,6 +265,8 @@ static struct option builtin_add_options[] = { N_("warn when adding an embedded repository")), OPT_PATHSPEC_FROM_FILE(&pathspec_from_file), OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul), + OPT_SET_INT('t', "table", &table_format, + N_("show status in table format"), STATUS_FORMAT_TABLE), OPT_END(), }; @@ -322,7 +325,7 @@ static void check_embedded_repo(const char *path) strbuf_release(&name); } -static int add_files(struct dir_struct *dir, int flags) +static int add_files(struct dir_struct *dir, int flags, struct wt_status *status) { int i, exit_status = 0; struct string_list matched_sparse_paths = STRING_LIST_INIT_NODUP; @@ -345,7 +348,7 @@ static int add_files(struct dir_struct *dir, int flags) dir->entries[i]->name); continue; } - if (add_file_to_index(&the_index, dir->entries[i]->name, flags)) { + if (add_file_to_index_with_status(&the_index, dir->entries[i]->name, flags, status)) { if (!ignore_add_errors) die(_("adding files failed")); exit_status = 1; @@ -374,6 +377,8 @@ int cmd_add(int argc, const char **argv, const char *prefix) int require_pathspec; char *seen = NULL; struct lock_file lock_file = LOCK_INIT; + struct wt_status status; + unsigned int progress_flag = 0; git_config(add_config, NULL); @@ -459,7 +464,8 @@ int cmd_add(int argc, const char **argv, const char *prefix) (intent_to_add ? ADD_CACHE_INTENT : 0) | (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) | (!(addremove || take_worktree_changes) - ? ADD_CACHE_IGNORE_REMOVAL : 0)); + ? ADD_CACHE_IGNORE_REMOVAL : 0) | + (table_format ? ADD_CACHE_FORMAT_TABLE : 0)); if (repo_read_index_preload(the_repository, &pathspec, 0) < 0) die(_("index file corrupt")); @@ -551,15 +557,35 @@ int cmd_add(int argc, const char **argv, const char *prefix) begin_odb_transaction(); - if (add_renormalize) + if (show_only && table_format) { + /* Prepare index and populate status */ + wt_status_prepare(the_repository, &status); + git_config(git_default_config, &status); + repo_read_index(the_repository); + refresh_index(&the_index, + REFRESH_QUIET|REFRESH_UNMERGED|progress_flag, + &status.pathspec, NULL, NULL); + status.status_format = STATUS_FORMAT_TABLE; + status.show_branch = 0; + } + + if (add_renormalize) { exit_status |= renormalize_tracked_files(&pathspec, flags); - else - exit_status |= add_files_to_cache(the_repository, prefix, + } else { + exit_status |= add_files_to_cache_with_status(the_repository, prefix, &pathspec, include_sparse, - flags); + flags, &status); + } - if (add_new_files) - exit_status |= add_files(&dir, flags); + if (add_new_files) { + exit_status |= add_files(&dir, flags, &status); + } + + if (show_only && table_format) { + wt_status_collect(&status); + wt_status_print(&status); + wt_status_collect_free_buffers(&status); + } if (chmod_arg && pathspec.nr) exit_status |= chmod_pathspec(&pathspec, chmod_arg[0], show_only); diff --git a/builtin/commit.c b/builtin/commit.c index 4338896dbf..33b15ef96e 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -310,7 +310,7 @@ static void add_remove_files(struct string_list *list) continue; if (!lstat(p->string, &st)) { - if (add_to_index(&the_index, p->string, &st, 0)) + if (add_file_to_index(&the_index, p->string, 0)) die(_("updating files failed")); } else remove_file_from_index(&the_index, p->string); diff --git a/read-cache-ll.h b/read-cache-ll.h index 9a1a7edc5a..b1cee2c7ee 100644 --- a/read-cache-ll.h +++ b/read-cache-ll.h @@ -4,6 +4,7 @@ #include "hash-ll.h" #include "hashmap.h" #include "statinfo.h" +#include "wt-status.h" /* * Basic data structures for the directory cache @@ -395,6 +396,7 @@ int remove_file_from_index(struct index_state *, const char *path); #define ADD_CACHE_IGNORE_ERRORS 4 #define ADD_CACHE_IGNORE_REMOVAL 8 #define ADD_CACHE_INTENT 16 +#define ADD_CACHE_FORMAT_TABLE 32 /* * These two are used to add the contents of the file at path * to the index, marking the working tree up-to-date by storing @@ -404,7 +406,8 @@ int remove_file_from_index(struct index_state *, const char *path); * the latter will do necessary lstat(2) internally before * calling the former. */ -int add_to_index(struct index_state *, const char *path, struct stat *, int flags); +int add_to_index(struct index_state *, const char *path, struct stat *, int flags, struct wt_status *status); +int add_file_to_index_with_status(struct index_state *, const char *path, int flags, struct wt_status *status); int add_file_to_index(struct index_state *, const char *path, int flags); int chmod_index_entry(struct index_state *, struct cache_entry *ce, char flip); @@ -475,6 +478,10 @@ int add_files_to_cache(struct repository *repo, const char *prefix, const struct pathspec *pathspec, int include_sparse, int flags); +int add_files_to_cache_with_status(struct repository *repo, const char *prefix, + const struct pathspec *pathspec, int include_sparse, + int flags, struct wt_status *status); + void overlay_tree_on_index(struct index_state *istate, const char *tree_name, const char *prefix); diff --git a/read-cache.c b/read-cache.c index 080bd39713..e777cdb210 100644 --- a/read-cache.c +++ b/read-cache.c @@ -45,6 +45,8 @@ #include "csum-file.h" #include "promisor-remote.h" #include "hook.h" +#include "wt-status.h" +#include "string-list.h" /* Mask for the name length in ce_flags in the on-disk index */ @@ -664,7 +666,7 @@ void set_object_name_for_intent_to_add_entry(struct cache_entry *ce) oidcpy(&ce->oid, &oid); } -int add_to_index(struct index_state *istate, const char *path, struct stat *st, int flags) +int add_to_index(struct index_state *istate, const char *path, struct stat *st, int flags, struct wt_status *status) { int namelen, was_same; mode_t st_mode = st->st_mode; @@ -672,6 +674,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st, unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE|CE_MATCH_RACY_IS_DIRTY; int verbose = flags & (ADD_CACHE_VERBOSE | ADD_CACHE_PRETEND); int pretend = flags & ADD_CACHE_PRETEND; + int table = flags & ADD_CACHE_FORMAT_TABLE; int intent_only = flags & ADD_CACHE_INTENT; int add_option = (ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE| (intent_only ? ADD_CACHE_NEW_ONLY : 0)); @@ -760,17 +763,26 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st, discard_cache_entry(ce); return error(_("unable to add '%s' to index"), path); } - if (verbose && !was_same) + if (verbose && !was_same && !table) printf("add '%s'\n", path); + if (table && pretend && !was_same) { + string_list_insert(&status->dry_run_added, path); + } return 0; } -int add_file_to_index(struct index_state *istate, const char *path, int flags) +int add_file_to_index_with_status(struct index_state *istate, const char *path, int flags, struct wt_status *status) { struct stat st; if (lstat(path, &st)) die_errno(_("unable to stat '%s'"), path); - return add_to_index(istate, path, &st, flags); + return add_to_index(istate, path, &st, flags, status); +} + +int add_file_to_index(struct index_state *istate, const char *path, int flags) +{ + struct wt_status status; + return add_file_to_index_with_status(istate, path, flags, &status); } struct cache_entry *make_empty_cache_entry(struct index_state *istate, size_t len) @@ -3872,6 +3884,7 @@ struct update_callback_data { int include_sparse; int flags; int add_errors; + struct wt_status *status; }; static int fix_unmerged_status(struct diff_filepair *p, @@ -3914,7 +3927,7 @@ static void update_callback(struct diff_queue_struct *q, die(_("unexpected diff status %c"), p->status); case DIFF_STATUS_MODIFIED: case DIFF_STATUS_TYPE_CHANGED: - if (add_file_to_index(data->index, path, data->flags)) { + if (add_file_to_index_with_status(data->index, path, data->flags, data->status)) { if (!(data->flags & ADD_CACHE_IGNORE_ERRORS)) die(_("updating files failed")); data->add_errors++; @@ -3935,6 +3948,14 @@ static void update_callback(struct diff_queue_struct *q, int add_files_to_cache(struct repository *repo, const char *prefix, const struct pathspec *pathspec, int include_sparse, int flags) +{ + struct wt_status status; + return add_files_to_cache_with_status(repo, prefix, pathspec, include_sparse, flags, &status); +} + +int add_files_to_cache_with_status(struct repository *repo, const char *prefix, + const struct pathspec *pathspec, int include_sparse, + int flags, struct wt_status *status) { struct update_callback_data data; struct rev_info rev; @@ -3943,6 +3964,7 @@ int add_files_to_cache(struct repository *repo, const char *prefix, data.index = repo->index; data.include_sparse = include_sparse; data.flags = flags; + data.status = status; repo_init_revisions(repo, &rev, prefix); setup_revisions(0, NULL, &rev, NULL); diff --git a/table.c b/table.c index 73751339da..a6fc660fec 100644 --- a/table.c +++ b/table.c @@ -65,18 +65,53 @@ static void build_table_entry(struct strbuf *buf, char *entry, int cols) strbuf_addchars(buf, ' ', (cols / 3 - len - 1) / 2); } -static void print_table_body_line(struct strbuf *buf1, struct strbuf *buf2, struct strbuf *buf3, struct wt_status *s) +static void add_arrow_to_entry(struct strbuf *buf, int add_after_entry) +{ + struct strbuf empty = STRBUF_INIT; + struct strbuf trimmed = STRBUF_INIT; + struct strbuf holder = STRBUF_INIT; + int len = strlen(buf->buf); + + strbuf_addstr(&trimmed, buf->buf); + strbuf_trim(&trimmed); + + if (!strbuf_cmp(&trimmed, &empty) && !add_after_entry) { + strbuf_reset(buf); + strbuf_addchars(buf, '-', len + 1); + } else if (add_after_entry) { + strbuf_rtrim(buf); + strbuf_addchars(buf, ' ', 1); + strbuf_addchars(buf, '-', len - strlen(buf->buf) + 1); + } else if (!add_after_entry) { + strbuf_ltrim(buf); + strbuf_addchars(&holder, '-', len - strlen(buf->buf) - 2); + strbuf_addchars(&holder, '>', 1); + strbuf_addchars(&holder, ' ', 1); + strbuf_addstr(&holder, buf->buf); + strbuf_reset(buf); + strbuf_addstr(buf, holder.buf); + } +} + +static void print_table_body_line(struct strbuf *buf1, struct strbuf *buf2, struct strbuf *buf3, struct wt_status *s, int hide_pipe) { printf(_("|")); color_fprintf(s->fp, color(WT_STATUS_UNTRACKED, s), "%s", buf1->buf); - printf(_("|")); + if (hide_pipe != 1 && hide_pipe != 3) + printf(_("|")); color_fprintf(s->fp, color(WT_STATUS_CHANGED, s), "%s", buf2->buf); - printf(_("|")); + if (hide_pipe != 2 && hide_pipe != 3) + printf(_("|")); color_fprintf(s->fp, color(WT_STATUS_UPDATED, s), "%s", buf3->buf); printf(_("|\n")); } -void build_and_draw_status_table(struct wt_status *s, int add_advice) +static void print_table_body_line_(struct strbuf *buf1, struct strbuf *buf2, struct strbuf *buf3, struct wt_status *s) +{ + print_table_body_line(buf1, buf2, buf3, s, 0); +} + +void build_and_draw_status_table(struct wt_status *s, int advice) { struct winsize w; int cols; @@ -84,7 +119,7 @@ void build_and_draw_status_table(struct wt_status *s, int add_advice) struct strbuf table_col_entry_1 = STRBUF_INIT; struct strbuf table_col_entry_2 = STRBUF_INIT; struct strbuf table_col_entry_3 = STRBUF_INIT; - struct string_list_item *item; + struct string_list_item *item, *item2; /* Get terminal width */ ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); @@ -104,7 +139,7 @@ void build_and_draw_status_table(struct wt_status *s, int add_advice) printf(_("%s\n"), table_border.buf); printf(_("|%s|%s|%s|\n"), table_col_entry_1.buf, table_col_entry_2.buf, table_col_entry_3.buf); - if (add_advice) { + if (advice) { build_table_entry(&table_col_entry_1, "(stage: git add )", cols); build_table_entry(&table_col_entry_2, "(stage: git add )", cols); build_table_entry(&table_col_entry_3, "(unstage: git restore --staged )", cols); @@ -122,14 +157,38 @@ void build_and_draw_status_table(struct wt_status *s, int add_advice) /* Draw table body */ for_each_string_list_item(item, &s->untracked) { - build_table_entry(&table_col_entry_1, item->string, cols); + struct strbuf buf_1 = STRBUF_INIT; + struct strbuf buf_2 = STRBUF_INIT; + int is_arrow = 0; + strbuf_addstr(&buf_1, item->string); + build_table_entry(&table_col_entry_1, buf_1.buf, cols); build_table_entry(&table_col_entry_2, "", cols); build_table_entry(&table_col_entry_3, "", cols); - print_table_body_line(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, s); + + for_each_string_list_item(item2, &s->dry_run_added) { + strbuf_reset(&buf_2); + strbuf_addstr(&buf_2, item2->string); + if (!strbuf_cmp(&buf_1, &buf_2)) { + build_table_entry(&table_col_entry_3, buf_1.buf, cols); + add_arrow_to_entry(&table_col_entry_1, 1); + add_arrow_to_entry(&table_col_entry_2, 0); + add_arrow_to_entry(&table_col_entry_3, 0); + is_arrow = 1; + } + } + + if (!is_arrow) + print_table_body_line_(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, s); + else + print_table_body_line(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, s, 3); } for_each_string_list_item(item, &s->change) { struct wt_status_change_data *d = item->util; + struct strbuf buf_1 = STRBUF_INIT; + struct strbuf buf_2 = STRBUF_INIT; + int is_arrow = 0; + strbuf_addstr(&buf_1, item->string); if (d->worktree_status && d->index_status) { build_table_entry(&table_col_entry_1, "", cols); build_table_entry(&table_col_entry_2, item->string, cols); @@ -138,12 +197,27 @@ void build_and_draw_status_table(struct wt_status *s, int add_advice) build_table_entry(&table_col_entry_1, "", cols); build_table_entry(&table_col_entry_2, item->string, cols); build_table_entry(&table_col_entry_3, "", cols); + + for_each_string_list_item(item2, &s->dry_run_added) { + strbuf_reset(&buf_2); + strbuf_addstr(&buf_2, item2->string); + if (!strbuf_cmp(&buf_1, &buf_2)) { + build_table_entry(&table_col_entry_3, buf_1.buf, cols); + add_arrow_to_entry(&table_col_entry_2, 1); + add_arrow_to_entry(&table_col_entry_3, 0); + is_arrow = 1; + } + } } else if (d->index_status) { build_table_entry(&table_col_entry_1, "", cols); build_table_entry(&table_col_entry_2, "", cols); build_table_entry(&table_col_entry_3, item->string, cols); } - print_table_body_line(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, s); + + if (!is_arrow) + print_table_body_line_(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, s); + else + print_table_body_line(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, s, 2); } if (!s->untracked.nr && !s->change.nr) { diff --git a/wt-status.c b/wt-status.c index 62731859fe..975cfc01a5 100644 --- a/wt-status.c +++ b/wt-status.c @@ -153,6 +153,7 @@ void wt_status_prepare(struct repository *r, struct wt_status *s) s->change.strdup_strings = 1; s->untracked.strdup_strings = 1; s->ignored.strdup_strings = 1; + s->dry_run_added.strdup_strings = 1; s->show_branch = -1; /* unspecified */ s->show_stash = 0; s->ahead_behind_flags = AHEAD_BEHIND_UNSPECIFIED; diff --git a/wt-status.h b/wt-status.h index 70a3b7a2e4..5d29c058c1 100644 --- a/wt-status.h +++ b/wt-status.h @@ -142,6 +142,7 @@ struct wt_status { struct string_list change; struct string_list untracked; struct string_list ignored; + struct string_list dry_run_added; uint32_t untracked_in_ms; }; From patchwork Fri Oct 20 18:39:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Stopak X-Patchwork-Id: 13431026 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7E482208BE for ; Fri, 20 Oct 2023 18:39:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=initialcommit-io.20230601.gappssmtp.com header.i=@initialcommit-io.20230601.gappssmtp.com header.b="hMO8PUZb" Received: from mail-pj1-x1041.google.com (mail-pj1-x1041.google.com [IPv6:2607:f8b0:4864:20::1041]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2587E114 for ; Fri, 20 Oct 2023 11:39:58 -0700 (PDT) Received: by mail-pj1-x1041.google.com with SMTP id 98e67ed59e1d1-27e1eea2f0dso423150a91.1 for ; Fri, 20 Oct 2023 11:39:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=initialcommit-io.20230601.gappssmtp.com; s=20230601; t=1697827197; x=1698431997; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Svq8NxQV/OT0dUN7+ij2gVZXDdztRgBFcT6CDxcaC0w=; b=hMO8PUZbgrCKFxPyQcNWweqlQ+KVESGj1u9XXJs2ZAYnHtM4YiJXrcTLqLzuGl1cMs CvYiloxcFNEnPaVOJ//NoqEDRFuLlX/uIofF2lVR2PPdLnzwhsWM5pCeMDVoCIGo8ECD BR/vVgqyOepbYa412CLOxkYYRDED5sYd0p7J9uYeNuTlFlud3dyomf6RpauXiqb5y5IT 50i1pFU3Z4+yeBEYmdSb4m4ErId7gcqdCBdhfmbJqzVhnSLHOSsjast5SvknEMuqgk1C zrcS3HUrPI6bWhhtumtJLME3b/C9r9dpvWHgyywCmX3tvV3LDVbPHuMTLGwRne9dIiVt Ih/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697827197; x=1698431997; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Svq8NxQV/OT0dUN7+ij2gVZXDdztRgBFcT6CDxcaC0w=; b=vKzg6n2OU02PmnwLlS7/+5zvPzMAI8k5t2ClKzPxr88GAgxel4ynuAhgFPSrj4HBEA SaRA25XF9tQ50H4X7JRnwB67A4i+wVKRKVo9BeI12WwuMfhgjOrhO3D4z9ptFfWM7JuX HILTecX0QDVPIvPp5WFu66mudWIiasaFIB30Bm00ORe6GVMbZw2oHkZAvIeGnzyKblN9 roVD+wWpr6nb3/HT18Xwy/tUuCe3jTpN7cyU2HaL/SZTHE/Xv+DfAQHz8SZqkg2iJWwk 83FrNFgRvKagy2uXSduiSMpMC2UPHBn6JEFZ0grnYVAQZ/epI8TK60wrpAF19YZ1AUYk awTQ== X-Gm-Message-State: AOJu0YxRBS1uYt8O5a34hZpQsTW/B8V1DYfoS9QWj7U1IQ1HUMaYduTn vkpfF/uYEz81/6usLsJqqn3F8RGrsXbeSL5OMS3GIRQnntLhYg== X-Google-Smtp-Source: AGHT+IGxkUhl+tm8J6xawrU1GKE2eM84xv+GpNf6yAqeBUs9XfkFfo+T9cNqfcuUgq6Rm1M//kbEjw== X-Received: by 2002:a17:90a:54:b0:27d:2dde:597a with SMTP id 20-20020a17090a005400b0027d2dde597amr2840638pjb.10.1697827197388; Fri, 20 Oct 2023 11:39:57 -0700 (PDT) Received: from localhost.localdomain (mobile-166-170-46-176.mycingular.net. [166.170.46.176]) by smtp.gmail.com with ESMTPSA id s15-20020a17090a5d0f00b0027e022bd62fsm2994353pji.5.2023.10.20.11.39.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 11:39:57 -0700 (PDT) From: Jacob Stopak To: git@vger.kernel.org Cc: Jacob Stopak Subject: [RFC PATCH 5/5] add: set unique color for -t, --table arrows Date: Fri, 20 Oct 2023 11:39:47 -0700 Message-ID: <20231020183947.463882-6-jacob@initialcommit.io> X-Mailer: git-send-email 2.42.0.402.gbe8243af7b.dirty In-Reply-To: <20231020183947.463882-1-jacob@initialcommit.io> References: <20231020183947.463882-1-jacob@initialcommit.io> Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Signed-off-by: Jacob Stopak --- table.c | 62 +++++++++++++++++++++++++++++++---------------------- wt-status.c | 1 + wt-status.h | 1 + 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/table.c b/table.c index a6fc660fec..390b2e2dd9 100644 --- a/table.c +++ b/table.c @@ -5,6 +5,7 @@ #include "wt-status.h" #include "config.h" #include "string-list.h" +#include "color.h" #include "sys/ioctl.h" static const char *color(int slot, struct wt_status *s) @@ -65,52 +66,51 @@ static void build_table_entry(struct strbuf *buf, char *entry, int cols) strbuf_addchars(buf, ' ', (cols / 3 - len - 1) / 2); } -static void add_arrow_to_entry(struct strbuf *buf, int add_after_entry) +static void build_arrow(struct strbuf *buf, struct strbuf* arrow, int add_after_entry) { struct strbuf empty = STRBUF_INIT; struct strbuf trimmed = STRBUF_INIT; - struct strbuf holder = STRBUF_INIT; int len = strlen(buf->buf); + strbuf_reset(arrow); strbuf_addstr(&trimmed, buf->buf); strbuf_trim(&trimmed); if (!strbuf_cmp(&trimmed, &empty) && !add_after_entry) { strbuf_reset(buf); - strbuf_addchars(buf, '-', len + 1); + strbuf_addchars(arrow, '-', len + 1); } else if (add_after_entry) { strbuf_rtrim(buf); - strbuf_addchars(buf, ' ', 1); - strbuf_addchars(buf, '-', len - strlen(buf->buf) + 1); + strbuf_addchars(arrow, ' ', 1); + strbuf_addchars(arrow, '-', len - strlen(buf->buf) + 1); } else if (!add_after_entry) { strbuf_ltrim(buf); - strbuf_addchars(&holder, '-', len - strlen(buf->buf) - 2); - strbuf_addchars(&holder, '>', 1); - strbuf_addchars(&holder, ' ', 1); - strbuf_addstr(&holder, buf->buf); - strbuf_reset(buf); - strbuf_addstr(buf, holder.buf); + strbuf_addchars(arrow, '-', len - strlen(buf->buf) - 3); + strbuf_addchars(arrow, '>', 1); + strbuf_addchars(arrow, ' ', 1); } } -static void print_table_body_line(struct strbuf *buf1, struct strbuf *buf2, struct strbuf *buf3, struct wt_status *s, int hide_pipe) +static void print_table_body_line(struct strbuf *buf1, struct strbuf *buf2, struct strbuf *buf3, struct strbuf *arrow1, struct strbuf *arrow2, struct strbuf *arrow3, struct wt_status *s, int hide_pipe) { printf(_("|")); color_fprintf(s->fp, color(WT_STATUS_UNTRACKED, s), "%s", buf1->buf); + if (strlen(arrow1->buf) > 0) + color_fprintf(s->fp, color(WT_STATUS_ARROW, s), "%s", arrow1->buf); if (hide_pipe != 1 && hide_pipe != 3) printf(_("|")); color_fprintf(s->fp, color(WT_STATUS_CHANGED, s), "%s", buf2->buf); + if (strlen(arrow2->buf) > 0) + color_fprintf(s->fp, color(WT_STATUS_ARROW, s), "%s", arrow2->buf); if (hide_pipe != 2 && hide_pipe != 3) printf(_("|")); + if (strlen(arrow3->buf) > 0) { + color_fprintf(s->fp, color(WT_STATUS_ARROW, s), "%s", arrow3->buf); + } color_fprintf(s->fp, color(WT_STATUS_UPDATED, s), "%s", buf3->buf); printf(_("|\n")); } -static void print_table_body_line_(struct strbuf *buf1, struct strbuf *buf2, struct strbuf *buf3, struct wt_status *s) -{ - print_table_body_line(buf1, buf2, buf3, s, 0); -} - void build_and_draw_status_table(struct wt_status *s, int advice) { struct winsize w; @@ -119,6 +119,9 @@ void build_and_draw_status_table(struct wt_status *s, int advice) struct strbuf table_col_entry_1 = STRBUF_INIT; struct strbuf table_col_entry_2 = STRBUF_INIT; struct strbuf table_col_entry_3 = STRBUF_INIT; + struct strbuf arrow_1 = STRBUF_INIT; + struct strbuf arrow_2 = STRBUF_INIT; + struct strbuf arrow_3 = STRBUF_INIT; struct string_list_item *item, *item2; /* Get terminal width */ @@ -170,17 +173,21 @@ void build_and_draw_status_table(struct wt_status *s, int advice) strbuf_addstr(&buf_2, item2->string); if (!strbuf_cmp(&buf_1, &buf_2)) { build_table_entry(&table_col_entry_3, buf_1.buf, cols); - add_arrow_to_entry(&table_col_entry_1, 1); - add_arrow_to_entry(&table_col_entry_2, 0); - add_arrow_to_entry(&table_col_entry_3, 0); + build_arrow(&table_col_entry_1, &arrow_1, 1); + build_arrow(&table_col_entry_2, &arrow_2, 0); + build_arrow(&table_col_entry_3, &arrow_3, 0); is_arrow = 1; } } if (!is_arrow) - print_table_body_line_(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, s); + print_table_body_line(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, &arrow_1, &arrow_2, &arrow_3, s, 0); else - print_table_body_line(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, s, 3); + print_table_body_line(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, &arrow_1, &arrow_2, &arrow_3, s, 3); + + strbuf_reset(&arrow_1); + strbuf_reset(&arrow_2); + strbuf_reset(&arrow_3); } for_each_string_list_item(item, &s->change) { @@ -203,8 +210,8 @@ void build_and_draw_status_table(struct wt_status *s, int advice) strbuf_addstr(&buf_2, item2->string); if (!strbuf_cmp(&buf_1, &buf_2)) { build_table_entry(&table_col_entry_3, buf_1.buf, cols); - add_arrow_to_entry(&table_col_entry_2, 1); - add_arrow_to_entry(&table_col_entry_3, 0); + build_arrow(&table_col_entry_2, &arrow_2, 1); + build_arrow(&table_col_entry_3, &arrow_3, 0); is_arrow = 1; } } @@ -215,9 +222,12 @@ void build_and_draw_status_table(struct wt_status *s, int advice) } if (!is_arrow) - print_table_body_line_(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, s); + print_table_body_line(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, &arrow_1, &arrow_2, &arrow_3, s, 0); else - print_table_body_line(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, s, 2); + print_table_body_line(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, &arrow_1, &arrow_2, &arrow_3, s, 2); + strbuf_reset(&arrow_1); + strbuf_reset(&arrow_2); + strbuf_reset(&arrow_3); } if (!s->untracked.nr && !s->change.nr) { diff --git a/wt-status.c b/wt-status.c index 975cfc01a5..fe38260baa 100644 --- a/wt-status.c +++ b/wt-status.c @@ -49,6 +49,7 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = { GIT_COLOR_GREEN, /* WT_STATUS_LOCAL_BRANCH */ GIT_COLOR_RED, /* WT_STATUS_REMOTE_BRANCH */ GIT_COLOR_NIL, /* WT_STATUS_ONBRANCH */ + GIT_COLOR_CYAN, /* WT_STATUS_ARROW */ }; static const char *color(int slot, struct wt_status *s) diff --git a/wt-status.h b/wt-status.h index 5d29c058c1..0517f81e1b 100644 --- a/wt-status.h +++ b/wt-status.h @@ -19,6 +19,7 @@ enum color_wt_status { WT_STATUS_LOCAL_BRANCH, WT_STATUS_REMOTE_BRANCH, WT_STATUS_ONBRANCH, + WT_STATUS_ARROW, WT_STATUS_MAXSLOT };