diff options
Diffstat (limited to 'src/diff_file.c')
-rw-r--r-- | src/diff_file.c | 89 |
1 files changed, 40 insertions, 49 deletions
diff --git a/src/diff_file.c b/src/diff_file.c index a4c8641bc..f2a1d5099 100644 --- a/src/diff_file.c +++ b/src/diff_file.c @@ -127,57 +127,38 @@ int git_diff_file_content__init_from_diff( return diff_file_content_init_common(fc, &diff->opts); } -int git_diff_file_content__init_from_blob( +int git_diff_file_content__init_from_src( git_diff_file_content *fc, git_repository *repo, const git_diff_options *opts, - const git_blob *blob, + const git_diff_file_content_src *src, git_diff_file *as_file) { memset(fc, 0, sizeof(*fc)); fc->repo = repo; fc->file = as_file; - fc->blob = blob; + fc->blob = src->blob; - if (!blob) { + if (!src->blob && !src->buf) { fc->flags |= GIT_DIFF_FLAG__NO_DATA; } else { fc->flags |= GIT_DIFF_FLAG__LOADED; - fc->file->flags |= GIT_DIFF_FLAG_VALID_OID; - fc->file->size = git_blob_rawsize(blob); + fc->file->flags |= GIT_DIFF_FLAG_VALID_ID; fc->file->mode = GIT_FILEMODE_BLOB; - git_oid_cpy(&fc->file->oid, git_blob_id(blob)); - fc->map.len = (size_t)fc->file->size; - fc->map.data = (char *)git_blob_rawcontent(blob); - } - - return diff_file_content_init_common(fc, opts); -} - -int git_diff_file_content__init_from_raw( - git_diff_file_content *fc, - git_repository *repo, - const git_diff_options *opts, - const char *buf, - size_t buflen, - git_diff_file *as_file) -{ - memset(fc, 0, sizeof(*fc)); - fc->repo = repo; - fc->file = as_file; + if (src->blob) { + fc->file->size = git_blob_rawsize(src->blob); + git_oid_cpy(&fc->file->id, git_blob_id(src->blob)); - if (!buf) { - fc->flags |= GIT_DIFF_FLAG__NO_DATA; - } else { - fc->flags |= GIT_DIFF_FLAG__LOADED; - fc->file->flags |= GIT_DIFF_FLAG_VALID_OID; - fc->file->size = buflen; - fc->file->mode = GIT_FILEMODE_BLOB; - git_odb_hash(&fc->file->oid, buf, buflen, GIT_OBJ_BLOB); + fc->map.len = (size_t)fc->file->size; + fc->map.data = (char *)git_blob_rawcontent(src->blob); + } else { + fc->file->size = src->buflen; + git_odb_hash(&fc->file->id, src->buf, src->buflen, GIT_OBJ_BLOB); - fc->map.len = buflen; - fc->map.data = (char *)buf; + fc->map.len = src->buflen; + fc->map.data = (char *)src->buf; + } } return diff_file_content_init_common(fc, opts); @@ -196,28 +177,36 @@ static int diff_file_content_commit_to_str( unsigned int sm_status = 0; const git_oid *sm_head; - if ((error = git_submodule_lookup(&sm, fc->repo, fc->file->path)) < 0 || - (error = git_submodule_status(&sm_status, sm)) < 0) { + if ((error = git_submodule_lookup(&sm, fc->repo, fc->file->path)) < 0) { /* GIT_EEXISTS means a "submodule" that has not been git added */ - if (error == GIT_EEXISTS) + if (error == GIT_EEXISTS) { + giterr_clear(); error = 0; + } + return error; + } + + if ((error = git_submodule_status(&sm_status, sm)) < 0) { + git_submodule_free(sm); return error; } /* update OID if we didn't have it previously */ - if ((fc->file->flags & GIT_DIFF_FLAG_VALID_OID) == 0 && + if ((fc->file->flags & GIT_DIFF_FLAG_VALID_ID) == 0 && ((sm_head = git_submodule_wd_id(sm)) != NULL || (sm_head = git_submodule_head_id(sm)) != NULL)) { - git_oid_cpy(&fc->file->oid, sm_head); - fc->file->flags |= GIT_DIFF_FLAG_VALID_OID; + git_oid_cpy(&fc->file->id, sm_head); + fc->file->flags |= GIT_DIFF_FLAG_VALID_ID; } if (GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status)) status = "-dirty"; + + git_submodule_free(sm); } - git_oid_tostr(oid, sizeof(oid), &fc->file->oid); + git_oid_tostr(oid, sizeof(oid), &fc->file->id); if (git_buf_printf(&content, "Subproject commit %s%s\n", oid, status) < 0) return -1; @@ -233,7 +222,7 @@ static int diff_file_content_load_blob(git_diff_file_content *fc) int error = 0; git_odb_object *odb_obj = NULL; - if (git_oid_iszero(&fc->file->oid)) + if (git_oid_iszero(&fc->file->id)) return 0; if (fc->file->mode == GIT_FILEMODE_COMMIT) @@ -255,7 +244,7 @@ static int diff_file_content_load_blob(git_diff_file_content *fc) git_odb_object_free(odb_obj); } else { error = git_blob_lookup( - (git_blob **)&fc->blob, fc->repo, &fc->file->oid); + (git_blob **)&fc->blob, fc->repo, &fc->file->id); } if (!error) { @@ -311,7 +300,8 @@ static int diff_file_content_load_workdir_file( goto cleanup; if ((error = git_filter_list_load( - &fl, fc->repo, NULL, fc->file->path, GIT_FILTER_TO_ODB)) < 0) + &fl, fc->repo, NULL, fc->file->path, + GIT_FILTER_TO_ODB, GIT_FILTER_OPT_ALLOW_UNSAFE)) < 0) goto cleanup; /* if there are no filters, try to mmap the file */ @@ -331,7 +321,8 @@ static int diff_file_content_load_workdir_file( error = git_filter_list_apply_to_data(&out, fl, &raw); - git_buf_free(&raw); + if (out.ptr != raw.ptr) + git_buf_free(&raw); if (!error) { fc->map.len = out.size; @@ -368,10 +359,10 @@ static int diff_file_content_load_workdir(git_diff_file_content *fc) error = diff_file_content_load_workdir_file(fc, &path); /* once data is loaded, update OID if we didn't have it previously */ - if (!error && (fc->file->flags & GIT_DIFF_FLAG_VALID_OID) == 0) { + if (!error && (fc->file->flags & GIT_DIFF_FLAG_VALID_ID) == 0) { error = git_odb_hash( - &fc->file->oid, fc->map.data, fc->map.len, GIT_OBJ_BLOB); - fc->file->flags |= GIT_DIFF_FLAG_VALID_OID; + &fc->file->id, fc->map.data, fc->map.len, GIT_OBJ_BLOB); + fc->file->flags |= GIT_DIFF_FLAG_VALID_ID; } git_buf_free(&path); |