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