diff options
author | Vicent Martà <vicent@github.com> | 2012-09-13 09:24:12 -0700 |
---|---|---|
committer | Vicent Martà <vicent@github.com> | 2012-09-13 09:24:12 -0700 |
commit | 9be2261eaae74552aaa9d568e663292f4382e141 (patch) | |
tree | fe9711595f4fe21e86989efcbd374ddb7bb5d157 /src | |
parent | 45c4697c48e50951a383f93d63ad0c192915df8c (diff) | |
parent | a13fb55afdbf9d74c3d4b6aa76476a005da49486 (diff) | |
download | libgit2-9be2261eaae74552aaa9d568e663292f4382e141.tar.gz |
Merge pull request #927 from arrbee/hashfile-with-filters
Add git_repository_hashfile to hash with filters
Diffstat (limited to 'src')
-rw-r--r-- | src/crlf.c | 5 | ||||
-rw-r--r-- | src/odb.c | 5 | ||||
-rw-r--r-- | src/repository.c | 70 |
3 files changed, 78 insertions, 2 deletions
diff --git a/src/crlf.c b/src/crlf.c index 1b6898ba6..5e86b4eb6 100644 --- a/src/crlf.c +++ b/src/crlf.c @@ -263,8 +263,9 @@ static int crlf_apply_to_workdir(git_filter *self, git_buf *dest, const git_buf return convert_line_endings(dest, source, workdir_ending); } -static int find_and_add_filter(git_vector *filters, git_repository *repo, const char *path, - int (*apply)(struct git_filter *self, git_buf *dest, const git_buf *source)) +static int find_and_add_filter( + git_vector *filters, git_repository *repo, const char *path, + int (*apply)(struct git_filter *self, git_buf *dest, const git_buf *source)) { struct crlf_attrs ca; struct crlf_filter *filter; @@ -117,6 +117,11 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type) git_hash_ctx *ctx; ssize_t read_len = -1; + if (!git_object_typeisloose(type)) { + giterr_set(GITERR_INVALID, "Invalid object type for hash"); + return -1; + } + hdr_len = format_object_header(hdr, sizeof(hdr), size, type); ctx = git_hash_new_ctx(); diff --git a/src/repository.c b/src/repository.c index b9d180da4..bcc6b1503 100644 --- a/src/repository.c +++ b/src/repository.c @@ -17,6 +17,8 @@ #include "fileops.h" #include "config.h" #include "refs.h" +#include "filter.h" +#include "odb.h" #define GIT_FILE_CONTENT_PREFIX "gitdir:" @@ -1372,3 +1374,71 @@ int git_repository_message_remove(git_repository *repo) return error; } + +int git_repository_hashfile( + git_oid *out, + git_repository *repo, + const char *path, + git_otype type, + const char *as_path) +{ + int error; + git_vector filters = GIT_VECTOR_INIT; + git_file fd; + git_off_t len; + git_buf full_path = GIT_BUF_INIT; + + assert(out && path && repo); /* as_path can be NULL */ + + /* At some point, it would be nice if repo could be NULL to just + * apply filter rules defined in system and global files, but for + * now that is not possible because git_filters_load() needs it. + */ + + error = git_path_join_unrooted( + &full_path, path, repo ? git_repository_workdir(repo) : NULL, NULL); + if (error < 0) + return error; + + if (!as_path) + as_path = path; + + /* passing empty string for "as_path" indicated --no-filters */ + if (strlen(as_path) > 0) { + error = git_filters_load(&filters, repo, as_path, GIT_FILTER_TO_ODB); + if (error < 0) + return error; + } else { + error = 0; + } + + /* at this point, error is a count of the number of loaded filters */ + + fd = git_futils_open_ro(full_path.ptr); + if (fd < 0) { + error = fd; + goto cleanup; + } + + len = git_futils_filesize(fd); + if (len < 0) { + error = len; + goto cleanup; + } + + if (!git__is_sizet(len)) { + giterr_set(GITERR_OS, "File size overflow for 32-bit systems"); + error = -1; + goto cleanup; + } + + error = git_odb__hashfd_filtered(out, fd, len, type, &filters); + +cleanup: + p_close(fd); + git_filters_free(&filters); + git_buf_free(&full_path); + + return error; +} + |