From: Caleb White <cdwhite3@pm.me>
To: git@vger.kernel.org
Cc: shejialuo <shejialuo@gmail.com>,
Junio C Hamano <gitster@pobox.com>, Caleb White <cdwhite3@pm.me>
Subject: [PATCH v2 2/3] worktree: rename worktree id during worktree move
Date: Fri, 29 Nov 2024 22:37:51 +0000 [thread overview]
Message-ID: <20241129-wt_unique_ids-v2-2-ff444e9e625a@pm.me> (raw)
In-Reply-To: <20241129-wt_unique_ids-v2-0-ff444e9e625a@pm.me>
During a `worktree move` the worktree directory is moved/renamed but the
repository under `worktrees/<id>` 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 <cdwhite3@pm.me>
---
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
--
2.47.0
next prev parent reply other threads:[~2024-11-29 22:37 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-29 22:37 [PATCH v2 0/3] Ensure unique worktree ids across repositories Caleb White
2024-11-29 22:37 ` [PATCH v2 1/3] worktree: add worktree with unique suffix Caleb White
2024-11-29 22:37 ` Caleb White [this message]
2024-11-29 22:37 ` [PATCH v2 3/3] worktree: add id to `worktree list` output Caleb White
2024-11-29 22:54 ` [PATCH v2 0/3] Ensure unique worktree ids across repositories rsbecker
2024-11-29 23:13 ` Caleb White
2024-11-29 23:17 ` rsbecker
2024-11-29 23:29 ` Caleb White
2024-11-29 23:44 ` rsbecker
2024-11-30 0:08 ` Caleb White
2024-11-30 0:38 ` rsbecker
2024-11-30 16:08 ` Caleb White
2024-11-30 17:16 ` rsbecker
2024-12-02 2:00 ` Junio C Hamano
2024-12-02 11:46 ` shejialuo
2024-12-03 0:46 ` Junio C Hamano
2024-12-03 0:56 ` Eric Sunshine
2024-12-03 1:46 ` Junio C Hamano
2024-12-03 1:53 ` rsbecker
2024-12-03 2:30 ` Junio C Hamano
2024-12-03 3:42 ` Caleb White
2024-12-03 4:37 ` Junio C Hamano
2024-12-03 5:31 ` Caleb White
2024-12-03 1:24 ` shejialuo
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=20241129-wt_unique_ids-v2-2-ff444e9e625a@pm.me \
--to=cdwhite3@pm.me \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=shejialuo@gmail.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.
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).