Derive the canonical repo root. * * Preferred (git 2.31+): abs_common_dir is `git rev-parse --path-format=absolute * --git-common-dir` — git's OWN absolute, canonical common-dir. Because a main * repo and its linked worktree both ask the same git binary, they resolve to the * IDENTICAL path, so canonical_root is consistent across worktrees AND platforms * with no manual join or realpath/_ful
| 143 | * common-dir so this branch isn't reached in practice, and _fullpath there |
| 144 | * reintroduces the msys divergence. */ |
| 145 | static char *derive_canonical_root(const char *input_path, const char *worktree_root, |
| 146 | const char *git_common_dir, const char *abs_common_dir) { |
| 147 | char *root = NULL; |
| 148 | if (abs_common_dir && abs_common_dir[0] && path_is_absolute(abs_common_dir)) { |
| 149 | root = git_strdup(abs_common_dir); |
| 150 | if (!root) { |
| 151 | return NULL; |
| 152 | } |
| 153 | } else { |
| 154 | const char *src = git_common_dir && git_common_dir[0] ? git_common_dir : worktree_root; |
| 155 | if (!src) { |
| 156 | return git_strdup(""); |
| 157 | } |
| 158 | #ifndef _WIN32 |
| 159 | root = path_is_absolute(src) ? git_strdup(src) : join_root_relative(input_path, src); |
| 160 | if (!root) { |
| 161 | return NULL; |
| 162 | } |
| 163 | { |
| 164 | char resolved[4096]; |
| 165 | if (realpath(root, resolved) != NULL) { |
| 166 | free(root); |
| 167 | root = git_strdup(resolved); |
| 168 | if (!root) { |
| 169 | return NULL; |
| 170 | } |
| 171 | } |
| 172 | } |
| 173 | #else |
| 174 | (void)input_path; |
| 175 | root = path_is_absolute(src) ? git_strdup(src) : join_root_relative(worktree_root, src); |
| 176 | if (!root) { |
| 177 | return NULL; |
| 178 | } |
| 179 | #endif |
| 180 | } |
| 181 | |
| 182 | size_t len = strlen(root); |
| 183 | while (len > 1 && (root[len - 1] == '/' || root[len - 1] == '\\')) { |
| 184 | root[--len] = '\0'; |
| 185 | } |
| 186 | |
| 187 | if (len >= 5 && strcmp(root + len - 5, "/.git") == 0) { |
| 188 | root[len - 5] = '\0'; |
| 189 | } |
| 190 | #ifdef _WIN32 |
| 191 | else if (len >= 5 && strcmp(root + len - 5, "\\.git") == 0) { |
| 192 | root[len - 5] = '\0'; |
| 193 | } |
| 194 | #endif |
| 195 | |
| 196 | return root; |
| 197 | } |
| 198 | |
| 199 | static char *slug_from_branch(const char *branch, bool detached) { |
| 200 | const char *fallback = detached ? "detached" : "working-tree"; |
no test coverage detected