5
static int inside_git_dir = -1;
6
static int inside_work_tree = -1;
7
8
+/*
9
+ * The input parameter must contain an absolute path, and it must already be
10
+ * normalized.
11
+ *
12
+ * Find the part of an absolute path that lies inside the work tree by
13
+ * dereferencing symlinks outside the work tree, for example:
14
+ * /dir1/repo/dir2/file (work tree is /dir1/repo) -> dir2/file
15
+ * /dir/file (work tree is /) -> dir/file
16
+ * /dir/symlink1/symlink2 (symlink1 points to work tree) -> symlink2
17
+ * /dir/repolink/file (repolink points to /dir/repo) -> file
18
+ * /dir/repo (exactly equal to work tree) -> (empty string)
19
+ */
20
+static int abspath_part_inside_repo(char *path)
21
+{
22
+ size_t len;
23
+ size_t wtlen;
24
+ char *path0;
25
+ int off;
26
+ const char *work_tree = get_git_work_tree();
27
+
28
+ if (!work_tree)
29
+ return -1;
30
+ wtlen = strlen(work_tree);
31
+ len = strlen(path);
32
+ off = 0;
33
+
34
+ /* check if work tree is already the prefix */
35
+ if (wtlen <= len && !strncmp(path, work_tree, wtlen)) {
36
+ if (path[wtlen] == '/') {
37
+ memmove(path, path + wtlen + 1, len - wtlen);
38
+ return 0;
39
+ } else if (path[wtlen - 1] == '/' || path[wtlen] == '\0') {
40
+ /* work tree is the root, or the whole path */
41
+ memmove(path, path + wtlen, len - wtlen + 1);
42
+ return 0;
43
+ }
44
+ /* work tree might match beginning of a symlink to work tree */
45
+ off = wtlen;
46
+ }
47
+ path0 = path;
48
+ path += offset_1st_component(path) + off;
49
+
50
+ /* check each '/'-terminated level */
51
+ while (*path) {
52
+ path++;
53
+ if (*path == '/') {
54
+ *path = '\0';
55
+ if (strcmp(real_path(path0), work_tree) == 0) {
56
+ memmove(path0, path + 1, len - (path - path0));
57
+ return 0;
58
+ }
59
+ *path = '/';
60
+ }
61
+ }
62
+
63
+ /* check whole path */
64
+ if (strcmp(real_path(path0), work_tree) == 0) {
65
+ *path0 = '\0';
66
+ return 0;
67
+ }
68
+
69
+ return -1;
70
+}
71
+
72
/*
73
* Normalize "path", prepending the "prefix" for relative paths. If
74
* remaining_prefix is not NULL, return the actual prefix still