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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
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);