* If both the main worktree and linked worktree have been moved, then the * gitfile /path/to/worktree/.git won't point into the repository, thus we * won't know which /worktrees/ /gitdir to repair. However, we may * be able to infer the gitdir by manually reading /path/to/worktree/.git, * extracting the , and checking if /worktrees/ exists. * * Returns -1 on failure an
| 787 | * Returns -1 on failure and strbuf.len on success. |
| 788 | */ |
| 789 | static ssize_t infer_backlink(const char *gitfile, struct strbuf *inferred) |
| 790 | { |
| 791 | struct strbuf actual = STRBUF_INIT; |
| 792 | const char *id; |
| 793 | |
| 794 | if (strbuf_read_file(&actual, gitfile, 0) < 0) |
| 795 | goto error; |
| 796 | if (!starts_with(actual.buf, "gitdir:")) |
| 797 | goto error; |
| 798 | if (!(id = find_last_dir_sep(actual.buf))) |
| 799 | goto error; |
| 800 | strbuf_trim(&actual); |
| 801 | id++; /* advance past '/' to point at <id> */ |
| 802 | if (!*id) |
| 803 | goto error; |
| 804 | repo_common_path_replace(the_repository, inferred, "worktrees/%s", id); |
| 805 | if (!is_directory(inferred->buf)) |
| 806 | goto error; |
| 807 | |
| 808 | strbuf_release(&actual); |
| 809 | return inferred->len; |
| 810 | error: |
| 811 | strbuf_release(&actual); |
| 812 | strbuf_reset(inferred); /* clear invalid path */ |
| 813 | return -1; |
| 814 | } |
| 815 | |
| 816 | /* |
| 817 | * Repair <repo>/worktrees/<id>/gitdir if missing, corrupt, or not pointing at |
no test coverage detected