git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jacob Stopak <jacob@initialcommit.io>
To: git@vger.kernel.org
Cc: Jacob Stopak <jacob@initialcommit.io>
Subject: [RFC PATCH v2 5/6] restore: implement noob mode
Date: Thu, 26 Oct 2023 15:46:14 -0700	[thread overview]
Message-ID: <20231026224615.675172-6-jacob@initialcommit.io> (raw)
In-Reply-To: <20231026224615.675172-1-jacob@initialcommit.io>

Signed-off-by: Jacob Stopak <jacob@initialcommit.io>
---
 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 [<options>] <branch>"),
@@ -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;
 };
 
-- 
2.42.0.404.g2bcc23f3db


  parent reply	other threads:[~2023-10-26 22:46 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-20 18:39 [RFC PATCH 0/5] Introduce -t, --table for status/add commands Jacob Stopak
2023-10-20 18:39 ` [RFC PATCH 1/5] status: introduce -t, --table flag Jacob Stopak
2023-10-20 18:39 ` [RFC PATCH 2/5] status: handle long paths with " Jacob Stopak
2023-10-20 18:39 ` [RFC PATCH 3/5] status: add advice arg for " Jacob Stopak
2023-10-20 18:39 ` [RFC PATCH 4/5] add: add -t, --table flag for visual dry runs Jacob Stopak
2023-10-20 18:39 ` [RFC PATCH 5/5] add: set unique color for -t, --table arrows Jacob Stopak
2023-10-20 18:48 ` [RFC PATCH 0/5] Introduce -t, --table for status/add commands Dragan Simic
2023-10-20 21:48   ` Jacob Stopak
2023-10-20 23:02     ` Dragan Simic
2023-10-20 23:28       ` Junio C Hamano
2023-10-22  6:04         ` Jacob Stopak
2023-10-22  6:52           ` Dragan Simic
2023-10-22  5:52       ` Jacob Stopak
2023-10-22  6:38         ` Dragan Simic
2023-10-22 10:30           ` Oswald Buddenhagen
2023-10-22 12:55             ` Dragan Simic
2023-10-23 10:52               ` Oswald Buddenhagen
2023-10-23 14:34                 ` Dragan Simic
2023-10-23 17:30                   ` Jacob Stopak
2023-10-23 17:59                     ` Dragan Simic
2023-10-23 18:16                     ` Oswald Buddenhagen
2023-10-23 19:29                       ` Jacob Stopak
2023-10-23 20:19                         ` Oswald Buddenhagen
2023-10-23 20:51                           ` Dragan Simic
2023-10-23 21:14                             ` Oswald Buddenhagen
2023-10-23 21:19                               ` Dragan Simic
2023-10-23 23:17                           ` Jacob Stopak
2023-10-24  1:10                             ` Dragan Simic
2023-10-24  2:03                               ` Junio C Hamano
2023-10-24  2:21                                 ` Dragan Simic
2024-01-05 19:14                                   ` Dragan Simic
2024-01-06  4:44                                     ` Jacob Stopak
2024-01-06  7:06                                       ` Dragan Simic
2023-10-23 20:29                         ` Dragan Simic
2023-10-23 19:01                     ` Junio C Hamano
2023-10-23 19:04                       ` Dragan Simic
2023-10-23 20:47                         ` Oswald Buddenhagen
2023-10-23 20:59                           ` Dragan Simic
2023-10-23 21:23                             ` Jacob Stopak
2023-10-23 21:26                               ` Dragan Simic
2023-10-23 21:12                       ` Jacob Stopak
2023-10-22 15:50             ` Jacob Stopak
2023-10-26 22:46 ` [RFC PATCH v2 0/6] Noobify format for status, add, restore Jacob Stopak
2023-10-26 22:46   ` [RFC PATCH v2 1/6] status: add noob format from status.noob config Jacob Stopak
2023-10-30  1:32     ` Junio C Hamano
2023-10-30  1:38       ` Dragan Simic
2023-10-30  6:06       ` Jacob Stopak
2023-10-26 22:46   ` [RFC PATCH v2 2/6] status: handle long paths in noob format Jacob Stopak
2023-10-26 22:46   ` [RFC PATCH v2 3/6] add: implement noob mode Jacob Stopak
2023-10-26 22:46   ` [RFC PATCH v2 4/6] add: set unique color for noob mode arrows Jacob Stopak
2023-10-26 22:46   ` Jacob Stopak [this message]
2023-10-26 22:46   ` [RFC PATCH v2 6/6] status: add advice status hints as table footer Jacob Stopak
2023-10-27 13:32   ` [RFC PATCH v2 0/6] Noobify format for status, add, restore Dragan Simic
2023-10-27 17:13     ` Jacob Stopak
2023-10-28  0:06       ` Dragan Simic
2023-10-28  2:52         ` Jacob Stopak
2023-10-28  5:55           ` Dragan Simic
2023-10-28 15:21             ` Jacob Stopak
2023-10-28 16:20               ` Dragan Simic
2023-10-28 17:35                 ` Jacob Stopak
2023-10-28 17:41                   ` Dragan Simic
2023-10-28 18:05                     ` Jacob Stopak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231026224615.675172-6-jacob@initialcommit.io \
    --to=jacob@initialcommit.io \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).