From patchwork Fri Nov 29 02:44:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Caleb White X-Patchwork-Id: 13888398 Received: from mail-10629.protonmail.ch (mail-10629.protonmail.ch [79.135.106.29]) (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 3E47F79CD for ; Fri, 29 Nov 2024 02:44:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.135.106.29 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732848297; cv=none; b=Q5x6KvIyHwlkmYjOFabWkFuI1JHd99mxjU4AKNTISAtyI5NjgpXFUokK9COlYsRuuZm9SXXHUSm3s35j7TNbjdsOAAX8kL70JstBrRy1LfTJMXzeCfRfLwADMZjy3h0Js4zIvWc84nbhgQnb95EHB/dvlVvuyd/+tLDIEadoU00= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732848297; c=relaxed/simple; bh=XosmYGWpRFTfxFVhYW/BvHcV9VWZYdiGax4AQq/3gEM=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=qSEcbHPzbSpgELpCJJpQlLYRuVCePX10DiUEcQ9/l388sWUO8nM2UofOz8xb2w7XskIjepZ/6lxkMTbRuUkZ+ELUy+REWD9R9Wdsp08IZv35ivOPRxwjlY13xyFhMgVhcXm92kmhIRr+G2cbfZ2sJGpTh6a28hx1+cKN7iNBJK0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me; spf=pass smtp.mailfrom=pm.me; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b=hUEifn4w; arc=none smtp.client-ip=79.135.106.29 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=pm.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pm.me Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pm.me header.i=@pm.me header.b="hUEifn4w" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail3; t=1732848286; x=1733107486; bh=8QUv9cFqo87UgTka1v+K4DTZdyX6hHsXOyESzd7rQa4=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=hUEifn4wWUx4KIWMmQa8Z45lFYkEmZe0q/2EZ4CIAYYIb8oB56hwjGNgO5RAxyAQM XJFuRIKau0T0mgxIyMxibjcGSWy7RM9ZEJg7kP9ampB3+Hu6n2eIljeSvDzWIAkiS6 /J/g7W4RdDLv40z4ndD37sSw/Wp0Cm9NGXP2wPSHisb2eqMR+cTp/Ftnn2tD3p6pzy XpYbZuslrkXIFwHz0yxh/OTokBQun3Q0F5XbRQAI/9qSoKgL1vZRMCxsgj8yKRYNv4 10OLLhfRKn774O8pwalUQnpGNmiEAVD+qZ4QMrVVY6pVjPVg610GdWOcMT9n9mV70G P8cl5bfZS6h1Q== Date: Fri, 29 Nov 2024 02:44:40 +0000 To: git@vger.kernel.org From: Caleb White Cc: Caleb White Subject: [PATCH 2/2] worktree: rename worktree id during worktree move Message-ID: <20241128-wt_unique_ids-v1-2-30345d010e43@pm.me> In-Reply-To: <20241128-wt_unique_ids-v1-0-30345d010e43@pm.me> References: <20241128-wt_unique_ids-v1-0-30345d010e43@pm.me> Feedback-ID: 31210263:user:proton X-Pm-Message-ID: 20ceac18e847b461ddd48518d62cbce218b18d9e Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 During a `worktree move` the worktree directory is moved/renamed but the repository under `worktrees/` is not updated. For example, given the following structure: foo/ ├── .git/worktrees/develop-5445874156/ └── develop/ moving `develop` to `master` results in foo/ ├── .git/worktrees/develop-5445874156/ └── master/ This works because the linking files still point to the correct repository, but this is a little weird. This teaches Git to also move/rename the repository / worktree id during a `move` so that the structure now looks like: foo/ ├── .git/worktrees/master-1565465986/ └── master/ Note that a new unique suffix is assigned to reduce the complexity of trying to parse and reuse the existing suffix. Signed-off-by: Caleb White --- builtin/worktree.c | 24 ++++++++++++++++++++++++ t/t2403-worktree-move.sh | 18 +++++++++--------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/builtin/worktree.c b/builtin/worktree.c index 3ad355ca762729401fc0c8625f4fd05b154a84ec..36235546b492803707707ff208b13fe777bff1b4 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -1202,9 +1202,14 @@ static int move_worktree(int ac, const char **av, const char *prefix) }; struct worktree **worktrees, *wt; struct strbuf dst = STRBUF_INIT; + struct strbuf repo = STRBUF_INIT; + struct strbuf repo_dst = STRBUF_INIT; struct strbuf errmsg = STRBUF_INIT; const char *reason = NULL; + const char *new_id; + const char *suffix; char *path; + int len; ac = parse_options(ac, av, prefix, options, git_worktree_move_usage, 0); @@ -1250,9 +1255,28 @@ static int move_worktree(int ac, const char **av, const char *prefix) if (rename(wt->path, dst.buf) == -1) die_errno(_("failed to move '%s' to '%s'"), wt->path, dst.buf); + strbuf_realpath(&repo, git_common_path("worktrees/%s", wt->id), 1); + new_id = worktree_basename(dst.buf, &len); + strbuf_add(&repo_dst, new_id, dst.buf + len - new_id); + strbuf_realpath(&repo_dst, git_common_path("worktrees/%s", repo_dst.buf), 1); + suffix = getenv("GIT_TEST_WORKTREE_SUFFIX"); + if (suffix) + strbuf_addf(&repo_dst, "-%s", suffix); + else + strbuf_addf(&repo_dst, "-%u", git_rand()); + new_id = strrchr(repo_dst.buf, '/') + 1; + if (rename(repo.buf, repo_dst.buf) == -1) + die_errno(_("failed to move '%s' to '%s'"), repo.buf, repo_dst.buf); + else { + free(wt->id); + wt->id = xstrdup(new_id); + } + update_worktree_location(wt, dst.buf, use_relative_paths); strbuf_release(&dst); + strbuf_release(&repo); + strbuf_release(&repo_dst); free_worktrees(worktrees); return 0; } diff --git a/t/t2403-worktree-move.sh b/t/t2403-worktree-move.sh index ba3f05c16a4969fb84d98052ae375ef162f3e73a..703aa58d10643e99ffaf803aa38dabfd4af68a10 100755 --- a/t/t2403-worktree-move.sh +++ b/t/t2403-worktree-move.sh @@ -250,26 +250,26 @@ test_expect_success 'not remove a repo with initialized submodule' ' test_expect_success 'move worktree with absolute path to relative path' ' test_config worktree.useRelativePaths false && GIT_TEST_WORKTREE_SUFFIX=123 git worktree add ./absolute && - git worktree move --relative-paths absolute relative && - echo "gitdir: ../.git/worktrees/absolute-123" >expect && + GIT_TEST_WORKTREE_SUFFIX=456 git worktree move --relative-paths absolute relative && + echo "gitdir: ../.git/worktrees/relative-456" >expect && test_cmp expect relative/.git && echo "../../../relative/.git" >expect && - test_cmp expect .git/worktrees/absolute-123/gitdir && + test_cmp expect .git/worktrees/relative-456/gitdir && test_config worktree.useRelativePaths true && - git worktree move relative relative2 && - echo "gitdir: ../.git/worktrees/absolute-123" >expect && + GIT_TEST_WORKTREE_SUFFIX=789 git worktree move relative relative2 && + echo "gitdir: ../.git/worktrees/relative2-789" >expect && test_cmp expect relative2/.git && echo "../../../relative2/.git" >expect && - test_cmp expect .git/worktrees/absolute-123/gitdir + test_cmp expect .git/worktrees/relative2-789/gitdir ' test_expect_success 'move worktree with relative path to absolute path' ' test_config worktree.useRelativePaths true && - git worktree move --no-relative-paths relative2 absolute && - echo "gitdir: $(pwd)/.git/worktrees/absolute-123" >expect && + GIT_TEST_WORKTREE_SUFFIX=851 git worktree move --no-relative-paths relative2 absolute && + echo "gitdir: $(pwd)/.git/worktrees/absolute-851" >expect && test_cmp expect absolute/.git && echo "$(pwd)/absolute/.git" >expect && - test_cmp expect .git/worktrees/absolute-123/gitdir + test_cmp expect .git/worktrees/absolute-851/gitdir ' test_done