summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/git2/index.h36
-rw-r--r--src/index.c25
-rw-r--r--src/odb_pack.c9
-rw-r--r--src/refs.c10
-rw-r--r--src/repository.c3
-rw-r--r--src/revwalk.c4
-rw-r--r--src/tree.c3
-rw-r--r--tests/t07-hashtable.c2
-rw-r--r--tests/t09-tree.c40
-rw-r--r--tests/t10-refs.c46
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")