From patchwork Mon Feb 6 23:06:11 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: 13130738 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 7CE5EC05027 for ; Mon, 6 Feb 2023 23:06:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229726AbjBFXGR (ORCPT ); Mon, 6 Feb 2023 18:06:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41234 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229515AbjBFXGQ (ORCPT ); Mon, 6 Feb 2023 18:06:16 -0500 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A9F39EFBA for ; Mon, 6 Feb 2023 15:06:15 -0800 (PST) Received: by mail-wm1-x336.google.com with SMTP id l21-20020a05600c1d1500b003dfe462b7e4so173271wms.0 for ; Mon, 06 Feb 2023 15:06:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=pB4yR6vlDAzMbAnUQV5ZCEyJTO90c6Jn5v02t2eAIAs=; b=RYteJ3mdhQKFItpNdGbXthCBqMqsAUYatArSWUzRpSEAH5YedJrftwBCGWUgeiR57K +Xdzi/ci23CD1H1p7StlaxW68AAYsP8LcEjhZePeCKXV+hSyrdb5NO4nyYxBU1TWb1VX 6utlLVKkAX5+gnNeOJ4h/Nw41WFwyLLKlfpk8Fco9m/wTnjMIgI7GVGayv6YEJA+w3h1 LlVo/DRmbmfRVR9dcqX0I8a5JGpSjtBtaopJCzyvYqGf8YQnmpZUG32zdRPVpt5qYHgZ /jhMG8GjnnpE/hlayRzk+w+PA9/zA99FwG9G1bykSaqDVF/i1ganhhePWjklgRE2ww1F qkXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=pB4yR6vlDAzMbAnUQV5ZCEyJTO90c6Jn5v02t2eAIAs=; b=bbZGKyQ579VfmXHRbYuDpKEkYd2FKahLg4gJf7/69TS1sG+aBOkybPAs8Bn4DargSy KNlHY09c5obTFF+mv4UigHY9CNY0FLueXBaEtYsOefhR4SagRH8JqnzyuUeARJ50knqT Aa58EAmbH0T1oi+Yaa6PKbIDGoIXDnCI23k20C6DAj6Ge39KKz5Z39BcJbUSWAisffh7 D8CNttTaJ1ASv/Qc6JcW3b2mdk3gUykJsJLh5236WxlDvYeLTCksBGLcLVbNtnXFS64d sBqMmKsAGQU6PgJ7r71LgVNopnALQuK11d/6aWBRnM8cyHWTzT7VfmavIt/PHJmjtCrm qVEQ== X-Gm-Message-State: AO0yUKXc3xQp+7YR7hHMDU2KLpgJNwJw9jTRKWkLu+6Ll6AeXrGq2wAz g5qg1qu7d4NtE079yt8hy6E= X-Google-Smtp-Source: AK7set+oG66oTUssY12Z0lJBB5MLm7Qnlkf4UDjcRXDpKuAfVFFSfUuqomMDLcDGgNWV2vRsfDyc4Q== X-Received: by 2002:a05:600c:331c:b0:3dc:5ab8:7d74 with SMTP id q28-20020a05600c331c00b003dc5ab87d74mr1229167wmp.3.1675724774209; Mon, 06 Feb 2023 15:06:14 -0800 (PST) Received: from [192.168.2.52] (85.red-88-14-56.dynamicip.rima-tde.net. [88.14.56.85]) by smtp.gmail.com with ESMTPSA id n9-20020a05600c3b8900b003d9aa76dc6asm18441017wms.0.2023.02.06.15.06.12 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 06 Feb 2023 15:06:13 -0800 (PST) Subject: [PATCH v3 1/3] branch: avoid unnecessary worktrees traversals From: =?utf-8?q?Rub=C3=A9n_Justo?= To: Git List Cc: Junio C Hamano References: <34a58449-4f2e-66ef-ea01-119186aebd23@gmail.com> <2193a4ed-b263-068e-92f8-847dcb053f8c@gmail.com> Message-ID: Date: Tue, 7 Feb 2023 00:06:11 +0100 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: <2193a4ed-b263-068e-92f8-847dcb053f8c@gmail.com> Content-Language: en-US Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org "reject_rebase_or_bisect_branch()" was introduced [1] to prevent a branch under bisect or rebase from being renamed or copied. It traverses all worktrees in the repository and dies if the specified branch is being rebased or bisected in any of them. "replace_each_worktree_head_symref()" was introduced [2] to adjust the HEAD in all worktrees after a branch rename succeeded. It traverses all worktrees in the repository and if any of them have their HEAD pointing to the renamed ref, it adjusts it. If we could know in advance if the renamed branch is not HEAD in any worktree we could avoid calling "replace_each_worktree_head_symref()", and so avoid that unnecessary second traversing. Let's rename "reject_rebase_or_bisect_branch()" to a more meaningful name "die_if_branch_is_being_rebased_or_bisected()" and make it return, if it does not die(), if the specified branch is HEAD in any worktree. Use this new information to avoid unnecessary calls to "replace_each_worktree_head_symref()". 1.- 14ace5b (branch: do not rename a branch under bisect or rebase, 2016-04-22) 2.- 70999e9 (branch -m: update all per-worktree HEADs, 2016-03-27) Signed-off-by: Rubén Justo --- builtin/branch.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index f63fd45edb..89198fa5bf 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -486,14 +486,21 @@ static void print_current_branch_name(void) die(_("HEAD (%s) points outside of refs/heads/"), refname); } -static void reject_rebase_or_bisect_branch(const char *target) +/* + * Dies if the specified branch is being rebased or bisected. Otherwise returns + * 0 or, if the branch is HEAD in any worktree, returns 1. + */ +static int die_if_branch_is_being_rebased_or_bisected(const char *target) { struct worktree **worktrees = get_worktrees(); - int i; + int i, ret = 0; for (i = 0; worktrees[i]; i++) { struct worktree *wt = worktrees[i]; + if (wt->head_ref && !strcmp(target, wt->head_ref)) + ret = 1; + if (!wt->is_detached) continue; @@ -507,6 +514,7 @@ static void reject_rebase_or_bisect_branch(const char *target) } free_worktrees(worktrees); + return ret; } static void copy_or_rename_branch(const char *oldname, const char *newname, int copy, int force) @@ -515,7 +523,7 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int struct strbuf oldsection = STRBUF_INIT, newsection = STRBUF_INIT; const char *interpreted_oldname = NULL; const char *interpreted_newname = NULL; - int recovery = 0; + int recovery = 0, oldref_is_head; if (strbuf_check_branch_ref(&oldref, oldname)) { /* @@ -544,7 +552,7 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int else validate_new_branchname(newname, &newref, force); - reject_rebase_or_bisect_branch(oldref.buf); + oldref_is_head = die_if_branch_is_being_rebased_or_bisected(oldref.buf); if (!skip_prefix(oldref.buf, "refs/heads/", &interpreted_oldname) || !skip_prefix(newref.buf, "refs/heads/", &interpreted_newname)) { @@ -574,7 +582,7 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int interpreted_oldname); } - if (!copy && + if (!copy && oldref_is_head && replace_each_worktree_head_symref(oldref.buf, newref.buf, logmsg.buf)) die(_("Branch renamed to %s, but HEAD is not updated!"), newname); From patchwork Mon Feb 6 23:06:24 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: 13130739 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 208F9C61DA4 for ; Mon, 6 Feb 2023 23:06:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229517AbjBFXGb (ORCPT ); Mon, 6 Feb 2023 18:06:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41388 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229515AbjBFXGa (ORCPT ); Mon, 6 Feb 2023 18:06:30 -0500 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D9DF11CF68 for ; Mon, 6 Feb 2023 15:06:28 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id d14so11926956wrr.9 for ; Mon, 06 Feb 2023 15:06:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=TJCf1xutCeCo8ubwaD3oEtA9eckTMa3e6O8UcGv8vOU=; b=h+DSeOruxHtpO7RKipwYeiEJQ0tCKCf0MUSoGlPaA2vifXzrxK/fecmq5qb+s85kJ4 yyLSHW4MCs7l30q+KJv7JakRVjps0JhW4cWf18D0O+KIKMkAXTOp/7JHyFomZKIhaDjZ H/hM4RtJZ5GMeq5zqzie8pzeVZunIDD1XgwP0GtFQLoZ67J6SACrVjEeN2YYUbrzR7zP D8/qf4nJmnczhaSEnagZbPtPU/qSdc+PooLCc+y2/WFVRttxicgoirl3DWA1VivgJ/l4 ogMb3yiN9cxp1/nee79xiNiWUU3UPA64OIa1TOu3tLifcf8d27emDNYFr82f0ONPwkIM E1lQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=TJCf1xutCeCo8ubwaD3oEtA9eckTMa3e6O8UcGv8vOU=; b=h59I94cAROADLBGV/+WKPzNxU2j05WUUZN6eSUmpOQbt9QkDeE2XrSzZdI/V6/eZaI Rdr/G5LSlQnROUaQc5c+QFjmnifebonKfN3a5FeG1zzM5uep622FKkQmIWqjGFszE1U8 6ec/pNQ4Cw3wDrazLh+kmVSpF6y/h1NRXmoLa2AWQEfkbFTYXoQXHREP8Tt2h5idPDSr 935rJZwvsS/5yPzsF4n24pNVAlf2ZqLsqsx+IDLvB81ZKB24SkIuYdFo4NieCZCFWOsp +DU/VqFe0G0rua+I4f0OfrUw8cA3Njc7m+H3fVmKA1fi+OvnmaetRd8x4aAckwM1BjtS VMSQ== X-Gm-Message-State: AO0yUKXOVLdjLaXewnlMP+jXSKYG7I4vootNZKa6iAh8PSzTnlr4JiPo CXVZap/NNxxdhTHp7jqPNCjSeHMgEZ0= X-Google-Smtp-Source: AK7set/8dTzhNJSMTsluo/b6KwHfn1Ff0NH200YsrNcZgRxEm8kb1+PN87x287bJFNpWFgbTyJm5dA== X-Received: by 2002:adf:cd10:0:b0:2bf:baf3:b5c with SMTP id w16-20020adfcd10000000b002bfbaf30b5cmr490329wrm.48.1675724787316; Mon, 06 Feb 2023 15:06:27 -0800 (PST) Received: from [192.168.2.52] (85.red-88-14-56.dynamicip.rima-tde.net. [88.14.56.85]) by smtp.gmail.com with ESMTPSA id hg15-20020a05600c538f00b003df7b40f99fsm15020090wmb.11.2023.02.06.15.06.25 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 06 Feb 2023 15:06:26 -0800 (PST) Subject: [PATCH v3 2/3] branch: description for orphan branch errors From: =?utf-8?q?Rub=C3=A9n_Justo?= To: Git List Cc: Junio C Hamano References: <34a58449-4f2e-66ef-ea01-119186aebd23@gmail.com> <2193a4ed-b263-068e-92f8-847dcb053f8c@gmail.com> Message-ID: <6ba2caa4-1584-ac7f-c547-d7787be2930d@gmail.com> Date: Tue, 7 Feb 2023 00:06:24 +0100 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: <2193a4ed-b263-068e-92f8-847dcb053f8c@gmail.com> Content-Language: en-US Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org In bcfc82bd48 (branch: description for non-existent branch errors, 2022-10-08) we checked the current HEAD to detect if the branch to operate with is an orphan branch, so as to avoid the confusing error: "No branch named...". If we are asked to operate with an orphan branch in a different working tree than the current one, we need to check the HEAD in that different working tree. Let's extend the check we did in bcfc82db48, to all HEADs in the repository, using the helper introduced in 31ad6b61bd (branch: add branch_checked_out() helper, 2022-06-15) "die_if_branch_is_being_rebased_or_bisected()" already returns whether the branch to operate with is HEAD in any worktree in the repository. Let's use this information in "copy_or_rename_branch()", instead of the helper. Note that we now call "die_if_branch_is_being_rebased_or_bisected()" earlier, which introduces a change in the error displayed when a combination of unsupported conditions occur simultaneously: the desired destination name is invalid, and the branch to operate with is being rebased or bisected. i.e. with "foo" being rebased or bisected, this: $ git branch -m foo / fatal: '/' is not a valid branch name. ... becomes: $ git branch -m foo / fatal: Branch refs/heads/foo is being ... Signed-off-by: Rubén Justo --- builtin/branch.c | 25 +++++++++++-------------- t/t3202-show-branch.sh | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index 89198fa5bf..28cec344ad 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -536,12 +536,12 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int die(_("Invalid branch name: '%s'"), oldname); } - if ((copy || strcmp(head, oldname)) && !ref_exists(oldref.buf)) { - if (copy && !strcmp(head, oldname)) - die(_("No commit on branch '%s' yet."), oldname); - else - die(_("No branch named '%s'."), oldname); - } + oldref_is_head = die_if_branch_is_being_rebased_or_bisected(oldref.buf); + + if ((copy || !oldref_is_head) && !ref_exists(oldref.buf)) + die(oldref_is_head + ? _("No commit on branch '%s' yet.") + : _("No branch named '%s'."), oldname); /* * A command like "git branch -M currentbranch currentbranch" cannot @@ -552,8 +552,6 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int else validate_new_branchname(newname, &newref, force); - oldref_is_head = die_if_branch_is_being_rebased_or_bisected(oldref.buf); - if (!skip_prefix(oldref.buf, "refs/heads/", &interpreted_oldname) || !skip_prefix(newref.buf, "refs/heads/", &interpreted_newname)) { BUG("expected prefix missing for refs"); @@ -814,7 +812,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) strbuf_addf(&branch_ref, "refs/heads/%s", branch_name); if (!ref_exists(branch_ref.buf)) - error((!argc || !strcmp(head, branch_name)) + error((!argc || branch_checked_out(branch_ref.buf)) ? _("No commit on branch '%s' yet.") : _("No branch named '%s'."), branch_name); @@ -858,11 +856,10 @@ int cmd_branch(int argc, const char **argv, const char *prefix) die(_("no such branch '%s'"), argv[0]); } - if (!ref_exists(branch->refname)) { - if (!argc || !strcmp(head, branch->name)) - die(_("No commit on branch '%s' yet."), branch->name); - die(_("branch '%s' does not exist"), branch->name); - } + if (!ref_exists(branch->refname)) + die((!argc || branch_checked_out(branch->refname)) + ? _("No commit on branch '%s' yet.") + : _("branch '%s' does not exist"), branch->name); dwim_and_setup_tracking(the_repository, branch->name, new_upstream, BRANCH_TRACK_OVERRIDE, diff --git a/t/t3202-show-branch.sh b/t/t3202-show-branch.sh index ea7cfd1951..be20ebe1d5 100755 --- a/t/t3202-show-branch.sh +++ b/t/t3202-show-branch.sh @@ -221,4 +221,22 @@ test_expect_success 'fatal descriptions on non-existent branch' ' test_cmp expect actual ' +test_expect_success 'error descriptions on orphan branch' ' + test_when_finished git worktree remove -f wt && + git worktree add wt --detach && + git -C wt checkout --orphan orphan-branch && + test_branch_op_in_wt() { + test_orphan_error() { + test_must_fail git $* 2>actual && + test_i18ngrep "No commit on branch .orphan-branch. yet.$" actual + } && + test_orphan_error -C wt branch $1 $2 && # implicit branch + test_orphan_error -C wt branch $1 orphan-branch $2 && # explicit branch + test_orphan_error branch $1 orphan-branch $2 # different worktree + } && + test_branch_op_in_wt --edit-description && + test_branch_op_in_wt --set-upstream-to=ne && + test_branch_op_in_wt -c new-branch +' + test_done From patchwork Mon Feb 6 23:06:39 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: 13130740 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 7D6CAC05027 for ; Mon, 6 Feb 2023 23:06:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229726AbjBFXGr (ORCPT ); Mon, 6 Feb 2023 18:06:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41536 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229498AbjBFXGq (ORCPT ); Mon, 6 Feb 2023 18:06:46 -0500 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 EEA252C676 for ; Mon, 6 Feb 2023 15:06:43 -0800 (PST) Received: by mail-wr1-x42c.google.com with SMTP id h16so11916515wrz.12 for ; Mon, 06 Feb 2023 15:06:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=z0AvMxXIs9j9HgcP5jTp403PlQDQYWd4vpAS+pJXyi0=; b=Ymll4dRCa8q/kfKScUJQZWv9tqVLDuBmqdH3fd5VB+wumeLCQInPO299CaXpwBuNGe +uWZiHZnmYcC59HgyFQlynXCJ3F/vU4jDXAkOMjKljDJcM7bNsBMX+8BDyaMwqbU//Fx ZkNcr6J+AgNqOglhtQRBBwFxtxyteJLs65I1xlq32wzm2l7OXFS7PeiZIVya223sKFyZ rlwphPM0BY1d5bqPo4+NZt4mgF+MNKK5YZRC2lVK5rTJvM6C/Kh5O1SlMOif+Rs7LO/5 yK7u8Q8jn9Fgq6rTcAO07QFGkugGeU3U4VzaIMKUjKLLbJqHNIKqKtIx8JSu5MVNTPQM nv4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=z0AvMxXIs9j9HgcP5jTp403PlQDQYWd4vpAS+pJXyi0=; b=4/FRW+4hzlnqi/shxzXr5E8jBbfUVYnGiJB5U6ve9GnBuozp1mm2O5Up+MX5wZzEQb CYHSdI8QNgWpNtfV9aFiQ3iAtCfNczSPaXJWCF3av3lGqcSPtYqNcOin1CS06rqI/Xgm 0MaxBleJWGsag/ImWWIJj7xexYHaatIskUKsQsiS10Ctkuwv7QawSiDpcFlziCD5pqO+ cyQHwy5Ei/1/988XRSuT24QzfKScQInsA+3TqySUakx4cMqU3XtQ9/Sld9fA9SSYbCWz EuQ2CK5qk5xbnTrWcBtAQTE0Iv5Yr5OTSCs28M1apMv+HW1GwdjIg1JJSlVkmb3jmZ8B g1lQ== X-Gm-Message-State: AO0yUKX/nuDxHhjCwV8GmtPnXKcdhS1MgtLOpjpA/qYaFFsiFFCIeJIJ YKhcxNRiTbt2xUxhbqj9GDqU54Us2ns= X-Google-Smtp-Source: AK7set+Ax6df0aFq0t9FcNzmIxMnHD+leA2tu8J3RsI+gln1dYymaYxU7CaRhfR4RJnA6U3wYiFS3w== X-Received: by 2002:a05:6000:1a48:b0:2c3:db98:3e93 with SMTP id t8-20020a0560001a4800b002c3db983e93mr576446wry.18.1675724802435; Mon, 06 Feb 2023 15:06:42 -0800 (PST) Received: from [192.168.2.52] (85.red-88-14-56.dynamicip.rima-tde.net. [88.14.56.85]) by smtp.gmail.com with ESMTPSA id i14-20020a0560001ace00b002bfb8f829eesm10402311wry.71.2023.02.06.15.06.41 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 06 Feb 2023 15:06:41 -0800 (PST) Subject: [PATCH v3 3/3] branch: rename orphan branches in any worktree From: =?utf-8?q?Rub=C3=A9n_Justo?= To: Git List Cc: Junio C Hamano References: <34a58449-4f2e-66ef-ea01-119186aebd23@gmail.com> <2193a4ed-b263-068e-92f8-847dcb053f8c@gmail.com> Message-ID: Date: Tue, 7 Feb 2023 00:06:39 +0100 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: <2193a4ed-b263-068e-92f8-847dcb053f8c@gmail.com> Content-Language: en-US Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org In cfaff3aac (branch -m: allow renaming a yet-unborn branch, 2020-12-13) we added support for renaming an orphan branch, skipping rename_ref() if the branch being renamed is an orphan branch; checking the current HEAD. But the orphan branch to be renamed can be an orphan branch in a different worktree than the current one, i.e. not the current HEAD. Let's make "die_if_branch_is_being_rebased_or_bisected()" return if the specified branch is HEAD and orphan, and use it to extend what we did in cfaff3aac, to check all HEADs in the repository. Signed-off-by: Rubén Justo --- builtin/branch.c | 16 +++++++++------- t/t3200-branch.sh | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index 28cec344ad..7efda62224 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -488,7 +488,8 @@ static void print_current_branch_name(void) /* * Dies if the specified branch is being rebased or bisected. Otherwise returns - * 0 or, if the branch is HEAD in any worktree, returns 1. + * 0 or, if the branch is HEAD in any worktree, returns 1. If the branch is HEAD + * and also orphan, returns 2. */ static int die_if_branch_is_being_rebased_or_bisected(const char *target) { @@ -499,7 +500,7 @@ static int die_if_branch_is_being_rebased_or_bisected(const char *target) struct worktree *wt = worktrees[i]; if (wt->head_ref && !strcmp(target, wt->head_ref)) - ret = 1; + ret = is_null_oid(&wt->head_oid) ? 2 : 1; if (!wt->is_detached) continue; @@ -523,7 +524,7 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int struct strbuf oldsection = STRBUF_INIT, newsection = STRBUF_INIT; const char *interpreted_oldname = NULL; const char *interpreted_newname = NULL; - int recovery = 0, oldref_is_head; + int recovery = 0, oldref_is_head, oldref_is_orphan; if (strbuf_check_branch_ref(&oldref, oldname)) { /* @@ -537,9 +538,11 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int } oldref_is_head = die_if_branch_is_being_rebased_or_bisected(oldref.buf); + oldref_is_orphan = (oldref_is_head > 1); - if ((copy || !oldref_is_head) && !ref_exists(oldref.buf)) - die(oldref_is_head + if ((copy || !oldref_is_head) && + (oldref_is_orphan || !ref_exists(oldref.buf))) + die(oldref_is_orphan ? _("No commit on branch '%s' yet.") : _("No branch named '%s'."), oldname); @@ -564,8 +567,7 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int strbuf_addf(&logmsg, "Branch: renamed %s to %s", oldref.buf, newref.buf); - if (!copy && - (!head || strcmp(oldname, head) || !is_null_oid(&head_oid)) && + if (!copy && !oldref_is_orphan && rename_ref(oldref.buf, newref.buf, logmsg.buf)) die(_("Branch rename failed")); if (copy && copy_existing_ref(oldref.buf, newref.buf, logmsg.buf)) diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 5a169b68d6..5aef00efde 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -279,6 +279,20 @@ test_expect_success 'git branch -M and -C fail on detached HEAD' ' test_cmp expect err ' +test_expect_success 'git branch -m should work with orphan branches' ' + test_when_finished git checkout - && + test_when_finished git worktree remove -f wt && + git worktree add wt --detach && + # rename orphan in another worktreee + git -C wt checkout --orphan orphan-foo-wt && + git branch -m orphan-foo-wt orphan-bar-wt && + test orphan-bar-wt=$(git -C orphan-worktree branch --show-current) && + # rename orphan in the current worktree + git checkout --orphan orphan-foo && + git branch -m orphan-foo orphan-bar && + test orphan-bar=$(git branch --show-current) +' + test_expect_success 'git branch -d on orphan HEAD (merged)' ' test_when_finished git checkout main && git checkout --orphan orphan &&