| 236 | } |
| 237 | |
| 238 | static int include_by_gitdir(const struct key_value_info *kvi, |
| 239 | const struct config_options *opts, |
| 240 | const char *cond, size_t cond_len, int icase) |
| 241 | { |
| 242 | struct strbuf text = STRBUF_INIT; |
| 243 | struct strbuf pattern = STRBUF_INIT; |
| 244 | size_t prefix; |
| 245 | int ret = 0; |
| 246 | const char *git_dir; |
| 247 | int already_tried_absolute = 0; |
| 248 | |
| 249 | if (opts->git_dir) |
| 250 | git_dir = opts->git_dir; |
| 251 | else |
| 252 | goto done; |
| 253 | |
| 254 | strbuf_realpath(&text, git_dir, 1); |
| 255 | strbuf_add(&pattern, cond, cond_len); |
| 256 | ret = prepare_include_condition_pattern(kvi, &pattern, &prefix); |
| 257 | if (ret < 0) |
| 258 | goto done; |
| 259 | |
| 260 | again: |
| 261 | if (prefix > 0) { |
| 262 | /* |
| 263 | * perform literal matching on the prefix part so that |
| 264 | * any wildcard character in it can't create side effects. |
| 265 | */ |
| 266 | if (text.len < prefix) |
| 267 | goto done; |
| 268 | if (!icase && strncmp(pattern.buf, text.buf, prefix)) |
| 269 | goto done; |
| 270 | if (icase && strncasecmp(pattern.buf, text.buf, prefix)) |
| 271 | goto done; |
| 272 | } |
| 273 | |
| 274 | ret = !wildmatch(pattern.buf + prefix, text.buf + prefix, |
| 275 | WM_PATHNAME | (icase ? WM_CASEFOLD : 0)); |
| 276 | |
| 277 | if (!ret && !already_tried_absolute) { |
| 278 | /* |
| 279 | * We've tried e.g. matching gitdir:~/work, but if |
| 280 | * ~/work is a symlink to /mnt/storage/work |
| 281 | * strbuf_realpath() will expand it, so the rule won't |
| 282 | * match. Let's match against a |
| 283 | * strbuf_add_absolute_path() version of the path, |
| 284 | * which'll do the right thing |
| 285 | */ |
| 286 | strbuf_reset(&text); |
| 287 | strbuf_add_absolute_path(&text, git_dir); |
| 288 | already_tried_absolute = 1; |
| 289 | goto again; |
| 290 | } |
| 291 | done: |
| 292 | strbuf_release(&pattern); |
| 293 | strbuf_release(&text); |
| 294 | return ret; |
| 295 | } |
no test coverage detected