diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2022-02-06 15:27:34 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-06 15:27:34 -0500 |
commit | d9863fc19eed8135f2fbcc4ee22ea950dcd6fddf (patch) | |
tree | 881d68ee13db8edbdb1370de319e536c515cdadd | |
parent | 4efd6563cab0caeeeb442b688523a7683cc20174 (diff) | |
parent | 70d9bfa47c14fd230d081cebb9933622136479ea (diff) | |
download | libgit2-d9863fc19eed8135f2fbcc4ee22ea950dcd6fddf.tar.gz |
Merge pull request #6192 from libgit2/ethomson/sha256_preparation
SHA256: early preparation
-rw-r--r-- | examples/index-pack.c | 4 | ||||
-rw-r--r-- | fuzzers/packfile_fuzzer.c | 4 | ||||
-rw-r--r-- | include/git2/index.h | 3 | ||||
-rw-r--r-- | include/git2/indexer.h | 14 | ||||
-rw-r--r-- | include/git2/pack.h | 28 | ||||
-rw-r--r-- | src/branch.c | 5 | ||||
-rw-r--r-- | src/commit_graph.c | 28 | ||||
-rw-r--r-- | src/commit_graph.h | 4 | ||||
-rw-r--r-- | src/config_file.c | 11 | ||||
-rw-r--r-- | src/hash.c | 16 | ||||
-rw-r--r-- | src/hash.h | 2 | ||||
-rw-r--r-- | src/index.c | 76 | ||||
-rw-r--r-- | src/index.h | 9 | ||||
-rw-r--r-- | src/indexer.c | 50 | ||||
-rw-r--r-- | src/midx.c | 32 | ||||
-rw-r--r-- | src/midx.h | 2 | ||||
-rw-r--r-- | src/pack-objects.c | 14 | ||||
-rw-r--r-- | src/pack-objects.h | 3 | ||||
-rw-r--r-- | src/reset.c | 5 | ||||
-rw-r--r-- | tests/checkout/crlf.c | 4 | ||||
-rw-r--r-- | tests/diff/workdir.c | 15 | ||||
-rw-r--r-- | tests/graph/commitgraph.c (renamed from tests/graph/commit_graph.c) | 6 | ||||
-rw-r--r-- | tests/pack/indexer.c | 3 | ||||
-rw-r--r-- | tests/pack/packbuilder.c | 21 |
24 files changed, 228 insertions, 131 deletions
diff --git a/examples/index-pack.c b/examples/index-pack.c index c58ac038a..df37dd0c4 100644 --- a/examples/index-pack.c +++ b/examples/index-pack.c @@ -17,7 +17,6 @@ int lg2_index_pack(git_repository *repo, int argc, char **argv) git_indexer *idx; git_indexer_progress stats = {0, 0}; int error; - char hash[GIT_OID_HEXSZ + 1] = {0}; int fd; ssize_t read_bytes; char buf[512]; @@ -61,8 +60,7 @@ int lg2_index_pack(git_repository *repo, int argc, char **argv) printf("\rIndexing %u of %u\n", stats.indexed_objects, stats.total_objects); - git_oid_fmt(hash, git_indexer_hash(idx)); - puts(hash); + puts(git_indexer_name(idx)); cleanup: close(fd); diff --git a/fuzzers/packfile_fuzzer.c b/fuzzers/packfile_fuzzer.c index 8667cb9c5..6002fa1de 100644 --- a/fuzzers/packfile_fuzzer.c +++ b/fuzzers/packfile_fuzzer.c @@ -101,13 +101,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) if (git_indexer_commit(indexer, &stats) < 0) goto cleanup; - if (git_str_printf(&path, "pack-%s.idx", git_oid_tostr_s(git_indexer_hash(indexer))) < 0) + if (git_str_printf(&path, "pack-%s.idx", git_indexer_name(indexer)) < 0) goto cleanup; p_unlink(git_str_cstr(&path)); git_str_clear(&path); - if (git_str_printf(&path, "pack-%s.pack", git_oid_tostr_s(git_indexer_hash(indexer))) < 0) + if (git_str_printf(&path, "pack-%s.pack", git_indexer_name(indexer)) < 0) goto cleanup; p_unlink(git_str_cstr(&path)); diff --git a/include/git2/index.h b/include/git2/index.h index 3cf64d827..981535dad 100644 --- a/include/git2/index.h +++ b/include/git2/index.h @@ -296,6 +296,7 @@ GIT_EXTERN(int) git_index_write(git_index *index); */ GIT_EXTERN(const char *) git_index_path(const git_index *index); +#ifndef GIT_DEPRECATE_HARD /** * Get the checksum of the index * @@ -303,10 +304,12 @@ GIT_EXTERN(const char *) git_index_path(const git_index *index); * last 20 bytes which are the checksum itself). In cases where the * index does not exist on-disk, it will be zeroed out. * + * @deprecated this function is deprecated with no replacement * @param index an existing index object * @return a pointer to the checksum of the index */ GIT_EXTERN(const git_oid *) git_index_checksum(git_index *index); +#endif /** * Read a tree into the index file with stats diff --git a/include/git2/indexer.h b/include/git2/indexer.h index 4bacbd317..ffe9bf366 100644 --- a/include/git2/indexer.h +++ b/include/git2/indexer.h @@ -129,16 +129,30 @@ GIT_EXTERN(int) git_indexer_append(git_indexer *idx, const void *data, size_t si */ GIT_EXTERN(int) git_indexer_commit(git_indexer *idx, git_indexer_progress *stats); +#ifndef GIT_DEPRECATE_HARD /** * Get the packfile's hash * * A packfile's name is derived from the sorted hashing of all object * names. This is only correct after the index has been finalized. * + * @deprecated use git_indexer_name * @param idx the indexer instance * @return the packfile's hash */ GIT_EXTERN(const git_oid *) git_indexer_hash(const git_indexer *idx); +#endif + +/** + * Get the unique name for the resulting packfile. + * + * The packfile's name is derived from the packfile's content. + * This is only correct after the index has been finalized. + * + * @param idx the indexer instance + * @return a NUL terminated string for the packfile name + */ +GIT_EXTERN(const char *) git_indexer_name(const git_indexer *idx); /** * Free the indexer and its resources diff --git a/include/git2/pack.h b/include/git2/pack.h index 253a860cd..0f6bd2ab9 100644 --- a/include/git2/pack.h +++ b/include/git2/pack.h @@ -170,16 +170,30 @@ GIT_EXTERN(int) git_packbuilder_write( git_indexer_progress_cb progress_cb, void *progress_cb_payload); +#ifndef GIT_DEPRECATE_HARD /** -* Get the packfile's hash -* -* A packfile's name is derived from the sorted hashing of all object -* names. This is only correct after the packfile has been written. -* -* @param pb The packbuilder object + * Get the packfile's hash + * + * A packfile's name is derived from the sorted hashing of all object + * names. This is only correct after the packfile has been written. + * + * @deprecated use git_packbuilder_name + * @param pb The packbuilder object * @return 0 or an error code -*/ + */ GIT_EXTERN(const git_oid *) git_packbuilder_hash(git_packbuilder *pb); +#endif + +/** + * Get the unique name for the resulting packfile. + * + * The packfile's name is derived from the packfile's content. + * This is only correct after the packfile has been written. + * + * @param pb the packbuilder instance + * @return a NUL terminated string for the packfile name + */ +GIT_EXTERN(const char *) git_packbuilder_name(git_packbuilder *pb); /** * Callback used to iterate over packed objects diff --git a/src/branch.c b/src/branch.c index 03892a4b0..2e29af99d 100644 --- a/src/branch.c +++ b/src/branch.c @@ -123,7 +123,10 @@ int git_branch_create( const git_commit *commit, int force) { - return create_branch(ref_out, repository, branch_name, commit, git_oid_tostr_s(git_commit_id(commit)), force); + char commit_id[GIT_OID_HEXSZ + 1]; + + git_oid_tostr(commit_id, GIT_OID_HEXSZ + 1, git_commit_id(commit)); + return create_branch(ref_out, repository, branch_name, commit, commit_id, force); } int git_branch_create_from_annotated( diff --git a/src/commit_graph.c b/src/commit_graph.c index 292250f65..70e866b92 100644 --- a/src/commit_graph.c +++ b/src/commit_graph.c @@ -201,7 +201,8 @@ int git_commit_graph_file_parse( struct git_commit_graph_chunk *last_chunk; uint32_t i; off64_t last_chunk_offset, chunk_offset, trailer_offset; - git_oid cgraph_checksum = {{0}}; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size; int error; struct git_commit_graph_chunk chunk_oid_fanout = {0}, chunk_oid_lookup = {0}, chunk_commit_data = {0}, chunk_extra_edge_list = {0}, @@ -227,13 +228,15 @@ int git_commit_graph_file_parse( */ last_chunk_offset = sizeof(struct git_commit_graph_header) + (1 + hdr->chunks) * 12; trailer_offset = size - GIT_OID_RAWSZ; + checksum_size = GIT_HASH_SHA1_SIZE; + if (trailer_offset < last_chunk_offset) return commit_graph_error("wrong commit-graph size"); - git_oid_cpy(&file->checksum, (git_oid *)(data + trailer_offset)); + memcpy(file->checksum, (data + trailer_offset), checksum_size); - if (git_hash_buf(cgraph_checksum.id, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) + if (git_hash_buf(checksum, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) return commit_graph_error("could not calculate signature"); - if (!git_oid_equal(&cgraph_checksum, &file->checksum)) + if (memcmp(checksum, file->checksum, checksum_size) != 0) return commit_graph_error("index signature mismatch"); chunk_hdr = data + sizeof(struct git_commit_graph_header); @@ -476,7 +479,8 @@ bool git_commit_graph_file_needs_refresh(const git_commit_graph_file *file, cons git_file fd = -1; struct stat st; ssize_t bytes_read; - git_oid cgraph_checksum = {{0}}; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size = GIT_HASH_SHA1_SIZE; /* TODO: properly open the file without access time using O_NOATIME */ fd = git_futils_open_ro(path); @@ -494,12 +498,12 @@ bool git_commit_graph_file_needs_refresh(const git_commit_graph_file *file, cons return true; } - bytes_read = p_pread(fd, cgraph_checksum.id, GIT_OID_RAWSZ, st.st_size - GIT_OID_RAWSZ); + bytes_read = p_pread(fd, checksum, checksum_size, st.st_size - checksum_size); p_close(fd); - if (bytes_read != GIT_OID_RAWSZ) + if (bytes_read != (ssize_t)checksum_size) return true; - return !git_oid_equal(&cgraph_checksum, &file->checksum); + return (memcmp(checksum, file->checksum, checksum_size) != 0); } int git_commit_graph_entry_find( @@ -974,7 +978,8 @@ static int commit_graph_write( off64_t offset; git_str oid_lookup = GIT_STR_INIT, commit_data = GIT_STR_INIT, extra_edge_list = GIT_STR_INIT; - git_oid cgraph_checksum = {{0}}; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size; git_hash_ctx ctx; struct commit_graph_write_hash_context hash_cb_data = {0}; @@ -987,6 +992,7 @@ static int commit_graph_write( hash_cb_data.cb_data = cb_data; hash_cb_data.ctx = &ctx; + checksum_size = GIT_HASH_SHA1_SIZE; error = git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1); if (error < 0) return error; @@ -1133,10 +1139,10 @@ static int commit_graph_write( goto cleanup; /* Finalize the checksum and write the trailer. */ - error = git_hash_final(cgraph_checksum.id, &ctx); + error = git_hash_final(checksum, &ctx); if (error < 0) goto cleanup; - error = write_cb((const char *)&cgraph_checksum, sizeof(cgraph_checksum), cb_data); + error = write_cb((char *)checksum, checksum_size, cb_data); if (error < 0) goto cleanup; diff --git a/src/commit_graph.h b/src/commit_graph.h index 4d2be431c..45e125b9e 100644 --- a/src/commit_graph.h +++ b/src/commit_graph.h @@ -15,6 +15,8 @@ #include "map.h" #include "vector.h" +#include "oid.h" +#include "hash.h" /** * A commit-graph file. @@ -55,7 +57,7 @@ typedef struct git_commit_graph_file { size_t num_extra_edge_list; /* The trailer of the file. Contains the SHA1-checksum of the whole file. */ - git_oid checksum; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; } git_commit_graph_file; /** diff --git a/src/config_file.c b/src/config_file.c index 43a6ba440..66fcb8ae2 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -19,13 +19,14 @@ #include "regexp.h" #include "sysdir.h" #include "wildmatch.h" +#include "hash.h" /* Max depth for [include] directives */ #define MAX_INCLUDE_DEPTH 10 typedef struct config_file { git_futils_filestamp stamp; - git_oid checksum; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; char *path; git_array_t(struct config_file) includes; } config_file; @@ -132,7 +133,7 @@ static int config_file_is_modified(int *modified, config_file *file) { config_file *include; git_str buf = GIT_STR_INIT; - git_oid hash; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; uint32_t i; int error = 0; @@ -144,10 +145,10 @@ static int config_file_is_modified(int *modified, config_file *file) if ((error = git_futils_readbuffer(&buf, file->path)) < 0) goto out; - if ((error = git_hash_buf(hash.id, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0) + if ((error = git_hash_buf(checksum, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0) goto out; - if (!git_oid_equal(&hash, &file->checksum)) { + if (memcmp(checksum, file->checksum, GIT_HASH_SHA1_SIZE) != 0) { *modified = 1; goto out; } @@ -880,7 +881,7 @@ static int config_file_read( goto out; git_futils_filestamp_set_from_stat(&file->stamp, &st); - if ((error = git_hash_buf(file->checksum.id, contents.ptr, contents.size, GIT_HASH_ALGORITHM_SHA1)) < 0) + if ((error = git_hash_buf(file->checksum, contents.ptr, contents.size, GIT_HASH_ALGORITHM_SHA1)) < 0) goto out; if ((error = config_file_read_buffer(entries, repo, file, level, depth, diff --git a/src/hash.c b/src/hash.c index 92e7ff219..98ceb05d2 100644 --- a/src/hash.c +++ b/src/hash.c @@ -124,3 +124,19 @@ done: return error; } + +int git_hash_fmt(char *out, unsigned char *hash, size_t hash_len) +{ + static char hex[] = "0123456789abcdef"; + char *str = out; + size_t i; + + for (i = 0; i < hash_len; i++) { + *str++ = hex[hash[i] >> 4]; + *str++ = hex[hash[i] & 0x0f]; + } + + *str++ = '\0'; + + return 0; +} diff --git a/src/hash.h b/src/hash.h index 2b2eaf6d6..507c1cb25 100644 --- a/src/hash.h +++ b/src/hash.h @@ -41,4 +41,6 @@ int git_hash_final(unsigned char *out, git_hash_ctx *c); int git_hash_buf(unsigned char *out, const void *data, size_t len, git_hash_algorithm_t algorithm); int git_hash_vec(unsigned char *out, git_str_vec *vec, size_t n, git_hash_algorithm_t algorithm); +int git_hash_fmt(char *out, unsigned char *hash, size_t hash_len); + #endif diff --git a/src/index.c b/src/index.c index 367fd9c38..aa97c6421 100644 --- a/src/index.c +++ b/src/index.c @@ -34,7 +34,6 @@ static int index_apply_to_wd_diff(git_index *index, int action, const git_strarr #define minimal_entry_size (offsetof(struct entry_short, path)) -static const size_t INDEX_FOOTER_SIZE = GIT_OID_RAWSZ; static const size_t INDEX_HEADER_SIZE = 12; static const unsigned int INDEX_VERSION_NUMBER_DEFAULT = 2; @@ -121,7 +120,7 @@ static int read_header(struct index_header *dest, const void *buffer); static int parse_index(git_index *index, const char *buffer, size_t buffer_size); static bool is_index_extended(git_index *index); -static int write_index(git_oid *checksum, git_index *index, git_filebuf *file); +static int write_index(unsigned char checksum[GIT_HASH_SHA1_SIZE], size_t *checksum_size, git_index *index, git_filebuf *file); static void index_entry_free(git_index_entry *entry); static void index_entry_reuc_free(git_index_reuc_entry *reuc); @@ -607,10 +606,12 @@ int git_index_caps(const git_index *index) (index->no_symlinks ? GIT_INDEX_CAPABILITY_NO_SYMLINKS : 0)); } +#ifndef GIT_DEPRECATE_HARD const git_oid *git_index_checksum(git_index *index) { - return &index->checksum; + return (git_oid *)index->checksum; } +#endif /** * Returns 1 for changed, 0 for not changed and <0 for errors @@ -619,24 +620,25 @@ static int compare_checksum(git_index *index) { int fd; ssize_t bytes_read; - git_oid checksum = {{ 0 }}; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size = GIT_HASH_SHA1_SIZE; if ((fd = p_open(index->index_file_path, O_RDONLY)) < 0) return fd; - if (p_lseek(fd, -20, SEEK_END) < 0) { + if (p_lseek(fd, (0 - (ssize_t)checksum_size), SEEK_END) < 0) { p_close(fd); git_error_set(GIT_ERROR_OS, "failed to seek to end of file"); return -1; } - bytes_read = p_read(fd, &checksum, GIT_OID_RAWSZ); + bytes_read = p_read(fd, checksum, checksum_size); p_close(fd); - if (bytes_read < 0) + if (bytes_read < (ssize_t)checksum_size) return -1; - return !!git_oid_cmp(&checksum, &index->checksum); + return !!memcmp(checksum, index->checksum, checksum_size); } int git_index_read(git_index *index, int force) @@ -703,16 +705,6 @@ int git_index_read_safely(git_index *index) return git_index_read(index, false); } -int git_index__changed_relative_to( - git_index *index, const git_oid *checksum) -{ - /* attempt to update index (ignoring errors) */ - if (git_index_read(index, false) < 0) - git_error_clear(); - - return !!git_oid_cmp(&index->checksum, checksum); -} - static bool is_racy_entry(git_index *index, const git_index_entry *entry) { /* Git special-cases submodules in the check */ @@ -2470,8 +2462,9 @@ static int read_entry( git_index_entry entry = {{0}}; bool compressed = index->version >= INDEX_VERSION_NUMBER_COMP; char *tmp_path = NULL; + size_t checksum_size = GIT_HASH_SHA1_SIZE; - if (INDEX_FOOTER_SIZE + minimal_entry_size > buffer_size) + if (checksum_size + minimal_entry_size > buffer_size) return -1; /* buffer is not guaranteed to be aligned */ @@ -2552,7 +2545,7 @@ static int read_entry( if (entry_size == 0) return -1; - if (INDEX_FOOTER_SIZE + entry_size > buffer_size) + if (checksum_size + entry_size > buffer_size) return -1; if (index_entry_dup(out, index, &entry) < 0) { @@ -2586,6 +2579,7 @@ static int read_extension(size_t *read_len, git_index *index, const char *buffer { struct index_extension dest; size_t total_size; + size_t checksum_size = GIT_HASH_SHA1_SIZE; /* buffer is not guaranteed to be aligned */ memcpy(&dest, buffer, sizeof(struct index_extension)); @@ -2595,7 +2589,7 @@ static int read_extension(size_t *read_len, git_index *index, const char *buffer if (dest.extension_size > total_size || buffer_size < total_size || - buffer_size - total_size < INDEX_FOOTER_SIZE) { + buffer_size - total_size < checksum_size) { index_error_invalid("extension is truncated"); return -1; } @@ -2632,7 +2626,8 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) int error = 0; unsigned int i; struct index_header header = { 0 }; - git_oid checksum_calculated, checksum_expected; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size = GIT_HASH_SHA1_SIZE; const char *last = NULL; const char *empty = ""; @@ -2644,12 +2639,12 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) buffer_size -= _increase;\ } - if (buffer_size < INDEX_HEADER_SIZE + INDEX_FOOTER_SIZE) + if (buffer_size < INDEX_HEADER_SIZE + checksum_size) return index_error_invalid("insufficient buffer space"); /* Precalculate the SHA1 of the files's contents -- we'll match it to * the provided SHA1 in the footer */ - git_hash_buf(checksum_calculated.id, buffer, buffer_size - INDEX_FOOTER_SIZE, GIT_HASH_ALGORITHM_SHA1); + git_hash_buf(checksum, buffer, buffer_size - checksum_size, GIT_HASH_ALGORITHM_SHA1); /* Parse header */ if ((error = read_header(&header, buffer)) < 0) @@ -2667,7 +2662,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) return error; /* Parse all the entries */ - for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) { + for (i = 0; i < header.entry_count && buffer_size > checksum_size; ++i) { git_index_entry *entry = NULL; size_t entry_size; @@ -2699,7 +2694,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) } /* There's still space for some extensions! */ - while (buffer_size > INDEX_FOOTER_SIZE) { + while (buffer_size > checksum_size) { size_t extension_size; if ((error = read_extension(&extension_size, index, buffer, buffer_size)) < 0) { @@ -2709,22 +2704,20 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) seek_forward(extension_size); } - if (buffer_size != INDEX_FOOTER_SIZE) { + if (buffer_size != checksum_size) { error = index_error_invalid( "buffer size does not match index footer size"); goto done; } /* 160-bit SHA-1 over the content of the index file before this checksum. */ - git_oid_fromraw(&checksum_expected, (const unsigned char *)buffer); - - if (git_oid__cmp(&checksum_calculated, &checksum_expected) != 0) { + if (memcmp(checksum, buffer, checksum_size) != 0) { error = index_error_invalid( "calculated checksum does not match expected"); goto done; } - git_oid_cpy(&index->checksum, &checksum_calculated); + memcpy(index->checksum, checksum, checksum_size); #undef seek_forward @@ -3040,9 +3033,12 @@ static void clear_uptodate(git_index *index) entry->flags_extended &= ~GIT_INDEX_ENTRY_UPTODATE; } -static int write_index(git_oid *checksum, git_index *index, git_filebuf *file) +static int write_index( + unsigned char checksum[GIT_HASH_SHA1_SIZE], + size_t *checksum_size, + git_index *index, + git_filebuf *file) { - git_oid hash_final; struct index_header header; bool is_extended; uint32_t index_version_number; @@ -3050,6 +3046,8 @@ static int write_index(git_oid *checksum, git_index *index, git_filebuf *file) GIT_ASSERT_ARG(index); GIT_ASSERT_ARG(file); + *checksum_size = GIT_HASH_SHA1_SIZE; + if (index->version <= INDEX_VERSION_NUMBER_EXT) { is_extended = is_index_extended(index); index_version_number = is_extended ? INDEX_VERSION_NUMBER_EXT : INDEX_VERSION_NUMBER_LB; @@ -3080,11 +3078,10 @@ static int write_index(git_oid *checksum, git_index *index, git_filebuf *file) return -1; /* get out the hash for all the contents we've appended to the file */ - git_filebuf_hash(hash_final.id, file); - git_oid_cpy(checksum, &hash_final); + git_filebuf_hash(checksum, file); /* write it at the end of the file */ - if (git_filebuf_write(file, hash_final.id, GIT_OID_RAWSZ) < 0) + if (git_filebuf_write(file, checksum, *checksum_size) < 0) return -1; /* file entries are no longer up to date */ @@ -3714,8 +3711,9 @@ int git_indexwriter_init_for_operation( int git_indexwriter_commit(git_indexwriter *writer) { + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size; int error; - git_oid checksum = {{ 0 }}; if (!writer->should_write) return 0; @@ -3723,7 +3721,7 @@ int git_indexwriter_commit(git_indexwriter *writer) git_vector_sort(&writer->index->entries); git_vector_sort(&writer->index->reuc); - if ((error = write_index(&checksum, writer->index, &writer->file)) < 0) { + if ((error = write_index(checksum, &checksum_size, writer->index, &writer->file)) < 0) { git_indexwriter_cleanup(writer); return error; } @@ -3739,7 +3737,7 @@ int git_indexwriter_commit(git_indexwriter *writer) writer->index->dirty = 0; writer->index->on_disk = 1; - git_oid_cpy(&writer->index->checksum, &checksum); + memcpy(writer->index->checksum, checksum, checksum_size); git_index_free(writer->index); writer->index = NULL; diff --git a/src/index.h b/src/index.h index a365867d0..71bb096f7 100644 --- a/src/index.h +++ b/src/index.h @@ -27,7 +27,7 @@ struct git_index { char *index_file_path; git_futils_filestamp stamp; - git_oid checksum; /* checksum at the end of the file */ + unsigned char checksum[GIT_HASH_SHA1_SIZE]; git_vector entries; git_idxmap *entries_map; @@ -133,10 +133,13 @@ extern unsigned int git_index__create_mode(unsigned int mode); GIT_INLINE(const git_futils_filestamp *) git_index__filestamp(git_index *index) { - return &index->stamp; + return &index->stamp; } -extern int git_index__changed_relative_to(git_index *index, const git_oid *checksum); +GIT_INLINE(unsigned char *) git_index__checksum(git_index *index) +{ + return index->checksum; +} /* Copy the current entries vector *and* increment the index refcount. * Call `git_index__release_snapshot` when done. diff --git a/src/indexer.c b/src/indexer.c index 16db9ca8d..f9a32e7ac 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -55,7 +55,8 @@ struct git_indexer { git_vector deltas; unsigned int fanout[256]; git_hash_ctx hash_ctx; - git_oid hash; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + char name[(GIT_HASH_SHA1_SIZE * 2) + 1]; git_indexer_progress_cb progress_cb; void *progress_payload; char objbuf[8*1024]; @@ -76,9 +77,16 @@ struct delta_info { off64_t delta_off; }; +#ifndef GIT_DEPRECATE_HARD const git_oid *git_indexer_hash(const git_indexer *idx) { - return &idx->hash; + return (git_oid *)idx->checksum; +} +#endif + +const char *git_indexer_name(const git_indexer *idx) +{ + return idx->name; } static int parse_header(struct git_pack_header *hdr, struct git_pack_file *pack) @@ -897,8 +905,7 @@ static int index_path(git_str *path, git_indexer *idx, const char *suffix) git_str_truncate(path, slash); git_str_puts(path, prefix); - git_oid_fmt(path->ptr + git_str_len(path), &idx->hash); - path->size += GIT_OID_HEXSZ; + git_str_puts(path, idx->name); git_str_puts(path, suffix); return git_str_oom(path) ? -1 : 0; @@ -919,12 +926,13 @@ static int inject_object(git_indexer *idx, git_oid *id) git_odb_object *obj = NULL; struct entry *entry = NULL; struct git_pack_entry *pentry = NULL; - git_oid foo = {{0}}; + unsigned char empty_checksum[GIT_HASH_SHA1_SIZE] = {0}; unsigned char hdr[64]; git_str buf = GIT_STR_INIT; off64_t entry_start; const void *data; size_t len, hdr_len; + size_t checksum_size = GIT_HASH_SHA1_SIZE; int error; if ((error = seek_back_trailer(idx)) < 0) @@ -966,7 +974,7 @@ static int inject_object(git_indexer *idx, git_oid *id) /* Write a fake trailer so the pack functions play ball */ - if ((error = append_to_pack(idx, &foo, GIT_OID_RAWSZ)) < 0) + if ((error = append_to_pack(idx, empty_checksum, checksum_size)) < 0) goto cleanup; idx->pack->mwf.size += GIT_OID_RAWSZ; @@ -1160,9 +1168,11 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) struct git_pack_idx_header hdr; git_str filename = GIT_STR_INIT; struct entry *entry; - git_oid trailer_hash, file_hash; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; git_filebuf index_file = {0}; void *packfile_trailer; + size_t checksum_size = GIT_HASH_SHA1_SIZE; + bool mismatch; if (!idx->parsed_header) { git_error_set(GIT_ERROR_INDEXER, "incomplete pack header"); @@ -1170,27 +1180,27 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) } /* Test for this before resolve_deltas(), as it plays with idx->off */ - if (idx->off + 20 < idx->pack->mwf.size) { + if (idx->off + (ssize_t)checksum_size < idx->pack->mwf.size) { git_error_set(GIT_ERROR_INDEXER, "unexpected data at the end of the pack"); return -1; } - if (idx->off + 20 > idx->pack->mwf.size) { + if (idx->off + (ssize_t)checksum_size > idx->pack->mwf.size) { git_error_set(GIT_ERROR_INDEXER, "missing trailer at the end of the pack"); return -1; } - packfile_trailer = git_mwindow_open(&idx->pack->mwf, &w, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ, &left); + packfile_trailer = git_mwindow_open(&idx->pack->mwf, &w, idx->pack->mwf.size - checksum_size, checksum_size, &left); if (packfile_trailer == NULL) { git_mwindow_close(&w); goto on_error; } /* Compare the packfile trailer as it was sent to us and what we calculated */ - git_oid_fromraw(&file_hash, packfile_trailer); + git_hash_final(checksum, &idx->trailer); + mismatch = !!memcmp(checksum, packfile_trailer, checksum_size); git_mwindow_close(&w); - git_hash_final(trailer_hash.id, &idx->trailer); - if (git_oid_cmp(&file_hash, &trailer_hash)) { + if (mismatch) { git_error_set(GIT_ERROR_INDEXER, "packfile trailer mismatch"); return -1; } @@ -1210,8 +1220,8 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) if (update_header_and_rehash(idx, stats) < 0) return -1; - git_hash_final(trailer_hash.id, &idx->trailer); - write_at(idx, &trailer_hash, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ); + git_hash_final(checksum, &idx->trailer); + write_at(idx, checksum, idx->pack->mwf.size - checksum_size, checksum_size); } /* @@ -1230,7 +1240,9 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) /* Use the trailer hash as the pack file name to ensure * files with different contents have different names */ - git_oid_cpy(&idx->hash, &trailer_hash); + memcpy(idx->checksum, checksum, checksum_size); + if (git_hash_fmt(idx->name, checksum, checksum_size) < 0) + return -1; git_str_sets(&filename, idx->pack->pack_name); git_str_shorten(&filename, strlen("pack")); @@ -1291,14 +1303,14 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats) } /* Write out the packfile trailer to the index */ - if (git_filebuf_write(&index_file, &trailer_hash, GIT_OID_RAWSZ) < 0) + if (git_filebuf_write(&index_file, checksum, checksum_size) < 0) goto on_error; /* Write out the hash of the idx */ - if (git_filebuf_hash(trailer_hash.id, &index_file) < 0) + if (git_filebuf_hash(checksum, &index_file) < 0) goto on_error; - git_filebuf_write(&index_file, &trailer_hash, sizeof(git_oid)); + git_filebuf_write(&index_file, checksum, checksum_size); /* Figure out what the final name should be */ if (index_path(&filename, idx, ".idx") < 0) diff --git a/src/midx.c b/src/midx.c index d4f9bd5a0..eb99e7373 100644 --- a/src/midx.c +++ b/src/midx.c @@ -178,7 +178,8 @@ int git_midx_parse( struct git_midx_chunk *last_chunk; uint32_t i; off64_t last_chunk_offset, chunk_offset, trailer_offset; - git_oid idx_checksum = {{0}}; + size_t checksum_size; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; int error; struct git_midx_chunk chunk_packfile_names = {0}, chunk_oid_fanout = {0}, @@ -208,14 +209,17 @@ int git_midx_parse( last_chunk_offset = sizeof(struct git_midx_header) + (1 + hdr->chunks) * 12; - trailer_offset = size - GIT_OID_RAWSZ; + + checksum_size = GIT_HASH_SHA1_SIZE; + trailer_offset = size - checksum_size; + if (trailer_offset < last_chunk_offset) return midx_error("wrong index size"); - git_oid_cpy(&idx->checksum, (git_oid *)(data + trailer_offset)); + memcpy(idx->checksum, data + trailer_offset, checksum_size); - if (git_hash_buf(idx_checksum.id, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) + if (git_hash_buf(checksum, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0) return midx_error("could not calculate signature"); - if (!git_oid_equal(&idx_checksum, &idx->checksum)) + if (memcmp(checksum, idx->checksum, checksum_size) != 0) return midx_error("index signature mismatch"); chunk_hdr = data + sizeof(struct git_midx_header); @@ -341,7 +345,8 @@ bool git_midx_needs_refresh( git_file fd = -1; struct stat st; ssize_t bytes_read; - git_oid idx_checksum = {{0}}; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size; /* TODO: properly open the file without access time using O_NOATIME */ fd = git_futils_open_ro(path); @@ -360,13 +365,14 @@ bool git_midx_needs_refresh( return true; } - bytes_read = p_pread(fd, &idx_checksum, GIT_OID_RAWSZ, st.st_size - GIT_OID_RAWSZ); + checksum_size = GIT_HASH_SHA1_SIZE; + bytes_read = p_pread(fd, checksum, checksum_size, st.st_size - GIT_OID_RAWSZ); p_close(fd); - if (bytes_read != GIT_OID_RAWSZ) + if (bytes_read != (ssize_t)checksum_size) return true; - return !git_oid_equal(&idx_checksum, &idx->checksum); + return (memcmp(checksum, idx->checksum, checksum_size) != 0); } int git_midx_entry_find( @@ -653,7 +659,8 @@ static int midx_write( oid_lookup = GIT_STR_INIT, object_offsets = GIT_STR_INIT, object_large_offsets = GIT_STR_INIT; - git_oid idx_checksum = {{0}}; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; + size_t checksum_size; git_midx_entry *entry; object_entry_array_t object_entries_array = GIT_ARRAY_INIT; git_vector object_entries = GIT_VECTOR_INIT; @@ -669,6 +676,7 @@ static int midx_write( hash_cb_data.cb_data = cb_data; hash_cb_data.ctx = &ctx; + checksum_size = GIT_HASH_SHA1_SIZE; error = git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1); if (error < 0) return error; @@ -820,10 +828,10 @@ static int midx_write( goto cleanup; /* Finalize the checksum and write the trailer. */ - error = git_hash_final(idx_checksum.id, &ctx); + error = git_hash_final(checksum, &ctx); if (error < 0) goto cleanup; - error = write_cb((const char *)&idx_checksum, sizeof(idx_checksum), cb_data); + error = write_cb((char *)checksum, checksum_size, cb_data); if (error < 0) goto cleanup; diff --git a/src/midx.h b/src/midx.h index ef3d534bc..7dd851bd3 100644 --- a/src/midx.h +++ b/src/midx.h @@ -51,7 +51,7 @@ typedef struct git_midx_file { size_t num_object_large_offsets; /* The trailer of the file. Contains the SHA1-checksum of the whole file. */ - git_oid checksum; + unsigned char checksum[GIT_HASH_SHA1_SIZE]; /* something like ".git/objects/pack/multi-pack-index". */ git_str filename; diff --git a/src/pack-objects.c b/src/pack-objects.c index e5fc625a4..35c1d55db 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -1422,7 +1422,12 @@ int git_packbuilder_write( if ((error = git_indexer_commit(indexer, &stats)) < 0) goto cleanup; +#ifndef GIT_DEPRECATE_HARD git_oid_cpy(&pb->pack_oid, git_indexer_hash(indexer)); +#endif + + pb->pack_name = git__strdup(git_indexer_name(indexer)); + GIT_ERROR_CHECK_ALLOC(pb->pack_name); cleanup: git_indexer_free(indexer); @@ -1432,10 +1437,17 @@ cleanup: #undef PREPARE_PACK +#ifndef GIT_DEPRECATE_HARD const git_oid *git_packbuilder_hash(git_packbuilder *pb) { return &pb->pack_oid; } +#endif + +const char *git_packbuilder_name(git_packbuilder *pb) +{ + return pb->pack_name; +} static int cb_tree_walk( @@ -1803,5 +1815,7 @@ void git_packbuilder_free(git_packbuilder *pb) git_hash_ctx_cleanup(&pb->ctx); git_zstream_free(&pb->zstream); + git__free(pb->pack_name); + git__free(pb); } diff --git a/src/pack-objects.h b/src/pack-objects.h index cefee40ef..53c9f5d45 100644 --- a/src/pack-objects.h +++ b/src/pack-objects.h @@ -73,7 +73,10 @@ struct git_packbuilder { git_oidmap *walk_objects; git_pool object_pool; +#ifndef GIT_DEPRECATE_HARD git_oid pack_oid; /* hash of written pack */ +#endif + char *pack_name; /* name of written pack */ /* synchronization objects */ git_mutex cache_mutex; diff --git a/src/reset.c b/src/reset.c index b8327fe5e..e0d942e5e 100644 --- a/src/reset.c +++ b/src/reset.c @@ -188,7 +188,10 @@ int git_reset( git_reset_t reset_type, const git_checkout_options *checkout_opts) { - return reset(repo, target, git_oid_tostr_s(git_object_id(target)), reset_type, checkout_opts); + char to[GIT_OID_HEXSZ + 1]; + + git_oid_tostr(to, GIT_OID_HEXSZ + 1, git_object_id(target)); + return reset(repo, target, to, reset_type, checkout_opts); } int git_reset_from_annotated( diff --git a/tests/checkout/crlf.c b/tests/checkout/crlf.c index 8fd16a004..21f8a852a 100644 --- a/tests/checkout/crlf.c +++ b/tests/checkout/crlf.c @@ -239,10 +239,10 @@ void test_checkout_crlf__autocrlf_false_index_size_is_unfiltered_size(void) cl_repo_set_bool(g_repo, "core.autocrlf", false); - git_repository_index(&index, g_repo); + cl_git_pass(git_repository_index(&index, g_repo)); tick_index(index); - git_checkout_head(g_repo, &opts); + cl_git_pass(git_checkout_head(g_repo, &opts)); cl_assert((entry = git_index_get_bypath(index, "all-lf", 0)) != NULL); cl_assert(entry->file_size == strlen(ALL_LF_TEXT_RAW)); diff --git a/tests/diff/workdir.c b/tests/diff/workdir.c index 444fc2f97..cdf53faa1 100644 --- a/tests/diff/workdir.c +++ b/tests/diff/workdir.c @@ -1,6 +1,7 @@ #include "clar_libgit2.h" #include "diff_helpers.h" #include "repository.h" +#include "index.h" #include "git2/sys/diff.h" #include "../checkout/checkout_helpers.h" @@ -2004,7 +2005,9 @@ void test_diff_workdir__only_writes_index_when_necessary(void) git_diff *diff = NULL; git_reference *head; git_object *head_object; - git_oid initial, first, second; + unsigned char initial[GIT_HASH_SHA1_SIZE], + first[GIT_HASH_SHA1_SIZE], + second[GIT_HASH_SHA1_SIZE]; git_str path = GIT_STR_INIT; struct stat st; struct p_timeval times[2]; @@ -2019,7 +2022,7 @@ void test_diff_workdir__only_writes_index_when_necessary(void) cl_git_pass(git_reset(g_repo, head_object, GIT_RESET_HARD, NULL)); - git_oid_cpy(&initial, git_index_checksum(index)); + memcpy(initial, git_index__checksum(index), GIT_HASH_SHA1_SIZE); /* update the index timestamp to avoid raciness */ cl_must_pass(p_stat("status/.git/index", &st)); @@ -2035,8 +2038,8 @@ void test_diff_workdir__only_writes_index_when_necessary(void) cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts)); git_diff_free(diff); - git_oid_cpy(&first, git_index_checksum(index)); - cl_assert(!git_oid_equal(&initial, &first)); + memcpy(first, git_index__checksum(index), GIT_HASH_SHA1_SIZE); + cl_assert(memcmp(initial, first, GIT_HASH_SHA1_SIZE) != 0); /* touch all the files so stat times are different */ cl_git_pass(git_str_sets(&path, "status")); @@ -2046,8 +2049,8 @@ void test_diff_workdir__only_writes_index_when_necessary(void) git_diff_free(diff); /* ensure the second diff did update the index */ - git_oid_cpy(&second, git_index_checksum(index)); - cl_assert(!git_oid_equal(&first, &second)); + memcpy(second, git_index__checksum(index), GIT_HASH_SHA1_SIZE); + cl_assert(memcmp(first, second, GIT_HASH_SHA1_SIZE) != 0); git_str_dispose(&path); git_object_free(head_object); diff --git a/tests/graph/commit_graph.c b/tests/graph/commitgraph.c index 83f53f1d4..7607c35a3 100644 --- a/tests/graph/commit_graph.c +++ b/tests/graph/commitgraph.c @@ -6,7 +6,7 @@ #include "commit_graph.h" #include "futils.h" -void test_graph_commit_graph__parse(void) +void test_graph_commitgraph__parse(void) { git_repository *repo; struct git_commit_graph_file *file; @@ -50,7 +50,7 @@ void test_graph_commit_graph__parse(void) git_str_dispose(&commit_graph_path); } -void test_graph_commit_graph__parse_octopus_merge(void) +void test_graph_commitgraph__parse_octopus_merge(void) { git_repository *repo; struct git_commit_graph_file *file; @@ -91,7 +91,7 @@ void test_graph_commit_graph__parse_octopus_merge(void) git_str_dispose(&commit_graph_path); } -void test_graph_commit_graph__writer(void) +void test_graph_commitgraph__writer(void) { git_repository *repo; git_commit_graph_writer *w = NULL; diff --git a/tests/pack/indexer.c b/tests/pack/indexer.c index 954bee953..ec48ffd98 100644 --- a/tests/pack/indexer.c +++ b/tests/pack/indexer.c @@ -169,8 +169,7 @@ void test_pack_indexer__fix_thin(void) cl_assert_equal_i(stats.indexed_objects, 2); cl_assert_equal_i(stats.local_objects, 1); - git_oid_fromstr(&should_id, "fefdb2d740a3a6b6c03a0c7d6ce431c6d5810e13"); - cl_assert_equal_oid(&should_id, git_indexer_hash(idx)); + cl_assert_equal_s("fefdb2d740a3a6b6c03a0c7d6ce431c6d5810e13", git_indexer_name(idx)); git_indexer_free(idx); git_odb_free(odb); diff --git a/tests/pack/packbuilder.c b/tests/pack/packbuilder.c index 5b1f7b9e9..f23579817 100644 --- a/tests/pack/packbuilder.c +++ b/tests/pack/packbuilder.c @@ -5,6 +5,7 @@ #include "iterator.h" #include "vector.h" #include "posix.h" +#include "hash.h" static git_repository *_repo; static git_revwalk *_revwalker; @@ -98,8 +99,8 @@ void test_pack_packbuilder__create_pack(void) git_indexer_progress stats; git_str buf = GIT_STR_INIT, path = GIT_STR_INIT; git_hash_ctx ctx; - git_oid hash; - char hex[GIT_OID_HEXSZ+1]; hex[GIT_OID_HEXSZ] = '\0'; + unsigned char hash[GIT_HASH_SHA1_SIZE]; + char hex[(GIT_HASH_SHA1_SIZE * 2) + 1]; seed_packbuilder(); @@ -107,8 +108,7 @@ void test_pack_packbuilder__create_pack(void) cl_git_pass(git_packbuilder_foreach(_packbuilder, feed_indexer, &stats)); cl_git_pass(git_indexer_commit(_indexer, &stats)); - git_oid_fmt(hex, git_indexer_hash(_indexer)); - git_str_printf(&path, "pack-%s.pack", hex); + git_str_printf(&path, "pack-%s.pack", git_indexer_name(_indexer)); /* * By default, packfiles are created with only one thread. @@ -128,27 +128,22 @@ void test_pack_packbuilder__create_pack(void) cl_git_pass(git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1)); cl_git_pass(git_hash_update(&ctx, buf.ptr, buf.size)); - cl_git_pass(git_hash_final(hash.id, &ctx)); + cl_git_pass(git_hash_final(hash, &ctx)); git_hash_ctx_cleanup(&ctx); git_str_dispose(&path); git_str_dispose(&buf); - git_oid_fmt(hex, &hash); - + git_hash_fmt(hex, hash, GIT_HASH_SHA1_SIZE); cl_assert_equal_s(hex, "5d410bdf97cf896f9007681b92868471d636954b"); } -void test_pack_packbuilder__get_hash(void) +void test_pack_packbuilder__get_name(void) { - char hex[GIT_OID_HEXSZ+1]; hex[GIT_OID_HEXSZ] = '\0'; - seed_packbuilder(); cl_git_pass(git_packbuilder_write(_packbuilder, ".", 0, NULL, NULL)); - git_oid_fmt(hex, git_packbuilder_hash(_packbuilder)); - - cl_assert_equal_s(hex, "7f5fa362c664d68ba7221259be1cbd187434b2f0"); + cl_assert_equal_s("7f5fa362c664d68ba7221259be1cbd187434b2f0", git_packbuilder_name(_packbuilder)); } void test_pack_packbuilder__write_default_path(void) |