diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2023-04-07 15:28:58 +0100 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2023-04-10 14:21:16 +0100 |
commit | db2a794dda2b6f92291b3758507f863f39314c72 (patch) | |
tree | 53c5b2d77c6c38cf26fecc90e91809df0397fa46 | |
parent | 7f70484799df14dbc666b3c395ded690d1a5a402 (diff) | |
download | libgit2-db2a794dda2b6f92291b3758507f863f39314c72.tar.gz |
diff: parse patches with sha256
-rw-r--r-- | examples/diff.c | 8 | ||||
-rw-r--r-- | include/git2/diff.h | 44 | ||||
-rw-r--r-- | src/libgit2/diff.c | 23 | ||||
-rw-r--r-- | src/libgit2/diff.h | 12 | ||||
-rw-r--r-- | src/libgit2/diff_file.c | 12 | ||||
-rw-r--r-- | src/libgit2/diff_generate.c | 51 | ||||
-rw-r--r-- | src/libgit2/diff_parse.c | 24 | ||||
-rw-r--r-- | src/libgit2/diff_print.c | 33 | ||||
-rw-r--r-- | src/libgit2/diff_tform.c | 8 | ||||
-rw-r--r-- | src/libgit2/patch.h | 8 | ||||
-rw-r--r-- | src/libgit2/patch_generate.c | 29 | ||||
-rw-r--r-- | src/libgit2/patch_parse.c | 24 | ||||
-rw-r--r-- | tests/libgit2/apply/apply_helpers.h | 1 | ||||
-rw-r--r-- | tests/libgit2/apply/both.c | 52 | ||||
-rw-r--r-- | tests/libgit2/apply/callbacks.c | 6 | ||||
-rw-r--r-- | tests/libgit2/apply/check.c | 6 | ||||
-rw-r--r-- | tests/libgit2/apply/index.c | 16 | ||||
-rw-r--r-- | tests/libgit2/apply/tree.c | 2 | ||||
-rw-r--r-- | tests/libgit2/apply/workdir.c | 20 | ||||
-rw-r--r-- | tests/libgit2/diff/diff_helpers.c | 17 | ||||
-rw-r--r-- | tests/libgit2/diff/diff_helpers.h | 4 | ||||
-rw-r--r-- | tests/libgit2/diff/parse.c | 40 | ||||
-rw-r--r-- | tests/libgit2/diff/patchid.c | 3 | ||||
-rw-r--r-- | tests/libgit2/diff/stats.c | 3 |
24 files changed, 307 insertions, 139 deletions
diff --git a/examples/diff.c b/examples/diff.c index a9fb5d442..80c5200e9 100644 --- a/examples/diff.c +++ b/examples/diff.c @@ -188,9 +188,17 @@ static void compute_diff_no_index(git_diff **diff, struct diff_options *o) { check_lg2( git_patch_to_buf(&buf, patch), "patch to buf", NULL); + +#ifdef GIT_EXPERIMENTAL_SHA256 + check_lg2( + git_diff_from_buffer(diff, buf.ptr, buf.size, NULL), + "diff from patch", NULL); +#else check_lg2( git_diff_from_buffer(diff, buf.ptr, buf.size), "diff from patch", NULL); +#endif + git_patch_free(patch); git_buf_dispose(&buf); free(file1_str); diff --git a/include/git2/diff.h b/include/git2/diff.h index 850d215a6..384b6e745 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -422,6 +422,22 @@ typedef struct { uint32_t interhunk_lines; /** + * The object ID type to emit in diffs; this is used by functions + * that operate without a repository - namely `git_diff_buffers`, + * or `git_diff_blobs` and `git_diff_blob_to_buffer` when one blob + * is `NULL`. + * + * This may be omitted (set to `0`). If a repository is available, + * the object ID format of the repository will be used. If no + * repository is available then the default is `GIT_OID_SHA`. + * + * If this is specified and a repository is available, then the + * specified `oid_type` must match the repository's object ID + * format. + */ + git_oid_t oid_type; + + /** * The abbreviation length to use when formatting object ids. * Defaults to the value of 'core.abbrev' from the config, or 7 if unset. */ @@ -1153,9 +1169,8 @@ GIT_EXTERN(int) git_diff_to_buf( /**@}*/ - /* - * Misc + * Low-level file comparison, invoking callbacks per difference. */ /** @@ -1271,6 +1286,25 @@ GIT_EXTERN(int) git_diff_buffers( git_diff_line_cb line_cb, void *payload); +/* Patch file parsing. */ + +/** + * Options for parsing a diff / patch file. + */ +typedef struct { + unsigned int version; + git_oid_t oid_type; +} git_diff_parse_options; + +/* The current version of the diff parse options structure */ +#define GIT_DIFF_PARSE_OPTIONS_VERSION 1 + +/* Stack initializer for diff parse options. Alternatively use + * `git_diff_parse_options_init` programmatic initialization. + */ +#define GIT_DIFF_PARSE_OPTIONS_INIT \ + { GIT_DIFF_PARSE_OPTIONS_VERSION, GIT_OID_DEFAULT } + /** * Read the contents of a git patch file into a `git_diff` object. * @@ -1293,7 +1327,11 @@ GIT_EXTERN(int) git_diff_buffers( GIT_EXTERN(int) git_diff_from_buffer( git_diff **out, const char *content, - size_t content_len); + size_t content_len +#ifdef GIT_EXPERIMENTAL_SHA256 + , git_diff_parse_options *opts +#endif + ); /** * This is an opaque structure which is allocated by `git_diff_get_stats`. diff --git a/src/libgit2/diff.c b/src/libgit2/diff.c index 20a18c4b9..db12ccd68 100644 --- a/src/libgit2/diff.c +++ b/src/libgit2/diff.c @@ -19,8 +19,10 @@ #include "git2/email.h" struct patch_id_args { + git_diff *diff; git_hash_ctx ctx; git_oid result; + git_oid_t oid_type; int first_file; }; @@ -280,17 +282,19 @@ int git_diff_find_options_init( return 0; } -static int flush_hunk(git_oid *result, git_hash_ctx *ctx) +static int flush_hunk(git_oid *result, struct patch_id_args *args) { + git_hash_ctx *ctx = &args->ctx; git_oid hash; unsigned short carry = 0; - int error, i; + size_t i; + int error; if ((error = git_hash_final(hash.id, ctx)) < 0 || (error = git_hash_init(ctx)) < 0) return error; - for (i = 0; i < GIT_OID_SHA1_SIZE; i++) { + for (i = 0; i < git_oid_size(args->oid_type); i++) { carry += result->id[i] + hash.id[i]; result->id[i] = (unsigned char)carry; carry >>= 8; @@ -338,7 +342,7 @@ static int diff_patchid_print_callback_to_buf( if (line->origin == GIT_DIFF_LINE_FILE_HDR && !args->first_file && - (error = flush_hunk(&args->result, &args->ctx) < 0)) + (error = flush_hunk(&args->result, args) < 0)) goto out; if ((error = git_hash_update(&args->ctx, buf.ptr, buf.size)) < 0) @@ -362,14 +366,19 @@ int git_diff_patchid_options_init(git_diff_patchid_options *opts, unsigned int v int git_diff_patchid(git_oid *out, git_diff *diff, git_diff_patchid_options *opts) { struct patch_id_args args; + git_hash_algorithm_t algorithm; int error; GIT_ERROR_CHECK_VERSION( opts, GIT_DIFF_PATCHID_OPTIONS_VERSION, "git_diff_patchid_options"); + algorithm = git_oid_algorithm(diff->opts.oid_type); + memset(&args, 0, sizeof(args)); + args.diff = diff; args.first_file = 1; - if ((error = git_hash_ctx_init(&args.ctx, GIT_HASH_ALGORITHM_SHA1)) < 0) + args.oid_type = diff->opts.oid_type; + if ((error = git_hash_ctx_init(&args.ctx, algorithm)) < 0) goto out; if ((error = git_diff_print(diff, @@ -378,11 +387,11 @@ int git_diff_patchid(git_oid *out, git_diff *diff, git_diff_patchid_options *opt &args)) < 0) goto out; - if ((error = (flush_hunk(&args.result, &args.ctx))) < 0) + if ((error = (flush_hunk(&args.result, &args))) < 0) goto out; #ifdef GIT_EXPERIMENTAL_SHA256 - args.result.type = GIT_OID_SHA1; + args.result.type = diff->opts.oid_type; #endif git_oid_cpy(out, &args.result); diff --git a/src/libgit2/diff.h b/src/libgit2/diff.h index 2cc35e65b..f21b27645 100644 --- a/src/libgit2/diff.h +++ b/src/libgit2/diff.h @@ -30,15 +30,15 @@ typedef enum { } git_diff_origin_t; struct git_diff { - git_refcount rc; + git_refcount rc; git_repository *repo; - git_attr_session attrsession; + git_attr_session attrsession; git_diff_origin_t type; - git_diff_options opts; - git_vector deltas; /* vector of git_diff_delta */ + git_diff_options opts; + git_vector deltas; /* vector of git_diff_delta */ git_pool pool; - git_iterator_t old_src; - git_iterator_t new_src; + git_iterator_t old_src; + git_iterator_t new_src; git_diff_perfdata perf; int (*strcomp)(const char *, const char *); diff --git a/src/libgit2/diff_file.c b/src/libgit2/diff_file.c index c2d08675a..6b7f9590c 100644 --- a/src/libgit2/diff_file.c +++ b/src/libgit2/diff_file.c @@ -144,7 +144,7 @@ int git_diff_file_content__init_from_src( if (!src->blob && !src->buf) { fc->flags |= GIT_DIFF_FLAG__NO_DATA; - git_oid_clear(&fc->file->id, GIT_OID_SHA1); + git_oid_clear(&fc->file->id, opts->oid_type); } else { fc->flags |= GIT_DIFF_FLAG__LOADED; fc->file->flags |= GIT_DIFF_FLAG_VALID_ID; @@ -154,7 +154,7 @@ int git_diff_file_content__init_from_src( git_blob_dup((git_blob **)&fc->blob, (git_blob *) src->blob); fc->file->size = git_blob_rawsize(src->blob); git_oid_cpy(&fc->file->id, git_blob_id(src->blob)); - fc->file->id_abbrev = GIT_OID_SHA1_HEXSIZE; + fc->file->id_abbrev = (uint16_t)git_oid_hexsize(repo->oid_type); fc->map.len = (size_t)fc->file->size; fc->map.data = (char *)git_blob_rawcontent(src->blob); @@ -162,10 +162,10 @@ int git_diff_file_content__init_from_src( fc->flags |= GIT_DIFF_FLAG__FREE_BLOB; } else { int error; - if ((error = git_odb__hash(&fc->file->id, src->buf, src->buflen, GIT_OBJECT_BLOB, GIT_OID_SHA1)) < 0) + if ((error = git_odb__hash(&fc->file->id, src->buf, src->buflen, GIT_OBJECT_BLOB, opts->oid_type)) < 0) return error; fc->file->size = src->buflen; - fc->file->id_abbrev = GIT_OID_SHA1_HEXSIZE; + fc->file->id_abbrev = (uint16_t)git_oid_hexsize(opts->oid_type); fc->map.len = src->buflen; fc->map.data = (char *)src->buf; @@ -178,7 +178,7 @@ int git_diff_file_content__init_from_src( static int diff_file_content_commit_to_str( git_diff_file_content *fc, bool check_status) { - char oid[GIT_OID_SHA1_HEXSIZE+1]; + char oid[GIT_OID_MAX_HEXSIZE+1]; git_str content = GIT_STR_INIT; const char *status = ""; @@ -420,7 +420,7 @@ static int diff_file_content_load_workdir( if (!error && (fc->file->flags & GIT_DIFF_FLAG_VALID_ID) == 0) { error = git_odb__hash( &fc->file->id, fc->map.data, fc->map.len, - GIT_OBJECT_BLOB, GIT_OID_SHA1); + GIT_OBJECT_BLOB, diff_opts->oid_type); fc->file->flags |= GIT_DIFF_FLAG_VALID_ID; } diff --git a/src/libgit2/diff_generate.c b/src/libgit2/diff_generate.c index a88ce8c32..78fe510e7 100644 --- a/src/libgit2/diff_generate.c +++ b/src/libgit2/diff_generate.c @@ -61,8 +61,8 @@ static git_diff_delta *diff_delta__alloc( } delta->status = status; - git_oid_clear(&delta->old_file.id, GIT_OID_SHA1); - git_oid_clear(&delta->new_file.id, GIT_OID_SHA1); + git_oid_clear(&delta->old_file.id, diff->base.opts.oid_type); + git_oid_clear(&delta->new_file.id, diff->base.opts.oid_type); return delta; } @@ -149,10 +149,13 @@ static int diff_delta__from_one( const git_index_entry *entry = nitem; bool has_old = false; git_diff_delta *delta; + git_oid_t oid_type; const char *matched_pathspec; GIT_ASSERT_ARG((oitem != NULL) ^ (nitem != NULL)); + oid_type = diff->base.opts.oid_type; + if (oitem) { entry = oitem; has_old = true; @@ -186,20 +189,23 @@ static int diff_delta__from_one( GIT_ASSERT(status != GIT_DELTA_MODIFIED); delta->nfiles = 1; + git_oid_clear(&delta->old_file.id, diff->base.opts.oid_type); + git_oid_clear(&delta->new_file.id, diff->base.opts.oid_type); + if (has_old) { delta->old_file.mode = entry->mode; delta->old_file.size = entry->file_size; delta->old_file.flags |= GIT_DIFF_FLAG_EXISTS; git_oid_cpy(&delta->old_file.id, &entry->id); - git_oid_clear(&delta->new_file.id, GIT_OID_SHA1); - delta->old_file.id_abbrev = GIT_OID_SHA1_HEXSIZE; + git_oid_clear(&delta->new_file.id, oid_type); + delta->old_file.id_abbrev = (uint16_t)git_oid_hexsize(oid_type); } else /* ADDED, IGNORED, UNTRACKED */ { delta->new_file.mode = entry->mode; delta->new_file.size = entry->file_size; delta->new_file.flags |= GIT_DIFF_FLAG_EXISTS; - git_oid_clear(&delta->old_file.id, GIT_OID_SHA1); + git_oid_clear(&delta->old_file.id, oid_type); git_oid_cpy(&delta->new_file.id, &entry->id); - delta->new_file.id_abbrev = GIT_OID_SHA1_HEXSIZE; + delta->new_file.id_abbrev = (uint16_t)git_oid_hexsize(oid_type); } delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID; @@ -225,6 +231,9 @@ static int diff_delta__from_two( const git_oid *old_id = &old_entry->id; git_diff_delta *delta; const char *canonical_path = old_entry->path; + git_oid_t oid_type; + + oid_type = diff->base.opts.oid_type; if (status == GIT_DELTA_UNMODIFIED && DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_UNMODIFIED)) @@ -254,14 +263,14 @@ static int diff_delta__from_two( delta->old_file.size = old_entry->file_size; delta->old_file.mode = old_mode; git_oid_cpy(&delta->old_file.id, old_id); - delta->old_file.id_abbrev = GIT_OID_SHA1_HEXSIZE; + delta->old_file.id_abbrev = (uint16_t)git_oid_hexsize(oid_type); delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID | GIT_DIFF_FLAG_EXISTS; } if (!git_index_entry_is_conflict(new_entry)) { git_oid_cpy(&delta->new_file.id, new_id); - delta->new_file.id_abbrev = GIT_OID_SHA1_HEXSIZE; + delta->new_file.id_abbrev = (uint16_t)git_oid_hexsize(oid_type); delta->new_file.size = new_entry->file_size; delta->new_file.mode = new_mode; delta->old_file.flags |= GIT_DIFF_FLAG_EXISTS; @@ -490,6 +499,14 @@ static int diff_generated_apply_options( return -1; } + if (!diff->base.opts.oid_type) { + diff->base.opts.oid_type = repo->oid_type; + } else if (diff->base.opts.oid_type != repo->oid_type) { + git_error_set(GIT_ERROR_INVALID, + "specified object ID type does not match repository object ID type"); + return -1; + } + /* flag INCLUDE_TYPECHANGE_TREES implies INCLUDE_TYPECHANGE */ if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_TYPECHANGE_TREES)) diff->base.opts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE; @@ -603,7 +620,7 @@ int git_diff__oid_for_file( entry.mode = mode; entry.file_size = (uint32_t)size; entry.path = (char *)path; - git_oid_clear(&entry.id, GIT_OID_SHA1); + git_oid_clear(&entry.id, diff->opts.oid_type); return git_diff__oid_for_entry(out, diff, &entry, mode, NULL); } @@ -624,7 +641,7 @@ int git_diff__oid_for_entry( GIT_ASSERT(d->type == GIT_DIFF_TYPE_GENERATED); diff = (git_diff_generated *)d; - git_oid_clear(out, GIT_OID_SHA1); + git_oid_clear(out, diff->base.opts.oid_type); if (git_repository_workdir_path(&full_path, diff->base.repo, entry.path) < 0) return -1; @@ -660,7 +677,8 @@ int git_diff__oid_for_entry( git_error_clear(); } } else if (S_ISLNK(mode)) { - error = git_odb__hashlink(out, full_path.ptr, GIT_OID_SHA1); + error = git_odb__hashlink(out, full_path.ptr, + diff->base.opts.oid_type); diff->base.perf.oid_calculations++; } else if (!git__is_sizet(entry.file_size)) { git_error_set(GIT_ERROR_NOMEMORY, "file size overflow (for 32-bits) on '%s'", @@ -676,7 +694,8 @@ int git_diff__oid_for_entry( else { error = git_odb__hashfd_filtered( out, fd, (size_t)entry.file_size, - GIT_OBJECT_BLOB, GIT_OID_SHA1, fl); + GIT_OBJECT_BLOB, diff->base.opts.oid_type, + fl); p_close(fd); diff->base.perf.oid_calculations++; } @@ -785,7 +804,7 @@ static int maybe_modified( git_diff_generated *diff, diff_in_progress *info) { - git_oid noid = GIT_OID_SHA1_ZERO; + git_oid noid; git_delta_t status = GIT_DELTA_MODIFIED; const git_index_entry *oitem = info->oitem; const git_index_entry *nitem = info->nitem; @@ -796,6 +815,8 @@ static int maybe_modified( const char *matched_pathspec; int error = 0; + git_oid_clear(&noid, diff->base.opts.oid_type); + if (!diff_pathspec_match(&matched_pathspec, diff, oitem)) return 0; @@ -1700,11 +1721,11 @@ int git_diff__commit( *out = NULL; if ((parents = git_commit_parentcount(commit)) > 1) { - char commit_oidstr[GIT_OID_SHA1_HEXSIZE + 1]; + char commit_oidstr[GIT_OID_MAX_HEXSIZE + 1]; error = -1; git_error_set(GIT_ERROR_INVALID, "commit %s is a merge commit", - git_oid_tostr(commit_oidstr, GIT_OID_SHA1_HEXSIZE + 1, git_commit_id(commit))); + git_oid_tostr(commit_oidstr, GIT_OID_MAX_HEXSIZE + 1, git_commit_id(commit))); goto on_error; } diff --git a/src/libgit2/diff_parse.c b/src/libgit2/diff_parse.c index 75e41a544..04603969e 100644 --- a/src/libgit2/diff_parse.c +++ b/src/libgit2/diff_parse.c @@ -29,7 +29,7 @@ static void diff_parsed_free(git_diff *d) git__free(diff); } -static git_diff_parsed *diff_parsed_alloc(void) +static git_diff_parsed *diff_parsed_alloc(git_oid_t oid_type) { git_diff_parsed *diff; @@ -51,6 +51,7 @@ static git_diff_parsed *diff_parsed_alloc(void) } diff->base.opts.flags &= ~GIT_DIFF_IGNORE_CASE; + diff->base.opts.oid_type = oid_type; if (git_pool_init(&diff->base.pool, 1) < 0 || git_vector_init(&diff->patches, 0, NULL) < 0 || @@ -67,19 +68,34 @@ static git_diff_parsed *diff_parsed_alloc(void) int git_diff_from_buffer( git_diff **out, const char *content, - size_t content_len) + size_t content_len +#ifdef GIT_EXPERIMENTAL_SHA256 + , git_diff_parse_options *opts +#endif + ) { git_diff_parsed *diff; git_patch *patch; git_patch_parse_ctx *ctx = NULL; + git_patch_options patch_opts = GIT_PATCH_OPTIONS_INIT; + git_oid_t oid_type; int error = 0; *out = NULL; - diff = diff_parsed_alloc(); +#ifdef GIT_EXPERIMENTAL_SHA256 + oid_type = (opts && opts->oid_type) ? opts->oid_type : + GIT_OID_DEFAULT; +#else + oid_type = GIT_OID_DEFAULT; +#endif + + patch_opts.oid_type = oid_type; + + diff = diff_parsed_alloc(oid_type); GIT_ERROR_CHECK_ALLOC(diff); - ctx = git_patch_parse_ctx_init(content, content_len, NULL); + ctx = git_patch_parse_ctx_init(content, content_len, &patch_opts); GIT_ERROR_CHECK_ALLOC(ctx); while (ctx->parse_ctx.remain_len) { diff --git a/src/libgit2/diff_print.c b/src/libgit2/diff_print.c index 3077e11e1..32c936826 100644 --- a/src/libgit2/diff_print.c +++ b/src/libgit2/diff_print.c @@ -29,6 +29,7 @@ typedef struct { const char *new_prefix; uint32_t flags; int id_strlen; + git_oid_t oid_type; int (*strcomp)(const char *, const char *); } diff_print_info; @@ -46,6 +47,8 @@ static int diff_print_info_init__common( pi->payload = payload; pi->buf = out; + GIT_ASSERT(pi->oid_type); + if (!pi->id_strlen) { if (!repo) pi->id_strlen = GIT_ABBREV_DEFAULT; @@ -53,8 +56,9 @@ static int diff_print_info_init__common( return -1; } - if (pi->id_strlen > GIT_OID_SHA1_HEXSIZE) - pi->id_strlen = GIT_OID_SHA1_HEXSIZE; + if (pi->id_strlen > 0 && + (size_t)pi->id_strlen > git_oid_hexsize(pi->oid_type)) + pi->id_strlen = (int)git_oid_hexsize(pi->oid_type); memset(&pi->line, 0, sizeof(pi->line)); pi->line.old_lineno = -1; @@ -78,6 +82,7 @@ static int diff_print_info_init_fromdiff( if (diff) { pi->flags = diff->opts.flags; + pi->oid_type = diff->opts.oid_type; pi->id_strlen = diff->opts.id_abbrev; pi->old_prefix = diff->opts.old_prefix; pi->new_prefix = diff->opts.new_prefix; @@ -101,6 +106,7 @@ static int diff_print_info_init_frompatch( memset(pi, 0, sizeof(diff_print_info)); pi->flags = patch->diff_opts.flags; + pi->oid_type = patch->diff_opts.oid_type; pi->id_strlen = patch->diff_opts.id_abbrev; pi->old_prefix = patch->diff_opts.old_prefix; pi->new_prefix = patch->diff_opts.new_prefix; @@ -212,7 +218,10 @@ static int diff_print_one_raw( git_str *out = pi->buf; int id_abbrev; char code = git_diff_status_char(delta->status); - char start_oid[GIT_OID_SHA1_HEXSIZE+1], end_oid[GIT_OID_SHA1_HEXSIZE+1]; + char start_oid[GIT_OID_MAX_HEXSIZE + 1], + end_oid[GIT_OID_MAX_HEXSIZE + 1]; + size_t oid_hexsize; + bool id_is_abbrev; GIT_UNUSED(progress); @@ -231,12 +240,21 @@ static int diff_print_one_raw( return -1; } +#ifdef GIT_EXPERIMENTAL_SHA256 + GIT_ASSERT(delta->old_file.id.type == delta->new_file.id.type); + oid_hexsize = git_oid_hexsize(delta->old_file.id.type); +#else + oid_hexsize = GIT_OID_SHA1_HEXSIZE; +#endif + + id_is_abbrev = (pi->id_strlen > 0 && + (size_t)pi->id_strlen <= oid_hexsize); + git_oid_tostr(start_oid, pi->id_strlen + 1, &delta->old_file.id); git_oid_tostr(end_oid, pi->id_strlen + 1, &delta->new_file.id); - git_str_printf( - out, (pi->id_strlen <= GIT_OID_SHA1_HEXSIZE) ? - ":%06o %06o %s... %s... %c" : ":%06o %06o %s %s %c", + git_str_printf(out, + id_is_abbrev ? ":%06o %06o %s... %s... %c" : ":%06o %06o %s %s %c", delta->old_file.mode, delta->new_file.mode, start_oid, end_oid, code); if (delta->similarity > 0) @@ -273,7 +291,8 @@ static int diff_print_oid_range( git_str *out, const git_diff_delta *delta, int id_strlen, bool print_index) { - char start_oid[GIT_OID_SHA1_HEXSIZE+1], end_oid[GIT_OID_SHA1_HEXSIZE+1]; + char start_oid[GIT_OID_MAX_HEXSIZE + 1], + end_oid[GIT_OID_MAX_HEXSIZE + 1]; if (delta->old_file.mode && id_strlen > delta->old_file.id_abbrev) { diff --git a/src/libgit2/diff_tform.c b/src/libgit2/diff_tform.c index 8c0c1b7fc..4a156c7a3 100644 --- a/src/libgit2/diff_tform.c +++ b/src/libgit2/diff_tform.c @@ -364,7 +364,7 @@ static int insert_delete_side_of_split( memset(&deleted->new_file, 0, sizeof(deleted->new_file)); deleted->new_file.path = deleted->old_file.path; deleted->new_file.flags |= GIT_DIFF_FLAG_VALID_ID; - git_oid_clear(&deleted->new_file.id, GIT_OID_SHA1); + git_oid_clear(&deleted->new_file.id, diff->opts.oid_type); return git_vector_insert(onto, deleted); } @@ -398,7 +398,7 @@ static int apply_splits_and_deletes( memset(&delta->old_file, 0, sizeof(delta->old_file)); delta->old_file.path = delta->new_file.path; delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID; - git_oid_clear(&delta->old_file.id, GIT_OID_SHA1); + git_oid_clear(&delta->old_file.id, diff->opts.oid_type); } /* clean up delta before inserting into new list */ @@ -997,7 +997,7 @@ find_best_matches: memset(&src->new_file, 0, sizeof(src->new_file)); src->new_file.path = src->old_file.path; src->new_file.flags |= GIT_DIFF_FLAG_VALID_ID; - git_oid_clear(&src->new_file.id, GIT_OID_SHA1); + git_oid_clear(&src->new_file.id, diff->opts.oid_type); num_updates++; @@ -1023,7 +1023,7 @@ find_best_matches: memset(&src->old_file, 0, sizeof(src->old_file)); src->old_file.path = src->new_file.path; src->old_file.flags |= GIT_DIFF_FLAG_VALID_ID; - git_oid_clear(&src->old_file.id, GIT_OID_SHA1); + git_oid_clear(&src->old_file.id, diff->opts.oid_type); src->flags &= ~GIT_DIFF_FLAG__TO_SPLIT; num_rewrites--; diff --git a/src/libgit2/patch.h b/src/libgit2/patch.h index 1e1471ed6..86328e886 100644 --- a/src/libgit2/patch.h +++ b/src/libgit2/patch.h @@ -59,9 +59,15 @@ typedef struct { * This prefix will be removed when looking for files. The default is 1. */ uint32_t prefix_len; + + /** + * The type of object IDs in the patch file. The default is + * `GIT_OID_DEFAULT`. + */ + git_oid_t oid_type; } git_patch_options; -#define GIT_PATCH_OPTIONS_INIT { 1 } +#define GIT_PATCH_OPTIONS_INIT { 1, GIT_OID_DEFAULT } extern int git_patch__to_buf(git_str *out, git_patch *patch); extern void git_patch_free(git_patch *patch); diff --git a/src/libgit2/patch_generate.c b/src/libgit2/patch_generate.c index bc598fea8..079bc53ae 100644 --- a/src/libgit2/patch_generate.c +++ b/src/libgit2/patch_generate.c @@ -81,7 +81,8 @@ static void patch_generated_init_common(git_patch_generated *patch) static int patch_generated_normalize_options( git_diff_options *out, - const git_diff_options *opts) + const git_diff_options *opts, + git_repository *repo) { if (opts) { GIT_ERROR_CHECK_VERSION(opts, GIT_DIFF_OPTIONS_VERSION, "git_diff_options"); @@ -91,6 +92,23 @@ static int patch_generated_normalize_options( memcpy(out, &default_opts, sizeof(git_diff_options)); } + if (repo && opts && opts->oid_type && repo->oid_type != opts->oid_type) { + /* + * This limitation feels unnecessary - we should consider + * allowing users to generate diffs with a different object + * ID format than the repository. + */ + git_error_set(GIT_ERROR_INVALID, + "specified object ID type does not match repository object ID type"); + return -1; + } else if (repo) { + out->oid_type = repo->oid_type; + } else if (opts && opts->oid_type) { + out->oid_type = opts->oid_type; + } else { + out->oid_type = GIT_OID_DEFAULT; + } + out->old_prefix = opts && opts->old_prefix ? git__strdup(opts->old_prefix) : git__strdup(DIFF_OLD_PREFIX_DEFAULT); @@ -118,7 +136,7 @@ static int patch_generated_init( patch->delta_index = delta_index; if ((error = patch_generated_normalize_options( - &patch->base.diff_opts, &diff->opts)) < 0 || + &patch->base.diff_opts, &diff->opts, diff->repo)) < 0 || (error = git_diff_file_content__init_from_diff( &patch->ofile, diff, patch->base.delta, true)) < 0 || (error = git_diff_file_content__init_from_diff( @@ -449,7 +467,7 @@ static int patch_generated_from_sources( git_xdiff_output *xo, git_diff_file_content_src *oldsrc, git_diff_file_content_src *newsrc, - const git_diff_options *opts) + const git_diff_options *given_opts) { int error = 0; git_repository *repo = @@ -457,11 +475,12 @@ static int patch_generated_from_sources( newsrc->blob ? git_blob_owner(newsrc->blob) : NULL; git_diff_file *lfile = &pd->delta.old_file, *rfile = &pd->delta.new_file; git_diff_file_content *ldata = &pd->patch.ofile, *rdata = &pd->patch.nfile; + git_diff_options *opts = &pd->patch.base.diff_opts; - if ((error = patch_generated_normalize_options(&pd->patch.base.diff_opts, opts)) < 0) + if ((error = patch_generated_normalize_options(opts, given_opts, repo)) < 0) return error; - if (opts && (opts->flags & GIT_DIFF_REVERSE) != 0) { + if ((opts->flags & GIT_DIFF_REVERSE) != 0) { void *tmp = lfile; lfile = rfile; rfile = tmp; tmp = ldata; ldata = rdata; rdata = tmp; } diff --git a/src/libgit2/patch_parse.c b/src/libgit2/patch_parse.c index ffdb99231..c06915537 100644 --- a/src/libgit2/patch_parse.c +++ b/src/libgit2/patch_parse.c @@ -166,15 +166,19 @@ static int parse_header_oid( uint16_t *oid_len, git_patch_parse_ctx *ctx) { - size_t len; + size_t hexsize, len; + + hexsize = git_oid_hexsize(ctx->opts.oid_type); - for (len = 0; len < ctx->parse_ctx.line_len && len < GIT_OID_SHA1_HEXSIZE; len++) { + for (len = 0; + len < ctx->parse_ctx.line_len && len < hexsize; + len++) { if (!git__isxdigit(ctx->parse_ctx.line[len])) break; } - if (len < GIT_OID_MINPREFIXLEN || len > GIT_OID_SHA1_HEXSIZE || - git_oid__fromstrn(oid, ctx->parse_ctx.line, len, GIT_OID_SHA1) < 0) + if (len < GIT_OID_MINPREFIXLEN || len > hexsize || + git_oid__fromstrn(oid, ctx->parse_ctx.line, len, ctx->opts.oid_type) < 0) return git_parse_err("invalid hex formatted object id at line %"PRIuZ, ctx->parse_ctx.line_num); @@ -1065,12 +1069,14 @@ static int check_patch(git_patch_parsed *patch) return git_parse_err("patch with no hunks"); if (delta->status == GIT_DELTA_ADDED) { - git_oid_clear(&delta->old_file.id, GIT_OID_SHA1); + git_oid_clear(&delta->old_file.id, + patch->base.diff_opts.oid_type); delta->old_file.id_abbrev = 0; } if (delta->status == GIT_DELTA_DELETED) { - git_oid_clear(&delta->new_file.id, GIT_OID_SHA1); + git_oid_clear(&delta->new_file.id, + patch->base.diff_opts.oid_type); delta->new_file.id_abbrev = 0; } @@ -1187,11 +1193,13 @@ int git_patch_parse( patch->base.delta->status = GIT_DELTA_MODIFIED; patch->base.delta->nfiles = 2; + patch->base.diff_opts.oid_type = ctx->opts.oid_type; + start = ctx->parse_ctx.remain_len; if ((error = parse_patch_header(patch, ctx)) < 0 || - (error = parse_patch_body(patch, ctx)) < 0 || - (error = check_patch(patch)) < 0) + (error = parse_patch_body(patch, ctx)) < 0 || + (error = check_patch(patch)) < 0) goto done; used = start - ctx->parse_ctx.remain_len; diff --git a/tests/libgit2/apply/apply_helpers.h b/tests/libgit2/apply/apply_helpers.h index 82094773e..b1a1479de 100644 --- a/tests/libgit2/apply/apply_helpers.h +++ b/tests/libgit2/apply/apply_helpers.h @@ -1,4 +1,5 @@ #include "../merge/merge_helpers.h" +#include "../diff/diff_helpers.h" #define TEST_REPO_PATH "merge-recursive" diff --git a/tests/libgit2/apply/both.c b/tests/libgit2/apply/both.c index 1331e7ea4..44c5b1937 100644 --- a/tests/libgit2/apply/both.c +++ b/tests/libgit2/apply/both.c @@ -78,7 +78,7 @@ void test_apply_both__parsed_diff(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -102,7 +102,7 @@ void test_apply_both__removes_file(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_DELETE_FILE, + cl_git_pass(diff_from_buffer(&diff, DIFF_DELETE_FILE, strlen(DIFF_DELETE_FILE))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -128,7 +128,7 @@ void test_apply_both__adds_file(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_ADD_FILE, strlen(DIFF_ADD_FILE))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -161,7 +161,7 @@ void test_apply_both__application_failure_leaves_index_unmodified(void) cl_git_pass(git_index_write(index)); git_index_free(index); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); validate_apply_index(repo, index_expected, index_expected_cnt); @@ -198,7 +198,7 @@ void test_apply_both__index_must_match_workdir(void) cl_git_pass(git_index_write(index)); git_index_free(index); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); git_diff_free(diff); @@ -214,7 +214,7 @@ void test_apply_both__index_mode_must_match_workdir(void) /* Set a file in the working directory executable. */ cl_must_pass(p_chmod("merge-recursive/asparagus.txt", 0755)); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_MODIFY_TWO_FILES, + cl_git_pass(diff_from_buffer(&diff, DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES))); cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -248,7 +248,7 @@ void test_apply_both__application_failure_leaves_workdir_unmodified(void) cl_git_pass(git_index_write(index)); git_index_free(index); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); validate_apply_workdir(repo, workdir_expected, workdir_expected_cnt); @@ -301,7 +301,7 @@ void test_apply_both__keeps_nonconflicting_changes(void) cl_git_rmfile("merge-recursive/oyster.txt"); cl_git_rewritefile("merge-recursive/gravy.txt", "Hello, world.\n"); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); validate_apply_index(repo, index_expected, index_expected_cnt); @@ -341,7 +341,7 @@ void test_apply_both__can_apply_nonconflicting_file_changes(void) cl_git_pass(git_index_write(index)); git_index_free(index); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); validate_apply_index(repo, both_expected, both_expected_cnt); @@ -391,7 +391,7 @@ void test_apply_both__honors_crlf_attributes(void) cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL)); git_commit_free(commit); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); validate_apply_index(repo, index_expected, index_expected_cnt); @@ -415,7 +415,7 @@ void test_apply_both__rename(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_FILE, + cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_FILE, strlen(DIFF_RENAME_FILE))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -440,7 +440,7 @@ void test_apply_both__rename_and_modify(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_AND_MODIFY_FILE, + cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_AND_MODIFY_FILE, strlen(DIFF_RENAME_AND_MODIFY_FILE))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -465,7 +465,7 @@ void test_apply_both__rename_a_to_b_to_c(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_A_TO_B_TO_C, + cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_A_TO_B_TO_C, strlen(DIFF_RENAME_A_TO_B_TO_C))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -490,7 +490,7 @@ void test_apply_both__rename_a_to_b_to_c_exact(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_A_TO_B_TO_C_EXACT, + cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_A_TO_B_TO_C_EXACT, strlen(DIFF_RENAME_A_TO_B_TO_C_EXACT))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -515,7 +515,7 @@ void test_apply_both__rename_circular(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_CIRCULAR, + cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_CIRCULAR, strlen(DIFF_RENAME_CIRCULAR))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -539,7 +539,7 @@ void test_apply_both__rename_2_to_1(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_2_TO_1, + cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_2_TO_1, strlen(DIFF_RENAME_2_TO_1))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -565,7 +565,7 @@ void test_apply_both__rename_1_to_2(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_1_TO_2, + cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_1_TO_2, strlen(DIFF_RENAME_1_TO_2))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -590,7 +590,7 @@ void test_apply_both__two_deltas_one_file(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_TWO_DELTAS_ONE_FILE, + cl_git_pass(diff_from_buffer(&diff, DIFF_TWO_DELTAS_ONE_FILE, strlen(DIFF_TWO_DELTAS_ONE_FILE))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -616,7 +616,7 @@ void test_apply_both__two_deltas_one_new_file(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_TWO_DELTAS_ONE_NEW_FILE, + cl_git_pass(diff_from_buffer(&diff, DIFF_TWO_DELTAS_ONE_NEW_FILE, strlen(DIFF_TWO_DELTAS_ONE_NEW_FILE))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -641,7 +641,7 @@ void test_apply_both__rename_and_modify_deltas(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_AND_MODIFY_DELTAS, + cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_AND_MODIFY_DELTAS, strlen(DIFF_RENAME_AND_MODIFY_DELTAS))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -667,7 +667,7 @@ void test_apply_both__rename_delta_after_modify_delta(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_AFTER_MODIFY, + cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_AFTER_MODIFY, strlen(DIFF_RENAME_AFTER_MODIFY))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -681,7 +681,7 @@ void test_apply_both__cant_rename_after_modify_nonexistent_target_path(void) { git_diff *diff; - cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_AFTER_MODIFY_TARGET_PATH, + cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_AFTER_MODIFY_TARGET_PATH, strlen(DIFF_RENAME_AFTER_MODIFY_TARGET_PATH))); cl_git_fail(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -692,7 +692,7 @@ void test_apply_both__cant_modify_source_path_after_rename(void) { git_diff *diff; - cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_AND_MODIFY_SOURCE_PATH, + cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_AND_MODIFY_SOURCE_PATH, strlen(DIFF_RENAME_AND_MODIFY_SOURCE_PATH))); cl_git_fail(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -714,7 +714,7 @@ void test_apply_both__readd_deleted_file(void) size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_DELETE_AND_READD_FILE, + cl_git_pass(diff_from_buffer(&diff, DIFF_DELETE_AND_READD_FILE, strlen(DIFF_DELETE_AND_READD_FILE))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -728,7 +728,7 @@ void test_apply_both__cant_remove_file_twice(void) { git_diff *diff; - cl_git_pass(git_diff_from_buffer(&diff, DIFF_REMOVE_FILE_TWICE, + cl_git_pass(diff_from_buffer(&diff, DIFF_REMOVE_FILE_TWICE, strlen(DIFF_REMOVE_FILE_TWICE))); cl_git_fail(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); @@ -739,7 +739,7 @@ void test_apply_both__cant_add_invalid_filename(void) { git_diff *diff; - cl_git_pass(git_diff_from_buffer(&diff, DIFF_ADD_INVALID_FILENAME, + cl_git_pass(diff_from_buffer(&diff, DIFF_ADD_INVALID_FILENAME, strlen(DIFF_ADD_INVALID_FILENAME))); cl_git_fail(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); diff --git a/tests/libgit2/apply/callbacks.c b/tests/libgit2/apply/callbacks.c index 2f9af3101..f076ca486 100644 --- a/tests/libgit2/apply/callbacks.c +++ b/tests/libgit2/apply/callbacks.c @@ -40,7 +40,7 @@ void test_apply_callbacks__delta_aborts(void) opts.delta_cb = delta_abort_cb; - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES))); cl_git_fail_with(-99, git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, &opts)); @@ -79,7 +79,7 @@ void test_apply_callbacks__delta_can_skip(void) opts.delta_cb = delta_skip_cb; - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, &opts)); @@ -117,7 +117,7 @@ void test_apply_callbacks__hunk_can_skip(void) opts.hunk_cb = hunk_skip_odds_cb; opts.payload = &count; - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_MANY_CHANGES_ONE, strlen(DIFF_MANY_CHANGES_ONE))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, &opts)); diff --git a/tests/libgit2/apply/check.c b/tests/libgit2/apply/check.c index d055d455b..0c1f86dc5 100644 --- a/tests/libgit2/apply/check.c +++ b/tests/libgit2/apply/check.c @@ -60,7 +60,7 @@ void test_apply_check__parsed_diff(void) git_apply_options opts = GIT_APPLY_OPTIONS_INIT; opts.flags |= GIT_APPLY_CHECK; - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, &opts)); @@ -76,7 +76,7 @@ void test_apply_check__binary(void) git_apply_options opts = GIT_APPLY_OPTIONS_INIT; opts.flags |= GIT_APPLY_CHECK; - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_MODIFY_TWO_FILES_BINARY, strlen(DIFF_MODIFY_TWO_FILES_BINARY))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, &opts)); @@ -112,7 +112,7 @@ void test_apply_check__does_not_apply(void) git_index_free(index); opts.flags |= GIT_APPLY_CHECK; - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, &opts)); validate_apply_index(repo, index_expected, index_expected_cnt); diff --git a/tests/libgit2/apply/index.c b/tests/libgit2/apply/index.c index 2dc0d53cb..564d55c8c 100644 --- a/tests/libgit2/apply/index.c +++ b/tests/libgit2/apply/index.c @@ -78,7 +78,7 @@ void test_apply_index__parsed_diff(void) size_t index_expected_cnt = sizeof(index_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL)); @@ -102,7 +102,7 @@ void test_apply_index__removes_file(void) size_t index_expected_cnt = sizeof(index_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_DELETE_FILE, + cl_git_pass(diff_from_buffer(&diff, DIFF_DELETE_FILE, strlen(DIFF_DELETE_FILE))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL)); @@ -128,7 +128,7 @@ void test_apply_index__adds_file(void) size_t index_expected_cnt = sizeof(index_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_ADD_FILE, strlen(DIFF_ADD_FILE))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL)); @@ -169,7 +169,7 @@ void test_apply_index__modified_workdir_with_unmodified_index_is_ok(void) cl_git_rmfile("merge-recursive/asparagus.txt"); cl_git_rewritefile("merge-recursive/veal.txt", "Hello, world.\n"); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL)); validate_apply_index(repo, index_expected, index_expected_cnt); @@ -201,7 +201,7 @@ void test_apply_index__application_failure_leaves_index_unmodified(void) cl_git_pass(git_index_write(index)); git_index_free(index); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL)); validate_apply_index(repo, index_expected, index_expected_cnt); @@ -240,7 +240,7 @@ void test_apply_index__keeps_nonconflicting_changes(void) cl_git_pass(git_index_write(index)); git_index_free(index); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL)); validate_apply_index(repo, index_expected, index_expected_cnt); @@ -285,7 +285,7 @@ void test_apply_index__can_apply_nonconflicting_file_changes(void) cl_git_pass(git_index_write(index)); git_index_free(index); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL)); validate_apply_index(repo, index_expected, index_expected_cnt); @@ -311,7 +311,7 @@ void test_apply_index__change_mode(void) size_t index_expected_cnt = sizeof(index_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL)); validate_apply_index(repo, index_expected, index_expected_cnt); diff --git a/tests/libgit2/apply/tree.c b/tests/libgit2/apply/tree.c index 667bb9d40..b97fe8d35 100644 --- a/tests/libgit2/apply/tree.c +++ b/tests/libgit2/apply/tree.c @@ -81,7 +81,7 @@ void test_apply_tree__adds_file(void) cl_git_pass(git_commit_tree(&a_tree, a_commit)); - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_ADD_FILE, strlen(DIFF_ADD_FILE))); cl_git_pass(git_apply_to_tree(&index, repo, a_tree, diff, NULL)); diff --git a/tests/libgit2/apply/workdir.c b/tests/libgit2/apply/workdir.c index e1011d114..5ae56847a 100644 --- a/tests/libgit2/apply/workdir.c +++ b/tests/libgit2/apply/workdir.c @@ -77,7 +77,7 @@ void test_apply_workdir__parsed_diff(void) size_t workdir_expected_cnt = sizeof(workdir_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL)); @@ -101,7 +101,7 @@ void test_apply_workdir__removes_file(void) size_t workdir_expected_cnt = sizeof(workdir_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, DIFF_DELETE_FILE, + cl_git_pass(diff_from_buffer(&diff, DIFF_DELETE_FILE, strlen(DIFF_DELETE_FILE))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL)); @@ -127,7 +127,7 @@ void test_apply_workdir__adds_file(void) size_t workdir_expected_cnt = sizeof(workdir_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_ADD_FILE, strlen(DIFF_ADD_FILE))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL)); @@ -177,7 +177,7 @@ void test_apply_workdir__modified_index_with_unmodified_workdir_is_ok(void) cl_git_pass(git_index_remove(index, "asparagus.txt", 0)); cl_git_pass(git_index_write(index)); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL)); validate_apply_index(repo, index_expected, index_expected_cnt); @@ -208,7 +208,7 @@ void test_apply_workdir__application_failure_leaves_workdir_unmodified(void) cl_git_rewritefile("merge-recursive/veal.txt", "This is a modification.\n"); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL)); validate_apply_workdir(repo, workdir_expected, workdir_expected_cnt); @@ -233,7 +233,7 @@ void test_apply_workdir__keeps_nonconflicting_changes(void) cl_git_rmfile("merge-recursive/oyster.txt"); cl_git_rewritefile("merge-recursive/gravy.txt", "Hello, world.\n"); - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL)); @@ -268,7 +268,7 @@ void test_apply_workdir__can_apply_nonconflicting_file_changes(void) cl_git_append2file("merge-recursive/asparagus.txt", "This line is added in the workdir.\n"); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL)); validate_index_unchanged(repo); @@ -295,7 +295,7 @@ void test_apply_workdir__change_mode(void) size_t workdir_expected_cnt = sizeof(workdir_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file))); + cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL)); validate_index_unchanged(repo); @@ -321,7 +321,7 @@ void test_apply_workdir__apply_many_changes_one(void) size_t workdir_expected_cnt = sizeof(workdir_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_MANY_CHANGES_ONE, strlen(DIFF_MANY_CHANGES_ONE))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, &opts)); @@ -347,7 +347,7 @@ void test_apply_workdir__apply_many_changes_two(void) size_t workdir_expected_cnt = sizeof(workdir_expected) / sizeof(struct merge_index_entry); - cl_git_pass(git_diff_from_buffer(&diff, + cl_git_pass(diff_from_buffer(&diff, DIFF_MANY_CHANGES_TWO, strlen(DIFF_MANY_CHANGES_TWO))); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, &opts)); diff --git a/tests/libgit2/diff/diff_helpers.c b/tests/libgit2/diff/diff_helpers.c index 341b0a448..5daebffeb 100644 --- a/tests/libgit2/diff/diff_helpers.c +++ b/tests/libgit2/diff/diff_helpers.c @@ -314,3 +314,20 @@ void diff_assert_equal(git_diff *a, git_diff *b) } } +#ifdef GIT_EXPERIMENTAL_SHA256 +int diff_from_buffer( + git_diff **out, + const char *content, + size_t content_len) +{ + return git_diff_from_buffer(out, content, content_len, NULL); +} +#else +int diff_from_buffer( + git_diff **out, + const char *content, + size_t content_len) +{ + return git_diff_from_buffer(out, content, content_len); +} +#endif diff --git a/tests/libgit2/diff/diff_helpers.h b/tests/libgit2/diff/diff_helpers.h index af855ce68..1be4b4780 100644 --- a/tests/libgit2/diff/diff_helpers.h +++ b/tests/libgit2/diff/diff_helpers.h @@ -71,3 +71,7 @@ extern void diff_print_raw(FILE *fp, git_diff *diff); extern void diff_assert_equal(git_diff *a, git_diff *b); +extern int diff_from_buffer( + git_diff **out, + const char *content, + size_t content_len); diff --git a/tests/libgit2/diff/parse.c b/tests/libgit2/diff/parse.c index cae843cc8..79745b995 100644 --- a/tests/libgit2/diff/parse.c +++ b/tests/libgit2/diff/parse.c @@ -19,19 +19,19 @@ void test_diff_parse__nonpatches_fail_with_notfound(void) const char *not_with_both = "Lead.\n" PATCH_NOT_A_PATCH "Trail.\n"; cl_git_fail_with(GIT_ENOTFOUND, - git_diff_from_buffer(&diff, + diff_from_buffer(&diff, not, strlen(not))); cl_git_fail_with(GIT_ENOTFOUND, - git_diff_from_buffer(&diff, + diff_from_buffer(&diff, not_with_leading, strlen(not_with_leading))); cl_git_fail_with(GIT_ENOTFOUND, - git_diff_from_buffer(&diff, + diff_from_buffer(&diff, not_with_trailing, strlen(not_with_trailing))); cl_git_fail_with(GIT_ENOTFOUND, - git_diff_from_buffer(&diff, + diff_from_buffer(&diff, not_with_both, strlen(not_with_both))); } @@ -51,7 +51,7 @@ static void test_parse_invalid_diff(const char *invalid_diff) git_str_puts(&buf, PATCH_BINARY_LITERAL); cl_git_fail_with(GIT_ERROR, - git_diff_from_buffer(&diff, buf.ptr, buf.size)); + diff_from_buffer(&diff, buf.ptr, buf.size)); git_str_dispose(&buf); } @@ -72,7 +72,7 @@ void test_diff_parse__exact_rename(void) "2.9.3\n"; git_diff *diff; - cl_git_pass(git_diff_from_buffer( + cl_git_pass(diff_from_buffer( &diff, content, strlen(content))); git_diff_free(diff); } @@ -92,7 +92,7 @@ void test_diff_parse__empty_file(void) "2.20.1\n"; git_diff *diff; - cl_git_pass(git_diff_from_buffer( + cl_git_pass(diff_from_buffer( &diff, content, strlen(content))); git_diff_free(diff); } @@ -102,7 +102,7 @@ void test_diff_parse__no_extended_headers(void) const char *content = PATCH_NO_EXTENDED_HEADERS; git_diff *diff; - cl_git_pass(git_diff_from_buffer( + cl_git_pass(diff_from_buffer( &diff, content, strlen(content))); git_diff_free(diff); } @@ -125,7 +125,7 @@ void test_diff_parse__add_delete_no_index(void) "-three\n"; git_diff *diff; - cl_git_pass(git_diff_from_buffer( + cl_git_pass(diff_from_buffer( &diff, content, strlen(content))); git_diff_free(diff); } @@ -166,7 +166,7 @@ static void test_tree_to_tree_computed_to_parsed( cl_git_pass(git_diff_to_buf(&computed_buf, computed, GIT_DIFF_FORMAT_PATCH)); - cl_git_pass(git_diff_from_buffer(&parsed, + cl_git_pass(diff_from_buffer(&parsed, computed_buf.ptr, computed_buf.size)); diff_assert_equal(computed, parsed); @@ -248,7 +248,7 @@ void test_diff_parse__get_patch_from_diff(void) computed, GIT_DIFF_FORMAT_PATCH)); cl_git_pass(git_patch_from_diff(&patch_computed, computed, 0)); - cl_git_pass(git_diff_from_buffer(&parsed, + cl_git_pass(diff_from_buffer(&parsed, computed_buf.ptr, computed_buf.size)); cl_git_pass(git_patch_from_diff(&patch_parsed, parsed, 0)); @@ -292,7 +292,7 @@ void test_diff_parse__foreach_works_with_parsed_patch(void) int called = 0; git_diff *diff; - cl_git_pass(git_diff_from_buffer(&diff, patch, strlen(patch))); + cl_git_pass(diff_from_buffer(&diff, patch, strlen(patch))); cl_git_pass(git_diff_foreach(diff, file_cb, NULL, NULL, NULL, &called)); cl_assert_equal_i(called, 1); @@ -312,7 +312,7 @@ void test_diff_parse__parsing_minimal_patch_succeeds(void) git_buf buf = GIT_BUF_INIT; git_diff *diff; - cl_git_pass(git_diff_from_buffer(&diff, patch, strlen(patch))); + cl_git_pass(diff_from_buffer(&diff, patch, strlen(patch))); cl_git_pass(git_diff_to_buf(&buf, diff, GIT_DIFF_FORMAT_PATCH)); cl_assert_equal_s(patch, buf.ptr); @@ -330,7 +330,7 @@ void test_diff_parse__patch_roundtrip_succeeds(void) cl_git_pass(git_patch_from_buffers(&patch, buf1, strlen(buf1), "obj1", buf2, strlen(buf2), "obj2", NULL)); cl_git_pass(git_patch_to_buf(&patchbuf, patch)); - cl_git_pass(git_diff_from_buffer(&diff, patchbuf.ptr, patchbuf.size)); + cl_git_pass(diff_from_buffer(&diff, patchbuf.ptr, patchbuf.size)); cl_git_pass(git_diff_to_buf(&diffbuf, diff, GIT_DIFF_FORMAT_PATCH)); cl_assert_equal_s(patchbuf.ptr, diffbuf.ptr); @@ -372,7 +372,7 @@ void test_diff_parse__issue4672(void) const git_diff_hunk *hunk; size_t n, l = 0; - cl_git_pass(git_diff_from_buffer(&diff, text, strlen(text))); + cl_git_pass(diff_from_buffer(&diff, text, strlen(text))); cl_git_pass(git_patch_from_diff(&patch, diff, 0)); cl_git_pass(git_patch_get_hunk(&hunk, &n, patch, 0)); @@ -393,7 +393,7 @@ void test_diff_parse__lineinfo(void) const git_diff_hunk *hunk; size_t n, l = 0; - cl_git_pass(git_diff_from_buffer(&diff, text, strlen(text))); + cl_git_pass(diff_from_buffer(&diff, text, strlen(text))); cl_git_pass(git_patch_from_diff(&patch, diff, 0)); cl_git_pass(git_patch_get_hunk(&hunk, &n, patch, 0)); @@ -419,7 +419,7 @@ void test_diff_parse__new_file_with_space(void) git_patch *patch; git_diff *diff; - cl_git_pass(git_diff_from_buffer(&diff, content, strlen(content))); + cl_git_pass(diff_from_buffer(&diff, content, strlen(content))); cl_git_pass(git_patch_from_diff((git_patch **) &patch, diff, 0)); cl_assert_equal_p(patch->diff_opts.old_prefix, NULL); @@ -437,7 +437,7 @@ void test_diff_parse__new_file_with_space_and_regenerate_patch(void) git_diff *diff = NULL; git_buf buf = GIT_BUF_INIT; - cl_git_pass(git_diff_from_buffer(&diff, content, strlen(content))); + cl_git_pass(diff_from_buffer(&diff, content, strlen(content))); cl_git_pass(git_diff_to_buf(&buf, diff, GIT_DIFF_FORMAT_PATCH)); git_buf_dispose(&buf); @@ -450,7 +450,7 @@ void test_diff_parse__delete_file_with_space_and_regenerate_patch(void) git_diff *diff = NULL; git_buf buf = GIT_BUF_INIT; - cl_git_pass(git_diff_from_buffer(&diff, content, strlen(content))); + cl_git_pass(diff_from_buffer(&diff, content, strlen(content))); cl_git_pass(git_diff_to_buf(&buf, diff, GIT_DIFF_FORMAT_PATCH)); git_buf_dispose(&buf); @@ -464,7 +464,7 @@ void test_diff_parse__crlf(void) git_patch *patch; const git_diff_delta *delta; - cl_git_pass(git_diff_from_buffer(&diff, text, strlen(text))); + cl_git_pass(diff_from_buffer(&diff, text, strlen(text))); cl_git_pass(git_patch_from_diff(&patch, diff, 0)); delta = git_patch_get_delta(patch); diff --git a/tests/libgit2/diff/patchid.c b/tests/libgit2/diff/patchid.c index 1cc368e21..91807e7b7 100644 --- a/tests/libgit2/diff/patchid.c +++ b/tests/libgit2/diff/patchid.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "patch/patch_common.h" +#include "diff_helpers.h" static void verify_patch_id(const char *diff_content, const char *expected_id) { @@ -7,7 +8,7 @@ static void verify_patch_id(const char *diff_content, const char *expected_id) git_diff *diff; cl_git_pass(git_oid__fromstr(&expected_oid, expected_id, GIT_OID_SHA1)); - cl_git_pass(git_diff_from_buffer(&diff, diff_content, strlen(diff_content))); + cl_git_pass(diff_from_buffer(&diff, diff_content, strlen(diff_content))); cl_git_pass(git_diff_patchid(&actual_oid, diff, NULL)); cl_assert_equal_oid(&expected_oid, &actual_oid); diff --git a/tests/libgit2/diff/stats.c b/tests/libgit2/diff/stats.c index b076ad5a9..7af891550 100644 --- a/tests/libgit2/diff/stats.c +++ b/tests/libgit2/diff/stats.c @@ -4,6 +4,7 @@ #include "commit.h" #include "diff.h" #include "diff_generate.h" +#include "diff_helpers.h" static git_repository *_repo; static git_diff_stats *_stats; @@ -368,7 +369,7 @@ void test_diff_stats__new_file(void) " 1 file changed, 1 insertion(+)\n" " create mode 100644 Gurjeet Singh\n"; - cl_git_pass(git_diff_from_buffer(&diff, input, strlen(input))); + cl_git_pass(diff_from_buffer(&diff, input, strlen(input))); cl_git_pass(git_diff_get_stats(&_stats, diff)); cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL | GIT_DIFF_STATS_INCLUDE_SUMMARY, 0)); cl_assert_equal_s(stat, buf.ptr); |