From patchwork Sat Apr 22 22:19:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Rub=C3=A9n_Justo?= X-Patchwork-Id: 13221136 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3F3FC7618E for ; Sat, 22 Apr 2023 22:19:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229785AbjDVWTN (ORCPT ); Sat, 22 Apr 2023 18:19:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39974 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229587AbjDVWTL (ORCPT ); Sat, 22 Apr 2023 18:19:11 -0400 Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 80AD126BE for ; Sat, 22 Apr 2023 15:19:09 -0700 (PDT) Received: by mail-wm1-x330.google.com with SMTP id 5b1f17b1804b1-3f178da21b2so31471765e9.1 for ; Sat, 22 Apr 2023 15:19:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682201948; x=1684793948; h=content-transfer-encoding:content-language:in-reply-to:mime-version :user-agent:date:message-id:references:cc:to:from:subject:from:to:cc :subject:date:message-id:reply-to; bh=+MAXPguIYG550wI+/5xI9tvNvJ0ttQc/qw6ldMv4KD4=; b=NEhuePwFjWRTsZk8TbxQV16v48kbC03JWhuTvjOB5vu5kf0W7fLGH/EfCOlYCg11sZ 1Mb8aRW/kkQgjjr6h3iglYVFSBvyqVEsJQCab8ofCBAHcPzwxcqrNrNJd7FA1S99DqC7 OJW1T7GT5mw01x31KwEUwiPbE4XUk4bzC1G8GYhouUtUqWCtywx3Bt0kai5VAmi8HDX4 /12WOa+kw1wmEUL82WuAZiWKE8isXDrDTgbNBHlEdpRiFiLokNXkaerpUA0NOkrsnHHr sy16VMp3BaSwuGY470a4Q6f8QnjyyyVv21lgy1Bwnz2vuHdrHXDiihUyTdSYh/4X8hrW XSOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682201948; x=1684793948; h=content-transfer-encoding:content-language:in-reply-to:mime-version :user-agent:date:message-id:references:cc:to:from:subject :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=+MAXPguIYG550wI+/5xI9tvNvJ0ttQc/qw6ldMv4KD4=; b=JgCOz9PDZwK0A/U7BV8/nU3k15fj2XmRpfZgFjDhQLkgmOdx5i2sC1o6VDnbt4JFzq gImzfXvmlNuoHH56mtxAaf+WxpuugMhs9XCiGGd0p9jvHWN3MnVisGoHzzsdg4w1cLg0 xSxQGwFzu5pFyenzyLxf4DXCmc5hK4Fr9ZHoRlya1aM74z7g5uUiKInWdlqIIF0bwj+t P/X7jx4jp9LT9VrGZs9+xh1A3fHNsO0bdGT3znxXXW6cWvcVzxrmbig6uV8BOHUdT6cy alNbGX6+788LpuPihHb0f+t9vOZQ+bHUvSkD77EaGTz+w2W6vF1lsywtz7VjWNSGQejc R9hg== X-Gm-Message-State: AAQBX9cz/mSqnfJFIy5uPgfFP7y/7XRH5iqx7jwnIRUl5YdKekHloVQM B9KaRur/yVePznBIKkO55Yk= X-Google-Smtp-Source: AKy350bRWJXMborPk54fWm4dFbiHBy3JM3ofUkYZqhU15ZsimoA1SvJrI3sikMbWARxaMgGIM92/Qg== X-Received: by 2002:a5d:4149:0:b0:2fe:61b0:d7a2 with SMTP id c9-20020a5d4149000000b002fe61b0d7a2mr6743885wrq.12.1682201947734; Sat, 22 Apr 2023 15:19:07 -0700 (PDT) Received: from [192.168.2.52] (32.red-88-14-41.dynamicip.rima-tde.net. [88.14.41.32]) by smtp.gmail.com with ESMTPSA id h1-20020a5d6e01000000b002fa834e1c69sm7372251wrz.52.2023.04.22.15.19.07 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 22 Apr 2023 15:19:07 -0700 (PDT) Subject: [PATCH 1/3] checkout: move orphaned_commit_warning() From: =?utf-8?q?Rub=C3=A9n_Justo?= To: Git List Cc: Junio C Hamano References: Message-ID: Date: Sun, 23 Apr 2023 00:19:05 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.14.0 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org In 8e2dc6ac06 (commit: give final warning when reattaching HEAD to leave commits behind, 2011-02-18) we introduced orphaned_commit_warning() in builtin/checkout.c. In subsequent commits we're going to use orphaned_commit_warning() not only from builtin/checkout.c, but from other builtin commands too. Let's move the function and its helpers to checkout.c and make it an API callable not just from builtin/checkout.c. Signed-off-by: Rubén Justo --- builtin/checkout.c | 124 ------------------------------------------- checkout.c | 129 +++++++++++++++++++++++++++++++++++++++++++++ checkout.h | 9 ++++ 3 files changed, 138 insertions(+), 124 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index 6f5d82ed3d..991413ef1a 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -656,24 +656,6 @@ static void show_local_changes(struct object *head, release_revisions(&rev); } -static void describe_detached_head(const char *msg, struct commit *commit) -{ - struct strbuf sb = STRBUF_INIT; - - if (!repo_parse_commit(the_repository, commit)) - pp_commit_easy(CMIT_FMT_ONELINE, commit, &sb); - if (print_sha1_ellipsis()) { - fprintf(stderr, "%s %s... %s\n", msg, - repo_find_unique_abbrev(the_repository, &commit->object.oid, DEFAULT_ABBREV), - sb.buf); - } else { - fprintf(stderr, "%s %s %s\n", msg, - repo_find_unique_abbrev(the_repository, &commit->object.oid, DEFAULT_ABBREV), - sb.buf); - } - strbuf_release(&sb); -} - static int reset_tree(struct tree *tree, const struct checkout_opts *o, int worktree, int *writeout_error, struct branch_info *info) @@ -1016,112 +998,6 @@ static void update_refs_for_switch(const struct checkout_opts *opts, report_tracking(new_branch_info); } -static int add_pending_uninteresting_ref(const char *refname, - const struct object_id *oid, - int flags UNUSED, void *cb_data) -{ - add_pending_oid(cb_data, refname, oid, UNINTERESTING); - return 0; -} - -static void describe_one_orphan(struct strbuf *sb, struct commit *commit) -{ - strbuf_addstr(sb, " "); - strbuf_add_unique_abbrev(sb, &commit->object.oid, DEFAULT_ABBREV); - strbuf_addch(sb, ' '); - if (!repo_parse_commit(the_repository, commit)) - pp_commit_easy(CMIT_FMT_ONELINE, commit, sb); - strbuf_addch(sb, '\n'); -} - -#define ORPHAN_CUTOFF 4 -static void suggest_reattach(struct commit *commit, struct rev_info *revs) -{ - struct commit *c, *last = NULL; - struct strbuf sb = STRBUF_INIT; - int lost = 0; - while ((c = get_revision(revs)) != NULL) { - if (lost < ORPHAN_CUTOFF) - describe_one_orphan(&sb, c); - last = c; - lost++; - } - if (ORPHAN_CUTOFF < lost) { - int more = lost - ORPHAN_CUTOFF; - if (more == 1) - describe_one_orphan(&sb, last); - else - strbuf_addf(&sb, _(" ... and %d more.\n"), more); - } - - fprintf(stderr, - Q_( - /* The singular version */ - "Warning: you are leaving %d commit behind, " - "not connected to\n" - "any of your branches:\n\n" - "%s\n", - /* The plural version */ - "Warning: you are leaving %d commits behind, " - "not connected to\n" - "any of your branches:\n\n" - "%s\n", - /* Give ngettext() the count */ - lost), - lost, - sb.buf); - strbuf_release(&sb); - - if (advice_enabled(ADVICE_DETACHED_HEAD)) - fprintf(stderr, - Q_( - /* The singular version */ - "If you want to keep it by creating a new branch, " - "this may be a good time\nto do so with:\n\n" - " git branch %s\n\n", - /* The plural version */ - "If you want to keep them by creating a new branch, " - "this may be a good time\nto do so with:\n\n" - " git branch %s\n\n", - /* Give ngettext() the count */ - lost), - repo_find_unique_abbrev(the_repository, &commit->object.oid, DEFAULT_ABBREV)); -} - -/* - * We are about to leave commit that was at the tip of a detached - * HEAD. If it is not reachable from any ref, this is the last chance - * for the user to do so without resorting to reflog. - */ -static void orphaned_commit_warning(struct commit *old_commit, struct commit *new_commit) -{ - struct rev_info revs; - struct object *object = &old_commit->object; - - repo_init_revisions(the_repository, &revs, NULL); - setup_revisions(0, NULL, &revs, NULL); - - object->flags &= ~UNINTERESTING; - add_pending_object(&revs, object, oid_to_hex(&object->oid)); - - for_each_ref(add_pending_uninteresting_ref, &revs); - if (new_commit) - add_pending_oid(&revs, "HEAD", - &new_commit->object.oid, - UNINTERESTING); - - if (prepare_revision_walk(&revs)) - die(_("internal error in revision walk")); - if (!(old_commit->object.flags & UNINTERESTING)) - suggest_reattach(old_commit, &revs); - else - describe_detached_head(_("Previous HEAD position was"), old_commit); - - /* Clean up objects used, as they will be reused. */ - repo_clear_commit_marks(the_repository, ALL_REV_FLAGS); - release_revisions(&revs); -} - static int switch_branches(const struct checkout_opts *opts, struct branch_info *new_branch_info) { diff --git a/checkout.c b/checkout.c index 04238b2713..18e7362043 100644 --- a/checkout.c +++ b/checkout.c @@ -5,6 +5,11 @@ #include "checkout.h" #include "config.h" #include "strbuf.h" +#include "environment.h" +#include "revision.h" +#include "advice.h" +#include "hex.h" +#include "refs.h" struct tracking_name_data { /* const */ char *src_ref; @@ -70,3 +75,127 @@ const char *unique_tracking_name(const char *name, struct object_id *oid, } return NULL; } + +void describe_detached_head(const char *msg, struct commit *commit) +{ + struct strbuf sb = STRBUF_INIT; + + if (!repo_parse_commit(the_repository, commit)) + pp_commit_easy(CMIT_FMT_ONELINE, commit, &sb); + if (print_sha1_ellipsis()) { + fprintf(stderr, "%s %s... %s\n", msg, + repo_find_unique_abbrev(the_repository, &commit->object.oid, DEFAULT_ABBREV), + sb.buf); + } else { + fprintf(stderr, "%s %s %s\n", msg, + repo_find_unique_abbrev(the_repository, &commit->object.oid, DEFAULT_ABBREV), + sb.buf); + } + strbuf_release(&sb); +} + +static int add_pending_uninteresting_ref(const char *refname, + const struct object_id *oid, + int flags UNUSED, void *cb_data) +{ + add_pending_oid(cb_data, refname, oid, UNINTERESTING); + return 0; +} + +static void describe_one_orphan(struct strbuf *sb, struct commit *commit) +{ + strbuf_addstr(sb, " "); + strbuf_add_unique_abbrev(sb, &commit->object.oid, DEFAULT_ABBREV); + strbuf_addch(sb, ' '); + if (!repo_parse_commit(the_repository, commit)) + pp_commit_easy(CMIT_FMT_ONELINE, commit, sb); + strbuf_addch(sb, '\n'); +} + +#define ORPHAN_CUTOFF 4 +static void suggest_reattach(struct commit *commit, struct rev_info *revs) +{ + struct commit *c, *last = NULL; + struct strbuf sb = STRBUF_INIT; + int lost = 0; + while ((c = get_revision(revs)) != NULL) { + if (lost < ORPHAN_CUTOFF) + describe_one_orphan(&sb, c); + last = c; + lost++; + } + if (ORPHAN_CUTOFF < lost) { + int more = lost - ORPHAN_CUTOFF; + if (more == 1) + describe_one_orphan(&sb, last); + else + strbuf_addf(&sb, _(" ... and %d more.\n"), more); + } + + fprintf(stderr, + Q_( + /* The singular version */ + "Warning: you are leaving %d commit behind, " + "not connected to\n" + "any of your branches:\n\n" + "%s\n", + /* The plural version */ + "Warning: you are leaving %d commits behind, " + "not connected to\n" + "any of your branches:\n\n" + "%s\n", + /* Give ngettext() the count */ + lost), + lost, + sb.buf); + strbuf_release(&sb); + + if (advice_enabled(ADVICE_DETACHED_HEAD)) + fprintf(stderr, + Q_( + /* The singular version */ + "If you want to keep it by creating a new branch, " + "this may be a good time\nto do so with:\n\n" + " git branch %s\n\n", + /* The plural version */ + "If you want to keep them by creating a new branch, " + "this may be a good time\nto do so with:\n\n" + " git branch %s\n\n", + /* Give ngettext() the count */ + lost), + repo_find_unique_abbrev(the_repository, &commit->object.oid, DEFAULT_ABBREV)); +} + +/* + * We are about to leave commit that was at the tip of a detached + * 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) +{ + struct rev_info revs; + struct object *object = &old_commit->object; + + repo_init_revisions(the_repository, &revs, NULL); + setup_revisions(0, NULL, &revs, NULL); + + object->flags &= ~UNINTERESTING; + add_pending_object(&revs, object, oid_to_hex(&object->oid)); + + for_each_ref(add_pending_uninteresting_ref, &revs); + if (new_commit) + add_pending_oid(&revs, "HEAD", + &new_commit->object.oid, + UNINTERESTING); + + if (prepare_revision_walk(&revs)) + die(_("internal error in revision walk")); + if (!(old_commit->object.flags & UNINTERESTING)) + suggest_reattach(old_commit, &revs); + else + describe_detached_head(_("Previous HEAD position was"), old_commit); + + /* Clean up objects used, as they will be reused. */ + repo_clear_commit_marks(the_repository, ALL_REV_FLAGS); + release_revisions(&revs); +} diff --git a/checkout.h b/checkout.h index 1917f3b323..c7dc056544 100644 --- a/checkout.h +++ b/checkout.h @@ -2,6 +2,7 @@ #define CHECKOUT_H #include "hash.h" +#include "commit.h" /* * Check if the branch name uniquely matches a branch name on a remote @@ -12,4 +13,12 @@ const char *unique_tracking_name(const char *name, struct object_id *oid, int *dwim_remotes_matched); +/* + * We are about to leave commit that was at the tip of a detached + * 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 describe_detached_head(const char *msg, struct commit *commit); #endif /* CHECKOUT_H */ From patchwork Sat Apr 22 22:19:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Rub=C3=A9n_Justo?= X-Patchwork-Id: 13221137 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B9D3EC77B78 for ; Sat, 22 Apr 2023 22:19:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229867AbjDVWT2 (ORCPT ); Sat, 22 Apr 2023 18:19:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40130 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229587AbjDVWT1 (ORCPT ); Sat, 22 Apr 2023 18:19:27 -0400 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2CFA126AD for ; Sat, 22 Apr 2023 15:19:25 -0700 (PDT) Received: by mail-wr1-x42c.google.com with SMTP id ffacd0b85a97d-2f87c5b4635so2808783f8f.1 for ; Sat, 22 Apr 2023 15:19:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682201963; x=1684793963; h=content-transfer-encoding:content-language:in-reply-to:mime-version :user-agent:date:message-id:references:cc:to:from:subject:from:to:cc :subject:date:message-id:reply-to; bh=LJ+aoC6ySzh7skTJeAMnkovekBqKSykLZlOBFW3/qEQ=; b=ffHotN7NCNWV2u4hoT/9ozsZvZwB9e8bIeVbl/A8o4+IWb6LvDdEFSLUp3MTVvsV3V muJyJ8MciCUMEZxxkSNlxRbuLsCi1u0Q6E67u5Xmim8OE2O+d0C6KWNoKVqShqExLgyj U5+XtdLYC5LWnhpH6Po6Pgp/6QzSKATNqeG2v8ISq6TIJL9scwdnFaXjFvpW/fhcayoB QGHNPBZkYXAUzQlZsbkNS9YUOmF/YkaOuK8HEZ8ECRWeALXREnU63ymhGeHgRq9NchhA mH4gSJDcsuUywc5mKI89Afpk4Df81p4YifUG9dky1G/8D0BsS9Wb9CEnIYgNM/a5Il3E o2dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682201963; x=1684793963; h=content-transfer-encoding:content-language:in-reply-to:mime-version :user-agent:date:message-id:references:cc:to:from:subject :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=LJ+aoC6ySzh7skTJeAMnkovekBqKSykLZlOBFW3/qEQ=; b=U1i6tSxkFtJF1t6h9BxhuNZVMEBAoJNmOw6nJhvr9z+Bv7a6FWjLVq6fnJunMNUmGi a2knuuXA0NG2xbt5xHVUjS3+H/nIaRfhksyalfCg4SkHTCWN8O+Tkq7v/7vkR6UDWrRc 2NLt5wbiFZywqRsFLIffJq4JiG8IXZsoU3nvs/fzRVx7CZV27UBgzbRBgyP8X+j4QkBG 3tygjPCAzuLFOknQmbFXLS8/ZbhJ99mwGC1K0bbY48ZKHKPRFo9yUzOcn+5wWfpJxOLR pz4uunrVer6FZOBgcMAIQWAEv2KgOOCCBJssit/s2lkVXmY+DLyJOtGBwr+SIM2bxoho zqNQ== X-Gm-Message-State: AAQBX9eKSp84OS9AI7nRheLs+tSCJDvtg2q/CIkyBkukM+xBAr5kYECy zJPlgGyOzbuCCUlGWsdBsgem4oSV1/Y= X-Google-Smtp-Source: AKy350Yh1u2gkTffuXaMQiaB2A2sQUW273PiptNxQ9+554eR45LI1Tm/UJn4nVZlNcRAEQ8lxomBtw== X-Received: by 2002:adf:cf0d:0:b0:2f1:e162:d48 with SMTP id o13-20020adfcf0d000000b002f1e1620d48mr6581118wrj.47.1682201963343; Sat, 22 Apr 2023 15:19:23 -0700 (PDT) Received: from [192.168.2.52] (32.red-88-14-41.dynamicip.rima-tde.net. [88.14.41.32]) by smtp.gmail.com with ESMTPSA id p8-20020a05600c358800b003f1738d0d13sm16016946wmq.1.2023.04.22.15.19.22 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 22 Apr 2023 15:19:23 -0700 (PDT) Subject: [PATCH 2/3] worktree: warn when removing a worktree with orphan commits From: =?utf-8?q?Rub=C3=A9n_Justo?= To: Git List Cc: Junio C Hamano References: Message-ID: <1897dff1-bb4d-9715-dd1c-86763c052589@gmail.com> Date: Sun, 23 Apr 2023 00:19:21 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.14.0 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org 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 --- 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 From patchwork Sat Apr 22 22:19:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Rub=C3=A9n_Justo?= X-Patchwork-Id: 13221138 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E945AC7618E for ; Sat, 22 Apr 2023 22:19:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229900AbjDVWTs (ORCPT ); Sat, 22 Apr 2023 18:19:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40306 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229725AbjDVWTr (ORCPT ); Sat, 22 Apr 2023 18:19:47 -0400 Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com [IPv6:2a00:1450:4864:20::32d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6558326A4 for ; Sat, 22 Apr 2023 15:19:45 -0700 (PDT) Received: by mail-wm1-x32d.google.com with SMTP id 5b1f17b1804b1-3f1957e80a2so41258365e9.1 for ; Sat, 22 Apr 2023 15:19:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682201984; x=1684793984; h=content-transfer-encoding:content-language:in-reply-to:mime-version :user-agent:date:message-id:references:cc:to:from:subject:from:to:cc :subject:date:message-id:reply-to; bh=2IfNvuAOxcb1q/KCOIJTYtIR4eUBUGg27dSrRoUzm1Y=; b=mKtJLVdBdegIDUxIfLotkuLLkr1XNZGFrTrteCPaDDgRLVaZATU5W8Al/V9i5480Ji 6rO/DXxyTqSv7y4uOVlCT0om6i5RSIgcKl+43159tFEMu5A+/9ZpxPWIfbVKiYeopBah IT1KFgVwdEK0RkpKv/W1vdisyPSK2R0QE1FH2JKTqRftDaJNE+39CmcW0RMRaX69cJn+ 9zfEPqA4fIXy950Mszx4Qokbhug23JBPx+zNgqb4YQbEJ4V50RIOZvfZzIte5iM6lWiM 7svCeMrOHGrgNHtppqlkJAg04O+LEZI/LGl1lm79ZaHUnCAWeOTYj8trUag6MYcSHe++ NnCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682201984; x=1684793984; h=content-transfer-encoding:content-language:in-reply-to:mime-version :user-agent:date:message-id:references:cc:to:from:subject :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=2IfNvuAOxcb1q/KCOIJTYtIR4eUBUGg27dSrRoUzm1Y=; b=XhTTGqoKFJzc3rsENDG4z00bq5X6MFEfG4o4wXdEtOKnKE2kZAmhMVVVRMX+iqRD0d ThQ+H93TY7XaAvgdD2l6/ByZSirIG75Y+K/iUTsbSCn9sSOfrCN0fnfFsXVCZz+NlsWG 5qAxRZ0tzfnIQ1OhHcMDVNTvAT8dE5gTIUlWbkoD0gHoBiz8bDjVWZrEKnKknD1VIczO QdxAlpWX7yJrMVncORR5kIG2AHwmF74VRkSoK0yoE/1LEiZodxw6YQ9xAO7FNyOAhy40 nyc0lnkPV+rQc/cbNnF91vkdXsTESsYMoHZaPmmu0Q7d1+3nzoAUPxVKL2tPiDdUTplS I6AA== X-Gm-Message-State: AAQBX9fS+aPfhgfLDH5pn8HtEZzTfdHwR+SbwFyQunXG6/uYl2TsYtfl HL933BEFo3m1WS1abBZaNxc= X-Google-Smtp-Source: AKy350bC9FId5OW6ULERVqHGB3GospvZP17wFo0qm+K8nKOJGvbetRRBZjcPItmp4fls7/3ZwtxULg== X-Received: by 2002:a05:6000:47:b0:2d9:10e7:57e8 with SMTP id k7-20020a056000004700b002d910e757e8mr9669723wrx.16.1682201983944; Sat, 22 Apr 2023 15:19:43 -0700 (PDT) Received: from [192.168.2.52] (32.red-88-14-41.dynamicip.rima-tde.net. [88.14.41.32]) by smtp.gmail.com with ESMTPSA id q17-20020a1cf311000000b003eeb1d6a470sm8243890wmq.13.2023.04.22.15.19.43 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 22 Apr 2023 15:19:43 -0700 (PDT) Subject: [PATCH 3/3] checkout: warn when unreachable commits after using --orphan From: =?utf-8?q?Rub=C3=A9n_Justo?= To: Git List Cc: Junio C Hamano References: Message-ID: <417ae16c-9ba7-1e6d-c8d7-5b20a188b4fe@gmail.com> Date: Sun, 23 Apr 2023 00:19:42 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.14.0 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org In 8e2dc6ac06 (commit: give final warning when reattaching HEAD to leave commits behind, 2011-02-18) we introduced a warning to be issued when, while checking out, the tip commit being left behind is not connected to any ref. We assumed that if the commit to be checked out is the same commit currently checked out, we would omit the warning. This makes sense because we're going to have HEAD pointing to the same commit anyway, so there is nothing to warn about. However, with "--orphan" the target commit is not going to be used as HEAD in the worktree, but a new orphan branch being created, which is not going to be connected to the previous commit. Therefore, we need to check if the commit it is reachable and warn otherwise. Let's fix the condition we introduced in 8e2dc6ac06, considering the "--orphan" flag situation. Signed-off-by: Rubén Justo --- builtin/checkout.c | 8 ++++++-- t/t2020-checkout-detach.sh | 9 +++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index 85ac4bca00..7fad3161b4 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -1050,8 +1050,12 @@ 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, 1); + if (!opts->quiet && !old_branch_info.path && old_branch_info.commit) { + if (new_branch_info->commit != old_branch_info.commit) + orphaned_commit_warning(old_branch_info.commit, new_branch_info->commit, 1); + else if (opts->new_orphan_branch) + orphaned_commit_warning(old_branch_info.commit, NULL, 1); + } update_refs_for_switch(opts, &old_branch_info, new_branch_info); diff --git a/t/t2020-checkout-detach.sh b/t/t2020-checkout-detach.sh index 2eab6474f8..6762a9a572 100755 --- a/t/t2020-checkout-detach.sh +++ b/t/t2020-checkout-detach.sh @@ -124,6 +124,15 @@ test_expect_success 'checkout warns on orphan commits: output' ' check_orphan_warning stderr "2 commits" ' +test_expect_success 'checkout --orphan warns on orphan commits' ' + git checkout "$orphan2" && + git checkout --orphan orphan 2>stderr +' + +test_expect_success 'checkout --orphan warns on orphan commits: output' ' + check_orphan_warning stderr "2 commits" +' + test_expect_success 'checkout warns orphaning 1 of 2 commits' ' git checkout "$orphan2" && git checkout HEAD^ 2>stderr