]> git.proxmox.com Git - libgit2.git/commitdiff
index: Add API for unmerged entries
authorJakob Pfender <jpfender@elegosoft.com>
Thu, 21 Apr 2011 08:54:54 +0000 (10:54 +0200)
committerJakob Pfender <jpfender@elegosoft.com>
Thu, 21 Apr 2011 08:54:54 +0000 (10:54 +0200)
New external functions:
- git_index_unmerged_entrycount: Counts the unmerged entries in
  the index
- git_index_get_unmerged: Gets an unmerged entry from the index
  by name

New internal functions:
- read_unmerged: Wrapper for read_unmerged_internal
- read_unmerged_internal: Reads unmerged entries from the index
  if the index has the INDEX_EXT_UNMERGED_SIG set
- unmerged_srch: Search function for unmerged vector
- unmerged_cmp: Compare function for unmerged vector

New data structures:
- git_index now contains a git_vector unmerged that stores
  unmerged entries
- git_index_entry_unmerged: Representation of an unmerged file
  entry. It represents all three versions of the file at the
  same time, with one name, three modes and three OIDs

include/git2/index.h
src/index.c
src/index.h

index 8a84f507b98515c86485a3f670c10cb3b2ebd869..09993a15491699aa6343e709bb0f2d2b30751f5e 100644 (file)
@@ -111,6 +111,12 @@ typedef struct git_index_entry {
        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
@@ -233,6 +239,24 @@ GIT_EXTERN(git_index_entry *) git_index_get(git_index *index, int n);
  */
 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
index 68bb9e2b954e19358aa45ea3f3c1af63a8d4f831..6a2afda06c903f4f0db059b303200fccd1ae04fe 100644 (file)
@@ -46,6 +46,7 @@ static const unsigned int INDEX_VERSION_NUMBER_EXT = 3;
 
 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;
@@ -98,7 +99,9 @@ static size_t read_entry(git_index_entry *dest, const void *buffer, size_t buffe
 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);
@@ -120,6 +123,21 @@ int index_cmp(const void *a, const void *b)
        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)
 {
@@ -142,6 +160,7 @@ static int index_initialize(git_index **index_out, git_repository *owner, const
        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)
@@ -282,6 +301,16 @@ unsigned int git_index_entrycount(git_index *index)
        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);
@@ -406,6 +435,22 @@ int git_index_find(git_index *index, const char *path)
        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)
 {
@@ -488,6 +533,68 @@ static int read_tree(git_index *index, const char *buffer, size_t buffer_size)
        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;
@@ -593,6 +700,13 @@ static size_t read_extension(git_index *index, const char *buffer, size_t buffer
 
                        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;
index e1e752f7c223c947bc592a346c36a043d4fe58d9..f2402fd71d5ce8b36f768a53e299e0f59d4d08cd 100644 (file)
@@ -29,6 +29,8 @@ struct git_index {
 
        unsigned int on_disk:1;
        git_index_tree *tree;
+
+       git_vector unmerged;
 };
 
 #endif