* Repair worktree's /path/to/worktree/.git file if missing, corrupt, or not * pointing at /worktrees/ . */
| 637 | * pointing at <repo>/worktrees/<id>. |
| 638 | */ |
| 639 | static void repair_gitfile(struct worktree *wt, |
| 640 | worktree_repair_fn fn, void *cb_data, |
| 641 | int use_relative_paths) |
| 642 | { |
| 643 | struct strbuf dotgit = STRBUF_INIT; |
| 644 | struct strbuf gitdir = STRBUF_INIT; |
| 645 | struct strbuf repo = STRBUF_INIT; |
| 646 | struct strbuf backlink = STRBUF_INIT; |
| 647 | char *dotgit_contents = NULL; |
| 648 | const char *repair = NULL; |
| 649 | char *path = NULL; |
| 650 | int err; |
| 651 | |
| 652 | /* missing worktree can't be repaired */ |
| 653 | if (!file_exists(wt->path)) |
| 654 | goto done; |
| 655 | |
| 656 | if (!is_directory(wt->path)) { |
| 657 | fn(1, wt->path, _("not a directory"), cb_data); |
| 658 | goto done; |
| 659 | } |
| 660 | |
| 661 | path = repo_common_path(the_repository, "worktrees/%s", wt->id); |
| 662 | strbuf_realpath(&repo, path, 1); |
| 663 | strbuf_addf(&dotgit, "%s/.git", wt->path); |
| 664 | strbuf_addf(&gitdir, "%s/gitdir", repo.buf); |
| 665 | dotgit_contents = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err)); |
| 666 | |
| 667 | if (dotgit_contents) { |
| 668 | if (is_absolute_path(dotgit_contents)) { |
| 669 | strbuf_addstr(&backlink, dotgit_contents); |
| 670 | } else { |
| 671 | strbuf_addf(&backlink, "%s/%s", wt->path, dotgit_contents); |
| 672 | strbuf_realpath_forgiving(&backlink, backlink.buf, 0); |
| 673 | } |
| 674 | } |
| 675 | |
| 676 | if (err == READ_GITFILE_ERR_NOT_A_FILE || |
| 677 | err == READ_GITFILE_ERR_IS_A_DIR) |
| 678 | fn(1, wt->path, _(".git is not a file"), cb_data); |
| 679 | else if (err) |
| 680 | repair = _(".git file broken"); |
| 681 | else if (fspathcmp(backlink.buf, repo.buf)) |
| 682 | repair = _(".git file incorrect"); |
| 683 | else if (use_relative_paths == is_absolute_path(dotgit_contents)) |
| 684 | repair = _(".git file absolute/relative path mismatch"); |
| 685 | |
| 686 | if (repair) { |
| 687 | fn(0, wt->path, repair, cb_data); |
| 688 | write_worktree_linking_files(dotgit.buf, gitdir.buf, use_relative_paths); |
| 689 | } |
| 690 | |
| 691 | done: |
| 692 | free(dotgit_contents); |
| 693 | free(path); |
| 694 | strbuf_release(&repo); |
| 695 | strbuf_release(&dotgit); |
| 696 | strbuf_release(&gitdir); |
no test coverage detected