Git fork
at reftables-rust 1683 lines 43 kB view raw
1/* 2 * Utilities for paths and pathnames 3 */ 4 5#include "git-compat-util.h" 6#include "abspath.h" 7#include "environment.h" 8#include "gettext.h" 9#include "repository.h" 10#include "strbuf.h" 11#include "string-list.h" 12#include "dir.h" 13#include "worktree.h" 14#include "setup.h" 15#include "submodule-config.h" 16#include "path.h" 17#include "packfile.h" 18#include "odb.h" 19#include "lockfile.h" 20#include "exec-cmd.h" 21 22static int get_st_mode_bits(const char *path, int *mode) 23{ 24 struct stat st; 25 if (lstat(path, &st) < 0) 26 return -1; 27 *mode = st.st_mode; 28 return 0; 29} 30 31static struct strbuf *get_pathname(void) 32{ 33 static struct strbuf pathname_array[4] = { 34 STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT 35 }; 36 static int index; 37 struct strbuf *sb = &pathname_array[index]; 38 index = (index + 1) % ARRAY_SIZE(pathname_array); 39 strbuf_reset(sb); 40 return sb; 41} 42 43static const char *cleanup_path(const char *path) 44{ 45 /* Clean it up */ 46 if (skip_prefix(path, "./", &path)) { 47 while (*path == '/') 48 path++; 49 } 50 return path; 51} 52 53static void strbuf_cleanup_path(struct strbuf *sb) 54{ 55 const char *path = cleanup_path(sb->buf); 56 if (path > sb->buf) 57 strbuf_remove(sb, 0, path - sb->buf); 58} 59 60static int dir_prefix(const char *buf, const char *dir) 61{ 62 int len = strlen(dir); 63 return !strncmp(buf, dir, len) && 64 (is_dir_sep(buf[len]) || buf[len] == '\0'); 65} 66 67/* $buf =~ m|$dir/+$file| but without regex */ 68static int is_dir_file(const char *buf, const char *dir, const char *file) 69{ 70 int len = strlen(dir); 71 if (strncmp(buf, dir, len) || !is_dir_sep(buf[len])) 72 return 0; 73 while (is_dir_sep(buf[len])) 74 len++; 75 return !strcmp(buf + len, file); 76} 77 78static void replace_dir(struct strbuf *buf, int len, const char *newdir) 79{ 80 int newlen = strlen(newdir); 81 int need_sep = (buf->buf[len] && !is_dir_sep(buf->buf[len])) && 82 !is_dir_sep(newdir[newlen - 1]); 83 if (need_sep) 84 len--; /* keep one char, to be replaced with '/' */ 85 strbuf_splice(buf, 0, len, newdir, newlen); 86 if (need_sep) 87 buf->buf[newlen] = '/'; 88} 89 90struct common_dir { 91 /* Not considered garbage for report_linked_checkout_garbage */ 92 unsigned ignore_garbage:1; 93 unsigned is_dir:1; 94 /* Belongs to the common dir, though it may contain paths that don't */ 95 unsigned is_common:1; 96 const char *path; 97}; 98 99static struct common_dir common_list[] = { 100 { 0, 1, 1, "branches" }, 101 { 0, 1, 1, "common" }, 102 { 0, 1, 1, "hooks" }, 103 { 0, 1, 1, "info" }, 104 { 0, 0, 0, "info/sparse-checkout" }, 105 { 1, 1, 1, "logs" }, 106 { 1, 0, 0, "logs/HEAD" }, 107 { 0, 1, 0, "logs/refs/bisect" }, 108 { 0, 1, 0, "logs/refs/rewritten" }, 109 { 0, 1, 0, "logs/refs/worktree" }, 110 { 0, 1, 1, "lost-found" }, 111 { 0, 1, 1, "objects" }, 112 { 0, 1, 1, "refs" }, 113 { 0, 1, 0, "refs/bisect" }, 114 { 0, 1, 0, "refs/rewritten" }, 115 { 0, 1, 0, "refs/worktree" }, 116 { 0, 1, 1, "remotes" }, 117 { 0, 1, 1, "worktrees" }, 118 { 0, 1, 1, "rr-cache" }, 119 { 0, 1, 1, "svn" }, 120 { 0, 0, 1, "config" }, 121 { 1, 0, 1, "gc.pid" }, 122 { 0, 0, 1, "packed-refs" }, 123 { 0, 0, 1, "shallow" }, 124 { 0, 0, 0, NULL } 125}; 126 127/* 128 * A compressed trie. A trie node consists of zero or more characters that 129 * are common to all elements with this prefix, optionally followed by some 130 * children. If value is not NULL, the trie node is a terminal node. 131 * 132 * For example, consider the following set of strings: 133 * abc 134 * def 135 * definite 136 * definition 137 * 138 * The trie would look like: 139 * root: len = 0, children a and d non-NULL, value = NULL. 140 * a: len = 2, contents = bc, value = (data for "abc") 141 * d: len = 2, contents = ef, children i non-NULL, value = (data for "def") 142 * i: len = 3, contents = nit, children e and i non-NULL, value = NULL 143 * e: len = 0, children all NULL, value = (data for "definite") 144 * i: len = 2, contents = on, children all NULL, 145 * value = (data for "definition") 146 */ 147struct trie { 148 struct trie *children[256]; 149 int len; 150 char *contents; 151 void *value; 152}; 153 154static struct trie *make_trie_node(const char *key, void *value) 155{ 156 struct trie *new_node = xcalloc(1, sizeof(*new_node)); 157 new_node->len = strlen(key); 158 if (new_node->len) { 159 new_node->contents = xmalloc(new_node->len); 160 memcpy(new_node->contents, key, new_node->len); 161 } 162 new_node->value = value; 163 return new_node; 164} 165 166/* 167 * Add a key/value pair to a trie. The key is assumed to be \0-terminated. 168 * If there was an existing value for this key, return it. 169 */ 170static void *add_to_trie(struct trie *root, const char *key, void *value) 171{ 172 struct trie *child; 173 void *old; 174 int i; 175 176 if (!*key) { 177 /* we have reached the end of the key */ 178 old = root->value; 179 root->value = value; 180 return old; 181 } 182 183 for (i = 0; i < root->len; i++) { 184 if (root->contents[i] == key[i]) 185 continue; 186 187 /* 188 * Split this node: child will contain this node's 189 * existing children. 190 */ 191 child = xmalloc(sizeof(*child)); 192 memcpy(child->children, root->children, sizeof(root->children)); 193 194 child->len = root->len - i - 1; 195 if (child->len) { 196 child->contents = xstrndup(root->contents + i + 1, 197 child->len); 198 } 199 child->value = root->value; 200 root->value = NULL; 201 root->len = i; 202 203 memset(root->children, 0, sizeof(root->children)); 204 root->children[(unsigned char)root->contents[i]] = child; 205 206 /* This is the newly-added child. */ 207 root->children[(unsigned char)key[i]] = 208 make_trie_node(key + i + 1, value); 209 return NULL; 210 } 211 212 /* We have matched the entire compressed section */ 213 if (key[i]) { 214 child = root->children[(unsigned char)key[root->len]]; 215 if (child) { 216 return add_to_trie(child, key + root->len + 1, value); 217 } else { 218 child = make_trie_node(key + root->len + 1, value); 219 root->children[(unsigned char)key[root->len]] = child; 220 return NULL; 221 } 222 } 223 224 old = root->value; 225 root->value = value; 226 return old; 227} 228 229typedef int (*match_fn)(const char *unmatched, void *value, void *baton); 230 231/* 232 * Search a trie for some key. Find the longest /-or-\0-terminated 233 * prefix of the key for which the trie contains a value. If there is 234 * no such prefix, return -1. Otherwise call fn with the unmatched 235 * portion of the key and the found value. If fn returns 0 or 236 * positive, then return its return value. If fn returns negative, 237 * then call fn with the next-longest /-terminated prefix of the key 238 * (i.e. a parent directory) for which the trie contains a value, and 239 * handle its return value the same way. If there is no shorter 240 * /-terminated prefix with a value left, then return the negative 241 * return value of the most recent fn invocation. 242 * 243 * The key is partially normalized: consecutive slashes are skipped. 244 * 245 * For example, consider the trie containing only [logs, 246 * logs/refs/bisect], both with values, but not logs/refs. 247 * 248 * | key | unmatched | prefix to node | return value | 249 * |--------------------|----------------|------------------|--------------| 250 * | a | not called | n/a | -1 | 251 * | logstore | not called | n/a | -1 | 252 * | logs | \0 | logs | as per fn | 253 * | logs/ | / | logs | as per fn | 254 * | logs/refs | /refs | logs | as per fn | 255 * | logs/refs/ | /refs/ | logs | as per fn | 256 * | logs/refs/b | /refs/b | logs | as per fn | 257 * | logs/refs/bisected | /refs/bisected | logs | as per fn | 258 * | logs/refs/bisect | \0 | logs/refs/bisect | as per fn | 259 * | logs/refs/bisect/ | / | logs/refs/bisect | as per fn | 260 * | logs/refs/bisect/a | /a | logs/refs/bisect | as per fn | 261 * | (If fn in the previous line returns -1, then fn is called once more:) | 262 * | logs/refs/bisect/a | /refs/bisect/a | logs | as per fn | 263 * |--------------------|----------------|------------------|--------------| 264 */ 265static int trie_find(struct trie *root, const char *key, match_fn fn, 266 void *baton) 267{ 268 int i; 269 int result; 270 struct trie *child; 271 272 if (!*key) { 273 /* we have reached the end of the key */ 274 if (root->value && !root->len) 275 return fn(key, root->value, baton); 276 else 277 return -1; 278 } 279 280 for (i = 0; i < root->len; i++) { 281 /* Partial path normalization: skip consecutive slashes. */ 282 if (key[i] == '/' && key[i+1] == '/') { 283 key++; 284 continue; 285 } 286 if (root->contents[i] != key[i]) 287 return -1; 288 } 289 290 /* Matched the entire compressed section */ 291 key += i; 292 if (!*key) { 293 /* End of key */ 294 if (root->value) 295 return fn(key, root->value, baton); 296 else 297 return -1; 298 } 299 300 /* Partial path normalization: skip consecutive slashes */ 301 while (key[0] == '/' && key[1] == '/') 302 key++; 303 304 child = root->children[(unsigned char)*key]; 305 if (child) 306 result = trie_find(child, key + 1, fn, baton); 307 else 308 result = -1; 309 310 if (result >= 0 || (*key != '/' && *key != 0)) 311 return result; 312 if (root->value) 313 return fn(key, root->value, baton); 314 else 315 return -1; 316} 317 318static struct trie common_trie; 319static int common_trie_done_setup; 320 321static void init_common_trie(void) 322{ 323 struct common_dir *p; 324 325 if (common_trie_done_setup) 326 return; 327 328 for (p = common_list; p->path; p++) 329 add_to_trie(&common_trie, p->path, p); 330 331 common_trie_done_setup = 1; 332} 333 334/* 335 * Helper function for update_common_dir: returns 1 if the dir 336 * prefix is common. 337 */ 338static int check_common(const char *unmatched, void *value, 339 void *baton UNUSED) 340{ 341 struct common_dir *dir = value; 342 343 if (dir->is_dir && (unmatched[0] == 0 || unmatched[0] == '/')) 344 return dir->is_common; 345 346 if (!dir->is_dir && unmatched[0] == 0) 347 return dir->is_common; 348 349 return 0; 350} 351 352static void update_common_dir(struct strbuf *buf, int git_dir_len, 353 const char *common_dir) 354{ 355 char *base = buf->buf + git_dir_len; 356 int has_lock_suffix = strbuf_strip_suffix(buf, LOCK_SUFFIX); 357 358 init_common_trie(); 359 if (trie_find(&common_trie, base, check_common, NULL) > 0) 360 replace_dir(buf, git_dir_len, common_dir); 361 362 if (has_lock_suffix) 363 strbuf_addstr(buf, LOCK_SUFFIX); 364} 365 366void report_linked_checkout_garbage(struct repository *r) 367{ 368 struct strbuf sb = STRBUF_INIT; 369 const struct common_dir *p; 370 int len; 371 372 if (!r->different_commondir) 373 return; 374 strbuf_addf(&sb, "%s/", r->gitdir); 375 len = sb.len; 376 for (p = common_list; p->path; p++) { 377 const char *path = p->path; 378 if (p->ignore_garbage) 379 continue; 380 strbuf_setlen(&sb, len); 381 strbuf_addstr(&sb, path); 382 if (file_exists(sb.buf)) 383 report_garbage(PACKDIR_FILE_GARBAGE, sb.buf); 384 } 385 strbuf_release(&sb); 386} 387 388static void adjust_git_path(struct repository *repo, 389 struct strbuf *buf, int git_dir_len) 390{ 391 const char *base = buf->buf + git_dir_len; 392 393 if (is_dir_file(base, "info", "grafts")) 394 strbuf_splice(buf, 0, buf->len, 395 repo->graft_file, strlen(repo->graft_file)); 396 else if (!strcmp(base, "index")) 397 strbuf_splice(buf, 0, buf->len, 398 repo->index_file, strlen(repo->index_file)); 399 else if (dir_prefix(base, "objects")) 400 replace_dir(buf, git_dir_len + 7, repo->objects->sources->path); 401 else if (repo_settings_get_hooks_path(repo) && dir_prefix(base, "hooks")) 402 replace_dir(buf, git_dir_len + 5, repo_settings_get_hooks_path(repo)); 403 else if (repo->different_commondir) 404 update_common_dir(buf, git_dir_len, repo->commondir); 405} 406 407static void strbuf_worktree_gitdir(struct strbuf *buf, 408 const struct repository *repo, 409 const struct worktree *wt) 410{ 411 if (!wt) 412 strbuf_addstr(buf, repo->gitdir); 413 else if (!wt->id) 414 strbuf_addstr(buf, repo->commondir); 415 else 416 repo_common_path_append(repo, buf, "worktrees/%s", wt->id); 417} 418 419static void repo_git_pathv(struct repository *repo, 420 const struct worktree *wt, struct strbuf *buf, 421 const char *fmt, va_list args) 422{ 423 int gitdir_len; 424 strbuf_worktree_gitdir(buf, repo, wt); 425 if (buf->len && !is_dir_sep(buf->buf[buf->len - 1])) 426 strbuf_addch(buf, '/'); 427 gitdir_len = buf->len; 428 strbuf_vaddf(buf, fmt, args); 429 if (!wt) 430 adjust_git_path(repo, buf, gitdir_len); 431 strbuf_cleanup_path(buf); 432} 433 434char *repo_git_path(struct repository *repo, 435 const char *fmt, ...) 436{ 437 struct strbuf path = STRBUF_INIT; 438 va_list args; 439 va_start(args, fmt); 440 repo_git_pathv(repo, NULL, &path, fmt, args); 441 va_end(args); 442 return strbuf_detach(&path, NULL); 443} 444 445const char *repo_git_path_append(struct repository *repo, 446 struct strbuf *sb, 447 const char *fmt, ...) 448{ 449 va_list args; 450 va_start(args, fmt); 451 repo_git_pathv(repo, NULL, sb, fmt, args); 452 va_end(args); 453 return sb->buf; 454} 455 456const char *repo_git_path_replace(struct repository *repo, 457 struct strbuf *sb, 458 const char *fmt, ...) 459{ 460 va_list args; 461 strbuf_reset(sb); 462 va_start(args, fmt); 463 repo_git_pathv(repo, NULL, sb, fmt, args); 464 va_end(args); 465 return sb->buf; 466} 467 468char *mkpathdup(const char *fmt, ...) 469{ 470 struct strbuf sb = STRBUF_INIT; 471 va_list args; 472 va_start(args, fmt); 473 strbuf_vaddf(&sb, fmt, args); 474 va_end(args); 475 strbuf_cleanup_path(&sb); 476 return strbuf_detach(&sb, NULL); 477} 478 479const char *mkpath(const char *fmt, ...) 480{ 481 va_list args; 482 struct strbuf *pathname = get_pathname(); 483 va_start(args, fmt); 484 strbuf_vaddf(pathname, fmt, args); 485 va_end(args); 486 return cleanup_path(pathname->buf); 487} 488 489const char *worktree_git_path(struct repository *r, 490 const struct worktree *wt, const char *fmt, ...) 491{ 492 struct strbuf *pathname = get_pathname(); 493 va_list args; 494 495 if (wt && wt->repo != r) 496 BUG("worktree not connected to expected repository"); 497 498 va_start(args, fmt); 499 repo_git_pathv(r, wt, pathname, fmt, args); 500 va_end(args); 501 return pathname->buf; 502} 503 504static void do_worktree_path(const struct repository *repo, 505 struct strbuf *buf, 506 const char *fmt, va_list args) 507{ 508 strbuf_addstr(buf, repo->worktree); 509 if(buf->len && !is_dir_sep(buf->buf[buf->len - 1])) 510 strbuf_addch(buf, '/'); 511 512 strbuf_vaddf(buf, fmt, args); 513 strbuf_cleanup_path(buf); 514} 515 516char *repo_worktree_path(const struct repository *repo, const char *fmt, ...) 517{ 518 struct strbuf path = STRBUF_INIT; 519 va_list args; 520 521 va_start(args, fmt); 522 do_worktree_path(repo, &path, fmt, args); 523 va_end(args); 524 525 return strbuf_detach(&path, NULL); 526} 527 528const char *repo_worktree_path_append(const struct repository *repo, 529 struct strbuf *sb, 530 const char *fmt, ...) 531{ 532 va_list args; 533 534 if (!repo->worktree) 535 return NULL; 536 537 va_start(args, fmt); 538 do_worktree_path(repo, sb, fmt, args); 539 va_end(args); 540 541 return sb->buf; 542} 543 544const char *repo_worktree_path_replace(const struct repository *repo, 545 struct strbuf *sb, 546 const char *fmt, ...) 547{ 548 va_list args; 549 550 strbuf_reset(sb); 551 if (!repo->worktree) 552 return NULL; 553 554 va_start(args, fmt); 555 do_worktree_path(repo, sb, fmt, args); 556 va_end(args); 557 558 return sb->buf; 559} 560 561/* Returns 0 on success, negative on failure. */ 562static int do_submodule_path(struct repository *repo, 563 struct strbuf *buf, const char *path, 564 const char *fmt, va_list args) 565{ 566 struct strbuf git_submodule_common_dir = STRBUF_INIT; 567 struct strbuf git_submodule_dir = STRBUF_INIT; 568 int ret; 569 570 ret = submodule_to_gitdir(repo, &git_submodule_dir, path); 571 if (ret) 572 goto cleanup; 573 574 strbuf_complete(&git_submodule_dir, '/'); 575 strbuf_addbuf(buf, &git_submodule_dir); 576 strbuf_vaddf(buf, fmt, args); 577 578 if (get_common_dir_noenv(&git_submodule_common_dir, git_submodule_dir.buf)) 579 update_common_dir(buf, git_submodule_dir.len, git_submodule_common_dir.buf); 580 581 strbuf_cleanup_path(buf); 582 583cleanup: 584 strbuf_release(&git_submodule_dir); 585 strbuf_release(&git_submodule_common_dir); 586 return ret; 587} 588 589char *repo_submodule_path(struct repository *repo, 590 const char *path, const char *fmt, ...) 591{ 592 int err; 593 va_list args; 594 struct strbuf buf = STRBUF_INIT; 595 va_start(args, fmt); 596 err = do_submodule_path(repo, &buf, path, fmt, args); 597 va_end(args); 598 if (err) { 599 strbuf_release(&buf); 600 return NULL; 601 } 602 return strbuf_detach(&buf, NULL); 603} 604 605const char *repo_submodule_path_append(struct repository *repo, 606 struct strbuf *buf, 607 const char *path, 608 const char *fmt, ...) 609{ 610 int err; 611 va_list args; 612 va_start(args, fmt); 613 err = do_submodule_path(repo, buf, path, fmt, args); 614 va_end(args); 615 if (err) 616 return NULL; 617 return buf->buf; 618} 619 620const char *repo_submodule_path_replace(struct repository *repo, 621 struct strbuf *buf, 622 const char *path, 623 const char *fmt, ...) 624{ 625 int err; 626 va_list args; 627 strbuf_reset(buf); 628 va_start(args, fmt); 629 err = do_submodule_path(repo, buf, path, fmt, args); 630 va_end(args); 631 if (err) 632 return NULL; 633 return buf->buf; 634} 635 636static void repo_common_pathv(const struct repository *repo, 637 struct strbuf *sb, 638 const char *fmt, 639 va_list args) 640{ 641 strbuf_addstr(sb, repo->commondir); 642 if (sb->len && !is_dir_sep(sb->buf[sb->len - 1])) 643 strbuf_addch(sb, '/'); 644 strbuf_vaddf(sb, fmt, args); 645 strbuf_cleanup_path(sb); 646} 647 648char *repo_common_path(const struct repository *repo, 649 const char *fmt, ...) 650{ 651 struct strbuf sb = STRBUF_INIT; 652 va_list args; 653 va_start(args, fmt); 654 repo_common_pathv(repo, &sb, fmt, args); 655 va_end(args); 656 return strbuf_detach(&sb, NULL); 657} 658 659const char *repo_common_path_append(const struct repository *repo, 660 struct strbuf *sb, 661 const char *fmt, ...) 662{ 663 va_list args; 664 va_start(args, fmt); 665 repo_common_pathv(repo, sb, fmt, args); 666 va_end(args); 667 return sb->buf; 668} 669 670const char *repo_common_path_replace(const struct repository *repo, 671 struct strbuf *sb, 672 const char *fmt, ...) 673{ 674 va_list args; 675 strbuf_reset(sb); 676 va_start(args, fmt); 677 repo_common_pathv(repo, sb, fmt, args); 678 va_end(args); 679 return sb->buf; 680} 681 682static struct passwd *getpw_str(const char *username, size_t len) 683{ 684 struct passwd *pw; 685 char *username_z = xmemdupz(username, len); 686 pw = getpwnam(username_z); 687 free(username_z); 688 return pw; 689} 690 691/* 692 * Return a string with ~ and ~user expanded via getpw*. Returns NULL on getpw 693 * failure or if path is NULL. 694 * 695 * If real_home is true, strbuf_realpath($HOME) is used in the `~/` expansion. 696 * 697 * If the path starts with `%(prefix)/`, the remainder is interpreted as 698 * relative to where Git is installed, and expanded to the absolute path. 699 */ 700char *interpolate_path(const char *path, int real_home) 701{ 702 struct strbuf user_path = STRBUF_INIT; 703 const char *to_copy = path; 704 705 if (!path) 706 goto return_null; 707 708 if (skip_prefix(path, "%(prefix)/", &path)) 709 return system_path(path); 710 711 if (path[0] == '~') { 712 const char *first_slash = strchrnul(path, '/'); 713 const char *username = path + 1; 714 size_t username_len = first_slash - username; 715 if (username_len == 0) { 716 const char *home = getenv("HOME"); 717 if (!home) 718 goto return_null; 719 if (real_home) 720 strbuf_add_real_path(&user_path, home); 721 else 722 strbuf_addstr(&user_path, home); 723#ifdef GIT_WINDOWS_NATIVE 724 convert_slashes(user_path.buf); 725#endif 726 } else { 727 struct passwd *pw = getpw_str(username, username_len); 728 if (!pw) 729 goto return_null; 730 strbuf_addstr(&user_path, pw->pw_dir); 731 } 732 to_copy = first_slash; 733 } 734 strbuf_addstr(&user_path, to_copy); 735 return strbuf_detach(&user_path, NULL); 736return_null: 737 strbuf_release(&user_path); 738 return NULL; 739} 740 741/* 742 * First, one directory to try is determined by the following algorithm. 743 * 744 * (0) If "strict" is given, the path is used as given and no DWIM is 745 * done. Otherwise: 746 * (1) "~/path" to mean path under the running user's home directory; 747 * (2) "~user/path" to mean path under named user's home directory; 748 * (3) "relative/path" to mean cwd relative directory; or 749 * (4) "/absolute/path" to mean absolute directory. 750 * 751 * Unless "strict" is given, we check "%s/.git", "%s", "%s.git/.git", "%s.git" 752 * in this order. We select the first one that is a valid git repository, and 753 * chdir() to it. If none match, or we fail to chdir, we return NULL. 754 * 755 * If all goes well, we return the directory we used to chdir() (but 756 * before ~user is expanded), avoiding getcwd() resolving symbolic 757 * links. User relative paths are also returned as they are given, 758 * except DWIM suffixing. 759 */ 760const char *enter_repo(const char *path, unsigned flags) 761{ 762 static struct strbuf validated_path = STRBUF_INIT; 763 static struct strbuf used_path = STRBUF_INIT; 764 765 if (!path) 766 return NULL; 767 768 if (!(flags & ENTER_REPO_STRICT)) { 769 static const char *suffix[] = { 770 "/.git", "", ".git/.git", ".git", NULL, 771 }; 772 const char *gitfile; 773 int len = strlen(path); 774 int i; 775 while ((1 < len) && (path[len-1] == '/')) 776 len--; 777 778 /* 779 * We can handle arbitrary-sized buffers, but this remains as a 780 * sanity check on untrusted input. 781 */ 782 if (PATH_MAX <= len) 783 return NULL; 784 785 strbuf_reset(&used_path); 786 strbuf_reset(&validated_path); 787 strbuf_add(&used_path, path, len); 788 strbuf_add(&validated_path, path, len); 789 790 if (used_path.buf[0] == '~') { 791 char *newpath = interpolate_path(used_path.buf, 0); 792 if (!newpath) 793 return NULL; 794 strbuf_attach(&used_path, newpath, strlen(newpath), 795 strlen(newpath)); 796 } 797 for (i = 0; suffix[i]; i++) { 798 struct stat st; 799 size_t baselen = used_path.len; 800 strbuf_addstr(&used_path, suffix[i]); 801 if (!stat(used_path.buf, &st) && 802 (S_ISREG(st.st_mode) || 803 (S_ISDIR(st.st_mode) && is_git_directory(used_path.buf)))) { 804 strbuf_addstr(&validated_path, suffix[i]); 805 break; 806 } 807 strbuf_setlen(&used_path, baselen); 808 } 809 if (!suffix[i]) 810 return NULL; 811 gitfile = read_gitfile(used_path.buf); 812 if (!(flags & ENTER_REPO_ANY_OWNER_OK)) 813 die_upon_dubious_ownership(gitfile, NULL, used_path.buf); 814 if (gitfile) { 815 strbuf_reset(&used_path); 816 strbuf_addstr(&used_path, gitfile); 817 } 818 if (chdir(used_path.buf)) 819 return NULL; 820 path = validated_path.buf; 821 } 822 else { 823 const char *gitfile = read_gitfile(path); 824 if (!(flags & ENTER_REPO_ANY_OWNER_OK)) 825 die_upon_dubious_ownership(gitfile, NULL, path); 826 if (gitfile) 827 path = gitfile; 828 if (chdir(path)) 829 return NULL; 830 } 831 832 if (is_git_directory(".")) { 833 set_git_dir(".", 0); 834 check_repository_format(NULL); 835 return path; 836 } 837 838 return NULL; 839} 840 841int calc_shared_perm(struct repository *repo, 842 int mode) 843{ 844 int tweak; 845 846 if (repo_settings_get_shared_repository(repo) < 0) 847 tweak = -repo_settings_get_shared_repository(repo); 848 else 849 tweak = repo_settings_get_shared_repository(repo); 850 851 if (!(mode & S_IWUSR)) 852 tweak &= ~0222; 853 if (mode & S_IXUSR) 854 /* Copy read bits to execute bits */ 855 tweak |= (tweak & 0444) >> 2; 856 if (repo_settings_get_shared_repository(repo) < 0) 857 mode = (mode & ~0777) | tweak; 858 else 859 mode |= tweak; 860 861 return mode; 862} 863 864int adjust_shared_perm(struct repository *repo, 865 const char *path) 866{ 867 int old_mode, new_mode; 868 869 if (!repo_settings_get_shared_repository(repo)) 870 return 0; 871 if (get_st_mode_bits(path, &old_mode) < 0) 872 return -1; 873 874 new_mode = calc_shared_perm(repo, old_mode); 875 if (S_ISDIR(old_mode)) { 876 /* Copy read bits to execute bits */ 877 new_mode |= (new_mode & 0444) >> 2; 878 879 /* 880 * g+s matters only if any extra access is granted 881 * based on group membership. 882 */ 883 if (FORCE_DIR_SET_GID && (new_mode & 060)) 884 new_mode |= FORCE_DIR_SET_GID; 885 } 886 887 if (((old_mode ^ new_mode) & ~S_IFMT) && 888 chmod(path, (new_mode & ~S_IFMT)) < 0) 889 return -2; 890 return 0; 891} 892 893void safe_create_dir(struct repository *repo, const char *dir, int share) 894{ 895 if (mkdir(dir, 0777) < 0) { 896 if (errno != EEXIST) { 897 perror(dir); 898 exit(1); 899 } 900 } 901 else if (share && adjust_shared_perm(repo, dir)) 902 die(_("Could not make %s writable by group"), dir); 903} 904 905int safe_create_dir_in_gitdir(struct repository *repo, const char *path) 906{ 907 if (mkdir(path, 0777)) { 908 int saved_errno = errno; 909 struct stat st; 910 struct strbuf sb = STRBUF_INIT; 911 912 if (errno != EEXIST) 913 return -1; 914 /* 915 * Are we looking at a path in a symlinked worktree 916 * whose original repository does not yet have it? 917 * e.g. .git/rr-cache pointing at its original 918 * repository in which the user hasn't performed any 919 * conflict resolution yet? 920 */ 921 if (lstat(path, &st) || !S_ISLNK(st.st_mode) || 922 strbuf_readlink(&sb, path, st.st_size) || 923 !is_absolute_path(sb.buf) || 924 mkdir(sb.buf, 0777)) { 925 strbuf_release(&sb); 926 errno = saved_errno; 927 return -1; 928 } 929 strbuf_release(&sb); 930 } 931 return adjust_shared_perm(repo, path); 932} 933 934static enum scld_error safe_create_leading_directories_1(struct repository *repo, 935 char *path) 936{ 937 char *next_component = path + offset_1st_component(path); 938 enum scld_error ret = SCLD_OK; 939 940 while (ret == SCLD_OK && next_component) { 941 struct stat st; 942 char *slash = next_component, slash_character; 943 944 while (*slash && !is_dir_sep(*slash)) 945 slash++; 946 947 if (!*slash) 948 break; 949 950 next_component = slash + 1; 951 while (is_dir_sep(*next_component)) 952 next_component++; 953 if (!*next_component) 954 break; 955 956 slash_character = *slash; 957 *slash = '\0'; 958 if (!stat(path, &st)) { 959 /* path exists */ 960 if (!S_ISDIR(st.st_mode)) { 961 errno = ENOTDIR; 962 ret = SCLD_EXISTS; 963 } 964 } else if (mkdir(path, 0777)) { 965 if (errno == EEXIST && 966 !stat(path, &st) && S_ISDIR(st.st_mode)) 967 ; /* somebody created it since we checked */ 968 else if (errno == ENOENT) 969 /* 970 * Either mkdir() failed because 971 * somebody just pruned the containing 972 * directory, or stat() failed because 973 * the file that was in our way was 974 * just removed. Either way, inform 975 * the caller that it might be worth 976 * trying again: 977 */ 978 ret = SCLD_VANISHED; 979 else 980 ret = SCLD_FAILED; 981 } else if (repo && adjust_shared_perm(repo, path)) { 982 ret = SCLD_PERMS; 983 } 984 *slash = slash_character; 985 } 986 return ret; 987} 988 989enum scld_error safe_create_leading_directories(struct repository *repo, 990 char *path) 991{ 992 return safe_create_leading_directories_1(repo, path); 993} 994 995enum scld_error safe_create_leading_directories_no_share(char *path) 996{ 997 return safe_create_leading_directories_1(NULL, path); 998} 999 1000enum scld_error safe_create_leading_directories_const(struct repository *repo, 1001 const char *path) 1002{ 1003 int save_errno; 1004 /* path points to cache entries, so xstrdup before messing with it */ 1005 char *buf = xstrdup(path); 1006 enum scld_error result = safe_create_leading_directories(repo, buf); 1007 1008 save_errno = errno; 1009 free(buf); 1010 errno = save_errno; 1011 return result; 1012} 1013 1014int safe_create_file_with_leading_directories(struct repository *repo, 1015 const char *path) 1016{ 1017 int fd; 1018 1019 fd = open(path, O_RDWR|O_CREAT|O_EXCL, 0600); 1020 if (0 <= fd) 1021 return fd; 1022 1023 /* slow path */ 1024 safe_create_leading_directories_const(repo, path); 1025 return open(path, O_RDWR|O_CREAT|O_EXCL, 0600); 1026} 1027 1028static int have_same_root(const char *path1, const char *path2) 1029{ 1030 int is_abs1, is_abs2; 1031 1032 is_abs1 = is_absolute_path(path1); 1033 is_abs2 = is_absolute_path(path2); 1034 return (is_abs1 && is_abs2 && tolower(path1[0]) == tolower(path2[0])) || 1035 (!is_abs1 && !is_abs2); 1036} 1037 1038/* 1039 * Give path as relative to prefix. 1040 * 1041 * The strbuf may or may not be used, so do not assume it contains the 1042 * returned path. 1043 */ 1044const char *relative_path(const char *in, const char *prefix, 1045 struct strbuf *sb) 1046{ 1047 int in_len = in ? strlen(in) : 0; 1048 int prefix_len = prefix ? strlen(prefix) : 0; 1049 int in_off = 0; 1050 int prefix_off = 0; 1051 int i = 0, j = 0; 1052 1053 if (!in_len) 1054 return "./"; 1055 else if (!prefix_len) 1056 return in; 1057 1058 if (have_same_root(in, prefix)) 1059 /* bypass dos_drive, for "c:" is identical to "C:" */ 1060 i = j = has_dos_drive_prefix(in); 1061 else { 1062 return in; 1063 } 1064 1065 while (i < prefix_len && j < in_len && prefix[i] == in[j]) { 1066 if (is_dir_sep(prefix[i])) { 1067 while (is_dir_sep(prefix[i])) 1068 i++; 1069 while (is_dir_sep(in[j])) 1070 j++; 1071 prefix_off = i; 1072 in_off = j; 1073 } else { 1074 i++; 1075 j++; 1076 } 1077 } 1078 1079 if ( 1080 /* "prefix" seems like prefix of "in" */ 1081 i >= prefix_len && 1082 /* 1083 * but "/foo" is not a prefix of "/foobar" 1084 * (i.e. prefix not end with '/') 1085 */ 1086 prefix_off < prefix_len) { 1087 if (j >= in_len) { 1088 /* in="/a/b", prefix="/a/b" */ 1089 in_off = in_len; 1090 } else if (is_dir_sep(in[j])) { 1091 /* in="/a/b/c", prefix="/a/b" */ 1092 while (is_dir_sep(in[j])) 1093 j++; 1094 in_off = j; 1095 } else { 1096 /* in="/a/bbb/c", prefix="/a/b" */ 1097 i = prefix_off; 1098 } 1099 } else if ( 1100 /* "in" is short than "prefix" */ 1101 j >= in_len && 1102 /* "in" not end with '/' */ 1103 in_off < in_len) { 1104 if (is_dir_sep(prefix[i])) { 1105 /* in="/a/b", prefix="/a/b/c/" */ 1106 while (is_dir_sep(prefix[i])) 1107 i++; 1108 in_off = in_len; 1109 } 1110 } 1111 in += in_off; 1112 in_len -= in_off; 1113 1114 if (i >= prefix_len) { 1115 if (!in_len) 1116 return "./"; 1117 else 1118 return in; 1119 } 1120 1121 strbuf_reset(sb); 1122 strbuf_grow(sb, in_len); 1123 1124 while (i < prefix_len) { 1125 if (is_dir_sep(prefix[i])) { 1126 strbuf_addstr(sb, "../"); 1127 while (is_dir_sep(prefix[i])) 1128 i++; 1129 continue; 1130 } 1131 i++; 1132 } 1133 if (!is_dir_sep(prefix[prefix_len - 1])) 1134 strbuf_addstr(sb, "../"); 1135 1136 strbuf_addstr(sb, in); 1137 1138 return sb->buf; 1139} 1140 1141/* 1142 * A simpler implementation of relative_path 1143 * 1144 * Get relative path by removing "prefix" from "in". This function 1145 * first appears in v1.5.6-1-g044bbbc, and makes git_dir shorter 1146 * to increase performance when traversing the path to work_tree. 1147 */ 1148const char *remove_leading_path(const char *in, const char *prefix) 1149{ 1150 static struct strbuf buf = STRBUF_INIT; 1151 int i = 0, j = 0; 1152 1153 if (!prefix || !prefix[0]) 1154 return in; 1155 while (prefix[i]) { 1156 if (is_dir_sep(prefix[i])) { 1157 if (!is_dir_sep(in[j])) 1158 return in; 1159 while (is_dir_sep(prefix[i])) 1160 i++; 1161 while (is_dir_sep(in[j])) 1162 j++; 1163 continue; 1164 } else if (in[j] != prefix[i]) { 1165 return in; 1166 } 1167 i++; 1168 j++; 1169 } 1170 if ( 1171 /* "/foo" is a prefix of "/foo" */ 1172 in[j] && 1173 /* "/foo" is not a prefix of "/foobar" */ 1174 !is_dir_sep(prefix[i-1]) && !is_dir_sep(in[j]) 1175 ) 1176 return in; 1177 while (is_dir_sep(in[j])) 1178 j++; 1179 1180 strbuf_reset(&buf); 1181 if (!in[j]) 1182 strbuf_addstr(&buf, "."); 1183 else 1184 strbuf_addstr(&buf, in + j); 1185 return buf.buf; 1186} 1187 1188/* 1189 * It is okay if dst == src, but they should not overlap otherwise. 1190 * The "dst" buffer must be at least as long as "src"; normalizing may shrink 1191 * the size of the path, but will never grow it. 1192 * 1193 * Performs the following normalizations on src, storing the result in dst: 1194 * - Ensures that components are separated by '/' (Windows only) 1195 * - Squashes sequences of '/' except "//server/share" on Windows 1196 * - Removes "." components. 1197 * - Removes ".." components, and the components the precede them. 1198 * Returns failure (non-zero) if a ".." component appears as first path 1199 * component anytime during the normalization. Otherwise, returns success (0). 1200 * 1201 * Note that this function is purely textual. It does not follow symlinks, 1202 * verify the existence of the path, or make any system calls. 1203 * 1204 * prefix_len != NULL is for a specific case of prefix_pathspec(): 1205 * assume that src == dst and src[0..prefix_len-1] is already 1206 * normalized, any time "../" eats up to the prefix_len part, 1207 * prefix_len is reduced. In the end prefix_len is the remaining 1208 * prefix that has not been overridden by user pathspec. 1209 * 1210 * NEEDSWORK: This function doesn't perform normalization w.r.t. trailing '/'. 1211 * For everything but the root folder itself, the normalized path should not 1212 * end with a '/', then the callers need to be fixed up accordingly. 1213 * 1214 */ 1215int normalize_path_copy_len(char *dst, const char *src, int *prefix_len) 1216{ 1217 char *dst0; 1218 const char *end; 1219 1220 /* 1221 * Copy initial part of absolute path: "/", "C:/", "//server/share/". 1222 */ 1223 end = src + offset_1st_component(src); 1224 while (src < end) { 1225 char c = *src++; 1226 if (is_dir_sep(c)) 1227 c = '/'; 1228 *dst++ = c; 1229 } 1230 dst0 = dst; 1231 1232 while (is_dir_sep(*src)) 1233 src++; 1234 1235 for (;;) { 1236 char c = *src; 1237 1238 /* 1239 * A path component that begins with . could be 1240 * special: 1241 * (1) "." and ends -- ignore and terminate. 1242 * (2) "./" -- ignore them, eat slash and continue. 1243 * (3) ".." and ends -- strip one and terminate. 1244 * (4) "../" -- strip one, eat slash and continue. 1245 */ 1246 if (c == '.') { 1247 if (!src[1]) { 1248 /* (1) */ 1249 src++; 1250 } else if (is_dir_sep(src[1])) { 1251 /* (2) */ 1252 src += 2; 1253 while (is_dir_sep(*src)) 1254 src++; 1255 continue; 1256 } else if (src[1] == '.') { 1257 if (!src[2]) { 1258 /* (3) */ 1259 src += 2; 1260 goto up_one; 1261 } else if (is_dir_sep(src[2])) { 1262 /* (4) */ 1263 src += 3; 1264 while (is_dir_sep(*src)) 1265 src++; 1266 goto up_one; 1267 } 1268 } 1269 } 1270 1271 /* copy up to the next '/', and eat all '/' */ 1272 while ((c = *src++) != '\0' && !is_dir_sep(c)) 1273 *dst++ = c; 1274 if (is_dir_sep(c)) { 1275 *dst++ = '/'; 1276 while (is_dir_sep(c)) 1277 c = *src++; 1278 src--; 1279 } else if (!c) 1280 break; 1281 continue; 1282 1283 up_one: 1284 /* 1285 * dst0..dst is prefix portion, and dst[-1] is '/'; 1286 * go up one level. 1287 */ 1288 dst--; /* go to trailing '/' */ 1289 if (dst <= dst0) 1290 return -1; 1291 /* Windows: dst[-1] cannot be backslash anymore */ 1292 while (dst0 < dst && dst[-1] != '/') 1293 dst--; 1294 if (prefix_len && *prefix_len > dst - dst0) 1295 *prefix_len = dst - dst0; 1296 } 1297 *dst = '\0'; 1298 return 0; 1299} 1300 1301int normalize_path_copy(char *dst, const char *src) 1302{ 1303 return normalize_path_copy_len(dst, src, NULL); 1304} 1305 1306int strbuf_normalize_path(struct strbuf *src) 1307{ 1308 struct strbuf dst = STRBUF_INIT; 1309 1310 strbuf_grow(&dst, src->len); 1311 if (normalize_path_copy(dst.buf, src->buf) < 0) { 1312 strbuf_release(&dst); 1313 return -1; 1314 } 1315 1316 /* 1317 * normalize_path does not tell us the new length, so we have to 1318 * compute it by looking for the new NUL it placed 1319 */ 1320 strbuf_setlen(&dst, strlen(dst.buf)); 1321 strbuf_swap(src, &dst); 1322 strbuf_release(&dst); 1323 return 0; 1324} 1325 1326/* 1327 * path = Canonical absolute path 1328 * prefixes = string_list containing normalized, absolute paths without 1329 * trailing slashes (except for the root directory, which is denoted by "/"). 1330 * 1331 * Determines, for each path in prefixes, whether the "prefix" 1332 * is an ancestor directory of path. Returns the length of the longest 1333 * ancestor directory, excluding any trailing slashes, or -1 if no prefix 1334 * is an ancestor. (Note that this means 0 is returned if prefixes is 1335 * ["/"].) "/foo" is not considered an ancestor of "/foobar". Directories 1336 * are not considered to be their own ancestors. path must be in a 1337 * canonical form: empty components, or "." or ".." components are not 1338 * allowed. 1339 */ 1340int longest_ancestor_length(const char *path, struct string_list *prefixes) 1341{ 1342 int max_len = -1; 1343 1344 if (!strcmp(path, "/")) 1345 return -1; 1346 1347 for (size_t i = 0; i < prefixes->nr; i++) { 1348 const char *ceil = prefixes->items[i].string; 1349 int len = strlen(ceil); 1350 1351 /* 1352 * For root directories (`/`, `C:/`, `//server/share/`) 1353 * adjust the length to exclude the trailing slash. 1354 */ 1355 if (len > 0 && ceil[len - 1] == '/') 1356 len--; 1357 1358 if (strncmp(path, ceil, len) || 1359 path[len] != '/' || !path[len + 1]) 1360 continue; /* no match */ 1361 1362 if (len > max_len) 1363 max_len = len; 1364 } 1365 1366 return max_len; 1367} 1368 1369/* strip arbitrary amount of directory separators at end of path */ 1370static inline int chomp_trailing_dir_sep(const char *path, int len) 1371{ 1372 while (len && is_dir_sep(path[len - 1])) 1373 len--; 1374 return len; 1375} 1376 1377/* 1378 * If path ends with suffix (complete path components), returns the offset of 1379 * the last character in the path before the suffix (sans trailing directory 1380 * separators), and -1 otherwise. 1381 */ 1382static ssize_t stripped_path_suffix_offset(const char *path, const char *suffix) 1383{ 1384 int path_len = strlen(path), suffix_len = strlen(suffix); 1385 1386 while (suffix_len) { 1387 if (!path_len) 1388 return -1; 1389 1390 if (is_dir_sep(path[path_len - 1])) { 1391 if (!is_dir_sep(suffix[suffix_len - 1])) 1392 return -1; 1393 path_len = chomp_trailing_dir_sep(path, path_len); 1394 suffix_len = chomp_trailing_dir_sep(suffix, suffix_len); 1395 } 1396 else if (path[--path_len] != suffix[--suffix_len]) 1397 return -1; 1398 } 1399 1400 if (path_len && !is_dir_sep(path[path_len - 1])) 1401 return -1; 1402 return chomp_trailing_dir_sep(path, path_len); 1403} 1404 1405/* 1406 * Returns true if the path ends with components, considering only complete path 1407 * components, and false otherwise. 1408 */ 1409int ends_with_path_components(const char *path, const char *components) 1410{ 1411 return stripped_path_suffix_offset(path, components) != -1; 1412} 1413 1414/* 1415 * If path ends with suffix (complete path components), returns the 1416 * part before suffix (sans trailing directory separators). 1417 * Otherwise returns NULL. 1418 */ 1419char *strip_path_suffix(const char *path, const char *suffix) 1420{ 1421 ssize_t offset = stripped_path_suffix_offset(path, suffix); 1422 1423 return offset == -1 ? NULL : xstrndup(path, offset); 1424} 1425 1426int daemon_avoid_alias(const char *p) 1427{ 1428 int sl, ndot; 1429 1430 /* 1431 * This resurrects the belts and suspenders paranoia check by HPA 1432 * done in <435560F7.4080006@zytor.com> thread, now enter_repo() 1433 * does not do getcwd() based path canonicalization. 1434 * 1435 * sl becomes true immediately after seeing '/' and continues to 1436 * be true as long as dots continue after that without intervening 1437 * non-dot character. 1438 */ 1439 if (!p || (*p != '/' && *p != '~')) 1440 return -1; 1441 sl = 1; ndot = 0; 1442 p++; 1443 1444 while (1) { 1445 char ch = *p++; 1446 if (sl) { 1447 if (ch == '.') 1448 ndot++; 1449 else if (ch == '/') { 1450 if (ndot < 3) 1451 /* reject //, /./ and /../ */ 1452 return -1; 1453 ndot = 0; 1454 } 1455 else if (ch == 0) { 1456 if (0 < ndot && ndot < 3) 1457 /* reject /.$ and /..$ */ 1458 return -1; 1459 return 0; 1460 } 1461 else 1462 sl = ndot = 0; 1463 } 1464 else if (ch == 0) 1465 return 0; 1466 else if (ch == '/') { 1467 sl = 1; 1468 ndot = 0; 1469 } 1470 } 1471} 1472 1473/* 1474 * On NTFS, we need to be careful to disallow certain synonyms of the `.git/` 1475 * directory: 1476 * 1477 * - For historical reasons, file names that end in spaces or periods are 1478 * automatically trimmed. Therefore, `.git . . ./` is a valid way to refer 1479 * to `.git/`. 1480 * 1481 * - For other historical reasons, file names that do not conform to the 8.3 1482 * format (up to eight characters for the basename, three for the file 1483 * extension, certain characters not allowed such as `+`, etc) are associated 1484 * with a so-called "short name", at least on the `C:` drive by default. 1485 * Which means that `git~1/` is a valid way to refer to `.git/`. 1486 * 1487 * Note: Technically, `.git/` could receive the short name `git~2` if the 1488 * short name `git~1` were already used. In Git, however, we guarantee that 1489 * `.git` is the first item in a directory, therefore it will be associated 1490 * with the short name `git~1` (unless short names are disabled). 1491 * 1492 * - For yet other historical reasons, NTFS supports so-called "Alternate Data 1493 * Streams", i.e. metadata associated with a given file, referred to via 1494 * `<filename>:<stream-name>:<stream-type>`. There exists a default stream 1495 * type for directories, allowing `.git/` to be accessed via 1496 * `.git::$INDEX_ALLOCATION/`. 1497 * 1498 * When this function returns 1, it indicates that the specified file/directory 1499 * name refers to a `.git` file or directory, or to any of these synonyms, and 1500 * Git should therefore not track it. 1501 * 1502 * For performance reasons, _all_ Alternate Data Streams of `.git/` are 1503 * forbidden, not just `::$INDEX_ALLOCATION`. 1504 * 1505 * This function is intended to be used by `git fsck` even on platforms where 1506 * the backslash is a regular filename character, therefore it needs to handle 1507 * backlash characters in the provided `name` specially: they are interpreted 1508 * as directory separators. 1509 */ 1510int is_ntfs_dotgit(const char *name) 1511{ 1512 char c; 1513 1514 /* 1515 * Note that when we don't find `.git` or `git~1` we end up with `name` 1516 * advanced partway through the string. That's okay, though, as we 1517 * return immediately in those cases, without looking at `name` any 1518 * further. 1519 */ 1520 c = *(name++); 1521 if (c == '.') { 1522 /* .git */ 1523 if (((c = *(name++)) != 'g' && c != 'G') || 1524 ((c = *(name++)) != 'i' && c != 'I') || 1525 ((c = *(name++)) != 't' && c != 'T')) 1526 return 0; 1527 } else if (c == 'g' || c == 'G') { 1528 /* git ~1 */ 1529 if (((c = *(name++)) != 'i' && c != 'I') || 1530 ((c = *(name++)) != 't' && c != 'T') || 1531 *(name++) != '~' || 1532 *(name++) != '1') 1533 return 0; 1534 } else 1535 return 0; 1536 1537 for (;;) { 1538 c = *(name++); 1539 if (!c || is_xplatform_dir_sep(c) || c == ':') 1540 return 1; 1541 if (c != '.' && c != ' ') 1542 return 0; 1543 } 1544} 1545 1546static int is_ntfs_dot_generic(const char *name, 1547 const char *dotgit_name, 1548 size_t len, 1549 const char *dotgit_ntfs_shortname_prefix) 1550{ 1551 int saw_tilde; 1552 size_t i; 1553 1554 if ((name[0] == '.' && !strncasecmp(name + 1, dotgit_name, len))) { 1555 i = len + 1; 1556only_spaces_and_periods: 1557 for (;;) { 1558 char c = name[i++]; 1559 if (!c || c == ':') 1560 return 1; 1561 if (c != ' ' && c != '.') 1562 return 0; 1563 } 1564 } 1565 1566 /* 1567 * Is it a regular NTFS short name, i.e. shortened to 6 characters, 1568 * followed by ~1, ... ~4? 1569 */ 1570 if (!strncasecmp(name, dotgit_name, 6) && name[6] == '~' && 1571 name[7] >= '1' && name[7] <= '4') { 1572 i = 8; 1573 goto only_spaces_and_periods; 1574 } 1575 1576 /* 1577 * Is it a fall-back NTFS short name (for details, see 1578 * https://en.wikipedia.org/wiki/8.3_filename? 1579 */ 1580 for (i = 0, saw_tilde = 0; i < 8; i++) 1581 if (name[i] == '\0') 1582 return 0; 1583 else if (saw_tilde) { 1584 if (name[i] < '0' || name[i] > '9') 1585 return 0; 1586 } else if (name[i] == '~') { 1587 if (name[++i] < '1' || name[i] > '9') 1588 return 0; 1589 saw_tilde = 1; 1590 } else if (i >= 6) 1591 return 0; 1592 else if (name[i] & 0x80) { 1593 /* 1594 * We know our needles contain only ASCII, so we clamp 1595 * here to make the results of tolower() sane. 1596 */ 1597 return 0; 1598 } else if (tolower(name[i]) != dotgit_ntfs_shortname_prefix[i]) 1599 return 0; 1600 1601 goto only_spaces_and_periods; 1602} 1603 1604/* 1605 * Inline helper to make sure compiler resolves strlen() on literals at 1606 * compile time. 1607 */ 1608static inline int is_ntfs_dot_str(const char *name, const char *dotgit_name, 1609 const char *dotgit_ntfs_shortname_prefix) 1610{ 1611 return is_ntfs_dot_generic(name, dotgit_name, strlen(dotgit_name), 1612 dotgit_ntfs_shortname_prefix); 1613} 1614 1615int is_ntfs_dotgitmodules(const char *name) 1616{ 1617 return is_ntfs_dot_str(name, "gitmodules", "gi7eba"); 1618} 1619 1620int is_ntfs_dotgitignore(const char *name) 1621{ 1622 return is_ntfs_dot_str(name, "gitignore", "gi250a"); 1623} 1624 1625int is_ntfs_dotgitattributes(const char *name) 1626{ 1627 return is_ntfs_dot_str(name, "gitattributes", "gi7d29"); 1628} 1629 1630int is_ntfs_dotmailmap(const char *name) 1631{ 1632 return is_ntfs_dot_str(name, "mailmap", "maba30"); 1633} 1634 1635int looks_like_command_line_option(const char *str) 1636{ 1637 return str && str[0] == '-'; 1638} 1639 1640char *xdg_config_home_for(const char *subdir, const char *filename) 1641{ 1642 const char *home, *config_home; 1643 1644 assert(subdir); 1645 assert(filename); 1646 config_home = getenv("XDG_CONFIG_HOME"); 1647 if (config_home && *config_home) 1648 return mkpathdup("%s/%s/%s", config_home, subdir, filename); 1649 1650 home = getenv("HOME"); 1651 if (home) 1652 return mkpathdup("%s/.config/%s/%s", home, subdir, filename); 1653 1654 return NULL; 1655} 1656 1657char *xdg_config_home(const char *filename) 1658{ 1659 return xdg_config_home_for("git", filename); 1660} 1661 1662char *xdg_cache_home(const char *filename) 1663{ 1664 const char *home, *cache_home; 1665 1666 assert(filename); 1667 cache_home = getenv("XDG_CACHE_HOME"); 1668 if (cache_home && *cache_home) 1669 return mkpathdup("%s/git/%s", cache_home, filename); 1670 1671 home = getenv("HOME"); 1672 if (home) 1673 return mkpathdup("%s/.cache/git/%s", home, filename); 1674 return NULL; 1675} 1676 1677REPO_GIT_PATH_FUNC(squash_msg, "SQUASH_MSG") 1678REPO_GIT_PATH_FUNC(merge_msg, "MERGE_MSG") 1679REPO_GIT_PATH_FUNC(merge_rr, "MERGE_RR") 1680REPO_GIT_PATH_FUNC(merge_mode, "MERGE_MODE") 1681REPO_GIT_PATH_FUNC(merge_head, "MERGE_HEAD") 1682REPO_GIT_PATH_FUNC(fetch_head, "FETCH_HEAD") 1683REPO_GIT_PATH_FUNC(shallow, "shallow")