@@ -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;
}
@@ -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
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(-)