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
| 133 | * common-dir so this branch isn't reached in practice, and _fullpath there |
| 134 | * reintroduces the msys divergence. */ |
| 135 | static char *derive_canonical_root(const char *input_path, const char *worktree_root, |
| 136 | const char *git_common_dir, const char *abs_common_dir) { |
| 137 | char *root = NULL; |
| 138 | if (abs_common_dir && abs_common_dir[0] && path_is_absolute(abs_common_dir)) { |
| 139 | root = git_strdup(abs_common_dir); |
| 140 | if (!root) { |
| 141 | return NULL; |
| 142 | } |
| 143 | } else { |
| 144 | const char *src = git_common_dir && git_common_dir[0] ? git_common_dir : worktree_root; |
| 145 | if (!src) { |
| 146 | return git_strdup(""); |
| 147 | } |
| 148 | #ifndef _WIN32 |
| 149 | root = path_is_absolute(src) ? git_strdup(src) : join_root_relative(input_path, src); |
| 150 | if (!root) { |
| 151 | return NULL; |
| 152 | } |
| 153 | { |
| 154 | char resolved[4096]; |
| 155 | if (realpath(root, resolved) != NULL) { |
| 156 | free(root); |
| 157 | root = git_strdup(resolved); |
| 158 | if (!root) { |
| 159 | return NULL; |
| 160 | } |
| 161 | } |
| 162 | } |
| 163 | #else |
| 164 | (void)input_path; |
| 165 | root = path_is_absolute(src) ? git_strdup(src) : join_root_relative(worktree_root, src); |
| 166 | if (!root) { |
| 167 | return NULL; |
| 168 | } |
| 169 | #endif |
| 170 | } |
| 171 | |
| 172 | size_t len = strlen(root); |
| 173 | while (len > 1 && (root[len - 1] == '/' || root[len - 1] == '\\')) { |
| 174 | root[--len] = '\0'; |
| 175 | } |
| 176 | |
| 177 | if (len >= 5 && strcmp(root + len - 5, "/.git") == 0) { |
| 178 | root[len - 5] = '\0'; |
| 179 | } |
| 180 | #ifdef _WIN32 |
| 181 | else if (len >= 5 && strcmp(root + len - 5, "\\.git") == 0) { |
| 182 | root[len - 5] = '\0'; |
| 183 | } |
| 184 | #endif |
| 185 | |
| 186 | return root; |
| 187 | } |
| 188 | |
| 189 | static char *slug_from_branch(const char *branch, bool detached) { |
| 190 | const char *fallback = detached ? "detached" : "working-tree"; |
no test coverage detected