Commit f7a5058aaf51635b3171eda182820a8f8c750060

Vicent Marti 2011-04-24T00:31:43

index: Refactor add/replace methods Removed the optional `replace` argument, we now have 4 add methods: `git_index_add`: add or update from path `git_index_add2`: add or update from struct `git_index_append`: add without replacing from path `git_index_append2`: add without replacing from struct Yes, this breaks the bindings.

diff --git a/include/git2/index.h b/include/git2/index.h
index adc4cb4..98a17a1 100644
--- a/include/git2/index.h
+++ b/include/git2/index.h
@@ -182,7 +182,12 @@ GIT_EXTERN(int) git_index_write(git_index *index);
 GIT_EXTERN(int) git_index_find(git_index *index, const char *path);
 
 /**
- * Add or update an index entry from a file in disk.
+ * Add or update an index entry from a file in disk
+ *
+ * The file `path` must be relative to the repository's
+ * working folder and must be readable.
+ *
+ * This method will fail in bare index instances.
  *
  * @param index an existing index object
  * @param path filename to add
@@ -192,27 +197,62 @@ GIT_EXTERN(int) git_index_find(git_index *index, const char *path);
 GIT_EXTERN(int) git_index_add(git_index *index, const char *path, int stage);
 
 /**
- * Remove an entry from the index 
+ * Add or update an index entry from an in-memory struct
+ *
+ * A full copy (including the 'path' string) of the given
+ * 'source_entry' will be inserted on the index.
  *
  * @param index an existing index object
- * @param position position of the entry to remove
+ * @param source_entry new entry object
  * @return 0 on success, otherwise an error code
  */
-GIT_EXTERN(int) git_index_remove(git_index *index, int position);
+GIT_EXTERN(int) git_index_add2(git_index *index, const git_index_entry *source_entry);
 
 /**
- * Insert an entry into the index.
+ * Add (append) an index entry from a file in disk
+ *
+ * A new entry will always be inserted into the index;
+ * if the index already contains an entry for such
+ * path, the old entry will **not** be replaced.
+ *
+ * The file `path` must be relative to the repository's
+ * working folder and must be readable.
+ *
+ * This method will fail in bare index instances.
+ *
+ * @param index an existing index object
+ * @param path filename to add
+ * @param stage stage for the entry
+ * @return 0 on success, otherwise an error code
+ */
+GIT_EXTERN(int) git_index_append(git_index *index, const char *path, int stage);
+
+/**
+ * Add (append) an index entry from an in-memory struct
+ *
+ * A new entry will always be inserted into the index;
+ * if the index already contains an entry for the path
+ * in the `entry` struct, the old entry will **not** be
+ * replaced.
+ *
  * A full copy (including the 'path' string) of the given
- * 'source_entry' will be inserted on the index; if the
- * replace flag is not set and the index already contains
- * an entry for the same path, the entry will be updated.
+ * 'source_entry' will be inserted on the index.
  *
  * @param index an existing index object
  * @param source_entry new entry object
- * @param replace if set, existing entries will be replaced
  * @return 0 on success, otherwise an error code
  */
-GIT_EXTERN(int) git_index_insert(git_index *index, const git_index_entry *source_entry, int replace);
+GIT_EXTERN(int) git_index_apppend2(git_index *index, const git_index_entry *source_entry);
+
+/**
+ * Remove an entry from the index 
+ *
+ * @param index an existing index object
+ * @param position position of the entry to remove
+ * @return 0 on success, otherwise an error code
+ */
+GIT_EXTERN(int) git_index_remove(git_index *index, int position);
+
 
 /**
  * Get a pointer to one of the entries in the index
diff --git a/src/index.c b/src/index.c
index c066d24..850f5de 100644
--- a/src/index.c
+++ b/src/index.c
@@ -289,56 +289,12 @@ git_index_entry *git_index_get(git_index *index, int n)
 	return git_vector_get(&index->entries, (unsigned int)n);
 }
 
-int git_index_add(git_index *index, const char *rel_path, int stage)
-{
-	git_index_entry entry;
-	char full_path[GIT_PATH_MAX];
-	struct stat st;
-	int error;
-
-	if (index->repository == NULL)
-		return GIT_EBAREINDEX;
-
-	git__joinpath(full_path, index->repository->path_workdir, rel_path);
-
-	if (gitfo_exists(full_path) < 0)
-		return GIT_ENOTFOUND;
-
-	if (gitfo_stat(full_path, &st) < 0)
-		return GIT_EOSERR;
-
-	if (stage < 0 || stage > 3)
-		return GIT_ERROR;
-
-	memset(&entry, 0x0, sizeof(git_index_entry));
-
-	entry.ctime.seconds = (git_time_t)st.st_ctime;
-	entry.mtime.seconds = (git_time_t)st.st_mtime;
-	/* entry.mtime.nanoseconds = st.st_mtimensec; */
-	/* entry.ctime.nanoseconds = st.st_ctimensec; */
-	entry.dev= st.st_rdev;
-	entry.ino = st.st_ino;
-	entry.mode = st.st_mode;
-	entry.uid = st.st_uid;
-	entry.gid = st.st_gid;
-	entry.file_size = st.st_size;
-
-	/* write the blob to disk and get the oid */
-	if ((error = git_blob_create_fromfile(&entry.oid, index->repository, rel_path)) < GIT_SUCCESS)
-		return error;
-
-	entry.flags |= (stage << GIT_IDXENTRY_STAGESHIFT);
-	entry.path = (char *)rel_path; /* do not duplicate; index_insert already does this */
-
-	return git_index_insert(index, &entry, 1);
-}
-
-void sort_index(git_index *index)
+static void sort_index(git_index *index)
 {
 	git_vector_sort(&index->entries);
 }
 
-int git_index_insert(git_index *index, const git_index_entry *source_entry, int replace)
+static int index_insert(git_index *index, const git_index_entry *source_entry, int replace)
 {
 	git_index_entry *entry;
 	size_t path_length;
@@ -395,6 +351,81 @@ int git_index_insert(git_index *index, const git_index_entry *source_entry, int 
 	return GIT_SUCCESS;
 }
 
+static int index_init_entry(git_index_entry *entry, git_index *index, const char *rel_path, int stage)
+{
+	char full_path[GIT_PATH_MAX];
+	struct stat st;
+	int error;
+
+	if (index->repository == NULL)
+		return GIT_EBAREINDEX;
+
+	git__joinpath(full_path, index->repository->path_workdir, rel_path);
+
+	if (gitfo_exists(full_path) < 0)
+		return GIT_ENOTFOUND;
+
+	if (gitfo_stat(full_path, &st) < 0)
+		return GIT_EOSERR;
+
+	if (stage < 0 || stage > 3)
+		return GIT_ERROR;
+
+	memset(entry, 0x0, sizeof(git_index_entry));
+
+	entry->ctime.seconds = (git_time_t)st.st_ctime;
+	entry->mtime.seconds = (git_time_t)st.st_mtime;
+	/* entry.mtime.nanoseconds = st.st_mtimensec; */
+	/* entry.ctime.nanoseconds = st.st_ctimensec; */
+	entry->dev= st.st_rdev;
+	entry->ino = st.st_ino;
+	entry->mode = st.st_mode;
+	entry->uid = st.st_uid;
+	entry->gid = st.st_gid;
+	entry->file_size = st.st_size;
+
+	/* write the blob to disk and get the oid */
+	if ((error = git_blob_create_fromfile(&entry->oid, index->repository, rel_path)) < GIT_SUCCESS)
+		return error;
+
+	entry->flags |= (stage << GIT_IDXENTRY_STAGESHIFT);
+	entry->path = (char *)rel_path; /* do not duplicate; index_insert already does this */
+	return GIT_SUCCESS;
+}
+
+int git_index_add(git_index *index, const char *path, int stage)
+{
+	int error;
+	git_index_entry entry;
+
+	if ((error = index_init_entry(&entry, index, path, stage)) < GIT_SUCCESS)
+		return error;
+
+	return index_insert(index, &entry, 1);
+}
+
+int git_index_append(git_index *index, const char *path, int stage)
+{
+	int error;
+	git_index_entry entry;
+
+	if ((error = index_init_entry(&entry, index, path, stage)) < GIT_SUCCESS)
+		return error;
+
+	return index_insert(index, &entry, 0);
+}
+
+int git_index_add2(git_index *index, const git_index_entry *source_entry)
+{
+	return index_insert(index, source_entry, 1);
+}
+
+int git_index_apppend2(git_index *index, const git_index_entry *source_entry)
+{
+	return index_insert(index, source_entry, 0);
+}
+
+
 int git_index_remove(git_index *index, int position)
 {
 	assert(index);