Git fork

worktree: add relative cli/config options to `move` command

This teaches the `worktree move` command to respect the
`--[no-]relative-paths` CLI option and `worktree.useRelativePaths`
config setting. If an existing worktree is moved with `--relative-paths`
the new path will be relative (and visa-versa).

Signed-off-by: Caleb White <cdwhite3@pm.me>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Caleb White and committed by
Junio C Hamano
298d2917 b7016344

+39 -16
+3 -1
builtin/worktree.c
··· 1190 1190 OPT__FORCE(&force, 1191 1191 N_("force move even if worktree is dirty or locked"), 1192 1192 PARSE_OPT_NOCOMPLETE), 1193 + OPT_BOOL(0, "relative-paths", &use_relative_paths, 1194 + N_("use relative paths for worktrees")), 1193 1195 OPT_END() 1194 1196 }; 1195 1197 struct worktree **worktrees, *wt; ··· 1242 1244 if (rename(wt->path, dst.buf) == -1) 1243 1245 die_errno(_("failed to move '%s' to '%s'"), wt->path, dst.buf); 1244 1246 1245 - update_worktree_location(wt, dst.buf); 1247 + update_worktree_location(wt, dst.buf, use_relative_paths); 1246 1248 1247 1249 strbuf_release(&dst); 1248 1250 free_worktrees(worktrees);
+25
t/t2403-worktree-move.sh
··· 247 247 ) 248 248 ' 249 249 250 + test_expect_success 'move worktree with absolute path to relative path' ' 251 + test_config worktree.useRelativePaths false && 252 + git worktree add ./absolute && 253 + git worktree move --relative-paths absolute relative && 254 + echo "gitdir: ../.git/worktrees/absolute" >expect && 255 + test_cmp expect relative/.git && 256 + echo "../../../relative/.git" >expect && 257 + test_cmp expect .git/worktrees/absolute/gitdir && 258 + test_config worktree.useRelativePaths true && 259 + git worktree move relative relative2 && 260 + echo "gitdir: ../.git/worktrees/absolute" >expect && 261 + test_cmp expect relative2/.git && 262 + echo "../../../relative2/.git" >expect && 263 + test_cmp expect .git/worktrees/absolute/gitdir 264 + ' 265 + 266 + test_expect_success 'move worktree with relative path to absolute path' ' 267 + test_config worktree.useRelativePaths true && 268 + git worktree move --no-relative-paths relative2 absolute && 269 + echo "gitdir: $(pwd)/.git/worktrees/absolute" >expect && 270 + test_cmp expect absolute/.git && 271 + echo "$(pwd)/absolute/.git" >expect && 272 + test_cmp expect .git/worktrees/absolute/gitdir 273 + ' 274 + 250 275 test_done
+9 -13
worktree.c
··· 376 376 return ret; 377 377 } 378 378 379 - void update_worktree_location(struct worktree *wt, const char *path_) 379 + void update_worktree_location(struct worktree *wt, const char *path_, 380 + int use_relative_paths) 380 381 { 381 382 struct strbuf path = STRBUF_INIT; 382 - struct strbuf repo = STRBUF_INIT; 383 - struct strbuf file = STRBUF_INIT; 384 - struct strbuf tmp = STRBUF_INIT; 383 + struct strbuf dotgit = STRBUF_INIT; 384 + struct strbuf gitdir = STRBUF_INIT; 385 385 386 386 if (is_main_worktree(wt)) 387 387 BUG("can't relocate main worktree"); 388 388 389 - strbuf_realpath(&repo, git_common_path("worktrees/%s", wt->id), 1); 389 + strbuf_realpath(&gitdir, git_common_path("worktrees/%s/gitdir", wt->id), 1); 390 390 strbuf_realpath(&path, path_, 1); 391 + strbuf_addf(&dotgit, "%s/.git", path.buf); 391 392 if (fspathcmp(wt->path, path.buf)) { 392 - strbuf_addf(&file, "%s/gitdir", repo.buf); 393 - write_file(file.buf, "%s/.git", relative_path(path.buf, repo.buf, &tmp)); 394 - strbuf_reset(&file); 395 - strbuf_addf(&file, "%s/.git", path.buf); 396 - write_file(file.buf, "gitdir: %s", relative_path(repo.buf, path.buf, &tmp)); 393 + write_worktree_linking_files(dotgit, gitdir, use_relative_paths); 397 394 398 395 free(wt->path); 399 396 wt->path = strbuf_detach(&path, NULL); 400 397 } 401 398 strbuf_release(&path); 402 - strbuf_release(&repo); 403 - strbuf_release(&file); 404 - strbuf_release(&tmp); 399 + strbuf_release(&dotgit); 400 + strbuf_release(&gitdir); 405 401 } 406 402 407 403 int is_worktree_being_rebased(const struct worktree *wt,
+2 -2
worktree.h
··· 117 117 /* 118 118 * Update worktrees/xxx/gitdir with the new path. 119 119 */ 120 - void update_worktree_location(struct worktree *wt, 121 - const char *path_); 120 + void update_worktree_location(struct worktree *wt, const char *path_, 121 + int use_relative_paths); 122 122 123 123 typedef void (* worktree_repair_fn)(int iserr, const char *path, 124 124 const char *msg, void *cb_data);