diff options
| -rw-r--r-- | include/git2/index.h | 36 | ||||
| -rw-r--r-- | src/index.c | 25 | ||||
| -rw-r--r-- | src/odb_pack.c | 9 | ||||
| -rw-r--r-- | src/refs.c | 10 | ||||
| -rw-r--r-- | src/repository.c | 3 | ||||
| -rw-r--r-- | src/revwalk.c | 4 | ||||
| -rw-r--r-- | src/tree.c | 3 | ||||
| -rw-r--r-- | tests/t07-hashtable.c | 2 | ||||
| -rw-r--r-- | tests/t09-tree.c | 40 | ||||
| -rw-r--r-- | tests/t10-refs.c | 46 |
10 files changed, 111 insertions, 67 deletions
diff --git a/include/git2/index.h b/include/git2/index.h index 98a17a18c..7991de92e 100644 --- a/include/git2/index.h +++ b/include/git2/index.h @@ -51,39 +51,29 @@ GIT_BEGIN_DECL * * In-memory only flags: */ -#define GIT_IDXENTRY_UPDATE (1 << 16) -#define GIT_IDXENTRY_REMOVE (1 << 17) -#define GIT_IDXENTRY_UPTODATE (1 << 18) -#define GIT_IDXENTRY_ADDED (1 << 19) +#define GIT_IDXENTRY_UPDATE (1 << 0) +#define GIT_IDXENTRY_REMOVE (1 << 1) +#define GIT_IDXENTRY_UPTODATE (1 << 2) +#define GIT_IDXENTRY_ADDED (1 << 3) -#define GIT_IDXENTRY_HASHED (1 << 20) -#define GIT_IDXENTRY_UNHASHED (1 << 21) -#define GIT_IDXENTRY_WT_REMOVE (1 << 22) /* remove in work directory */ -#define GIT_IDXENTRY_CONFLICTED (1 << 23) +#define GIT_IDXENTRY_HASHED (1 << 4) +#define GIT_IDXENTRY_UNHASHED (1 << 5) +#define GIT_IDXENTRY_WT_REMOVE (1 << 6) /* remove in work directory */ +#define GIT_IDXENTRY_CONFLICTED (1 << 7) -#define GIT_IDXENTRY_UNPACKED (1 << 24) -#define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 25) +#define GIT_IDXENTRY_UNPACKED (1 << 8) +#define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 9) /* * Extended on-disk flags: */ -#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 29) -#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 30) +#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13) +#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14) /* GIT_IDXENTRY_EXTENDED2 is for future extension */ -#define GIT_IDXENTRY_EXTENDED2 (1 << 31) +#define GIT_IDXENTRY_EXTENDED2 (1 << 15) #define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE) -/* - * Safeguard to avoid saving wrong flags: - * - GIT_IDXENTRY_EXTENDED2 won't get saved until its semantic is known - * - Bits in 0x0000FFFF have been saved in flags already - * - Bits in 0x003F0000 are currently in-memory flags - */ -#if GIT_IDXENTRY_EXTENDED_FLAGS & 0x803FFFFF -#error "GIT_IDXENTRY_EXTENDED_FLAGS out of range" -#endif - /** Time used in a git index entry */ typedef struct { git_time_t seconds; diff --git a/src/index.c b/src/index.c index 850f5de85..130d1fd36 100644 --- a/src/index.c +++ b/src/index.c @@ -101,6 +101,7 @@ static int read_tree(git_index *index, const char *buffer, size_t buffer_size); static git_index_tree *read_tree_internal(const char **, const char *, git_index_tree *); static int parse_index(git_index *index, const char *buffer, size_t buffer_size); +static int is_index_extended(git_index *index); static void sort_index(git_index *index); static int write_index(git_index *index, git_filebuf *file); @@ -718,6 +719,24 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) return GIT_SUCCESS; } +static int is_index_extended(git_index *index) +{ + unsigned int i, extended; + + extended = 0; + + for (i = 0; i < index->entries.length; ++i) { + git_index_entry *entry; + entry = git_vector_get(&index->entries, i); + entry->flags &= ~GIT_IDXENTRY_EXTENDED; + if (entry->flags_extended & GIT_IDXENTRY_EXTENDED_FLAGS) { + extended++; + entry->flags |= GIT_IDXENTRY_EXTENDED; + } + } + return extended; +} + static int write_disk_entry(git_filebuf *file, git_index_entry *entry) { struct entry_short *ondisk; @@ -786,12 +805,14 @@ static int write_index(git_index *index, git_filebuf *file) struct index_header header; - int is_extended = 1; + int is_extended; assert(index && file); + is_extended = is_index_extended(index); + header.signature = htonl(INDEX_HEADER_SIG); - header.version = htonl(is_extended ? INDEX_VERSION_NUMBER : INDEX_VERSION_NUMBER_EXT); + header.version = htonl(is_extended ? INDEX_VERSION_NUMBER_EXT : INDEX_VERSION_NUMBER); header.entry_count = htonl(index->entries.length); git_filebuf_write(file, &header, sizeof(struct index_header)); diff --git a/src/odb_pack.c b/src/odb_pack.c index 40ef48faf..57ad5e34b 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -113,7 +113,7 @@ struct pack_backend { git_vector packs; struct pack_file *last_found; char *pack_folder; - size_t pack_folder_size; + time_t pack_folder_mtime; size_t window_size; /* needs default value */ @@ -874,7 +874,7 @@ static int packfile_refresh_all(struct pack_backend *backend) if (gitfo_stat(backend->pack_folder, &st) < 0 || !S_ISDIR(st.st_mode)) return GIT_ENOTFOUND; - if ((size_t)st.st_size != backend->pack_folder_size) { + if (st.st_mtime != backend->pack_folder_mtime) { char path[GIT_PATH_MAX]; strcpy(path, backend->pack_folder); @@ -884,7 +884,7 @@ static int packfile_refresh_all(struct pack_backend *backend) return error; git_vector_sort(&backend->packs); - backend->pack_folder_size = (size_t)st.st_size; + backend->pack_folder_mtime = st.st_mtime; } return GIT_SUCCESS; @@ -1385,6 +1385,7 @@ void pack_backend__free(git_odb_backend *_backend) } git_vector_free(&backend->packs); + free(backend->pack_folder); free(backend); } @@ -1408,7 +1409,7 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir) git__joinpath(path, objects_dir, "pack"); if (gitfo_isdir(path) == GIT_SUCCESS) { backend->pack_folder = git__strdup(path); - backend->pack_folder_size = 0; + backend->pack_folder_mtime = 0; if (backend->pack_folder == NULL) { free(backend); diff --git a/src/refs.c b/src/refs.c index b88e047e1..ea968196f 100644 --- a/src/refs.c +++ b/src/refs.c @@ -684,7 +684,7 @@ static int packed_loadloose(git_repository *repository) /* Remove any loose references from the cache */ { - const void *_unused; + const void *GIT_UNUSED(_unused); git_reference *reference; GIT_HASHTABLE_FOREACH(repository->references.loose_cache, _unused, reference, @@ -787,6 +787,8 @@ static int packed_find_peel(reference_oid *ref) */ } + git_object_close(object); + return GIT_SUCCESS; } @@ -868,7 +870,7 @@ static int packed_write(git_repository *repo) /* Load all the packfile into a vector */ { git_reference *reference; - const void *_unused; + const void *GIT_UNUSED(_unused); GIT_HASHTABLE_FOREACH(repo->references.packfile, _unused, reference, git_vector_insert(&packing_list, reference); /* cannot fail: vector already has the right size */ @@ -1519,7 +1521,7 @@ int git_reference_listcb(git_repository *repo, unsigned int list_flags, int (*ca /* list all the packed references first */ if (list_flags & GIT_REF_PACKED) { const char *ref_name; - void *_unused; + void *GIT_UNUSED(_unused); if ((error = packed_load(repo)) < GIT_SUCCESS) return error; @@ -1598,7 +1600,7 @@ int git_repository__refcache_init(git_refcache *refs) void git_repository__refcache_free(git_refcache *refs) { git_reference *reference; - const void *_unused; + const void *GIT_UNUSED(_unused); assert(refs); diff --git a/src/repository.c b/src/repository.c index c428b00af..8cc2644ca 100644 --- a/src/repository.c +++ b/src/repository.c @@ -58,7 +58,6 @@ static int assign_repository_dirs( const char *git_work_tree) { char path_aux[GIT_PATH_MAX]; - size_t git_dir_path_len; int error = GIT_SUCCESS; assert(repo); @@ -70,8 +69,6 @@ static int assign_repository_dirs( if (error < GIT_SUCCESS) return error; - git_dir_path_len = strlen(path_aux); - /* store GIT_DIR */ repo->path_repository = git__strdup(path_aux); if (repo->path_repository == NULL) diff --git a/src/revwalk.c b/src/revwalk.c index b62b09961..78798480f 100644 --- a/src/revwalk.c +++ b/src/revwalk.c @@ -483,7 +483,7 @@ int git_revwalk_new(git_revwalk **revwalk_out, git_repository *repo) void git_revwalk_free(git_revwalk *walk) { unsigned int i; - const void *_unused; + const void *GIT_UNUSED(_unused); commit_object *commit; if (walk == NULL) @@ -558,7 +558,7 @@ int git_revwalk_next(git_oid *oid, git_revwalk *walk) void git_revwalk_reset(git_revwalk *walk) { - const void *_unused; + const void *GIT_UNUSED(_unused); commit_object *commit; assert(walk); diff --git a/src/tree.c b/src/tree.c index 64f81d780..b7daf39c4 100644 --- a/src/tree.c +++ b/src/tree.c @@ -424,7 +424,8 @@ int git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *b if (entry->removed) continue; - size += (entry->attr > 0x7FF) ? 7 : 6; + snprintf(filemode, sizeof(filemode), "%o ", entry->attr); + size += strlen(filemode); size += entry->filename_len + 1; size += GIT_OID_RAWSZ; } diff --git a/tests/t07-hashtable.c b/tests/t07-hashtable.c index 597136965..0b362cafd 100644 --- a/tests/t07-hashtable.c +++ b/tests/t07-hashtable.c @@ -155,7 +155,7 @@ BEGIN_TEST(tableit0, "iterate through all the contents of the table") const int objects_n = 32; int i; table_item *objects, *ob; - const void *_unused; + const void *GIT_UNUSED(_unused); git_hashtable *table = NULL; diff --git a/tests/t09-tree.c b/tests/t09-tree.c index 9b39dfd07..af992fdb3 100644 --- a/tests/t09-tree.c +++ b/tests/t09-tree.c @@ -32,6 +32,7 @@ static const char *tree_oid = "1810dff58d8a660512d4832e740f692884338ccd"; static const char *blob_oid = "fa49b077972391ad58037050f2a75f74e3671e92"; static const char *first_tree = "181037049a54a1eb5fab404658a3a250b44335d7"; static const char *second_tree = "f60079018b664e4e79329a7ef9559c8d9e0378d1"; +static const char *third_tree = "eb86d8b81d6adbd5290a935d6c9976882de98488"; #if 0 static int print_tree(git_repository *repo, const git_oid *tree_oid, int depth) @@ -159,6 +160,44 @@ BEGIN_TEST(write2, "write a tree from a memory") close_temp_repo(repo); END_TEST +BEGIN_TEST(write3, "write a hierarchical tree from a memory") + git_repository *repo; + git_treebuilder *builder; + git_tree *tree; + git_oid id, bid, subtree_id, id2, id3; + git_oid id_hiearar; + + must_pass(open_temp_repo(&repo, REPOSITORY_FOLDER)); + git_oid_mkstr(&id, first_tree); + git_oid_mkstr(&id2, second_tree); + git_oid_mkstr(&id3, third_tree); + git_oid_mkstr(&bid, blob_oid); + + //create subtree + must_pass(git_treebuilder_create(&builder, NULL)); + must_pass(git_treebuilder_insert(NULL,builder,"new.txt",&bid,0100644)); + must_pass(git_treebuilder_write(&subtree_id,repo,builder)); + git_treebuilder_free(builder); + + // create parent tree + must_pass(git_tree_lookup(&tree, repo, &id)); + must_pass(git_treebuilder_create(&builder, tree)); + must_pass(git_treebuilder_insert(NULL,builder,"new",&subtree_id,040000)); + must_pass(git_treebuilder_write(&id_hiearar,repo,builder)); + git_treebuilder_free(builder); + git_tree_close(tree); + + must_be_true(git_oid_cmp(&id_hiearar, &id3) == 0); + + // check data is correct + must_pass(git_tree_lookup(&tree, repo, &id_hiearar)); + must_be_true(2 == git_tree_entrycount(tree)); + git_tree_close(tree); + + close_temp_repo(repo); + +END_TEST + BEGIN_SUITE(tree) //ADD_TEST(print0); ADD_TEST(read0); @@ -166,5 +205,6 @@ BEGIN_SUITE(tree) //ADD_TEST(write0); //ADD_TEST(write1); ADD_TEST(write2); + ADD_TEST(write3); END_SUITE diff --git a/tests/t10-refs.c b/tests/t10-refs.c index d3f5620c9..db767a107 100644 --- a/tests/t10-refs.c +++ b/tests/t10-refs.c @@ -198,7 +198,7 @@ END_TEST BEGIN_TEST(create0, "create a new symbolic reference") git_reference *new_reference, *looked_up_ref, *resolved_ref; - git_repository *repo; + git_repository *repo, *repo2; git_oid id; char ref_path[GIT_PATH_MAX]; @@ -206,7 +206,7 @@ BEGIN_TEST(create0, "create a new symbolic reference") git_oid_mkstr(&id, current_master_tip); - must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); + must_pass(open_temp_repo(&repo, REPOSITORY_FOLDER)); /* Retrieve the physical path to the symbolic ref for further cleaning */ git__joinpath(ref_path, repo->path_repository, new_head_tracker); @@ -230,14 +230,13 @@ BEGIN_TEST(create0, "create a new symbolic reference") git_repository_free(repo); /* Similar test with a fresh new repository */ - must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); + must_pass(git_repository_open(&repo2, TEMP_REPO_FOLDER)); - must_pass(git_reference_lookup(&looked_up_ref, repo, new_head_tracker)); + must_pass(git_reference_lookup(&looked_up_ref, repo2, new_head_tracker)); must_pass(git_reference_resolve(&resolved_ref, looked_up_ref)); must_be_true(git_oid_cmp(&id, git_reference_oid(resolved_ref)) == 0); - git_reference_delete(looked_up_ref); - git_repository_free(repo); + close_temp_repo(repo2); END_TEST BEGIN_TEST(create1, "create a deep symbolic reference") @@ -250,7 +249,7 @@ BEGIN_TEST(create1, "create a deep symbolic reference") git_oid_mkstr(&id, current_master_tip); - must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); + must_pass(open_temp_repo(&repo, REPOSITORY_FOLDER)); git__joinpath(ref_path, repo->path_repository, new_head_tracker); must_pass(git_reference_create_symbolic(&new_reference, repo, new_head_tracker, current_head_target)); @@ -258,13 +257,12 @@ BEGIN_TEST(create1, "create a deep symbolic reference") must_pass(git_reference_resolve(&resolved_ref, looked_up_ref)); must_be_true(git_oid_cmp(&id, git_reference_oid(resolved_ref)) == 0); - git_reference_delete(looked_up_ref); - git_repository_free(repo); + close_temp_repo(repo); END_TEST BEGIN_TEST(create2, "create a new OID reference") git_reference *new_reference, *looked_up_ref; - git_repository *repo; + git_repository *repo, *repo2; git_oid id; char ref_path[GIT_PATH_MAX]; @@ -272,7 +270,7 @@ BEGIN_TEST(create2, "create a new OID reference") git_oid_mkstr(&id, current_master_tip); - must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); + must_pass(open_temp_repo(&repo, REPOSITORY_FOLDER)); /* Retrieve the physical path to the symbolic ref for further cleaning */ git__joinpath(ref_path, repo->path_repository, new_head); @@ -292,13 +290,12 @@ BEGIN_TEST(create2, "create a new OID reference") git_repository_free(repo); /* Similar test with a fresh new repository */ - must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); + must_pass(git_repository_open(&repo2, TEMP_REPO_FOLDER)); must_pass(git_reference_lookup(&looked_up_ref, repo, new_head)); must_be_true(git_oid_cmp(&id, git_reference_oid(looked_up_ref)) == 0); - git_reference_delete(looked_up_ref); - git_repository_free(repo); + close_temp_repo(repo2); END_TEST BEGIN_TEST(create3, "Can not create a new OID reference which targets at an unknown id") @@ -329,7 +326,7 @@ BEGIN_TEST(overwrite0, "Overwrite an existing symbolic reference") git_reference *ref, *branch_ref; git_repository *repo; - must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); + must_pass(open_temp_repo(&repo, REPOSITORY_FOLDER)); /* The target needds to exist and we need to check the name has changed */ must_pass(git_reference_create_symbolic(&branch_ref, repo, ref_branch_name, ref_master_name)); @@ -348,9 +345,7 @@ BEGIN_TEST(overwrite0, "Overwrite an existing symbolic reference") must_be_true(git_reference_type(ref) & GIT_REF_SYMBOLIC); must_be_true(!strcmp(git_reference_target(ref), ref_master_name)); - must_pass(git_reference_delete(ref)); - must_pass(git_reference_delete(branch_ref)); - git_repository_free(repo); + close_temp_repo(repo); END_TEST BEGIN_TEST(overwrite1, "Overwrite an existing object id reference") @@ -358,7 +353,7 @@ BEGIN_TEST(overwrite1, "Overwrite an existing object id reference") git_repository *repo; git_oid id; - must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); + must_pass(open_temp_repo(&repo, REPOSITORY_FOLDER)); must_pass(git_reference_lookup(&ref, repo, ref_master_name)); must_be_true(ref->type & GIT_REF_OID); @@ -379,8 +374,7 @@ BEGIN_TEST(overwrite1, "Overwrite an existing object id reference") must_pass(git_reference_lookup(&ref, repo, ref_name)); must_be_true(!git_oid_cmp(&id, git_reference_oid(ref))); - git_reference_delete(ref); - git_repository_free(repo); + close_temp_repo(repo); END_TEST BEGIN_TEST(overwrite2, "Overwrite an existing object id reference with a symbolic one") @@ -388,7 +382,7 @@ BEGIN_TEST(overwrite2, "Overwrite an existing object id reference with a symboli git_repository *repo; git_oid id; - must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); + must_pass(open_temp_repo(&repo, REPOSITORY_FOLDER)); must_pass(git_reference_lookup(&ref, repo, ref_master_name)); must_be_true(ref->type & GIT_REF_OID); @@ -403,8 +397,7 @@ BEGIN_TEST(overwrite2, "Overwrite an existing object id reference with a symboli must_be_true(git_reference_type(ref) & GIT_REF_SYMBOLIC); must_be_true(!strcmp(git_reference_target(ref), ref_master_name)); - git_reference_delete(ref); - git_repository_free(repo); + close_temp_repo(repo); END_TEST BEGIN_TEST(overwrite3, "Overwrite an existing symbolic reference with an object id one") @@ -412,7 +405,7 @@ BEGIN_TEST(overwrite3, "Overwrite an existing symbolic reference with an object git_repository *repo; git_oid id; - must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); + must_pass(open_temp_repo(&repo, REPOSITORY_FOLDER)); must_pass(git_reference_lookup(&ref, repo, ref_master_name)); must_be_true(ref->type & GIT_REF_OID); @@ -429,8 +422,7 @@ BEGIN_TEST(overwrite3, "Overwrite an existing symbolic reference with an object must_be_true(git_reference_type(ref) & GIT_REF_OID); must_be_true(!git_oid_cmp(git_reference_oid(ref), &id)); - git_reference_delete(ref); - git_repository_free(repo); + close_temp_repo(repo); END_TEST BEGIN_TEST(pack0, "create a packfile for an empty folder") |
