summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2015-02-17 20:25:31 +0000
committerEdward Thomson <ethomson@microsoft.com>2015-02-17 16:03:45 -0500
commit646364e780c65b1af2e28a7bdeabd22b67816454 (patch)
tree41788ffd76de01e2f995a00bd127c35f5aa73109
parente78f5c9f4282319cf8e1afc8631e6259e91653a6 (diff)
downloadlibgit2-646364e780c65b1af2e28a7bdeabd22b67816454.tar.gz
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.
-rw-r--r--src/checkout.c3
-rw-r--r--src/filter.c33
-rw-r--r--src/filter.h3
3 files changed, 27 insertions, 12 deletions
diff --git a/src/checkout.c b/src/checkout.c
index 623ac92a1..35129d771 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 d930b2399..2cae24e20 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 390ffebad..53f3afdbb 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(