git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "Rubén Justo" <rjusto@gmail.com>
To: Git List <git@vger.kernel.org>
Cc: Junio C Hamano <gitster@pobox.com>
Subject: [PATCH 2/3] worktree: warn when removing a worktree with orphan commits
Date: Sun, 23 Apr 2023 00:19:21 +0200	[thread overview]
Message-ID: <1897dff1-bb4d-9715-dd1c-86763c052589@gmail.com> (raw)
In-Reply-To: <f702476a-543a-da9b-ccd9-4431c80471e1@gmail.com>

While working in a detached worktree, the user can create some commits
which won't be automatically connected to any ref.

Eventually, that worktree can be removed and, if the user has not
created any ref connected to the HEAD in that worktree (e.g. branch,
tag), those commits will become unreachable.

Let's issue a warning to remind the user for safety, when deleting a
worktree whose HEAD is not connected to an existing ref.

Let's also add an option to modify the message we show in
orphaned_commit_warning(): "Previous HEAD position was..."; allowing to
omit the word "Previous" as it may cause confusion, erroneously
suggesting that there is a "Current HEAD" while the worktree has been
removed.

Signed-off-by: Rubén Justo <rjusto@gmail.com>
---
 builtin/checkout.c       |  2 +-
 builtin/worktree.c       |  8 ++++++++
 checkout.c               |  7 +++++--
 checkout.h               |  3 ++-
 t/t2403-worktree-move.sh | 10 ++++++++++
 5 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 991413ef1a..85ac4bca00 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1051,7 +1051,7 @@ static int switch_branches(const struct checkout_opts *opts,
 	}
 
 	if (!opts->quiet && !old_branch_info.path && old_branch_info.commit && new_branch_info->commit != old_branch_info.commit)
-		orphaned_commit_warning(old_branch_info.commit, new_branch_info->commit);
+		orphaned_commit_warning(old_branch_info.commit, new_branch_info->commit, 1);
 
 	update_refs_for_switch(opts, &old_branch_info, new_branch_info);
 
diff --git a/builtin/worktree.c b/builtin/worktree.c
index a61bc32189..df269bccc8 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -1138,6 +1138,14 @@ static int remove_worktree(int ac, const char **av, const char *prefix)
 
 		ret |= delete_git_work_tree(wt);
 	}
+
+	if (!wt->head_ref && !is_null_oid(&wt->head_oid)) {
+		struct commit* wt_commit = lookup_commit_reference_gently(the_repository,
+									  &wt->head_oid, 1);
+		if (wt_commit)
+			orphaned_commit_warning(wt_commit, NULL, 0);
+	}
+
 	/*
 	 * continue on even if ret is non-zero, there's no going back
 	 * from here.
diff --git a/checkout.c b/checkout.c
index 18e7362043..5f7b0b3c49 100644
--- a/checkout.c
+++ b/checkout.c
@@ -171,7 +171,8 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs)
  * HEAD.  If it is not reachable from any ref, this is the last chance
  * for the user to do so without resorting to reflog.
  */
-void orphaned_commit_warning(struct commit *old_commit, struct commit *new_commit)
+void orphaned_commit_warning(struct commit *old_commit, struct commit *new_commit,
+			     int show_previous_position)
 {
 	struct rev_info revs;
 	struct object *object = &old_commit->object;
@@ -192,8 +193,10 @@ void orphaned_commit_warning(struct commit *old_commit, struct commit *new_commi
 		die(_("internal error in revision walk"));
 	if (!(old_commit->object.flags & UNINTERESTING))
 		suggest_reattach(old_commit, &revs);
-	else
+	else if (show_previous_position)
 		describe_detached_head(_("Previous HEAD position was"), old_commit);
+	else
+		describe_detached_head(_("HEAD position was"), old_commit);
 
 	/* Clean up objects used, as they will be reused. */
 	repo_clear_commit_marks(the_repository, ALL_REV_FLAGS);
diff --git a/checkout.h b/checkout.h
index c7dc056544..ee400376d5 100644
--- a/checkout.h
+++ b/checkout.h
@@ -18,7 +18,8 @@ const char *unique_tracking_name(const char *name,
  * HEAD.  If it is not reachable from any ref, this is the last chance
  * for the user to do so without resorting to reflog.
  */
-void orphaned_commit_warning(struct commit *old_commit, struct commit *new_commit);
+void orphaned_commit_warning(struct commit *old_commit, struct commit *new_commit,
+			     int show_previous_position);
 
 void describe_detached_head(const char *msg, struct commit *commit);
 #endif /* CHECKOUT_H */
diff --git a/t/t2403-worktree-move.sh b/t/t2403-worktree-move.sh
index 230a55e99a..f2756f7137 100755
--- a/t/t2403-worktree-move.sh
+++ b/t/t2403-worktree-move.sh
@@ -247,4 +247,14 @@ test_expect_success 'not remove a repo with initialized submodule' '
 	)
 '
 
+test_expect_success 'warn when removing a worktree with orphan commits' '
+	git worktree add --detach foo &&
+	git -C foo commit -m one --allow-empty &&
+	git -C foo commit -m two --allow-empty &&
+	git worktree remove foo 2>err &&
+	test_i18ngrep "you are leaving 2 commits behind" err &&
+	test_i18ngrep ! "Previous HEAD position was" err
+	test_i18ngrep "HEAD position was" err
+'
+
 test_done
-- 
2.39.2

  parent reply	other threads:[~2023-04-22 22:19 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-22 22:10 [PATCH 0/3] warn when unreachable commits are left behind Rubén Justo
2023-04-22 22:19 ` [PATCH 1/3] checkout: move orphaned_commit_warning() Rubén Justo
2023-04-22 22:19 ` Rubén Justo [this message]
2023-04-24 20:28   ` [PATCH 2/3] worktree: warn when removing a worktree with orphan commits Junio C Hamano
2023-04-26 22:29     ` Rubén Justo
2023-04-27  5:46       ` Junio C Hamano
2023-04-27  6:16         ` Eric Sunshine
2023-04-28  0:49           ` Junio C Hamano
2023-04-27 23:08         ` Rubén Justo
2023-04-22 22:19 ` [PATCH 3/3] checkout: warn when unreachable commits after using --orphan Rubén Justo
2023-04-27  0:28   ` Andrei Rybak
2023-04-27 23:09     ` Rubén Justo

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

  List information: http://vger.kernel.org/majordomo-info.html

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

  git send-email \
    --in-reply-to=1897dff1-bb4d-9715-dd1c-86763c052589@gmail.com \
    --to=rjusto@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).