Git fork
at reftables-rust 1462 lines 42 kB view raw
1#define USE_THE_REPOSITORY_VARIABLE 2#define DISABLE_SIGN_COMPARE_WARNINGS 3 4#include "builtin.h" 5#include "abspath.h" 6#include "advice.h" 7#include "checkout.h" 8#include "config.h" 9#include "copy.h" 10#include "dir.h" 11#include "environment.h" 12#include "gettext.h" 13#include "hex.h" 14#include "object-file.h" 15#include "object-name.h" 16#include "parse-options.h" 17#include "path.h" 18#include "strvec.h" 19#include "branch.h" 20#include "read-cache-ll.h" 21#include "refs.h" 22#include "remote.h" 23#include "run-command.h" 24#include "hook.h" 25#include "sigchain.h" 26#include "submodule.h" 27#include "utf8.h" 28#include "worktree.h" 29#include "quote.h" 30 31#define BUILTIN_WORKTREE_ADD_USAGE \ 32 N_("git worktree add [-f] [--detach] [--checkout] [--lock [--reason <string>]]\n" \ 33 " [--orphan] [(-b | -B) <new-branch>] <path> [<commit-ish>]") 34 35#define BUILTIN_WORKTREE_LIST_USAGE \ 36 N_("git worktree list [-v | --porcelain [-z]]") 37#define BUILTIN_WORKTREE_LOCK_USAGE \ 38 N_("git worktree lock [--reason <string>] <worktree>") 39#define BUILTIN_WORKTREE_MOVE_USAGE \ 40 N_("git worktree move <worktree> <new-path>") 41#define BUILTIN_WORKTREE_PRUNE_USAGE \ 42 N_("git worktree prune [-n] [-v] [--expire <expire>]") 43#define BUILTIN_WORKTREE_REMOVE_USAGE \ 44 N_("git worktree remove [-f] <worktree>") 45#define BUILTIN_WORKTREE_REPAIR_USAGE \ 46 N_("git worktree repair [<path>...]") 47#define BUILTIN_WORKTREE_UNLOCK_USAGE \ 48 N_("git worktree unlock <worktree>") 49 50#define WORKTREE_ADD_DWIM_ORPHAN_INFER_TEXT \ 51 _("No possible source branch, inferring '--orphan'") 52 53#define WORKTREE_ADD_ORPHAN_WITH_DASH_B_HINT_TEXT \ 54 _("If you meant to create a worktree containing a new unborn branch\n" \ 55 "(branch with no commits) for this repository, you can do so\n" \ 56 "using the --orphan flag:\n" \ 57 "\n" \ 58 " git worktree add --orphan -b %s %s\n") 59 60#define WORKTREE_ADD_ORPHAN_NO_DASH_B_HINT_TEXT \ 61 _("If you meant to create a worktree containing a new unborn branch\n" \ 62 "(branch with no commits) for this repository, you can do so\n" \ 63 "using the --orphan flag:\n" \ 64 "\n" \ 65 " git worktree add --orphan %s\n") 66 67static const char * const git_worktree_usage[] = { 68 BUILTIN_WORKTREE_ADD_USAGE, 69 BUILTIN_WORKTREE_LIST_USAGE, 70 BUILTIN_WORKTREE_LOCK_USAGE, 71 BUILTIN_WORKTREE_MOVE_USAGE, 72 BUILTIN_WORKTREE_PRUNE_USAGE, 73 BUILTIN_WORKTREE_REMOVE_USAGE, 74 BUILTIN_WORKTREE_REPAIR_USAGE, 75 BUILTIN_WORKTREE_UNLOCK_USAGE, 76 NULL 77}; 78 79static const char * const git_worktree_add_usage[] = { 80 BUILTIN_WORKTREE_ADD_USAGE, 81 NULL, 82}; 83 84static const char * const git_worktree_list_usage[] = { 85 BUILTIN_WORKTREE_LIST_USAGE, 86 NULL 87}; 88 89static const char * const git_worktree_lock_usage[] = { 90 BUILTIN_WORKTREE_LOCK_USAGE, 91 NULL 92}; 93 94static const char * const git_worktree_move_usage[] = { 95 BUILTIN_WORKTREE_MOVE_USAGE, 96 NULL 97}; 98 99static const char * const git_worktree_prune_usage[] = { 100 BUILTIN_WORKTREE_PRUNE_USAGE, 101 NULL 102}; 103 104static const char * const git_worktree_remove_usage[] = { 105 BUILTIN_WORKTREE_REMOVE_USAGE, 106 NULL 107}; 108 109static const char * const git_worktree_repair_usage[] = { 110 BUILTIN_WORKTREE_REPAIR_USAGE, 111 NULL 112}; 113 114static const char * const git_worktree_unlock_usage[] = { 115 BUILTIN_WORKTREE_UNLOCK_USAGE, 116 NULL 117}; 118 119struct add_opts { 120 int force; 121 int detach; 122 int quiet; 123 int checkout; 124 int orphan; 125 int relative_paths; 126 const char *keep_locked; 127}; 128 129static int show_only; 130static int verbose; 131static int guess_remote; 132static int use_relative_paths; 133static timestamp_t expire; 134 135static int git_worktree_config(const char *var, const char *value, 136 const struct config_context *ctx, void *cb) 137{ 138 if (!strcmp(var, "worktree.guessremote")) { 139 guess_remote = git_config_bool(var, value); 140 return 0; 141 } else if (!strcmp(var, "worktree.userelativepaths")) { 142 use_relative_paths = git_config_bool(var, value); 143 return 0; 144 } 145 146 return git_default_config(var, value, ctx, cb); 147} 148 149static int delete_git_dir(const char *id) 150{ 151 struct strbuf sb = STRBUF_INIT; 152 int ret; 153 154 repo_common_path_append(the_repository, &sb, "worktrees/%s", id); 155 ret = remove_dir_recursively(&sb, 0); 156 if (ret < 0 && errno == ENOTDIR) 157 ret = unlink(sb.buf); 158 if (ret) 159 error_errno(_("failed to delete '%s'"), sb.buf); 160 strbuf_release(&sb); 161 return ret; 162} 163 164static void delete_worktrees_dir_if_empty(void) 165{ 166 char *path = repo_git_path(the_repository, "worktrees"); 167 rmdir(path); /* ignore failed removal */ 168 free(path); 169} 170 171static void prune_worktree(const char *id, const char *reason) 172{ 173 if (show_only || verbose) 174 fprintf_ln(stderr, _("Removing %s/%s: %s"), "worktrees", id, reason); 175 if (!show_only) 176 delete_git_dir(id); 177} 178 179static int prune_cmp(const void *a, const void *b) 180{ 181 const struct string_list_item *x = a; 182 const struct string_list_item *y = b; 183 int c; 184 185 if ((c = fspathcmp(x->string, y->string))) 186 return c; 187 /* 188 * paths same; prune_dupes() removes all but the first worktree entry 189 * having the same path, so sort main worktree ('util' is NULL) above 190 * linked worktrees ('util' not NULL) since main worktree can't be 191 * removed 192 */ 193 if (!x->util) 194 return -1; 195 if (!y->util) 196 return 1; 197 /* paths same; sort by .git/worktrees/<id> */ 198 return strcmp(x->util, y->util); 199} 200 201static void prune_dups(struct string_list *l) 202{ 203 int i; 204 205 QSORT(l->items, l->nr, prune_cmp); 206 for (i = 1; i < l->nr; i++) { 207 if (!fspathcmp(l->items[i].string, l->items[i - 1].string)) 208 prune_worktree(l->items[i].util, "duplicate entry"); 209 } 210} 211 212static void prune_worktrees(void) 213{ 214 struct strbuf reason = STRBUF_INIT; 215 struct strbuf main_path = STRBUF_INIT; 216 struct string_list kept = STRING_LIST_INIT_DUP; 217 char *path; 218 DIR *dir; 219 struct dirent *d; 220 221 path = repo_git_path(the_repository, "worktrees"); 222 dir = opendir(path); 223 free(path); 224 if (!dir) 225 return; 226 while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL) { 227 char *path; 228 strbuf_reset(&reason); 229 if (should_prune_worktree(d->d_name, &reason, &path, expire)) 230 prune_worktree(d->d_name, reason.buf); 231 else if (path) 232 string_list_append_nodup(&kept, path)->util = xstrdup(d->d_name); 233 } 234 closedir(dir); 235 236 strbuf_add_absolute_path(&main_path, repo_get_common_dir(the_repository)); 237 /* massage main worktree absolute path to match 'gitdir' content */ 238 strbuf_strip_suffix(&main_path, "/."); 239 string_list_append_nodup(&kept, strbuf_detach(&main_path, NULL)); 240 prune_dups(&kept); 241 string_list_clear(&kept, 1); 242 243 if (!show_only) 244 delete_worktrees_dir_if_empty(); 245 strbuf_release(&reason); 246} 247 248static int prune(int ac, const char **av, const char *prefix, 249 struct repository *repo UNUSED) 250{ 251 struct option options[] = { 252 OPT__DRY_RUN(&show_only, N_("do not remove, show only")), 253 OPT__VERBOSE(&verbose, N_("report pruned working trees")), 254 OPT_EXPIRY_DATE(0, "expire", &expire, 255 N_("expire working trees older than <time>")), 256 OPT_END() 257 }; 258 259 expire = TIME_MAX; 260 ac = parse_options(ac, av, prefix, options, git_worktree_prune_usage, 261 0); 262 if (ac) 263 usage_with_options(git_worktree_prune_usage, options); 264 prune_worktrees(); 265 return 0; 266} 267 268static char *junk_work_tree; 269static char *junk_git_dir; 270static int is_junk; 271static pid_t junk_pid; 272 273static void remove_junk(void) 274{ 275 struct strbuf sb = STRBUF_INIT; 276 if (!is_junk || getpid() != junk_pid) 277 return; 278 if (junk_git_dir) { 279 strbuf_addstr(&sb, junk_git_dir); 280 remove_dir_recursively(&sb, 0); 281 strbuf_reset(&sb); 282 } 283 if (junk_work_tree) { 284 strbuf_addstr(&sb, junk_work_tree); 285 remove_dir_recursively(&sb, 0); 286 } 287 strbuf_release(&sb); 288} 289 290static void remove_junk_on_signal(int signo) 291{ 292 remove_junk(); 293 sigchain_pop(signo); 294 raise(signo); 295} 296 297static const char *worktree_basename(const char *path, int *olen) 298{ 299 const char *name; 300 int len; 301 302 len = strlen(path); 303 while (len && is_dir_sep(path[len - 1])) 304 len--; 305 306 for (name = path + len - 1; name > path; name--) 307 if (is_dir_sep(*name)) { 308 name++; 309 break; 310 } 311 312 *olen = len; 313 return name; 314} 315 316/* check that path is viable location for worktree */ 317static void check_candidate_path(const char *path, 318 int force, 319 struct worktree **worktrees, 320 const char *cmd) 321{ 322 struct worktree *wt; 323 int locked; 324 325 if (file_exists(path) && !is_empty_dir(path)) 326 die(_("'%s' already exists"), path); 327 328 wt = find_worktree_by_path(worktrees, path); 329 if (!wt) 330 return; 331 332 locked = !!worktree_lock_reason(wt); 333 if ((!locked && force) || (locked && force > 1)) { 334 if (delete_git_dir(wt->id)) 335 die(_("unusable worktree destination '%s'"), path); 336 return; 337 } 338 339 if (locked) 340 die(_("'%s' is a missing but locked worktree;\nuse '%s -f -f' to override, or 'unlock' and 'prune' or 'remove' to clear"), path, cmd); 341 else 342 die(_("'%s' is a missing but already registered worktree;\nuse '%s -f' to override, or 'prune' or 'remove' to clear"), path, cmd); 343} 344 345static void copy_sparse_checkout(const char *worktree_git_dir) 346{ 347 char *from_file = repo_git_path(the_repository, "info/sparse-checkout"); 348 char *to_file = xstrfmt("%s/info/sparse-checkout", worktree_git_dir); 349 350 if (file_exists(from_file)) { 351 if (safe_create_leading_directories(the_repository, to_file) || 352 copy_file(to_file, from_file, 0666)) 353 error(_("failed to copy '%s' to '%s'; sparse-checkout may not work correctly"), 354 from_file, to_file); 355 } 356 357 free(from_file); 358 free(to_file); 359} 360 361static void copy_filtered_worktree_config(const char *worktree_git_dir) 362{ 363 char *from_file = repo_git_path(the_repository, "config.worktree"); 364 char *to_file = xstrfmt("%s/config.worktree", worktree_git_dir); 365 366 if (file_exists(from_file)) { 367 struct config_set cs = { { 0 } }; 368 int bare; 369 370 if (safe_create_leading_directories(the_repository, to_file) || 371 copy_file(to_file, from_file, 0666)) { 372 error(_("failed to copy worktree config from '%s' to '%s'"), 373 from_file, to_file); 374 goto worktree_copy_cleanup; 375 } 376 377 git_configset_init(&cs); 378 git_configset_add_file(&cs, from_file); 379 380 if (!git_configset_get_bool(&cs, "core.bare", &bare) && 381 bare && 382 repo_config_set_multivar_in_file_gently(the_repository, 383 to_file, "core.bare", NULL, "true", NULL, 0)) 384 error(_("failed to unset '%s' in '%s'"), 385 "core.bare", to_file); 386 if (!git_configset_get(&cs, "core.worktree") && 387 repo_config_set_in_file_gently(the_repository, to_file, 388 "core.worktree", NULL, NULL)) 389 error(_("failed to unset '%s' in '%s'"), 390 "core.worktree", to_file); 391 392 git_configset_clear(&cs); 393 } 394 395worktree_copy_cleanup: 396 free(from_file); 397 free(to_file); 398} 399 400static int checkout_worktree(const struct add_opts *opts, 401 struct strvec *child_env) 402{ 403 struct child_process cp = CHILD_PROCESS_INIT; 404 cp.git_cmd = 1; 405 strvec_pushl(&cp.args, "reset", "--hard", "--no-recurse-submodules", NULL); 406 if (opts->quiet) 407 strvec_push(&cp.args, "--quiet"); 408 strvec_pushv(&cp.env, child_env->v); 409 return run_command(&cp); 410} 411 412static int make_worktree_orphan(const char * ref, const struct add_opts *opts, 413 struct strvec *child_env) 414{ 415 struct strbuf symref = STRBUF_INIT; 416 struct child_process cp = CHILD_PROCESS_INIT; 417 418 validate_new_branchname(ref, &symref, 0); 419 strvec_pushl(&cp.args, "symbolic-ref", "HEAD", symref.buf, NULL); 420 if (opts->quiet) 421 strvec_push(&cp.args, "--quiet"); 422 strvec_pushv(&cp.env, child_env->v); 423 strbuf_release(&symref); 424 cp.git_cmd = 1; 425 return run_command(&cp); 426} 427 428static int add_worktree(const char *path, const char *refname, 429 const struct add_opts *opts) 430{ 431 struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT; 432 struct strbuf sb = STRBUF_INIT; 433 const char *name; 434 struct strvec child_env = STRVEC_INIT; 435 unsigned int counter = 0; 436 int len, ret; 437 struct strbuf symref = STRBUF_INIT; 438 struct commit *commit = NULL; 439 int is_branch = 0; 440 struct strbuf sb_name = STRBUF_INIT; 441 struct worktree **worktrees, *wt = NULL; 442 struct ref_store *wt_refs; 443 444 worktrees = get_worktrees(); 445 check_candidate_path(path, opts->force, worktrees, "add"); 446 free_worktrees(worktrees); 447 worktrees = NULL; 448 449 /* is 'refname' a branch or commit? */ 450 if (!opts->detach && !check_branch_ref(&symref, refname) && 451 refs_ref_exists(get_main_ref_store(the_repository), symref.buf)) { 452 is_branch = 1; 453 if (!opts->force) 454 die_if_checked_out(symref.buf, 0); 455 } 456 commit = lookup_commit_reference_by_name(refname); 457 if (!commit && !opts->orphan) 458 die(_("invalid reference: %s"), refname); 459 460 name = worktree_basename(path, &len); 461 strbuf_add(&sb, name, path + len - name); 462 sanitize_refname_component(sb.buf, &sb_name); 463 if (!sb_name.len) 464 BUG("How come '%s' becomes empty after sanitization?", sb.buf); 465 strbuf_reset(&sb); 466 name = sb_name.buf; 467 repo_git_path_replace(the_repository, &sb_repo, "worktrees/%s", name); 468 len = sb_repo.len; 469 if (safe_create_leading_directories_const(the_repository, sb_repo.buf)) 470 die_errno(_("could not create leading directories of '%s'"), 471 sb_repo.buf); 472 473 while (mkdir(sb_repo.buf, 0777)) { 474 counter++; 475 if ((errno != EEXIST) || !counter /* overflow */) 476 die_errno(_("could not create directory of '%s'"), 477 sb_repo.buf); 478 strbuf_setlen(&sb_repo, len); 479 strbuf_addf(&sb_repo, "%d", counter); 480 } 481 name = strrchr(sb_repo.buf, '/') + 1; 482 483 junk_pid = getpid(); 484 atexit(remove_junk); 485 sigchain_push_common(remove_junk_on_signal); 486 487 junk_git_dir = xstrdup(sb_repo.buf); 488 is_junk = 1; 489 490 /* 491 * lock the incomplete repo so prune won't delete it, unlock 492 * after the preparation is over. 493 */ 494 strbuf_addf(&sb, "%s/locked", sb_repo.buf); 495 if (opts->keep_locked) 496 write_file(sb.buf, "%s", opts->keep_locked); 497 else 498 write_file(sb.buf, _("initializing")); 499 500 strbuf_addf(&sb_git, "%s/.git", path); 501 if (safe_create_leading_directories_const(the_repository, sb_git.buf)) 502 die_errno(_("could not create leading directories of '%s'"), 503 sb_git.buf); 504 junk_work_tree = xstrdup(path); 505 506 strbuf_reset(&sb); 507 strbuf_addf(&sb, "%s/gitdir", sb_repo.buf); 508 write_worktree_linking_files(sb_git, sb, opts->relative_paths); 509 strbuf_reset(&sb); 510 strbuf_addf(&sb, "%s/commondir", sb_repo.buf); 511 write_file(sb.buf, "../.."); 512 513 /* 514 * Set up the ref store of the worktree and create the HEAD reference. 515 */ 516 wt = get_linked_worktree(name, 1); 517 if (!wt) { 518 ret = error(_("could not find created worktree '%s'"), name); 519 goto done; 520 } 521 wt_refs = get_worktree_ref_store(wt); 522 523 ret = ref_store_create_on_disk(wt_refs, REF_STORE_CREATE_ON_DISK_IS_WORKTREE, &sb); 524 if (ret) 525 goto done; 526 527 if (!is_branch && commit) 528 ret = refs_update_ref(wt_refs, NULL, "HEAD", &commit->object.oid, 529 NULL, 0, UPDATE_REFS_MSG_ON_ERR); 530 else 531 ret = refs_update_symref(wt_refs, "HEAD", symref.buf, NULL); 532 if (ret) 533 goto done; 534 535 /* 536 * If the current worktree has sparse-checkout enabled, then copy 537 * the sparse-checkout patterns from the current worktree. 538 */ 539 if (core_apply_sparse_checkout) 540 copy_sparse_checkout(sb_repo.buf); 541 542 /* 543 * If we are using worktree config, then copy all current config 544 * values from the current worktree into the new one, that way the 545 * new worktree behaves the same as this one. 546 */ 547 if (the_repository->repository_format_worktree_config) 548 copy_filtered_worktree_config(sb_repo.buf); 549 550 strvec_pushf(&child_env, "%s=%s", GIT_DIR_ENVIRONMENT, sb_git.buf); 551 strvec_pushf(&child_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path); 552 553 if (opts->orphan && 554 (ret = make_worktree_orphan(refname, opts, &child_env))) 555 goto done; 556 557 if (opts->checkout && 558 (ret = checkout_worktree(opts, &child_env))) 559 goto done; 560 561 is_junk = 0; 562 FREE_AND_NULL(junk_work_tree); 563 FREE_AND_NULL(junk_git_dir); 564 565done: 566 if (ret || !opts->keep_locked) { 567 strbuf_reset(&sb); 568 strbuf_addf(&sb, "%s/locked", sb_repo.buf); 569 unlink_or_warn(sb.buf); 570 } 571 572 /* 573 * Hook failure does not warrant worktree deletion, so run hook after 574 * is_junk is cleared, but do return appropriate code when hook fails. 575 */ 576 if (!ret && opts->checkout && !opts->orphan) { 577 struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT; 578 579 strvec_pushl(&opt.env, "GIT_DIR", "GIT_WORK_TREE", NULL); 580 strvec_pushl(&opt.args, 581 oid_to_hex(null_oid(the_hash_algo)), 582 oid_to_hex(&commit->object.oid), 583 "1", 584 NULL); 585 opt.dir = path; 586 587 ret = run_hooks_opt(the_repository, "post-checkout", &opt); 588 } 589 590 strvec_clear(&child_env); 591 strbuf_release(&sb); 592 strbuf_release(&symref); 593 strbuf_release(&sb_repo); 594 strbuf_release(&sb_git); 595 strbuf_release(&sb_name); 596 free_worktree(wt); 597 return ret; 598} 599 600static void print_preparing_worktree_line(int detach, 601 const char *branch, 602 const char *new_branch, 603 int force_new_branch) 604{ 605 if (force_new_branch) { 606 struct commit *commit = lookup_commit_reference_by_name(new_branch); 607 if (!commit) 608 fprintf_ln(stderr, _("Preparing worktree (new branch '%s')"), new_branch); 609 else 610 fprintf_ln(stderr, _("Preparing worktree (resetting branch '%s'; was at %s)"), 611 new_branch, 612 repo_find_unique_abbrev(the_repository, &commit->object.oid, DEFAULT_ABBREV)); 613 } else if (new_branch) { 614 fprintf_ln(stderr, _("Preparing worktree (new branch '%s')"), new_branch); 615 } else { 616 struct strbuf s = STRBUF_INIT; 617 if (!detach && !check_branch_ref(&s, branch) && 618 refs_ref_exists(get_main_ref_store(the_repository), s.buf)) 619 fprintf_ln(stderr, _("Preparing worktree (checking out '%s')"), 620 branch); 621 else { 622 struct commit *commit = lookup_commit_reference_by_name(branch); 623 if (!commit) 624 BUG("unreachable: invalid reference: %s", branch); 625 fprintf_ln(stderr, _("Preparing worktree (detached HEAD %s)"), 626 repo_find_unique_abbrev(the_repository, &commit->object.oid, DEFAULT_ABBREV)); 627 } 628 strbuf_release(&s); 629 } 630} 631 632/** 633 * Callback to short circuit iteration over refs on the first reference 634 * corresponding to a valid oid. 635 * 636 * Returns 0 on failure and non-zero on success. 637 */ 638static int first_valid_ref(const char *refname UNUSED, 639 const char *referent UNUSED, 640 const struct object_id *oid UNUSED, 641 int flags UNUSED, 642 void *cb_data UNUSED) 643{ 644 return 1; 645} 646 647/** 648 * Verifies HEAD and determines whether there exist any valid local references. 649 * 650 * - Checks whether HEAD points to a valid reference. 651 * 652 * - Checks whether any valid local branches exist. 653 * 654 * - Emits a warning if there exist any valid branches but HEAD does not point 655 * to a valid reference. 656 * 657 * Returns 1 if any of the previous checks are true, otherwise returns 0. 658 */ 659static int can_use_local_refs(const struct add_opts *opts) 660{ 661 if (refs_head_ref(get_main_ref_store(the_repository), first_valid_ref, NULL)) { 662 return 1; 663 } else if (refs_for_each_branch_ref(get_main_ref_store(the_repository), first_valid_ref, NULL)) { 664 if (!opts->quiet) { 665 struct strbuf path = STRBUF_INIT; 666 struct strbuf contents = STRBUF_INIT; 667 char *wt_gitdir = get_worktree_git_dir(NULL); 668 669 strbuf_add_real_path(&path, wt_gitdir); 670 strbuf_addstr(&path, "/HEAD"); 671 strbuf_read_file(&contents, path.buf, 64); 672 strbuf_stripspace(&contents, NULL); 673 strbuf_strip_suffix(&contents, "\n"); 674 675 warning(_("HEAD points to an invalid (or orphaned) reference.\n" 676 "HEAD path: '%s'\n" 677 "HEAD contents: '%s'"), 678 path.buf, contents.buf); 679 strbuf_release(&path); 680 strbuf_release(&contents); 681 free(wt_gitdir); 682 } 683 return 1; 684 } 685 return 0; 686} 687 688/** 689 * Reports whether the necessary flags were set and whether the repository has 690 * remote references to attempt DWIM tracking of upstream branches. 691 * 692 * 1. Checks that `--guess-remote` was used or `worktree.guessRemote = true`. 693 * 694 * 2. Checks whether any valid remote branches exist. 695 * 696 * 3. Checks that there exists at least one remote and emits a warning/error 697 * if both checks 1. and 2. are false (can be bypassed with `--force`). 698 * 699 * Returns 1 if checks 1. and 2. are true, otherwise 0. 700 */ 701static int can_use_remote_refs(const struct add_opts *opts) 702{ 703 if (!guess_remote) { 704 return 0; 705 } else if (refs_for_each_remote_ref(get_main_ref_store(the_repository), first_valid_ref, NULL)) { 706 return 1; 707 } else if (!opts->force && remote_get(NULL)) { 708 die(_("No local or remote refs exist despite at least one remote\n" 709 "present, stopping; use 'add -f' to override or fetch a remote first")); 710 } 711 return 0; 712} 713 714/** 715 * Determines whether `--orphan` should be inferred in the evaluation of 716 * `worktree add path/` or `worktree add -b branch path/` and emits an error 717 * if the supplied arguments would produce an illegal combination when the 718 * `--orphan` flag is included. 719 * 720 * `opts` and `opt_track` contain the other options & flags supplied to the 721 * command. 722 * 723 * remote determines whether to check `can_use_remote_refs()` or not. This 724 * is primarily to differentiate between the basic `add` DWIM and `add -b`. 725 * 726 * Returns 1 when inferring `--orphan`, 0 otherwise, and emits an error when 727 * `--orphan` is inferred but doing so produces an illegal combination of 728 * options and flags. Additionally produces an error when remote refs are 729 * checked and the repo is in a state that looks like the user added a remote 730 * but forgot to fetch (and did not override the warning with -f). 731 */ 732static int dwim_orphan(const struct add_opts *opts, int opt_track, int remote) 733{ 734 if (can_use_local_refs(opts)) { 735 return 0; 736 } else if (remote && can_use_remote_refs(opts)) { 737 return 0; 738 } else if (!opts->quiet) { 739 fprintf_ln(stderr, WORKTREE_ADD_DWIM_ORPHAN_INFER_TEXT); 740 } 741 742 if (opt_track) { 743 die(_("options '%s' and '%s' cannot be used together"), 744 "--orphan", "--track"); 745 } else if (!opts->checkout) { 746 die(_("options '%s' and '%s' cannot be used together"), 747 "--orphan", "--no-checkout"); 748 } 749 return 1; 750} 751 752static char *dwim_branch(const char *path, char **new_branch) 753{ 754 int n; 755 int branch_exists; 756 const char *s = worktree_basename(path, &n); 757 char *branchname = xstrndup(s, n); 758 struct strbuf ref = STRBUF_INIT; 759 760 branch_exists = !check_branch_ref(&ref, branchname) && 761 refs_ref_exists(get_main_ref_store(the_repository), 762 ref.buf); 763 strbuf_release(&ref); 764 if (branch_exists) 765 return branchname; 766 767 *new_branch = branchname; 768 if (guess_remote) { 769 struct object_id oid; 770 char *remote = unique_tracking_name(*new_branch, &oid, NULL); 771 return remote; 772 } 773 return NULL; 774} 775 776static int add(int ac, const char **av, const char *prefix, 777 struct repository *repo UNUSED) 778{ 779 struct add_opts opts; 780 const char *new_branch_force = NULL; 781 char *path; 782 const char *branch; 783 char *branch_to_free = NULL; 784 char *new_branch_to_free = NULL; 785 const char *new_branch = NULL; 786 char *opt_track = NULL; 787 const char *lock_reason = NULL; 788 int keep_locked = 0; 789 int used_new_branch_options; 790 struct option options[] = { 791 OPT__FORCE(&opts.force, 792 N_("checkout <branch> even if already checked out in other worktree"), 793 PARSE_OPT_NOCOMPLETE), 794 OPT_STRING('b', NULL, &new_branch, N_("branch"), 795 N_("create a new branch")), 796 OPT_STRING('B', NULL, &new_branch_force, N_("branch"), 797 N_("create or reset a branch")), 798 OPT_BOOL(0, "orphan", &opts.orphan, N_("create unborn branch")), 799 OPT_BOOL('d', "detach", &opts.detach, N_("detach HEAD at named commit")), 800 OPT_BOOL(0, "checkout", &opts.checkout, N_("populate the new working tree")), 801 OPT_BOOL(0, "lock", &keep_locked, N_("keep the new working tree locked")), 802 OPT_STRING(0, "reason", &lock_reason, N_("string"), 803 N_("reason for locking")), 804 OPT__QUIET(&opts.quiet, N_("suppress progress reporting")), 805 OPT_PASSTHRU(0, "track", &opt_track, NULL, 806 N_("set up tracking mode (see git-branch(1))"), 807 PARSE_OPT_NOARG | PARSE_OPT_OPTARG), 808 OPT_BOOL(0, "guess-remote", &guess_remote, 809 N_("try to match the new branch name with a remote-tracking branch")), 810 OPT_BOOL(0, "relative-paths", &opts.relative_paths, 811 N_("use relative paths for worktrees")), 812 OPT_END() 813 }; 814 int ret; 815 816 memset(&opts, 0, sizeof(opts)); 817 opts.checkout = 1; 818 opts.relative_paths = use_relative_paths; 819 ac = parse_options(ac, av, prefix, options, git_worktree_add_usage, 0); 820 if (!!opts.detach + !!new_branch + !!new_branch_force > 1) 821 die(_("options '%s', '%s', and '%s' cannot be used together"), "-b", "-B", "--detach"); 822 if (opts.detach && opts.orphan) 823 die(_("options '%s' and '%s' cannot be used together"), 824 "--orphan", "--detach"); 825 if (opts.orphan && opt_track) 826 die(_("options '%s' and '%s' cannot be used together"), 827 "--orphan", "--track"); 828 if (opts.orphan && !opts.checkout) 829 die(_("options '%s' and '%s' cannot be used together"), 830 "--orphan", "--no-checkout"); 831 if (opts.orphan && ac == 2) 832 die(_("option '%s' and commit-ish cannot be used together"), 833 "--orphan"); 834 if (lock_reason && !keep_locked) 835 die(_("the option '%s' requires '%s'"), "--reason", "--lock"); 836 if (lock_reason) 837 opts.keep_locked = lock_reason; 838 else if (keep_locked) 839 opts.keep_locked = _("added with --lock"); 840 841 if (ac < 1 || ac > 2) 842 usage_with_options(git_worktree_add_usage, options); 843 844 path = prefix_filename(prefix, av[0]); 845 branch = ac < 2 ? "HEAD" : av[1]; 846 used_new_branch_options = new_branch || new_branch_force; 847 848 if (!strcmp(branch, "-")) 849 branch = "@{-1}"; 850 851 if (new_branch_force) { 852 struct strbuf symref = STRBUF_INIT; 853 854 new_branch = new_branch_force; 855 856 if (!opts.force && 857 !check_branch_ref(&symref, new_branch) && 858 refs_ref_exists(get_main_ref_store(the_repository), symref.buf)) 859 die_if_checked_out(symref.buf, 0); 860 strbuf_release(&symref); 861 } 862 863 if (opts.orphan && !new_branch) { 864 int n; 865 const char *s = worktree_basename(path, &n); 866 new_branch = new_branch_to_free = xstrndup(s, n); 867 } else if (opts.orphan) { 868 ; /* no-op */ 869 } else if (opts.detach) { 870 /* Check HEAD */ 871 if (!strcmp(branch, "HEAD")) 872 can_use_local_refs(&opts); 873 } else if (ac < 2 && new_branch) { 874 /* DWIM: Infer --orphan when repo has no refs. */ 875 opts.orphan = dwim_orphan(&opts, !!opt_track, 0); 876 } else if (ac < 2) { 877 /* DWIM: Guess branch name from path. */ 878 char *s = dwim_branch(path, &new_branch_to_free); 879 if (s) 880 branch = branch_to_free = s; 881 new_branch = new_branch_to_free; 882 883 /* DWIM: Infer --orphan when repo has no refs. */ 884 opts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1); 885 } else if (ac == 2) { 886 struct object_id oid; 887 struct commit *commit; 888 char *remote; 889 890 commit = lookup_commit_reference_by_name(branch); 891 if (!commit) { 892 remote = unique_tracking_name(branch, &oid, NULL); 893 if (remote) { 894 new_branch = branch; 895 branch = new_branch_to_free = remote; 896 } 897 } 898 899 if (!strcmp(branch, "HEAD")) 900 can_use_local_refs(&opts); 901 902 } 903 904 if (!opts.orphan && !lookup_commit_reference_by_name(branch)) { 905 int attempt_hint = !opts.quiet && (ac < 2); 906 if (attempt_hint && used_new_branch_options) { 907 advise_if_enabled(ADVICE_WORKTREE_ADD_ORPHAN, 908 WORKTREE_ADD_ORPHAN_WITH_DASH_B_HINT_TEXT, 909 new_branch, path); 910 } else if (attempt_hint) { 911 advise_if_enabled(ADVICE_WORKTREE_ADD_ORPHAN, 912 WORKTREE_ADD_ORPHAN_NO_DASH_B_HINT_TEXT, path); 913 } 914 die(_("invalid reference: %s"), branch); 915 } 916 917 if (!opts.quiet) 918 print_preparing_worktree_line(opts.detach, branch, new_branch, !!new_branch_force); 919 920 if (opts.orphan) { 921 branch = new_branch; 922 } else if (new_branch) { 923 struct child_process cp = CHILD_PROCESS_INIT; 924 cp.git_cmd = 1; 925 strvec_push(&cp.args, "branch"); 926 if (new_branch_force) 927 strvec_push(&cp.args, "--force"); 928 if (opts.quiet) 929 strvec_push(&cp.args, "--quiet"); 930 strvec_push(&cp.args, new_branch); 931 strvec_push(&cp.args, branch); 932 if (opt_track) 933 strvec_push(&cp.args, opt_track); 934 if (run_command(&cp)) 935 return -1; 936 branch = new_branch; 937 } else if (opt_track) { 938 die(_("--[no-]track can only be used if a new branch is created")); 939 } 940 941 ret = add_worktree(path, branch, &opts); 942 free(path); 943 free(opt_track); 944 free(branch_to_free); 945 free(new_branch_to_free); 946 return ret; 947} 948 949static void show_worktree_porcelain(struct worktree *wt, int line_terminator) 950{ 951 const char *reason; 952 953 printf("worktree %s%c", wt->path, line_terminator); 954 if (wt->is_bare) 955 printf("bare%c", line_terminator); 956 else { 957 printf("HEAD %s%c", oid_to_hex(&wt->head_oid), line_terminator); 958 if (wt->is_detached) 959 printf("detached%c", line_terminator); 960 else if (wt->head_ref) 961 printf("branch %s%c", wt->head_ref, line_terminator); 962 } 963 964 reason = worktree_lock_reason(wt); 965 if (reason) { 966 fputs("locked", stdout); 967 if (*reason) { 968 fputc(' ', stdout); 969 write_name_quoted(reason, stdout, line_terminator); 970 } else { 971 fputc(line_terminator, stdout); 972 } 973 } 974 975 reason = worktree_prune_reason(wt, expire); 976 if (reason) 977 printf("prunable %s%c", reason, line_terminator); 978 979 fputc(line_terminator, stdout); 980} 981 982static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len) 983{ 984 struct strbuf sb = STRBUF_INIT; 985 int cur_path_len = strlen(wt->path); 986 int path_adj = cur_path_len - utf8_strwidth(wt->path); 987 const char *reason; 988 989 strbuf_addf(&sb, "%-*s ", 1 + path_maxlen + path_adj, wt->path); 990 if (wt->is_bare) 991 strbuf_addstr(&sb, "(bare)"); 992 else { 993 strbuf_addf(&sb, "%-*s ", abbrev_len, 994 repo_find_unique_abbrev(the_repository, &wt->head_oid, DEFAULT_ABBREV)); 995 if (wt->is_detached) 996 strbuf_addstr(&sb, "(detached HEAD)"); 997 else if (wt->head_ref) { 998 char *ref = refs_shorten_unambiguous_ref(get_main_ref_store(the_repository), 999 wt->head_ref, 1000 0); 1001 strbuf_addf(&sb, "[%s]", ref); 1002 free(ref); 1003 } else 1004 strbuf_addstr(&sb, "(error)"); 1005 } 1006 1007 reason = worktree_lock_reason(wt); 1008 if (verbose && reason && *reason) 1009 strbuf_addf(&sb, "\n\tlocked: %s", reason); 1010 else if (reason) 1011 strbuf_addstr(&sb, " locked"); 1012 1013 reason = worktree_prune_reason(wt, expire); 1014 if (verbose && reason) 1015 strbuf_addf(&sb, "\n\tprunable: %s", reason); 1016 else if (reason) 1017 strbuf_addstr(&sb, " prunable"); 1018 1019 printf("%s\n", sb.buf); 1020 strbuf_release(&sb); 1021} 1022 1023static void measure_widths(struct worktree **wt, int *abbrev, int *maxlen) 1024{ 1025 int i; 1026 1027 for (i = 0; wt[i]; i++) { 1028 int sha1_len; 1029 int path_len = strlen(wt[i]->path); 1030 1031 if (path_len > *maxlen) 1032 *maxlen = path_len; 1033 sha1_len = strlen(repo_find_unique_abbrev(the_repository, &wt[i]->head_oid, *abbrev)); 1034 if (sha1_len > *abbrev) 1035 *abbrev = sha1_len; 1036 } 1037} 1038 1039static int pathcmp(const void *a_, const void *b_) 1040{ 1041 const struct worktree *const *a = a_; 1042 const struct worktree *const *b = b_; 1043 return fspathcmp((*a)->path, (*b)->path); 1044} 1045 1046static void pathsort(struct worktree **wt) 1047{ 1048 int n = 0; 1049 struct worktree **p = wt; 1050 1051 while (*p++) 1052 n++; 1053 QSORT(wt, n, pathcmp); 1054} 1055 1056static int list(int ac, const char **av, const char *prefix, 1057 struct repository *repo UNUSED) 1058{ 1059 int porcelain = 0; 1060 int line_terminator = '\n'; 1061 1062 struct option options[] = { 1063 OPT_BOOL(0, "porcelain", &porcelain, N_("machine-readable output")), 1064 OPT__VERBOSE(&verbose, N_("show extended annotations and reasons, if available")), 1065 OPT_EXPIRY_DATE(0, "expire", &expire, 1066 N_("add 'prunable' annotation to worktrees older than <time>")), 1067 OPT_SET_INT('z', NULL, &line_terminator, 1068 N_("terminate records with a NUL character"), '\0'), 1069 OPT_END() 1070 }; 1071 1072 expire = TIME_MAX; 1073 ac = parse_options(ac, av, prefix, options, git_worktree_list_usage, 0); 1074 if (ac) 1075 usage_with_options(git_worktree_list_usage, options); 1076 else if (verbose && porcelain) 1077 die(_("options '%s' and '%s' cannot be used together"), "--verbose", "--porcelain"); 1078 else if (!line_terminator && !porcelain) 1079 die(_("the option '%s' requires '%s'"), "-z", "--porcelain"); 1080 else { 1081 struct worktree **worktrees = get_worktrees(); 1082 int path_maxlen = 0, abbrev = DEFAULT_ABBREV, i; 1083 1084 /* sort worktrees by path but keep main worktree at top */ 1085 pathsort(worktrees + 1); 1086 1087 if (!porcelain) 1088 measure_widths(worktrees, &abbrev, &path_maxlen); 1089 1090 for (i = 0; worktrees[i]; i++) { 1091 if (porcelain) 1092 show_worktree_porcelain(worktrees[i], 1093 line_terminator); 1094 else 1095 show_worktree(worktrees[i], path_maxlen, abbrev); 1096 } 1097 free_worktrees(worktrees); 1098 } 1099 return 0; 1100} 1101 1102static int lock_worktree(int ac, const char **av, const char *prefix, 1103 struct repository *repo UNUSED) 1104{ 1105 const char *reason = "", *old_reason; 1106 struct option options[] = { 1107 OPT_STRING(0, "reason", &reason, N_("string"), 1108 N_("reason for locking")), 1109 OPT_END() 1110 }; 1111 struct worktree **worktrees, *wt; 1112 char *path; 1113 1114 ac = parse_options(ac, av, prefix, options, git_worktree_lock_usage, 0); 1115 if (ac != 1) 1116 usage_with_options(git_worktree_lock_usage, options); 1117 1118 worktrees = get_worktrees(); 1119 wt = find_worktree(worktrees, prefix, av[0]); 1120 if (!wt) 1121 die(_("'%s' is not a working tree"), av[0]); 1122 if (is_main_worktree(wt)) 1123 die(_("The main working tree cannot be locked or unlocked")); 1124 1125 old_reason = worktree_lock_reason(wt); 1126 if (old_reason) { 1127 if (*old_reason) 1128 die(_("'%s' is already locked, reason: %s"), 1129 av[0], old_reason); 1130 die(_("'%s' is already locked"), av[0]); 1131 } 1132 1133 path = repo_common_path(the_repository, "worktrees/%s/locked", wt->id); 1134 write_file(path, "%s", reason); 1135 1136 free_worktrees(worktrees); 1137 free(path); 1138 return 0; 1139} 1140 1141static int unlock_worktree(int ac, const char **av, const char *prefix, 1142 struct repository *repo UNUSED) 1143{ 1144 struct option options[] = { 1145 OPT_END() 1146 }; 1147 struct worktree **worktrees, *wt; 1148 char *path; 1149 int ret; 1150 1151 ac = parse_options(ac, av, prefix, options, git_worktree_unlock_usage, 0); 1152 if (ac != 1) 1153 usage_with_options(git_worktree_unlock_usage, options); 1154 1155 worktrees = get_worktrees(); 1156 wt = find_worktree(worktrees, prefix, av[0]); 1157 if (!wt) 1158 die(_("'%s' is not a working tree"), av[0]); 1159 if (is_main_worktree(wt)) 1160 die(_("The main working tree cannot be locked or unlocked")); 1161 if (!worktree_lock_reason(wt)) 1162 die(_("'%s' is not locked"), av[0]); 1163 1164 path = repo_common_path(the_repository, "worktrees/%s/locked", wt->id); 1165 ret = unlink_or_warn(path); 1166 1167 free_worktrees(worktrees); 1168 free(path); 1169 return ret; 1170} 1171 1172static void validate_no_submodules(const struct worktree *wt) 1173{ 1174 struct index_state istate = INDEX_STATE_INIT(the_repository); 1175 struct strbuf path = STRBUF_INIT; 1176 int i, found_submodules = 0; 1177 char *wt_gitdir; 1178 1179 wt_gitdir = get_worktree_git_dir(wt); 1180 1181 if (is_directory(worktree_git_path(the_repository, wt, "modules"))) { 1182 /* 1183 * There could be false positives, e.g. the "modules" 1184 * directory exists but is empty. But it's a rare case and 1185 * this simpler check is probably good enough for now. 1186 */ 1187 found_submodules = 1; 1188 } else if (read_index_from(&istate, worktree_git_path(the_repository, wt, "index"), 1189 wt_gitdir) > 0) { 1190 for (i = 0; i < istate.cache_nr; i++) { 1191 struct cache_entry *ce = istate.cache[i]; 1192 int err; 1193 1194 if (!S_ISGITLINK(ce->ce_mode)) 1195 continue; 1196 1197 strbuf_reset(&path); 1198 strbuf_addf(&path, "%s/%s", wt->path, ce->name); 1199 if (!is_submodule_populated_gently(path.buf, &err)) 1200 continue; 1201 1202 found_submodules = 1; 1203 break; 1204 } 1205 } 1206 discard_index(&istate); 1207 strbuf_release(&path); 1208 free(wt_gitdir); 1209 1210 if (found_submodules) 1211 die(_("working trees containing submodules cannot be moved or removed")); 1212} 1213 1214static int move_worktree(int ac, const char **av, const char *prefix, 1215 struct repository *repo UNUSED) 1216{ 1217 int force = 0; 1218 struct option options[] = { 1219 OPT__FORCE(&force, 1220 N_("force move even if worktree is dirty or locked"), 1221 PARSE_OPT_NOCOMPLETE), 1222 OPT_BOOL(0, "relative-paths", &use_relative_paths, 1223 N_("use relative paths for worktrees")), 1224 OPT_END() 1225 }; 1226 struct worktree **worktrees, *wt; 1227 struct strbuf dst = STRBUF_INIT; 1228 struct strbuf errmsg = STRBUF_INIT; 1229 const char *reason = NULL; 1230 char *path; 1231 1232 ac = parse_options(ac, av, prefix, options, git_worktree_move_usage, 1233 0); 1234 if (ac != 2) 1235 usage_with_options(git_worktree_move_usage, options); 1236 1237 path = prefix_filename(prefix, av[1]); 1238 strbuf_addstr(&dst, path); 1239 free(path); 1240 1241 worktrees = get_worktrees(); 1242 wt = find_worktree(worktrees, prefix, av[0]); 1243 if (!wt) 1244 die(_("'%s' is not a working tree"), av[0]); 1245 if (is_main_worktree(wt)) 1246 die(_("'%s' is a main working tree"), av[0]); 1247 if (is_directory(dst.buf)) { 1248 const char *sep = find_last_dir_sep(wt->path); 1249 1250 if (!sep) 1251 die(_("could not figure out destination name from '%s'"), 1252 wt->path); 1253 strbuf_trim_trailing_dir_sep(&dst); 1254 strbuf_addstr(&dst, sep); 1255 } 1256 check_candidate_path(dst.buf, force, worktrees, "move"); 1257 1258 validate_no_submodules(wt); 1259 1260 if (force < 2) 1261 reason = worktree_lock_reason(wt); 1262 if (reason) { 1263 if (*reason) 1264 die(_("cannot move a locked working tree, lock reason: %s\nuse 'move -f -f' to override or unlock first"), 1265 reason); 1266 die(_("cannot move a locked working tree;\nuse 'move -f -f' to override or unlock first")); 1267 } 1268 if (validate_worktree(wt, &errmsg, 0)) 1269 die(_("validation failed, cannot move working tree: %s"), 1270 errmsg.buf); 1271 strbuf_release(&errmsg); 1272 1273 if (rename(wt->path, dst.buf) == -1) 1274 die_errno(_("failed to move '%s' to '%s'"), wt->path, dst.buf); 1275 1276 update_worktree_location(wt, dst.buf, use_relative_paths); 1277 1278 strbuf_release(&dst); 1279 free_worktrees(worktrees); 1280 return 0; 1281} 1282 1283/* 1284 * Note, "git status --porcelain" is used to determine if it's safe to 1285 * delete a whole worktree. "git status" does not ignore user 1286 * configuration, so if a normal "git status" shows "clean" for the 1287 * user, then it's ok to remove it. 1288 * 1289 * This assumption may be a bad one. We may want to ignore 1290 * (potentially bad) user settings and only delete a worktree when 1291 * it's absolutely safe to do so from _our_ point of view because we 1292 * know better. 1293 */ 1294static void check_clean_worktree(struct worktree *wt, 1295 const char *original_path) 1296{ 1297 struct child_process cp; 1298 char buf[1]; 1299 int ret; 1300 1301 /* 1302 * Until we sort this out, all submodules are "dirty" and 1303 * will abort this function. 1304 */ 1305 validate_no_submodules(wt); 1306 1307 child_process_init(&cp); 1308 strvec_pushf(&cp.env, "%s=%s/.git", 1309 GIT_DIR_ENVIRONMENT, wt->path); 1310 strvec_pushf(&cp.env, "%s=%s", 1311 GIT_WORK_TREE_ENVIRONMENT, wt->path); 1312 strvec_pushl(&cp.args, "status", 1313 "--porcelain", "--ignore-submodules=none", 1314 NULL); 1315 cp.git_cmd = 1; 1316 cp.dir = wt->path; 1317 cp.out = -1; 1318 ret = start_command(&cp); 1319 if (ret) 1320 die_errno(_("failed to run 'git status' on '%s'"), 1321 original_path); 1322 ret = xread(cp.out, buf, sizeof(buf)); 1323 if (ret) 1324 die(_("'%s' contains modified or untracked files, use --force to delete it"), 1325 original_path); 1326 close(cp.out); 1327 ret = finish_command(&cp); 1328 if (ret) 1329 die_errno(_("failed to run 'git status' on '%s', code %d"), 1330 original_path, ret); 1331} 1332 1333static int delete_git_work_tree(struct worktree *wt) 1334{ 1335 struct strbuf sb = STRBUF_INIT; 1336 int ret = 0; 1337 1338 strbuf_addstr(&sb, wt->path); 1339 if (remove_dir_recursively(&sb, 0)) { 1340 error_errno(_("failed to delete '%s'"), sb.buf); 1341 ret = -1; 1342 } 1343 strbuf_release(&sb); 1344 return ret; 1345} 1346 1347static int remove_worktree(int ac, const char **av, const char *prefix, 1348 struct repository *repo UNUSED) 1349{ 1350 int force = 0; 1351 struct option options[] = { 1352 OPT__FORCE(&force, 1353 N_("force removal even if worktree is dirty or locked"), 1354 PARSE_OPT_NOCOMPLETE), 1355 OPT_END() 1356 }; 1357 struct worktree **worktrees, *wt; 1358 struct strbuf errmsg = STRBUF_INIT; 1359 const char *reason = NULL; 1360 int ret = 0; 1361 1362 ac = parse_options(ac, av, prefix, options, git_worktree_remove_usage, 0); 1363 if (ac != 1) 1364 usage_with_options(git_worktree_remove_usage, options); 1365 1366 worktrees = get_worktrees(); 1367 wt = find_worktree(worktrees, prefix, av[0]); 1368 if (!wt) 1369 die(_("'%s' is not a working tree"), av[0]); 1370 if (is_main_worktree(wt)) 1371 die(_("'%s' is a main working tree"), av[0]); 1372 if (force < 2) 1373 reason = worktree_lock_reason(wt); 1374 if (reason) { 1375 if (*reason) 1376 die(_("cannot remove a locked working tree, lock reason: %s\nuse 'remove -f -f' to override or unlock first"), 1377 reason); 1378 die(_("cannot remove a locked working tree;\nuse 'remove -f -f' to override or unlock first")); 1379 } 1380 if (validate_worktree(wt, &errmsg, WT_VALIDATE_WORKTREE_MISSING_OK)) 1381 die(_("validation failed, cannot remove working tree: %s"), 1382 errmsg.buf); 1383 strbuf_release(&errmsg); 1384 1385 if (file_exists(wt->path)) { 1386 if (!force) 1387 check_clean_worktree(wt, av[0]); 1388 1389 ret |= delete_git_work_tree(wt); 1390 } 1391 /* 1392 * continue on even if ret is non-zero, there's no going back 1393 * from here. 1394 */ 1395 ret |= delete_git_dir(wt->id); 1396 delete_worktrees_dir_if_empty(); 1397 1398 free_worktrees(worktrees); 1399 return ret; 1400} 1401 1402static void report_repair(int iserr, const char *path, const char *msg, void *cb_data) 1403{ 1404 if (!iserr) { 1405 fprintf_ln(stderr, _("repair: %s: %s"), msg, path); 1406 } else { 1407 int *exit_status = (int *)cb_data; 1408 fprintf_ln(stderr, _("error: %s: %s"), msg, path); 1409 *exit_status = 1; 1410 } 1411} 1412 1413static int repair(int ac, const char **av, const char *prefix, 1414 struct repository *repo UNUSED) 1415{ 1416 const char **p; 1417 const char *self[] = { ".", NULL }; 1418 struct option options[] = { 1419 OPT_BOOL(0, "relative-paths", &use_relative_paths, 1420 N_("use relative paths for worktrees")), 1421 OPT_END() 1422 }; 1423 int rc = 0; 1424 1425 ac = parse_options(ac, av, prefix, options, git_worktree_repair_usage, 0); 1426 p = ac > 0 ? av : self; 1427 for (; *p; p++) 1428 repair_worktree_at_path(*p, report_repair, &rc, use_relative_paths); 1429 repair_worktrees(report_repair, &rc, use_relative_paths); 1430 return rc; 1431} 1432 1433int cmd_worktree(int ac, 1434 const char **av, 1435 const char *prefix, 1436 struct repository *repo) 1437{ 1438 parse_opt_subcommand_fn *fn = NULL; 1439 struct option options[] = { 1440 OPT_SUBCOMMAND("add", &fn, add), 1441 OPT_SUBCOMMAND("prune", &fn, prune), 1442 OPT_SUBCOMMAND("list", &fn, list), 1443 OPT_SUBCOMMAND("lock", &fn, lock_worktree), 1444 OPT_SUBCOMMAND("unlock", &fn, unlock_worktree), 1445 OPT_SUBCOMMAND("move", &fn, move_worktree), 1446 OPT_SUBCOMMAND("remove", &fn, remove_worktree), 1447 OPT_SUBCOMMAND("repair", &fn, repair), 1448 OPT_END() 1449 }; 1450 1451 repo_config(the_repository, git_worktree_config, NULL); 1452 1453 if (!prefix) 1454 prefix = ""; 1455 1456 ac = parse_options(ac, av, prefix, options, git_worktree_usage, 0); 1457 1458 prepare_repo_settings(the_repository); 1459 the_repository->settings.command_requires_full_index = 0; 1460 1461 return fn(ac, av, prefix, repo); 1462}