diff options
| author | nulltoken <emeric.fermas@gmail.com> | 2012-09-17 10:38:57 +0200 |
|---|---|---|
| committer | nulltoken <emeric.fermas@gmail.com> | 2012-09-17 10:48:36 +0200 |
| commit | 5e4cb4f4da0baef99683be95cb5eeb5288d8ba84 (patch) | |
| tree | 558ccfa1cb25ec06bdf4b5cc51ac8330fd8f4282 /src/checkout.c | |
| parent | 44af67a8b6679ac33c3407d45fee042178d97e76 (diff) | |
| download | libgit2-5e4cb4f4da0baef99683be95cb5eeb5288d8ba84.tar.gz | |
checkout : reduce memory usage when not filtering
Diffstat (limited to 'src/checkout.c')
| -rw-r--r-- | src/checkout.c | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/src/checkout.c b/src/checkout.c index c39bccbaa..30799b608 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -59,28 +59,50 @@ static int blob_content_to_file( unsigned int entry_filemode, git_checkout_opts *opts) { - int retcode; - git_buf content = GIT_BUF_INIT; - int file_mode = opts->file_mode; + int error, nb_filters = 0, file_mode = opts->file_mode; + bool dont_free_filtered = false; + git_buf unfiltered = GIT_BUF_INIT, filtered = GIT_BUF_INIT; + git_vector filters = GIT_VECTOR_INIT; + + if (opts->disable_filters || + (nb_filters = git_filters_load( + &filters, + git_object_owner((git_object *)blob), + path, + GIT_FILTER_TO_WORKTREE)) == 0) { + + /* Create a fake git_buf from the blob raw data... */ + filtered.ptr = blob->odb_object->raw.data; + filtered.size = blob->odb_object->raw.len; + + /* ... and make sure it doesn't get unexpectedly freed */ + dont_free_filtered = true; + } - /* Allow disabling of filters */ - if (opts->disable_filters) - retcode = git_blob__getbuf(&content, blob); - else - retcode = git_filter_blob_content(&content, blob, path); + if (nb_filters < 0) + return nb_filters; - if (retcode < 0) - goto cleanup; + if (nb_filters > 0) { + if (git_blob__getbuf(&unfiltered, blob) < 0) + goto cleanup; + + if ((error = git_filters_apply(&filtered, &unfiltered, &filters)) < 0) + goto cleanup; + } /* Allow overriding of file mode */ if (!file_mode) file_mode = entry_filemode; - retcode = buffer_to_file(&content, path, opts->dir_mode, opts->file_open_flags, file_mode); + error = buffer_to_file(&filtered, path, opts->dir_mode, opts->file_open_flags, file_mode); cleanup: - git_buf_free(&content); - return retcode; + git_filters_free(&filters); + git_buf_free(&unfiltered); + if (!dont_free_filtered) + git_buf_free(&filtered); + + return error; } static int blob_content_to_link(git_blob *blob, const char *path, bool can_symlink) |
