1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#include "cache.h"
const char **get_pathspec(const char *prefix, char **pathspec)
{
char *entry = *pathspec;
char **p;
int prefixlen;
if (!prefix) {
char **p;
if (!entry)
return NULL;
p = pathspec;
do {
if (*entry != '.')
continue;
/* fixup ? */
} while ((entry = *++p) != NULL);
return (const char **) pathspec;
}
if (!entry) {
static const char *spec[2];
spec[0] = prefix;
spec[1] = NULL;
return spec;
}
/* Otherwise we have to re-write the entries.. */
prefixlen = strlen(prefix);
p = pathspec;
do {
int speclen, len = prefixlen;
char *n;
for (;;) {
if (!strcmp(entry, ".")) {
entry++;
break;
}
if (!strncmp(entry, "./", 2)) {
entry += 2;
continue;
}
if (!strncmp(entry, "../", 3)) {
do {
if (!len)
die("'%s' is outside repository", *p);
len--;
} while (len && prefix[len-1] != '/');
entry += 3;
continue;
}
break;
}
speclen = strlen(entry);
n = xmalloc(speclen + len + 1);
memcpy(n, prefix, len);
memcpy(n + len, entry, speclen+1);
*p = n;
} while ((entry = *++p) != NULL);
return (const char **) pathspec;
}
const char *setup_git_directory(void)
{
static char cwd[PATH_MAX+1];
int len, offset;
/*
* If GIT_DIR is set explicitly, we're not going
* to do any discovery
*/
if (gitenv(GIT_DIR_ENVIRONMENT))
return NULL;
if (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')
die("Unable to read current working directory");
offset = len = strlen(cwd);
for (;;) {
/*
* We always want to see a .git/HEAD and a .git/refs/
* subdirectory
*/
if (!access(".git/HEAD", R_OK) && !access(".git/refs/", X_OK)) {
/*
* Then we need either a GIT_OBJECT_DIRECTORY define
* or a .git/objects/ directory
*/
if (gitenv(DB_ENVIRONMENT) || !access(".git/objects/", X_OK))
break;
}
chdir("..");
do {
if (!offset)
die("Not a git repository");
} while (cwd[--offset] != '/');
}
if (offset == len)
return NULL;
/* Make "offset" point to past the '/', and add a '/' at the end */
offset++;
cwd[len++] = '/';
cwd[len] = 0;
return cwd + offset;
}
|