checkout: maintain temporary buffer for filters Let the filters use the checkout data's temporary buffer, instead of having to allocate new buffers each time.
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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
diff --git a/src/checkout.c b/src/checkout.c
index 623ac92..35129d7 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -1444,6 +1444,9 @@ static int blob_content_to_file(
GIT_FILTER_TO_WORKTREE, GIT_FILTER_OPT_DEFAULT)))
return error;
+ if (fl)
+ git_filter_list__set_temp_buf(fl, &data->tmp);
+
/* setup the writer */
memset(&writer, 0, sizeof(struct checkout_stream));
writer.base.write = checkout_stream_write;
diff --git a/src/filter.c b/src/filter.c
index d930b23..2cae24e 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -34,6 +34,7 @@ typedef struct {
struct git_filter_list {
git_array_t(git_filter_entry) filters;
git_filter_source source;
+ git_buf *temp_buf;
char path[GIT_FLEX_ARRAY];
};
@@ -522,7 +523,6 @@ int git_filter_list__load_with_attr_session(
fe = git_array_alloc(fl->filters);
GITERR_CHECK_ALLOC(fe);
fe->filter = fdef->filter;
- fe->stream = NULL;
fe->payload = payload;
}
}
@@ -549,6 +549,11 @@ int git_filter_list_load(
filters, repo, NULL, blob, path, mode, options);
}
+void git_filter_list__set_temp_buf(git_filter_list *fl, git_buf *temp_buf)
+{
+ fl->temp_buf = temp_buf;
+}
+
void git_filter_list_free(git_filter_list *fl)
{
uint32_t i;
@@ -591,7 +596,6 @@ int git_filter_list_push(
fe = git_array_alloc(fl->filters);
GITERR_CHECK_ALLOC(fe);
fe->filter = filter;
- fe->stream = NULL;
fe->payload = payload;
return 0;
@@ -745,7 +749,8 @@ struct proxy_stream {
const git_filter_source *source;
void **payload;
git_buf input;
- git_buf output;
+ git_buf temp_buf;
+ git_buf *output;
git_filter_stream *target;
};
@@ -769,15 +774,15 @@ static int proxy_stream_close(git_filter_stream *s)
error = proxy_stream->filter->apply(
proxy_stream->filter,
proxy_stream->payload,
- &proxy_stream->output,
+ proxy_stream->output,
&proxy_stream->input,
proxy_stream->source);
if (error == GIT_PASSTHROUGH) {
writebuf = &proxy_stream->input;
} else if (error == 0) {
- git_buf_sanitize(&proxy_stream->output);
- writebuf = &proxy_stream->output;
+ git_buf_sanitize(proxy_stream->output);
+ writebuf = proxy_stream->output;
} else {
return error;
}
@@ -795,13 +800,14 @@ static void proxy_stream_free(git_filter_stream *s)
assert(proxy_stream);
git_buf_free(&proxy_stream->input);
- git_buf_free(&proxy_stream->output);
+ git_buf_free(&proxy_stream->temp_buf);
git__free(proxy_stream);
}
static int proxy_stream_init(
git_filter_stream **out,
git_filter *filter,
+ git_buf *temp_buf,
void **payload,
const git_filter_source *source,
git_filter_stream *target)
@@ -816,6 +822,7 @@ static int proxy_stream_init(
proxy_stream->payload = payload;
proxy_stream->source = source;
proxy_stream->target = target;
+ proxy_stream->output = temp_buf ? temp_buf : &proxy_stream->temp_buf;
*out = (git_filter_stream *)proxy_stream;
return 0;
@@ -844,18 +851,20 @@ static int stream_list_init(
git_array_size(filters->filters) - 1 - i : i;
git_filter_entry *fe = git_array_get(filters->filters, filter_idx);
git_filter_stream *filter_stream;
- git_filter_stream_fn stream_init;
assert(fe->filter->stream || fe->filter->apply);
/* If necessary, create a stream that proxies the traditional
* application.
*/
- stream_init = fe->filter->stream ?
- fe->filter->stream : proxy_stream_init;
-
- error = stream_init(&filter_stream, fe->filter,
+ if (fe->filter->stream)
+ error = fe->filter->stream(&filter_stream, fe->filter,
&fe->payload, &filters->source, last_stream);
+ else
+ /* Create a stream that proxies the one-shot apply */
+ error = proxy_stream_init(&filter_stream, fe->filter,
+ filters->temp_buf, &fe->payload, &filters->source,
+ last_stream);
if (error < 0)
return error;
diff --git a/src/filter.h b/src/filter.h
index 390ffeb..53f3afd 100644
--- a/src/filter.h
+++ b/src/filter.h
@@ -24,6 +24,9 @@ typedef enum {
GIT_CRLF_AUTO,
} git_crlf_t;
+extern void git_filter_list__set_temp_buf(
+ git_filter_list *fl, git_buf *temp_buf);
+
extern void git_filter_free(git_filter *filter);
extern int git_filter_list__load_with_attr_session(