char *path;
} git_index_entry;
+/** Representation of an unmerged file entry in the index. */
+typedef struct git_index_entry_unmerged {
+ unsigned int mode[3];
+ git_oid oid[3];
+ char *path;
+} git_index_entry_unmerged;
/**
* Create a new Git index object as a memory representation
*/
GIT_EXTERN(unsigned int) git_index_entrycount(git_index *index);
+/**
+ * Get the count of unmerged entries currently in the index
+ *
+ * @param index an existing index object
+ * @return integer of count of current unmerged entries
+ */
+GIT_EXTERN(unsigned int) git_index_unmerged_entrycount(git_index *index);
+
+/**
+ * Get an unmerged entry from the index.
+ *
+ * @param entry the pointer to the new unmerged entry
+ * @param index an existing index object
+ * @param path path to search
+ * @return 0 on success, otherwise an error code
+ */
+GIT_EXTERN(int) git_index_get_unmerged(git_index_entry_unmerged **entry, git_index *index, const char *path);
+
/** @} */
GIT_END_DECL
static const unsigned int INDEX_HEADER_SIG = 0x44495243;
static const char INDEX_EXT_TREECACHE_SIG[] = {'T', 'R', 'E', 'E'};
+static const char INDEX_EXT_UNMERGED_SIG[] = {'R', 'E', 'U', 'C'};
struct index_header {
uint32_t signature;
static int read_header(struct index_header *dest, const void *buffer);
static int read_tree(git_index *index, const char *buffer, size_t buffer_size);
+static int read_unmerged_internal(git_index *, const char **, size_t buffer_size);
static git_index_tree *read_tree_internal(const char **, const char *, git_index_tree *);
+static int read_unmerged_internal(git_index *, const char **, size_t buffer_size);
static int parse_index(git_index *index, const char *buffer, size_t buffer_size);
static void sort_index(git_index *index);
return strcmp(entry_a->path, entry_b->path);
}
+int unmerged_srch(const void *key, const void *array_member)
+{
+ const char *path = (const char *) key;
+ const git_index_entry_unmerged *entry = *(const git_index_entry_unmerged **) (array_member);
+
+ return strcmp(path, entry->path);
+}
+
+int unmerged_cmp(const void *a, const void *b)
+{
+ const git_index_entry_unmerged *info_a = *(const git_index_entry_unmerged **)(a);
+ const git_index_entry_unmerged *info_b = *(const git_index_entry_unmerged **)(b);
+
+ return strcmp(info_a->path, info_b->path);
+}
static int index_initialize(git_index **index_out, git_repository *owner, const char *index_path)
{
index->repository = owner;
git_vector_init(&index->entries, 32, index_cmp);
+ git_vector_init(&index->unmerged, 32, unmerged_cmp);
/* Check if index file is stored on disk already */
if (gitfo_exists(index->index_file_path) == 0)
return index->entries.length;
}
+unsigned int git_index_unmerged_entrycount(git_index *index)
+{
+ assert(index);
+
+ if (!&index->unmerged)
+ return 0;
+
+ return index->unmerged.length;
+}
+
git_index_entry *git_index_get(git_index *index, int n)
{
assert(index);
return git_vector_bsearch2(&index->entries, index_srch, path);
}
+int git_index_get_unmerged(git_index_entry_unmerged **entry, git_index *index, const char *path)
+{
+ int pos;
+ assert(index);
+
+ if ((pos = git_vector_bsearch2(&index->unmerged, unmerged_srch, path)) < GIT_SUCCESS)
+ return pos;
+
+ if ((*entry = git_vector_get(&index->unmerged, pos)) == NULL) {
+ return GIT_ENOTFOUND;
+ }
+
+ return GIT_SUCCESS;
+}
+
+
static git_index_tree *read_tree_internal(
const char **buffer_in, const char *buffer_end, git_index_tree *parent)
{
return (index->tree != NULL && buffer == buffer_end) ? GIT_SUCCESS : GIT_EOBJCORRUPTED;
}
+static int read_unmerged_internal(
+ git_index *index, const char **buffer_in, size_t buffer_size)
+{
+ const char *buffer, *endptr;
+ size_t size, len;
+ int i;
+
+ size = buffer_size;
+
+ while (size) {
+ git_index_entry_unmerged *lost;
+
+ buffer = *buffer_in;
+
+ len = strlen(buffer) + 1;
+ if (size <= len)
+ return GIT_ERROR;
+
+ if ((lost = git__malloc(sizeof(git_index_entry_unmerged))) == NULL)
+ return GIT_ERROR;
+
+ if ((lost->path = git__malloc(strlen(buffer))) == NULL)
+ return GIT_ERROR;
+ strcpy(lost->path, buffer);
+
+ if (git_vector_insert(&index->unmerged, lost) < GIT_SUCCESS)
+ return GIT_ERROR;
+
+ size -= len;
+ buffer += len;
+
+ for (i = 0; i < 3; i++) {
+ if (git__strtol32((long int *) &lost->mode[i], buffer, &endptr, 8) < GIT_SUCCESS || !endptr || endptr == buffer || *endptr)
+ return GIT_ERROR;
+ len = (endptr + 1) - (char *) buffer;
+ if (size <= len)
+ return GIT_ERROR;
+ size -= len;
+ buffer += len;
+ }
+
+ for (i = 0; i < 3; i++) {
+ if (!lost->mode[i])
+ continue;
+ if (size < 20)
+ return GIT_ERROR;
+ git_oid_mkraw(&lost->oid[i], (unsigned char *) buffer);
+ size -= 20;
+ buffer += 20;
+ }
+ }
+
+ *buffer_in = buffer;
+ return GIT_SUCCESS;
+}
+
+static int read_unmerged(git_index *index, const char *buffer, size_t buffer_size)
+{
+ read_unmerged_internal(index, &buffer, buffer_size);
+ return (&index->unmerged != NULL) ? GIT_SUCCESS : GIT_EOBJCORRUPTED;
+}
+
static size_t read_entry(git_index_entry *dest, const void *buffer, size_t buffer_size)
{
size_t path_length, entry_size;
if (read_tree(index, buffer + 8, dest.extension_size) < GIT_SUCCESS)
return 0;
+
+ } else if (memcmp(dest.signature, INDEX_EXT_UNMERGED_SIG, 4) == 0) {
+
+ if (read_unmerged(index, buffer + 8, dest.extension_size) < GIT_SUCCESS)
+ return 0;
+ } else {
+ ;
}
} else {
/* we cannot handle non-ignorable extensions;