* Repair /worktrees/ /gitdir if missing, corrupt, or not pointing at * the worktree's path. */
| 818 | * the worktree's path. |
| 819 | */ |
| 820 | void repair_worktree_at_path(const char *path, |
| 821 | worktree_repair_fn fn, void *cb_data, |
| 822 | int use_relative_paths) |
| 823 | { |
| 824 | struct strbuf dotgit = STRBUF_INIT; |
| 825 | struct strbuf backlink = STRBUF_INIT; |
| 826 | struct strbuf inferred_backlink = STRBUF_INIT; |
| 827 | struct strbuf gitdir = STRBUF_INIT; |
| 828 | struct strbuf olddotgit = STRBUF_INIT; |
| 829 | char *dotgit_contents = NULL; |
| 830 | const char *repair = NULL; |
| 831 | int err; |
| 832 | |
| 833 | if (!fn) |
| 834 | fn = repair_noop; |
| 835 | |
| 836 | if (is_main_worktree_path(path)) |
| 837 | goto done; |
| 838 | |
| 839 | strbuf_addf(&dotgit, "%s/.git", path); |
| 840 | if (!strbuf_realpath(&dotgit, dotgit.buf, 0)) { |
| 841 | fn(1, path, _("not a valid path"), cb_data); |
| 842 | goto done; |
| 843 | } |
| 844 | |
| 845 | infer_backlink(dotgit.buf, &inferred_backlink); |
| 846 | strbuf_realpath_forgiving(&inferred_backlink, inferred_backlink.buf, 0); |
| 847 | dotgit_contents = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err)); |
| 848 | if (dotgit_contents) { |
| 849 | if (is_absolute_path(dotgit_contents)) { |
| 850 | strbuf_addstr(&backlink, dotgit_contents); |
| 851 | } else { |
| 852 | strbuf_addbuf(&backlink, &dotgit); |
| 853 | strbuf_strip_suffix(&backlink, ".git"); |
| 854 | strbuf_addstr(&backlink, dotgit_contents); |
| 855 | strbuf_realpath_forgiving(&backlink, backlink.buf, 0); |
| 856 | } |
| 857 | } else if (err == READ_GITFILE_ERR_NOT_A_FILE || |
| 858 | err == READ_GITFILE_ERR_IS_A_DIR) { |
| 859 | fn(1, dotgit.buf, _("unable to locate repository; .git is not a file"), cb_data); |
| 860 | goto done; |
| 861 | } else if (err == READ_GITFILE_ERR_NOT_A_REPO) { |
| 862 | if (inferred_backlink.len) { |
| 863 | /* |
| 864 | * Worktree's .git file does not point at a repository |
| 865 | * but we found a .git/worktrees/<id> in this |
| 866 | * repository with the same <id> as recorded in the |
| 867 | * worktree's .git file so make the worktree point at |
| 868 | * the discovered .git/worktrees/<id>. |
| 869 | */ |
| 870 | strbuf_swap(&backlink, &inferred_backlink); |
| 871 | } else { |
| 872 | fn(1, dotgit.buf, _("unable to locate repository; .git file does not reference a repository"), cb_data); |
| 873 | goto done; |
| 874 | } |
| 875 | } else { |
| 876 | fn(1, dotgit.buf, _("unable to locate repository; .git file broken"), cb_data); |
| 877 | goto done; |
no test coverage detected