From patchwork Thu Oct 26 22:46:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Stopak X-Patchwork-Id: 13437985 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 97B02168C7 for ; Thu, 26 Oct 2023 22:46:43 +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="1NVQGw+/" Received: from mail-oo1-xc29.google.com (mail-oo1-xc29.google.com [IPv6:2607:f8b0:4864:20::c29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C2EDE1AB for ; Thu, 26 Oct 2023 15:46:41 -0700 (PDT) Received: by mail-oo1-xc29.google.com with SMTP id 006d021491bc7-581f78a0206so795093eaf.2 for ; Thu, 26 Oct 2023 15:46:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=initialcommit-io.20230601.gappssmtp.com; s=20230601; t=1698360401; x=1698965201; 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=Q4jOTBwwBH7nKoPw0WlSovtQkR5f47OUKV5RsyaQ71k=; b=1NVQGw+/ghDrl1mhDaVH9JS1tZV42iEwtvTTg8vFqxUKLIeEAglRagUOYHlurA1jjg m2BcZAZlC2ho+yLGAHNHRwIxpZR7ilROFzs/qwJArJwC6aXwY2db25QV0+SLCQat9i72 ARCreir+W0hmJhOs2bg6schd05KUzD6ciD/AS+8tVC4Fj8VpRfroqchFuCuPMbw0jVB7 PaGNrsTuB15difE92x7cBl9JaXdqE4DSO8o/WkND+PjiT4CPH+COL43aVSLvztJkn2iu UVbmpeaeKEE3x6pA5wjESonedWAaX1+u4zjK8rLcKqyIMdFdMVvTGH1TIrfuhBIzCJXC A+iw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698360401; x=1698965201; 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=Q4jOTBwwBH7nKoPw0WlSovtQkR5f47OUKV5RsyaQ71k=; b=Psp5EDPMZIaOwqKGVtACGr3vyqwM1uXb0Wxgasaj2uIk3HTQmDsVNlTXvcgNMsdTZ4 T6S+OAgSra7MK8GYdtYxHGtG1kJLYwPbRGxD97kZAii7glQKYLR5PsN5m3TP45sSE6Jj KLvs8U03alO40aOeQaEoO0GzDGgHkr9Q6oqshxXG6Cb9T6li2KG2Ghb/5LaeP+nVPPgG u5bLFGRGM+Q/pRI4kMcsMVGF1+ofUb+mBnpDzTbhYCzDPc1IEDm11uUGPXvUeg7EtkMu GI/QOs3JF+rlNq/fSZ+qhAKLnHLZovq5eAJNyuv9R1Vw1IclRxFvDyFC6rBe1eUhHRNA SjSg== X-Gm-Message-State: AOJu0YywECiQIbtp9KkTO/+9DuO691DJQ2uinHCUsF0OVd9hu9RJo1rM gSxFtKTbrqN+JyuNEjGyjB/fyBUTuF1B/9UbTQk= X-Google-Smtp-Source: AGHT+IEpkOdz8EvQRO0X6Vd2VEIVf8L2udCRwEEJawb+FiF6o6M+uhQoi6ggfR1Fu0vqXcwAY3ZK3Q== X-Received: by 2002:a05:6358:5241:b0:168:e5ee:8fbd with SMTP id c1-20020a056358524100b00168e5ee8fbdmr1515480rwa.27.1698360400670; Thu, 26 Oct 2023 15:46:40 -0700 (PDT) Received: from localhost.localdomain (mobile-166-170-45-225.mycingular.net. [166.170.45.225]) by smtp.gmail.com with ESMTPSA id s194-20020a6377cb000000b0058ac101ad83sm112318pgc.33.2023.10.26.15.46.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Oct 2023 15:46:39 -0700 (PDT) From: Jacob Stopak To: git@vger.kernel.org Cc: Jacob Stopak Subject: [RFC PATCH v2 1/6] status: add noob format from status.noob config Date: Thu, 26 Oct 2023 15:46:10 -0700 Message-ID: <20231026224615.675172-2-jacob@initialcommit.io> X-Mailer: git-send-email 2.42.0.404.g2bcc23f3db In-Reply-To: <20231026224615.675172-1-jacob@initialcommit.io> References: <20231020183947.463882-1-jacob@initialcommit.io> <20231026224615.675172-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 | 7 +++ table.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++ table.h | 6 +++ wt-status.c | 72 +++++++++++++++++++---------- wt-status.h | 1 + 6 files changed, 179 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..880c42f5b7 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1430,6 +1430,13 @@ static int git_status_config(const char *k, const char *v, status_deferred_config.status_format = STATUS_FORMAT_NONE; return 0; } + if (!strcmp(k, "status.noob")) { + if (git_config_bool(k, v)) + status_deferred_config.status_format = STATUS_FORMAT_NOOB; + else + status_deferred_config.status_format = STATUS_FORMAT_NONE; + return 0; + } if (!strcmp(k, "status.branch")) { status_deferred_config.show_branch = git_config_bool(k, v); return 0; diff --git a/table.c b/table.c new file mode 100644 index 0000000000..15600e117f --- /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 print_noob_status(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, "Unstaged changes", cols); + build_table_entry(&table_col_entry_3, "Staging area", 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..c9e8c386de --- /dev/null +++ b/table.h @@ -0,0 +1,6 @@ +#ifndef TABLE_H +#define TABLE_H + +void print_noob_status(struct wt_status *s); + +#endif /* TABLE_H */ diff --git a/wt-status.c b/wt-status.c index 9f45bf6949..712807aa8f 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_noobstatus_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); + } + + print_noob_status(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_NOOB: + wt_noobstatus_print(s); + break; } trace2_region_leave("status", "print", s->repo); diff --git a/wt-status.h b/wt-status.h index ab9cc9d8f0..3f08f0d72b 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_NOOB, STATUS_FORMAT_UNSPECIFIED }; From patchwork Thu Oct 26 22:46:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Stopak X-Patchwork-Id: 13437986 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 836072D792 for ; Thu, 26 Oct 2023 22:46:44 +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="eqMzNjJK" Received: from mail-oo1-xc2a.google.com (mail-oo1-xc2a.google.com [IPv6:2607:f8b0:4864:20::c2a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E91EE1B2 for ; Thu, 26 Oct 2023 15:46:42 -0700 (PDT) Received: by mail-oo1-xc2a.google.com with SMTP id 006d021491bc7-5842a94feb2so924548eaf.0 for ; Thu, 26 Oct 2023 15:46:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=initialcommit-io.20230601.gappssmtp.com; s=20230601; t=1698360402; x=1698965202; 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=FO8nzutUerGj+rNocMCvjOeeegjB0orbkFZh5eeWFo8=; b=eqMzNjJKHcvZk0it/R5nkLzyr7LhV3UMZOlmjewusWl4ScpGJlKv94yRr42AU1j7fi p6JnUbU4WxCxBUZQeeYWNLj3ppekgHb8monx+2x4cEDncnI8nwJoXzWsSQbrLrurw8Rz Ym8n9RaqscvC60uF//jMh9DPH4xHr7urQpvf+1ybz4QLatIwiH+uDK+NxzVaoXQQ7XtP xCPXQDunTlEIYz4WZynqkfPJbjAwHhk9SMn8iPe6WoVW3rzmiajLkIzEcSl3RtPn5ram xT6rVuhwybygohi/ad0gUdTEmpGVCKxgkeMY1ixrDs4JZv9WEvcKvIFD/BzgZa5nywWH 6uNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698360402; x=1698965202; 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=FO8nzutUerGj+rNocMCvjOeeegjB0orbkFZh5eeWFo8=; b=mUY5RuVTWA0QZeAeBg8/+r6/tk92IT6fyga86GcOiGy6FWQPt9eHaTMNdJWC3sg2id JW1x2IPXWbrk3xSgMdXI6OLbWmRqTlM7gQCxppDyRqs3c5SZ2CqsKE0VgpeqodJxD8eu NZMY6lpPGstfVLbPNvULsGy8OixSAVoT8R6S8QpAvCQF3fHToZznYp0PR34Vp4QKnLjw BfjRKfFcGqewZ1gZwo3ToA4dOsbVj48gdM1YuDvgcR0J4cfC4ljeWUZAGEiN1rUTJ1yq m/ZKtraUdddPvcSUBBEOTjRXVERGUDO8Ub+J96CZvWaaQL+rFKu/CSxKZnUmn4mNowsO 3LgA== X-Gm-Message-State: AOJu0YwHKaQ55U7yeF3Xra/DWgp081Ut0sOr4oh5fsqEm0/SL9yJgC6A aVa8Gb0HF2ymfUO7xvbKCNNO7bdA8orHW66cV+0= X-Google-Smtp-Source: AGHT+IHCRgAtVQt4i4twQcwf4hgtTAna6uHJiOSX334sGis3Etz73mo308EYufMhU8xDj23OgHYiPQ== X-Received: by 2002:a05:6358:2809:b0:168:dd31:73f6 with SMTP id k9-20020a056358280900b00168dd3173f6mr1448648rwb.2.1698360401982; Thu, 26 Oct 2023 15:46:41 -0700 (PDT) Received: from localhost.localdomain (mobile-166-170-45-225.mycingular.net. [166.170.45.225]) by smtp.gmail.com with ESMTPSA id s194-20020a6377cb000000b0058ac101ad83sm112318pgc.33.2023.10.26.15.46.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Oct 2023 15:46:41 -0700 (PDT) From: Jacob Stopak To: git@vger.kernel.org Cc: Jacob Stopak Subject: [RFC PATCH v2 2/6] status: handle long paths in noob format Date: Thu, 26 Oct 2023 15:46:11 -0700 Message-ID: <20231026224615.675172-3-jacob@initialcommit.io> X-Mailer: git-send-email 2.42.0.404.g2bcc23f3db In-Reply-To: <20231026224615.675172-1-jacob@initialcommit.io> References: <20231020183947.463882-1-jacob@initialcommit.io> <20231026224615.675172-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 | 58 ++++++++++++++++++++++++++++++++++++++++++++++------- table.h | 2 +- wt-status.c | 2 +- 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/table.c b/table.c index 15600e117f..d085f2a098 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) @@ -47,7 +76,7 @@ static void print_table_body_line(struct strbuf *buf1, struct strbuf *buf2, stru printf(_("|\n")); } -void print_noob_status(struct wt_status *s) +void print_noob_status(struct wt_status *s, int add_advice) { struct winsize w; int cols; @@ -66,14 +95,29 @@ void print_noob_status(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, "Unstaged changes", cols); build_table_entry(&table_col_entry_3, "Staging area", 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 c9e8c386de..5dff7162a4 100644 --- a/table.h +++ b/table.h @@ -1,6 +1,6 @@ #ifndef TABLE_H #define TABLE_H -void print_noob_status(struct wt_status *s); +void print_noob_status(struct wt_status *s, int i); #endif /* TABLE_H */ diff --git a/wt-status.c b/wt-status.c index 712807aa8f..b5899dcc98 100644 --- a/wt-status.c +++ b/wt-status.c @@ -2149,7 +2149,7 @@ static void wt_noobstatus_print(struct wt_status *s) wt_longstatus_print_tracking(s); } - print_noob_status(s); + print_noob_status(s, 0); } static void wt_porcelain_print(struct wt_status *s) From patchwork Thu Oct 26 22:46:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Stopak X-Patchwork-Id: 13437988 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 198B13F4C0 for ; Thu, 26 Oct 2023 22:46:47 +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="QN5cukgj" Received: from mail-pf1-x42c.google.com (mail-pf1-x42c.google.com [IPv6:2607:f8b0:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8236D1A7 for ; Thu, 26 Oct 2023 15:46:44 -0700 (PDT) Received: by mail-pf1-x42c.google.com with SMTP id d2e1a72fcca58-6b6f4c118b7so1457691b3a.0 for ; Thu, 26 Oct 2023 15:46:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=initialcommit-io.20230601.gappssmtp.com; s=20230601; t=1698360404; x=1698965204; 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=3ePENa1rEU8OP3HHuwxyawix2ePhdaJNAh62a9RCjcA=; b=QN5cukgjdyMv6BMtmcCttfQIx1Cevo+JIJmUlzVGZ0jbFbL+L+N3m45DRdrn58BTSG b8dEqqOiKS92gi7EkWGicJ/LffpeHIcvCYjNlwwmqNxLZ2e4gaquUK8trqgpMFvEnNQu lFvgdFVTvwbFw7+rOVZ5lOV4ysWY3z5yARHwWEthLC07jb5CfQQ6D7JCfdpzMuDgO0kq fCHYcMeldjBeF73oeiUMY8KPiuzcWAPbywG7RQoKPaEG2MpNUSoVqa9eqAZQVAOHkEIf idZqtmpP/n067gEyQuoaWB3MUkDToW9h0NvV7A6e9IQvZ+eEH1Pxmf6FlMolr9cYL1Qg bpPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698360404; x=1698965204; 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=3ePENa1rEU8OP3HHuwxyawix2ePhdaJNAh62a9RCjcA=; b=DyMQMHdr+ssbJieqc3YCcYcJYDYamoXBLRIO/YMJO2cVOZmJl2TOepBOI0pNIvMgf/ qfhsKCcXEs3Wkd0vngfHWlZVXGb98YPW0W2Kjv0HD2kF43xS8LZdsH7arlhRdMUpj43+ tX6YJcQQc0bdqU7BXs9pkSoZJDHJkQc2SiUjqHKzhkvfTPqThBgyhzSWwGsUojRN3Jxy kYZFX8i90cDm1BeQpqnggc2CYRr0Xw07nK2p2CyR5tO6DOFaHdeFs464i58BoeVvgOdt SY11XUxYOQujncSLP9zA/Dou9iV89ek15g/KAiGPEivwwVxV2FG0Dw4LZcdOihFz1+df lg7w== X-Gm-Message-State: AOJu0YymysolBuld7bjHO2QfbFa2oGb9TQHGBUuUAgwQGdcVUhG8wo8w 1HKxcEdmEtQvcrpNIN+B6ynSU5ejpCpyslbN21o= X-Google-Smtp-Source: AGHT+IFyVTzMNJR3m/FsdMoUIikKt1crrsMgy+xXUEi0QPZN7Q7FJpkaZhyaTl1tUjMBXUEy4gBo4g== X-Received: by 2002:a05:6a00:24d2:b0:6b9:f641:272e with SMTP id d18-20020a056a0024d200b006b9f641272emr999250pfv.24.1698360403464; Thu, 26 Oct 2023 15:46:43 -0700 (PDT) Received: from localhost.localdomain (mobile-166-170-45-225.mycingular.net. [166.170.45.225]) by smtp.gmail.com with ESMTPSA id s194-20020a6377cb000000b0058ac101ad83sm112318pgc.33.2023.10.26.15.46.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Oct 2023 15:46:42 -0700 (PDT) From: Jacob Stopak To: git@vger.kernel.org Cc: Jacob Stopak Subject: [RFC PATCH v2 3/6] add: implement noob mode Date: Thu, 26 Oct 2023 15:46:12 -0700 Message-ID: <20231026224615.675172-4-jacob@initialcommit.io> X-Mailer: git-send-email 2.42.0.404.g2bcc23f3db In-Reply-To: <20231026224615.675172-1-jacob@initialcommit.io> References: <20231020183947.463882-1-jacob@initialcommit.io> <20231026224615.675172-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/add.c | 47 ++++++++--- builtin/commit.c | 163 +------------------------------------- commit.c | 2 + noob.c | 198 +++++++++++++++++++++++++++++++++++++++++++++++ noob.h | 21 +++++ read-cache-ll.h | 9 ++- read-cache.c | 32 ++++++-- table.c | 92 +++++++++++++++++++--- wt-status.c | 1 + wt-status.h | 1 + 11 files changed, 381 insertions(+), 186 deletions(-) create mode 100644 noob.c create mode 100644 noob.h diff --git a/Makefile b/Makefile index a7399ca8f0..78acfaf14d 100644 --- a/Makefile +++ b/Makefile @@ -1070,6 +1070,7 @@ LIB_OBJS += name-hash.o LIB_OBJS += negotiator/default.o LIB_OBJS += negotiator/noop.o LIB_OBJS += negotiator/skipping.o +LIB_OBJS += noob.o LIB_OBJS += notes-cache.o LIB_OBJS += notes-merge.o LIB_OBJS += notes-utils.o diff --git a/builtin/add.c b/builtin/add.c index c27254a5cd..dbb99d179e 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -27,6 +27,9 @@ #include "strvec.h" #include "submodule.h" #include "add-interactive.h" +#include "wt-status.h" +#include "commit.h" +#include "noob.h" static const char * const builtin_add_usage[] = { N_("git add [] [--] ..."), @@ -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,8 +377,14 @@ 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; + + wt_status_prepare(the_repository, &status); git_config(add_config, NULL); + git_config(git_status_config, &status); + finalize_deferred_config(&status); + status.status_format = status_format; argc = parse_options(argc, argv, prefix, builtin_add_options, builtin_add_usage, PARSE_OPT_KEEP_ARGV0); @@ -459,7 +468,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) | + (status.status_format == STATUS_FORMAT_NOOB ? ADD_CACHE_FORMAT_NOOB : 0)); if (repo_read_index_preload(the_repository, &pathspec, 0) < 0) die(_("index file corrupt")); @@ -551,15 +561,32 @@ int cmd_add(int argc, const char **argv, const char *prefix) begin_odb_transaction(); - if (add_renormalize) + if (status.status_format == STATUS_FORMAT_NOOB) { + /* Read index and populate status */ + repo_read_index(the_repository); + refresh_index(&the_index, + REFRESH_QUIET|REFRESH_UNMERGED|progress_flag, + &status.pathspec, NULL, NULL); + status.show_branch = 0; + wt_status_collect(&status); + } + + 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 (status.status_format == STATUS_FORMAT_NOOB) { + 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 880c42f5b7..3f816c117d 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -46,6 +46,7 @@ #include "commit-reach.h" #include "commit-graph.h" #include "pretty.h" +#include "noob.h" static const char * const builtin_commit_usage[] = { N_("git commit [-a | --interactive | --patch] [-s] [-v] [-u] [--amend]\n" @@ -148,8 +149,6 @@ static int use_editor = 1, include_status = 1; static int have_option_m; static struct strbuf message = STRBUF_INIT; -static enum wt_status_format status_format = STATUS_FORMAT_UNSPECIFIED; - static int opt_pass_trailer(const struct option *opt, const char *arg, int unset) { BUG_ON_OPT_NEG(unset); @@ -310,7 +309,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); @@ -1196,59 +1195,6 @@ static const char *read_commit_message(const char *name) return repo_logmsg_reencode(the_repository, commit, NULL, out_enc); } -/* - * Enumerate what needs to be propagated when --porcelain - * is not in effect here. - */ -static struct status_deferred_config { - enum wt_status_format status_format; - int show_branch; - enum ahead_behind_flags ahead_behind; -} status_deferred_config = { - STATUS_FORMAT_UNSPECIFIED, - -1, /* unspecified */ - AHEAD_BEHIND_UNSPECIFIED, -}; - -static void finalize_deferred_config(struct wt_status *s) -{ - int use_deferred_config = (status_format != STATUS_FORMAT_PORCELAIN && - status_format != STATUS_FORMAT_PORCELAIN_V2 && - !s->null_termination); - - if (s->null_termination) { - if (status_format == STATUS_FORMAT_NONE || - status_format == STATUS_FORMAT_UNSPECIFIED) - status_format = STATUS_FORMAT_PORCELAIN; - else if (status_format == STATUS_FORMAT_LONG) - die(_("options '%s' and '%s' cannot be used together"), "--long", "-z"); - } - - if (use_deferred_config && status_format == STATUS_FORMAT_UNSPECIFIED) - status_format = status_deferred_config.status_format; - if (status_format == STATUS_FORMAT_UNSPECIFIED) - status_format = STATUS_FORMAT_NONE; - - if (use_deferred_config && s->show_branch < 0) - s->show_branch = status_deferred_config.show_branch; - if (s->show_branch < 0) - s->show_branch = 0; - - /* - * If the user did not give a "--[no]-ahead-behind" command - * line argument *AND* we will print in a human-readable format - * (short, long etc.) then we inherit from the status.aheadbehind - * config setting. In all other cases (and porcelain V[12] formats - * in particular), we inherit _FULL for backwards compatibility. - */ - if (use_deferred_config && - s->ahead_behind_flags == AHEAD_BEHIND_UNSPECIFIED) - s->ahead_behind_flags = status_deferred_config.ahead_behind; - - if (s->ahead_behind_flags == AHEAD_BEHIND_UNSPECIFIED) - s->ahead_behind_flags = AHEAD_BEHIND_FULL; -} - static void check_fixup_reword_options(int argc, const char *argv[]) { if (whence != FROM_COMMIT) { if (whence == FROM_MERGE) @@ -1399,111 +1345,6 @@ static int dry_run_commit(const char **argv, const char *prefix, define_list_config_array_extra(color_status_slots, {"added"}); -static int parse_status_slot(const char *slot) -{ - if (!strcasecmp(slot, "added")) - return WT_STATUS_UPDATED; - - return LOOKUP_CONFIG(color_status_slots, slot); -} - -static int git_status_config(const char *k, const char *v, - const struct config_context *ctx, void *cb) -{ - struct wt_status *s = cb; - const char *slot_name; - - if (starts_with(k, "column.")) - return git_column_config(k, v, "status", &s->colopts); - if (!strcmp(k, "status.submodulesummary")) { - int is_bool; - s->submodule_summary = git_config_bool_or_int(k, v, ctx->kvi, - &is_bool); - if (is_bool && s->submodule_summary) - s->submodule_summary = -1; - return 0; - } - if (!strcmp(k, "status.short")) { - if (git_config_bool(k, v)) - status_deferred_config.status_format = STATUS_FORMAT_SHORT; - else - status_deferred_config.status_format = STATUS_FORMAT_NONE; - return 0; - } - if (!strcmp(k, "status.noob")) { - if (git_config_bool(k, v)) - status_deferred_config.status_format = STATUS_FORMAT_NOOB; - else - status_deferred_config.status_format = STATUS_FORMAT_NONE; - return 0; - } - if (!strcmp(k, "status.branch")) { - status_deferred_config.show_branch = git_config_bool(k, v); - return 0; - } - if (!strcmp(k, "status.aheadbehind")) { - status_deferred_config.ahead_behind = git_config_bool(k, v); - return 0; - } - if (!strcmp(k, "status.showstash")) { - s->show_stash = git_config_bool(k, v); - return 0; - } - if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) { - s->use_color = git_config_colorbool(k, v); - return 0; - } - if (!strcmp(k, "status.displaycommentprefix")) { - s->display_comment_prefix = git_config_bool(k, v); - return 0; - } - if (skip_prefix(k, "status.color.", &slot_name) || - skip_prefix(k, "color.status.", &slot_name)) { - int slot = parse_status_slot(slot_name); - if (slot < 0) - return 0; - if (!v) - return config_error_nonbool(k); - return color_parse(v, s->color_palette[slot]); - } - if (!strcmp(k, "status.relativepaths")) { - s->relative_paths = git_config_bool(k, v); - return 0; - } - if (!strcmp(k, "status.showuntrackedfiles")) { - if (!v) - return config_error_nonbool(k); - else if (!strcmp(v, "no")) - s->show_untracked_files = SHOW_NO_UNTRACKED_FILES; - else if (!strcmp(v, "normal")) - s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES; - else if (!strcmp(v, "all")) - s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES; - else - return error(_("Invalid untracked files mode '%s'"), v); - return 0; - } - if (!strcmp(k, "diff.renamelimit")) { - if (s->rename_limit == -1) - s->rename_limit = git_config_int(k, v, ctx->kvi); - return 0; - } - if (!strcmp(k, "status.renamelimit")) { - s->rename_limit = git_config_int(k, v, ctx->kvi); - return 0; - } - if (!strcmp(k, "diff.renames")) { - if (s->detect_rename == -1) - s->detect_rename = git_config_rename(k, v); - return 0; - } - if (!strcmp(k, "status.renames")) { - s->detect_rename = git_config_rename(k, v); - return 0; - } - return git_diff_ui_config(k, v, ctx, NULL); -} - int cmd_status(int argc, const char **argv, const char *prefix) { static int no_renames = -1; diff --git a/commit.c b/commit.c index b3223478bc..c08faf48fd 100644 --- a/commit.c +++ b/commit.c @@ -28,6 +28,8 @@ #include "shallow.h" #include "tree.h" #include "hook.h" +#include "column.h" +#include "config.h" static struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len, const char **); diff --git a/noob.c b/noob.c new file mode 100644 index 0000000000..680d461698 --- /dev/null +++ b/noob.c @@ -0,0 +1,198 @@ +#include "git-compat-util.h" +#include "tag.h" +#include "commit.h" +#include "commit-graph.h" +#include "environment.h" +#include "gettext.h" +#include "hex.h" +#include "repository.h" +#include "object-name.h" +#include "object-store-ll.h" +#include "pkt-line.h" +#include "utf8.h" +#include "diff.h" +#include "revision.h" +#include "notes.h" +#include "alloc.h" +#include "gpg-interface.h" +#include "mergesort.h" +#include "commit-slab.h" +#include "prio-queue.h" +#include "hash-lookup.h" +#include "wt-status.h" +#include "advice.h" +#include "refs.h" +#include "commit-reach.h" +#include "run-command.h" +#include "setup.h" +#include "shallow.h" +#include "tree.h" +#include "hook.h" +#include "column.h" +#include "config.h" +#include "noob.h" + +static const char *color_status_slots[] = { + [WT_STATUS_HEADER] = "header", + [WT_STATUS_UPDATED] = "updated", + [WT_STATUS_CHANGED] = "changed", + [WT_STATUS_UNTRACKED] = "untracked", + [WT_STATUS_NOBRANCH] = "noBranch", + [WT_STATUS_UNMERGED] = "unmerged", + [WT_STATUS_LOCAL_BRANCH] = "localBranch", + [WT_STATUS_REMOTE_BRANCH] = "remoteBranch", + [WT_STATUS_ONBRANCH] = "branch", +}; + +enum wt_status_format status_format = STATUS_FORMAT_UNSPECIFIED; + +struct status_deferred_config status_deferred_config = { + STATUS_FORMAT_UNSPECIFIED, + -1, /* unspecified */ + AHEAD_BEHIND_UNSPECIFIED, +}; + +int parse_status_slot(const char *slot) +{ + if (!strcasecmp(slot, "added")) + return WT_STATUS_UPDATED; + + return LOOKUP_CONFIG(color_status_slots, slot); +} + +int git_status_config(const char *k, const char *v, + const struct config_context *ctx, void *cb) +{ + struct wt_status *s = cb; + const char *slot_name; + + if (starts_with(k, "column.")) + return git_column_config(k, v, "status", &s->colopts); + if (!strcmp(k, "status.submodulesummary")) { + int is_bool; + s->submodule_summary = git_config_bool_or_int(k, v, ctx->kvi, + &is_bool); + if (is_bool && s->submodule_summary) + s->submodule_summary = -1; + return 0; + } + if (!strcmp(k, "status.short")) { + if (git_config_bool(k, v)) + status_deferred_config.status_format = STATUS_FORMAT_SHORT; + else + status_deferred_config.status_format = STATUS_FORMAT_NONE; + return 0; + } + if (!strcmp(k, "status.noob")) { + if (git_config_bool(k, v)) + status_deferred_config.status_format = STATUS_FORMAT_NOOB; + else + status_deferred_config.status_format = STATUS_FORMAT_NONE; + return 0; + } + if (!strcmp(k, "status.branch")) { + status_deferred_config.show_branch = git_config_bool(k, v); + return 0; + } + if (!strcmp(k, "status.aheadbehind")) { + status_deferred_config.ahead_behind = git_config_bool(k, v); + return 0; + } + if (!strcmp(k, "status.showstash")) { + s->show_stash = git_config_bool(k, v); + return 0; + } + if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) { + s->use_color = git_config_colorbool(k, v); + return 0; + } + if (!strcmp(k, "status.displaycommentprefix")) { + s->display_comment_prefix = git_config_bool(k, v); + return 0; + } + if (skip_prefix(k, "status.color.", &slot_name) || + skip_prefix(k, "color.status.", &slot_name)) { + int slot = parse_status_slot(slot_name); + if (slot < 0) + return 0; + if (!v) + return config_error_nonbool(k); + return color_parse(v, s->color_palette[slot]); + } + if (!strcmp(k, "status.relativepaths")) { + s->relative_paths = git_config_bool(k, v); + return 0; + } + if (!strcmp(k, "status.showuntrackedfiles")) { + if (!v) + return config_error_nonbool(k); + else if (!strcmp(v, "no")) + s->show_untracked_files = SHOW_NO_UNTRACKED_FILES; + else if (!strcmp(v, "normal")) + s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES; + else if (!strcmp(v, "all")) + s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES; + else + return error(_("Invalid untracked files mode '%s'"), v); + return 0; + } + if (!strcmp(k, "diff.renamelimit")) { + if (s->rename_limit == -1) + s->rename_limit = git_config_int(k, v, ctx->kvi); + return 0; + } + if (!strcmp(k, "status.renamelimit")) { + s->rename_limit = git_config_int(k, v, ctx->kvi); + return 0; + } + if (!strcmp(k, "diff.renames")) { + if (s->detect_rename == -1) + s->detect_rename = git_config_rename(k, v); + return 0; + } + if (!strcmp(k, "status.renames")) { + s->detect_rename = git_config_rename(k, v); + return 0; + } + return git_diff_ui_config(k, v, ctx, NULL); +} + +void finalize_deferred_config(struct wt_status *s) +{ + int use_deferred_config = (status_format != STATUS_FORMAT_PORCELAIN && + status_format != STATUS_FORMAT_PORCELAIN_V2 && + !s->null_termination); + + if (s->null_termination) { + if (status_format == STATUS_FORMAT_NONE || + status_format == STATUS_FORMAT_UNSPECIFIED) + status_format = STATUS_FORMAT_PORCELAIN; + else if (status_format == STATUS_FORMAT_LONG) + die(_("options '%s' and '%s' cannot be used together"), "--long", "-z"); + } + + if (use_deferred_config && status_format == STATUS_FORMAT_UNSPECIFIED) { + status_format = status_deferred_config.status_format; + } + if (status_format == STATUS_FORMAT_UNSPECIFIED) + status_format = STATUS_FORMAT_NONE; + + if (use_deferred_config && s->show_branch < 0) + s->show_branch = status_deferred_config.show_branch; + if (s->show_branch < 0) + s->show_branch = 0; + + /* + * If the user did not give a "--[no]-ahead-behind" command + * line argument *AND* we will print in a human-readable format + * (short, long etc.) then we inherit from the status.aheadbehind + * config setting. In all other cases (and porcelain V[12] formats + * in particular), we inherit _FULL for backwards compatibility. + */ + if (use_deferred_config && + s->ahead_behind_flags == AHEAD_BEHIND_UNSPECIFIED) + s->ahead_behind_flags = status_deferred_config.ahead_behind; + + if (s->ahead_behind_flags == AHEAD_BEHIND_UNSPECIFIED) + s->ahead_behind_flags = AHEAD_BEHIND_FULL; +} diff --git a/noob.h b/noob.h new file mode 100644 index 0000000000..d5bc073594 --- /dev/null +++ b/noob.h @@ -0,0 +1,21 @@ +#ifndef NOOB_H +#define NOOB_H + +struct status_deferred_config { + enum wt_status_format status_format; + int show_branch; + enum ahead_behind_flags ahead_behind; +}; + +extern enum wt_status_format status_format; + +extern struct status_deferred_config status_deferred_config; + +int git_status_config(const char *k, const char *v, + const struct config_context *ctx, void *cb); + +int parse_status_slot(const char *slot); + +void finalize_deferred_config(struct wt_status *s); + +#endif /* NOOB_H */ diff --git a/read-cache-ll.h b/read-cache-ll.h index 9a1a7edc5a..302a075714 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_NOOB 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..319415430a 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 noob = flags & ADD_CACHE_FORMAT_NOOB; 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 && !noob) printf("add '%s'\n", path); + if (noob && !was_same) { + string_list_insert(&status->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 d085f2a098..527e38c07d 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 print_noob_status(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 print_noob_status(struct wt_status *s, int advice) { struct winsize w; int cols; @@ -84,7 +119,7 @@ void print_noob_status(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 print_noob_status(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 print_noob_status(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->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 print_noob_status(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->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 b5899dcc98..969f79f441 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->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 3f08f0d72b..64551f3a75 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 added; uint32_t untracked_in_ms; }; From patchwork Thu Oct 26 22:46:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Stopak X-Patchwork-Id: 13437987 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 85E4E3E488 for ; Thu, 26 Oct 2023 22:46:47 +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="xyDJYUvx" Received: from mail-oo1-xc2c.google.com (mail-oo1-xc2c.google.com [IPv6:2607:f8b0:4864:20::c2c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CA5F61B4 for ; Thu, 26 Oct 2023 15:46:45 -0700 (PDT) Received: by mail-oo1-xc2c.google.com with SMTP id 006d021491bc7-586ad15f9aaso593477eaf.2 for ; Thu, 26 Oct 2023 15:46:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=initialcommit-io.20230601.gappssmtp.com; s=20230601; t=1698360405; x=1698965205; 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=MuOo59OigsBMXEvYkxbmw8PjDWl6n5fyljau8ya574Q=; b=xyDJYUvxlvBZrMK5gTso5u3PERgJMwhg0Q353OMtA529zcLZTiCgYBbTplJM6YWo/q VSRUn/b4d/+QRexTYdDLy7QZJJEQta0CtlZjT2L1cve1rb3eQ9GAHamxRaPukWcYFn0T 0F7emWYl44AUGvaQXx8aWS4iloQS7fcmmKWpjHJomuEmdqOLMs9IIWNc7jaonsg41iDu rI/fo0zOPOnYkuUY1ifGxPj/Z5xEYnYYqER/JNA3mW75gOzqHXOIgIPt/TkprRqPQ4VP QulIbSR1R9km33/G0ZSzm9y6ipkANHqu+RdZQWnpxNu8AaevnrcMsUeZYIZ5clOuKuZp oUEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698360405; x=1698965205; 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=MuOo59OigsBMXEvYkxbmw8PjDWl6n5fyljau8ya574Q=; b=KnXoetm3ZQwJIRwJO3k3lsmMrd6D7cCHjY/7C42XqV1aPGy3roeANWWA+CZcVedY96 nrU/BGMyXzhFWOjsdDxF3MPhoYSOmd94k2DohuB2ZJVRbafvur8S7kQqr0inch9CE3es A642KjixzjcZAxJ7o0mObXWprZOlLjIldz9HP39/y1Q2EDV2CJ/ze+F8JQaL6rKK+IF/ hB2CBbfYADYZIMg87jdrwvOi/zypBDzUq73D7FQmrAAmpHHdwKqiVBVFjzxfEgeEFyDo N55LXdK/3Zbc8iylYe7Hjsgf4gyx5jgBHGgi+2Q+tjrVehb51SUkL/wVn6vUOT060pHP n8bg== X-Gm-Message-State: AOJu0YwGSjkbf2bM2OsY3t6xxc0ZjUt8MKm9wnlvVu7owRNegSMpTGaa Vc9pEBUlLoBA0n2IXWoI0PWfVBNxhlfneikbIaU= X-Google-Smtp-Source: AGHT+IHCcX9W8F0qo9Kx/gMFQUxLUPTLrPLsKDTA0XCNleRWWEEsuGInFbX8ziuOPzXmNSQ7qQ4ldA== X-Received: by 2002:a05:6358:903:b0:168:eded:d6c9 with SMTP id r3-20020a056358090300b00168ededd6c9mr1393532rwi.29.1698360404883; Thu, 26 Oct 2023 15:46:44 -0700 (PDT) Received: from localhost.localdomain (mobile-166-170-45-225.mycingular.net. [166.170.45.225]) by smtp.gmail.com with ESMTPSA id s194-20020a6377cb000000b0058ac101ad83sm112318pgc.33.2023.10.26.15.46.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Oct 2023 15:46:44 -0700 (PDT) From: Jacob Stopak To: git@vger.kernel.org Cc: Jacob Stopak Subject: [RFC PATCH v2 4/6] add: set unique color for noob mode arrows Date: Thu, 26 Oct 2023 15:46:13 -0700 Message-ID: <20231026224615.675172-5-jacob@initialcommit.io> X-Mailer: git-send-email 2.42.0.404.g2bcc23f3db In-Reply-To: <20231026224615.675172-1-jacob@initialcommit.io> References: <20231020183947.463882-1-jacob@initialcommit.io> <20231026224615.675172-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 | 64 +++++++++++++++++++++++++++++++---------------------- wt-status.c | 1 + wt-status.h | 1 + 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/table.c b/table.c index 527e38c07d..d29b311440 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) @@ -26,7 +27,7 @@ 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 */ + size_t col_width = (cols / 3) - 9; /* subtract for padding */ strbuf_reset(buf); @@ -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 print_noob_status(struct wt_status *s, int advice) { struct winsize w; @@ -119,6 +119,9 @@ void print_noob_status(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 print_noob_status(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 print_noob_status(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 print_noob_status(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 969f79f441..1332d07dba 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 64551f3a75..7b883fd476 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 }; From patchwork Thu Oct 26 22:46:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Stopak X-Patchwork-Id: 13437989 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 23B4D171DF for ; Thu, 26 Oct 2023 22:46:49 +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="jD50dil2" Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3D4ED1AB for ; Thu, 26 Oct 2023 15:46:47 -0700 (PDT) Received: by mail-pf1-x434.google.com with SMTP id d2e1a72fcca58-6b5af4662b7so1378434b3a.3 for ; Thu, 26 Oct 2023 15:46:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=initialcommit-io.20230601.gappssmtp.com; s=20230601; t=1698360406; x=1698965206; 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=3jpis/aPcpBI1zfIbeqY4n9p1XyHUUNCJMvbE7Bv7CY=; b=jD50dil21PxIypULMZBwsprF9bGJI8sSqRvjUi9Fz21DPsNEtqZaqIIeYeVca2hwBJ WjoyA93+J+Fhy7VWUJqcDQ0EMuPe9LtsOrCn34+1boiu15bk70Jowialx+8IBDwHjsX2 AbJoz5yAk2om9TbAnlPYDxrURhExNg4cwbgKQeFdPOI13BPza2Zz2QAOdBVvHL+hXAA2 U4Q9bALX3RWT+zOGbuR8bPL8799qSBH/PcNGKGXiiN7MPhAhTgG44d0tRhmLQaR8uchI 8uFMwbXkFCywNHwR//em/w8GiazZ0fMJY8gPyTAU5XcQYhQ06p2ZRoswEA7U0bDmi++f tvAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698360406; x=1698965206; 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=3jpis/aPcpBI1zfIbeqY4n9p1XyHUUNCJMvbE7Bv7CY=; b=Vl0E0ttmRadgFCA0JwnO5AnZIgBxw2DTMKs3yi/Gt96g3M+DcVkUycuWoRTE5G2Qgu eXstw+BwDdMmurlFHYqQLBzjF70JWZLc/wAk0TtRTm76IKUUYNdrQOHy3gbgPeCB5mq/ 4bebp27z+Wg7B1APCoKaVNd2/CZJ/CSze69HC8q8vzAAlKzAGIS5/FUHc0XUvG+Spxdy 7Il+Gb6/MnhzXaKj3tdMnR6ZRj0jT0roCoZjaDtA2hgOoYeJwmkJLIKs+jqnAFpwN2bV oYBvXHTe3UBTpVztwiLZMIhJc7JST9LQDPT6Ji0sbQUe//YqIqClaCY4WWI1Rtlaf2Pd Mv7Q== X-Gm-Message-State: AOJu0YxEhtLHBvLoE9CTsiaHJuT1yInQcZfKuz1PZxi6azyNU5Q6K/f6 T6DBELkOD5kCcN7L2rFwtzW53fiYnCtCuNB+AUE= X-Google-Smtp-Source: AGHT+IFPhMnshkjA+k/ew9SOqI6AuKXCdGNKehBNaGR8+G5cqsyV0I62N+U3rkx/8nxelJ5Z7PnTPg== X-Received: by 2002:a05:6a21:7988:b0:161:7a0c:3c38 with SMTP id bh8-20020a056a21798800b001617a0c3c38mr1184459pzc.32.1698360406344; Thu, 26 Oct 2023 15:46:46 -0700 (PDT) Received: from localhost.localdomain (mobile-166-170-45-225.mycingular.net. [166.170.45.225]) by smtp.gmail.com with ESMTPSA id s194-20020a6377cb000000b0058ac101ad83sm112318pgc.33.2023.10.26.15.46.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Oct 2023 15:46:45 -0700 (PDT) From: Jacob Stopak To: git@vger.kernel.org Cc: Jacob Stopak Subject: [RFC PATCH v2 5/6] restore: implement noob mode Date: Thu, 26 Oct 2023 15:46:14 -0700 Message-ID: <20231026224615.675172-6-jacob@initialcommit.io> X-Mailer: git-send-email 2.42.0.404.g2bcc23f3db In-Reply-To: <20231026224615.675172-1-jacob@initialcommit.io> References: <20231020183947.463882-1-jacob@initialcommit.io> <20231026224615.675172-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/checkout.c | 46 ++++++++++++++++++++++++++++------- read-cache-ll.h | 1 + read-cache.c | 9 ++++++- table.c | 60 +++++++++++++++++++++++++++++++++++++++------- wt-status.h | 1 + 5 files changed, 100 insertions(+), 17 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index f02434bc15..afc414b0b1 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -41,6 +41,7 @@ #include "entry.h" #include "parallel-checkout.h" #include "add-interactive.h" +#include "noob.h" static const char * const checkout_usage[] = { N_("git checkout [] "), @@ -456,7 +457,8 @@ static int checkout_worktree(const struct checkout_opts *opts, } static int checkout_paths(const struct checkout_opts *opts, - const struct branch_info *new_branch_info) + const struct branch_info *new_branch_info, + struct wt_status *status) { int pos; static char *ps_matched; @@ -598,8 +600,10 @@ static int checkout_paths(const struct checkout_opts *opts, for (pos = 0; pos < the_index.cache_nr; pos++) { const struct cache_entry *ce = the_index.cache[pos]; if (ce->ce_flags & CE_MATCHED) { - if (!ce_stage(ce)) + if (!ce_stage(ce)) { + string_list_insert(&status->restored, ce->name); continue; + } if (opts->ignore_unmerged) { if (!opts->quiet) warning(_("path '%s' is unmerged"), ce->name); @@ -621,7 +625,7 @@ static int checkout_paths(const struct checkout_opts *opts, if (opts->checkout_worktree) errs |= checkout_worktree(opts, new_branch_info); else - remove_marked_cache_entries(&the_index, 1); + remove_marked_cache_entries_with_status(&the_index, 1, status); /* * Allow updating the index when checking out from the index. @@ -1668,7 +1672,8 @@ static char cb_option = 'b'; static int checkout_main(int argc, const char **argv, const char *prefix, struct checkout_opts *opts, struct option *options, const char * const usagestr[], - struct branch_info *new_branch_info) + struct branch_info *new_branch_info, + struct wt_status *status) { int parseopt_flags = 0; @@ -1865,7 +1870,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix, } if (opts->patch_mode || opts->pathspec.nr) - return checkout_paths(opts, new_branch_info); + return checkout_paths(opts, new_branch_info, status); else return checkout_branch(opts, new_branch_info); } @@ -1887,6 +1892,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) }; int ret; struct branch_info new_branch_info = { 0 }; + struct wt_status status; memset(&opts, 0, sizeof(opts)); opts.dwim_new_local_branch = 1; @@ -1917,7 +1923,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) options = add_checkout_path_options(&opts, options); ret = checkout_main(argc, argv, prefix, &opts, - options, checkout_usage, &new_branch_info); + options, checkout_usage, + &new_branch_info, &status); branch_info_release(&new_branch_info); clear_pathspec(&opts.pathspec); free(opts.pathspec_from_file); @@ -1942,6 +1949,7 @@ int cmd_switch(int argc, const char **argv, const char *prefix) }; int ret; struct branch_info new_branch_info = { 0 }; + struct wt_status status; memset(&opts, 0, sizeof(opts)); opts.dwim_new_local_branch = 1; @@ -1961,7 +1969,8 @@ int cmd_switch(int argc, const char **argv, const char *prefix) cb_option = 'c'; ret = checkout_main(argc, argv, prefix, &opts, - options, switch_branch_usage, &new_branch_info); + options, switch_branch_usage, + &new_branch_info, &status); branch_info_release(&new_branch_info); FREE_AND_NULL(options); return ret; @@ -1985,6 +1994,13 @@ int cmd_restore(int argc, const char **argv, const char *prefix) }; int ret; struct branch_info new_branch_info = { 0 }; + struct wt_status status; + unsigned int progress_flag = 0; + + wt_status_prepare(the_repository, &status); + git_config(git_status_config, &status); + finalize_deferred_config(&status); + status.status_format = status_format; memset(&opts, 0, sizeof(opts)); opts.accept_ref = 0; @@ -2000,7 +2016,21 @@ int cmd_restore(int argc, const char **argv, const char *prefix) options = add_checkout_path_options(&opts, options); ret = checkout_main(argc, argv, prefix, &opts, - options, restore_usage, &new_branch_info); + options, restore_usage, + &new_branch_info, &status); + + if (status.status_format == STATUS_FORMAT_NOOB) { + /* Read index and populate status */ + repo_read_index(the_repository); + refresh_index(&the_index, + REFRESH_QUIET|REFRESH_UNMERGED|progress_flag, + &status.pathspec, NULL, NULL); + status.show_branch = 0; + wt_status_collect(&status); + wt_status_print(&status); + wt_status_collect_free_buffers(&status); + } + branch_info_release(&new_branch_info); FREE_AND_NULL(options); return ret; diff --git a/read-cache-ll.h b/read-cache-ll.h index 302a075714..8bdc157196 100644 --- a/read-cache-ll.h +++ b/read-cache-ll.h @@ -389,6 +389,7 @@ void rename_index_entry_at(struct index_state *, int pos, const char *new_name); /* Remove entry, return true if there are more entries to go. */ int remove_index_entry_at(struct index_state *, int pos); +void remove_marked_cache_entries_with_status(struct index_state *istate, int invalidate, struct wt_status *status); void remove_marked_cache_entries(struct index_state *istate, int invalidate); int remove_file_from_index(struct index_state *, const char *path); #define ADD_CACHE_VERBOSE 1 diff --git a/read-cache.c b/read-cache.c index 319415430a..1c1a3290c0 100644 --- a/read-cache.c +++ b/read-cache.c @@ -558,7 +558,7 @@ int remove_index_entry_at(struct index_state *istate, int pos) * CE_REMOVE is set in ce_flags. This is much more effective than * calling remove_index_entry_at() for each entry to be removed. */ -void remove_marked_cache_entries(struct index_state *istate, int invalidate) +void remove_marked_cache_entries_with_status(struct index_state *istate, int invalidate, struct wt_status *status) { struct cache_entry **ce_array = istate->cache; unsigned int i, j; @@ -570,6 +570,7 @@ void remove_marked_cache_entries(struct index_state *istate, int invalidate) ce_array[i]->name); untracked_cache_remove_from_index(istate, ce_array[i]->name); + string_list_insert(&status->restored, ce_array[i]->name); } remove_name_hash(istate, ce_array[i]); save_or_free_index_entry(istate, ce_array[i]); @@ -583,6 +584,12 @@ void remove_marked_cache_entries(struct index_state *istate, int invalidate) istate->cache_nr = j; } +void remove_marked_cache_entries(struct index_state *istate, int invalidate) +{ + struct wt_status status; + remove_marked_cache_entries_with_status(istate, invalidate, &status); +} + int remove_file_from_index(struct index_state *istate, const char *path) { int pos = index_name_pos(istate, path, strlen(path)); diff --git a/table.c b/table.c index d29b311440..3602def17a 100644 --- a/table.c +++ b/table.c @@ -66,7 +66,7 @@ static void build_table_entry(struct strbuf *buf, char *entry, int cols) strbuf_addchars(buf, ' ', (cols / 3 - len - 1) / 2); } -static void build_arrow(struct strbuf *buf, struct strbuf* arrow, int add_after_entry) +static void build_arrow_(struct strbuf *buf, struct strbuf* arrow, int add_after_entry, int reversed) { struct strbuf empty = STRBUF_INIT; struct strbuf trimmed = STRBUF_INIT; @@ -80,17 +80,38 @@ static void build_arrow(struct strbuf *buf, struct strbuf* arrow, int add_after_ strbuf_reset(buf); strbuf_addchars(arrow, '-', len + 1); } else if (add_after_entry) { - strbuf_rtrim(buf); - strbuf_addchars(arrow, ' ', 1); - strbuf_addchars(arrow, '-', len - strlen(buf->buf) + 1); + if (!reversed) { + strbuf_rtrim(buf); + strbuf_addchars(arrow, ' ', 1); + strbuf_addchars(arrow, '-', len - strlen(buf->buf) + 1); + } else { + strbuf_rtrim(buf); + strbuf_addchars(arrow, ' ', 1); + strbuf_addchars(arrow, '<', 1); + strbuf_addchars(arrow, '-', len - strlen(buf->buf) - 3); + } } else if (!add_after_entry) { - strbuf_ltrim(buf); - strbuf_addchars(arrow, '-', len - strlen(buf->buf) - 3); - strbuf_addchars(arrow, '>', 1); - strbuf_addchars(arrow, ' ', 1); + if (!reversed) { + strbuf_ltrim(buf); + strbuf_addchars(arrow, '-', len - strlen(buf->buf) - 3); + strbuf_addchars(arrow, '>', 1); + strbuf_addchars(arrow, ' ', 1); + } else { + strbuf_ltrim(buf); + strbuf_addchars(arrow, '-', len - strlen(buf->buf) + 1); + strbuf_addchars(arrow, ' ', 1); + } } } +static void build_arrow(struct strbuf *buf, struct strbuf* arrow, int add_after_entry) { + build_arrow_(buf, arrow, add_after_entry, 0); +} + +static void build_reversed_arrow(struct strbuf *buf, struct strbuf* arrow, int add_after_entry) { + build_arrow_(buf, arrow, add_after_entry, 1); +} + 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(_("|")); @@ -180,6 +201,18 @@ void print_noob_status(struct wt_status *s, int advice) } } + for_each_string_list_item(item2, &s->restored) { + 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); + build_reversed_arrow(&table_col_entry_1, &arrow_1, 1); + build_reversed_arrow(&table_col_entry_2, &arrow_2, 0); + build_reversed_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, &arrow_1, &arrow_2, &arrow_3, s, 0); else @@ -215,6 +248,17 @@ void print_noob_status(struct wt_status *s, int advice) is_arrow = 1; } } + + for_each_string_list_item(item2, &s->restored) { + 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); + build_reversed_arrow(&table_col_entry_2, &arrow_2, 1); + build_reversed_arrow(&table_col_entry_3, &arrow_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); diff --git a/wt-status.h b/wt-status.h index 7b883fd476..c6bce8f74a 100644 --- a/wt-status.h +++ b/wt-status.h @@ -144,6 +144,7 @@ struct wt_status { struct string_list untracked; struct string_list ignored; struct string_list added; + struct string_list restored; uint32_t untracked_in_ms; }; From patchwork Thu Oct 26 22:46:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Stopak X-Patchwork-Id: 13437990 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 B4259273D1 for ; Thu, 26 Oct 2023 22:46:49 +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="PylVT53k" Received: from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com [IPv6:2607:f8b0:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 58E5C1B2 for ; Thu, 26 Oct 2023 15:46:48 -0700 (PDT) Received: by mail-pf1-x42a.google.com with SMTP id d2e1a72fcca58-6bd0e1b1890so1383930b3a.3 for ; Thu, 26 Oct 2023 15:46:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=initialcommit-io.20230601.gappssmtp.com; s=20230601; t=1698360407; x=1698965207; 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=Y/myvL0wBmCeIacYTdD9mDqkuo8P/UBGmG+cU/3jDDE=; b=PylVT53kjQgfwZr2vYWx5xAEGsuJu/5w96LIM4wvjNsalWlct3W5MKblEPUkmIxzHC a6OgiN047hKWh35teUgfJrNWzuJFKzqGfFI3dpqbFBYjePgcQpfIimVVsYl+xbDmllIL Dvd4HXYfZ8MjFUUnBtXq5iEW72ngfXqxlJrtmhNluzvrp8iaaOAUis6vKbmpLZOhawDG LOvt8UPMPaQaxJG4g+Pd3tbwjUVBqDMqKIIPc4Gpqfq5y0bblA6J5Ld9KESgg4vYz4em s7eXWhlMNrlJkwgKjROxcf/gyBx1L1qv6P6ywyHUsI2wHuSIfL1mY+XVhx0Ju5P0L8IK PBsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698360407; x=1698965207; 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=Y/myvL0wBmCeIacYTdD9mDqkuo8P/UBGmG+cU/3jDDE=; b=D8bqORve+F4Ns+Zoa/tjwKEcwadg15LgWYNEb+PJeCReoNMfXw3PuZLnPJTQPeXq5i T+gnLMgL4nZUhbKqcS7rqesyXiu7z/vWnDNP+hLCwRuPU4dDFc93uSexFoGsYjLwWwZL GZvzJkH3IX2kys/w2w8WZacj3xDYSLdWvTssIO18a0EtrgqTiBOaLoYTq+Y8L8CiEGMp EgVi5L+HEE3EldP3oZ6ySxFxFU2SJ3f984SaNjtjqX+j5Ue3BbbBY/TgwGV/hMpYRYPE mX6l9Z7HeYLWAR2Q66tnbpADfoBXHn18ws7xg83QpsUyzqMyKKfN93gLl6bUIoy4oROw KDnw== X-Gm-Message-State: AOJu0YzOstc030cKhgI5GGTIUnKMLE1AApdWEvEt1sXHyOJAQd0srkME SXfhej78lihRN+9G3L6AocS40MzFuMte5erGtT8= X-Google-Smtp-Source: AGHT+IE5233cIBC4QDjUtuKrewtP1MGenM4au6Ls2CVyPSx3ecS7wd5i2GofdPnBDFKxGk518e+Wgg== X-Received: by 2002:a05:6a20:3d8b:b0:137:514a:984f with SMTP id s11-20020a056a203d8b00b00137514a984fmr1365100pzi.35.1698360407633; Thu, 26 Oct 2023 15:46:47 -0700 (PDT) Received: from localhost.localdomain (mobile-166-170-45-225.mycingular.net. [166.170.45.225]) by smtp.gmail.com with ESMTPSA id s194-20020a6377cb000000b0058ac101ad83sm112318pgc.33.2023.10.26.15.46.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Oct 2023 15:46:46 -0700 (PDT) From: Jacob Stopak To: git@vger.kernel.org Cc: Jacob Stopak Subject: [RFC PATCH v2 6/6] status: add advice status hints as table footer Date: Thu, 26 Oct 2023 15:46:15 -0700 Message-ID: <20231026224615.675172-7-jacob@initialcommit.io> X-Mailer: git-send-email 2.42.0.404.g2bcc23f3db In-Reply-To: <20231026224615.675172-1-jacob@initialcommit.io> References: <20231020183947.463882-1-jacob@initialcommit.io> <20231026224615.675172-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/commit.c | 1 + table.c | 42 +++++++++++++++++++++++++++--------------- table.h | 2 +- wt-status.c | 3 ++- wt-status.h | 2 ++ 5 files changed, 33 insertions(+), 17 deletions(-) diff --git a/builtin/commit.c b/builtin/commit.c index 3f816c117d..b97943e642 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1434,6 +1434,7 @@ int cmd_status(int argc, const char **argv, const char *prefix) s.ignore_submodule_arg = ignore_submodule_arg; s.status_format = status_format; s.verbose = verbose; + s.is_cmd_status = 1; if (no_renames != -1) s.detect_rename = !no_renames; if ((intptr_t)rename_score_arg != -1) { diff --git a/table.c b/table.c index 3602def17a..36719e3d09 100644 --- a/table.c +++ b/table.c @@ -6,6 +6,7 @@ #include "config.h" #include "string-list.h" #include "color.h" +#include "advice.h" #include "sys/ioctl.h" static const char *color(int slot, struct wt_status *s) @@ -132,7 +133,18 @@ static void print_table_body_line(struct strbuf *buf1, struct strbuf *buf2, stru printf(_("|\n")); } -void print_noob_status(struct wt_status *s, int advice) +static void print_table_hint_line(struct strbuf *buf1, struct strbuf *buf2, struct strbuf *buf3, struct wt_status *s) +{ + printf(_("|")); + color_fprintf(s->fp, color(WT_STATUS_HINT, s), "%s", buf1->buf); + printf(_("|")); + color_fprintf(s->fp, color(WT_STATUS_HINT, s), "%s", buf2->buf); + printf(_("|")); + color_fprintf(s->fp, color(WT_STATUS_HINT, s), "%s", buf3->buf); + printf(_("|\n")); +} + +void print_noob_status(struct wt_status *s) { struct winsize w; int cols; @@ -163,20 +175,6 @@ void print_noob_status(struct wt_status *s, int 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 (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 */ @@ -282,6 +280,20 @@ void print_noob_status(struct wt_status *s, int advice) } printf(_("%s\n"), table_border.buf); + + if (s->is_cmd_status && advice_enabled(ADVICE_STATUS_HINTS)) { + 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); + print_table_hint_line(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, s); + + 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); + print_table_hint_line(&table_col_entry_1, &table_col_entry_2, &table_col_entry_3, s); + printf(_("%s\n"), table_border.buf); + } + strbuf_release(&table_border); strbuf_release(&table_col_entry_1); strbuf_release(&table_col_entry_2); diff --git a/table.h b/table.h index 5dff7162a4..c9e8c386de 100644 --- a/table.h +++ b/table.h @@ -1,6 +1,6 @@ #ifndef TABLE_H #define TABLE_H -void print_noob_status(struct wt_status *s, int i); +void print_noob_status(struct wt_status *s); #endif /* TABLE_H */ diff --git a/wt-status.c b/wt-status.c index 1332d07dba..288817dcf7 100644 --- a/wt-status.c +++ b/wt-status.c @@ -50,6 +50,7 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = { GIT_COLOR_RED, /* WT_STATUS_REMOTE_BRANCH */ GIT_COLOR_NIL, /* WT_STATUS_ONBRANCH */ GIT_COLOR_CYAN, /* WT_STATUS_ARROW */ + GIT_COLOR_YELLOW, /* WT_STATUS_HINT */ }; static const char *color(int slot, struct wt_status *s) @@ -2151,7 +2152,7 @@ static void wt_noobstatus_print(struct wt_status *s) wt_longstatus_print_tracking(s); } - print_noob_status(s, 0); + print_noob_status(s); } static void wt_porcelain_print(struct wt_status *s) diff --git a/wt-status.h b/wt-status.h index c6bce8f74a..0a14b4b064 100644 --- a/wt-status.h +++ b/wt-status.h @@ -20,6 +20,7 @@ enum color_wt_status { WT_STATUS_REMOTE_BRANCH, WT_STATUS_ONBRANCH, WT_STATUS_ARROW, + WT_STATUS_HINT, WT_STATUS_MAXSLOT }; @@ -146,6 +147,7 @@ struct wt_status { struct string_list added; struct string_list restored; uint32_t untracked_in_ms; + int is_cmd_status; }; size_t wt_status_locate_end(const char *s, size_t len);