]>
Commit | Line | Data |
---|---|---|
18125644 LH |
1 | #include "cache.h" |
2 | #include "commit.h" | |
3 | #include "attr.h" | |
4 | ||
5 | static void format_subst(const struct commit *commit, | |
6 | const char *src, size_t len, | |
7 | struct strbuf *buf) | |
8 | { | |
9 | char *to_free = NULL; | |
10 | struct strbuf fmt; | |
11 | ||
12 | if (src == buf->buf) | |
13 | to_free = strbuf_detach(buf, NULL); | |
14 | strbuf_init(&fmt, 0); | |
15 | for (;;) { | |
16 | const char *b, *c; | |
17 | ||
18 | b = memmem(src, len, "$Format:", 8); | |
19 | if (!b || src + len < b + 9) | |
20 | break; | |
21 | c = memchr(b + 8, '$', len - 8); | |
22 | if (!c) | |
23 | break; | |
24 | ||
25 | strbuf_reset(&fmt); | |
26 | strbuf_add(&fmt, b + 8, c - b - 8); | |
27 | ||
28 | strbuf_add(buf, src, b - src); | |
29 | format_commit_message(commit, fmt.buf, buf); | |
30 | len -= c + 1 - src; | |
31 | src = c + 1; | |
32 | } | |
33 | strbuf_add(buf, src, len); | |
34 | strbuf_release(&fmt); | |
35 | free(to_free); | |
36 | } | |
37 | ||
38 | static int convert_to_archive(const char *path, | |
39 | const void *src, size_t len, | |
40 | struct strbuf *buf, | |
41 | const struct commit *commit) | |
42 | { | |
43 | static struct git_attr *attr_export_subst; | |
44 | struct git_attr_check check[1]; | |
45 | ||
46 | if (!commit) | |
47 | return 0; | |
48 | ||
49 | if (!attr_export_subst) | |
50 | attr_export_subst = git_attr("export-subst", 12); | |
51 | ||
52 | check[0].attr = attr_export_subst; | |
53 | if (git_checkattr(path, ARRAY_SIZE(check), check)) | |
54 | return 0; | |
55 | if (!ATTR_TRUE(check[0].value)) | |
56 | return 0; | |
57 | ||
58 | format_subst(commit, src, len, buf); | |
59 | return 1; | |
60 | } | |
61 | ||
62 | void *sha1_file_to_archive(const char *path, const unsigned char *sha1, | |
63 | unsigned int mode, enum object_type *type, | |
64 | unsigned long *sizep, | |
65 | const struct commit *commit) | |
66 | { | |
67 | void *buffer; | |
68 | ||
69 | buffer = read_sha1_file(sha1, type, sizep); | |
70 | if (buffer && S_ISREG(mode)) { | |
71 | struct strbuf buf; | |
72 | size_t size = 0; | |
73 | ||
74 | strbuf_init(&buf, 0); | |
75 | strbuf_attach(&buf, buffer, *sizep, *sizep + 1); | |
76 | convert_to_working_tree(path, buf.buf, buf.len, &buf); | |
77 | convert_to_archive(path, buf.buf, buf.len, &buf, commit); | |
78 | buffer = strbuf_detach(&buf, &size); | |
79 | *sizep = size; | |
80 | } | |
81 | ||
82 | return buffer; | |
83 | } | |
84 |