New take on iterating over diff content Allow diff deltas to be accessed by index and make patch generation explicit with hunk and line access by index as well.
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 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
diff --git a/include/git2/diff.h b/include/git2/diff.h
index 05825c5..2a5cdac 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -98,9 +98,6 @@ enum {
GIT_DIFF_FILE_FREE_PATH = (1 << 1),
GIT_DIFF_FILE_BINARY = (1 << 2),
GIT_DIFF_FILE_NOT_BINARY = (1 << 3),
- GIT_DIFF_FILE_FREE_DATA = (1 << 4),
- GIT_DIFF_FILE_UNMAP_DATA = (1 << 5),
- GIT_DIFF_FILE_NO_DATA = (1 << 6),
};
/**
@@ -220,9 +217,13 @@ typedef int (*git_diff_data_fn)(
size_t content_len);
/**
- * The diff iterator object is used to scan a diff list.
+ * The diff patch is used to store all the text diffs for a delta.
+ *
+ * You can easily loop over the content of patches and get information about
+ * them.
*/
-typedef struct git_diff_iterator git_diff_iterator;
+typedef struct git_diff_patch git_diff_patch;
+
/** @name Diff List Generator Functions
*
@@ -349,7 +350,7 @@ GIT_EXTERN(int) git_diff_merge(
/**@{*/
/**
- * Iterate over a diff list issuing callbacks.
+ * Loop over all deltas in a diff list issuing callbacks.
*
* This will iterate through all of the files described in a diff. You
* should provide a file callback to learn about each file.
@@ -381,137 +382,6 @@ GIT_EXTERN(int) git_diff_foreach(
git_diff_data_fn line_cb);
/**
- * Create a diff iterator object that can be used to traverse a diff.
- *
- * This iterator can be used instead of `git_diff_foreach` in situations
- * where callback functions are awkward to use. Because of the way that
- * diffs are calculated internally, using an iterator will use somewhat
- * more memory than `git_diff_foreach` would.
- *
- * @param iterator Output parameter of newly created iterator.
- * @param diff Diff over which you wish to iterate.
- * @return 0 on success, < 0 on error
- */
-GIT_EXTERN(int) git_diff_iterator_new(
- git_diff_iterator **iterator,
- git_diff_list *diff);
-
-/**
- * Release the iterator object.
- *
- * Call this when you are done using the iterator.
- *
- * @param iterator The diff iterator to be freed.
- */
-GIT_EXTERN(void) git_diff_iterator_free(git_diff_iterator *iterator);
-
-/**
- * Return progress value for traversing the diff.
- *
- * This returns a value between 0.0 and 1.0 that represents the progress
- * through the diff iterator. The value is monotonically increasing and
- * will advance gradually as you progress through the iteration.
- *
- * @param iterator The diff iterator
- * @return Value between 0.0 and 1.0
- */
-GIT_EXTERN(float) git_diff_iterator_progress(git_diff_iterator *iterator);
-
-/**
- * Return the number of hunks in the current file
- *
- * This will return the number of diff hunks in the current file. If the
- * diff has not been performed yet, this may result in loading the file and
- * performing the diff.
- *
- * @param iterator The iterator object
- * @return The number of hunks in the current file or <0 on loading failure
- */
-GIT_EXTERN(int) git_diff_iterator_num_hunks_in_file(git_diff_iterator *iterator);
-
-/**
- * Return the number of lines in the hunk currently being examined.
- *
- * This will return the number of lines in the current hunk. If the diff
- * has not been performed yet, this may result in loading the file and
- * performing the diff.
- *
- * @param iterator The iterator object
- * @return The number of lines in the current hunk (context, added, and
- * removed all added together) or <0 on loading failure
- */
-GIT_EXTERN(int) git_diff_iterator_num_lines_in_hunk(git_diff_iterator *iterator);
-
-/**
- * Return the delta information for the next file in the diff.
- *
- * This will return a pointer to the next git_diff_delta` to be processed or
- * NULL if the iterator is at the end of the diff, then advance. This
- * returns the value `GIT_ITEROVER` after processing the last file.
- *
- * @param delta Output parameter for the next delta object
- * @param iterator The iterator object
- * @return 0 on success, GIT_ITEROVER when done, other value < 0 on error
- */
-GIT_EXTERN(int) git_diff_iterator_next_file(
- git_diff_delta **delta,
- git_diff_iterator *iterator);
-
-/**
- * Return the hunk information for the next hunk in the current file.
- *
- * It is recommended that you not call this if the file is a binary
- * file, but it is allowed to do so.
- *
- * The `header` text output will contain the standard hunk header that
- * would appear in diff output. The header string will be NUL terminated.
- *
- * WARNING! Call this function for the first time on a file is when the
- * actual text diff will be computed (it cannot be computed incrementally)
- * so the first call for a new file is expensive (at least in relative
- * terms - in reality, it is still pretty darn fast).
- *
- * @param range Output pointer to range of lines covered by the hunk;
- * This range object is owned by the library and should not be freed.
- * @param header Output pointer to the text of the hunk header
- * This string is owned by the library and should not be freed.
- * @param header_len Output pointer to store the length of the header text
- * @param iterator The iterator object
- * @return 0 on success, GIT_ITEROVER when done with current file, other
- * value < 0 on error
- */
-GIT_EXTERN(int) git_diff_iterator_next_hunk(
- git_diff_range **range,
- const char **header,
- size_t *header_len,
- git_diff_iterator *iterator);
-
-/**
- * Return the next line of the current hunk of diffs.
- *
- * The `line_origin` output will tell you what type of line this is
- * (e.g. was it added or removed or is it just context for the diff).
- *
- * The `content` will be a pointer to the file data that goes in the
- * line. IT WILL NOT BE NUL TERMINATED. You have to use the `content_len`
- * value and only process that many bytes of data from the content string.
- *
- * @param line_origin Output pointer to store a GIT_DIFF_LINE value for this
- * next chunk of data. The value is a single character, not a buffer.
- * @param content Output pointer to store the content of the diff; this
- * string is owned by the library and should not be freed.
- * @param content_len Output pointer to store the length of the content.
- * @param iterator The iterator object
- * @return 0 on success, GIT_ITEROVER when done with current line, other
- * value < 0 on error
- */
-GIT_EXTERN(int) git_diff_iterator_next_line(
- char *line_origin, /**< GIT_DIFF_LINE_... value from above */
- const char **content,
- size_t *content_len,
- git_diff_iterator *iterator);
-
-/**
* Iterate over a diff generating text output like "git diff --name-status".
*
* Returning a non-zero value from the callbacks will terminate the
@@ -552,17 +422,104 @@ GIT_EXTERN(int) git_diff_print_patch(
/**
* Query how many diff records are there in a diff list.
*
- * You can optionally pass in a `git_delta_t` value if you want a count
- * of just entries that match that delta type, or pass -1 for all delta
- * records.
+ * @param diff A git_diff_list generated by one of the above functions
+ * @return Count of number of deltas in the list
+ */
+GIT_EXTERN(size_t) git_diff_entrycount(git_diff_list *diff);
+
+/**
+ * Query how many diff deltas are there in a diff list filtered by type.
+ *
+ * This works just like `git_diff_entrycount()` with an extra parameter
+ * that is a `git_delta_t` and returns just the count of how many deltas
+ * match that particular type.
*
* @param diff A git_diff_list generated by one of the above functions
- * @param delta_t A git_delta_t value to filter the count, or -1 for all records
+ * @param type A git_delta_t value to filter the count
* @return Count of number of deltas matching delta_t type
*/
-GIT_EXTERN(int) git_diff_entrycount(
+GIT_EXTERN(size_t) git_diff_entrycount_of_type(
git_diff_list *diff,
- int delta_t);
+ git_delta_t type);
+
+/**
+ * Return the diff delta and patch for an entry in the diff list.
+ *
+ * The `git_diff_patch` is a newly created object contains the text diffs
+ * for the delta. You have to call `git_diff_patch_free()` when you are
+ * done with it. You can use the patch object to loop over all the hunks
+ * and lines in the diff of the one delta.
+ *
+ * For a binary file, no `git_diff_patch` will be created, the output will
+ * be set to NULL, and the `binary` flag will be set true in the
+ * `git_diff_delta` structure.
+ *
+ * The `git_diff_delta` pointer points to internal data and you do not have
+ * to release it when you are done with it. It will go away when the
+ * `git_diff_list` and `git_diff_patch` go away.
+ *
+ * It is okay to pass NULL for either of the output parameters; if you pass
+ * NULL for the `git_diff_patch`, then the text diff will not be calculated.
+ *
+ * @param patch Output parameter for the delta patch object
+ * @param delta Output parameter for the delta object
+ * @param diff Diff list object
+ * @param idx Index into diff list
+ * @return 0 on success, other value < 0 on error
+ */
+GIT_EXTERN(int) git_diff_get_patch(
+ git_diff_patch **patch,
+ const git_diff_delta **delta,
+ git_diff_list *diff,
+ size_t idx);
+
+/**
+ * Free a git_diff_patch object.
+ */
+GIT_EXTERN(void) git_diff_patch_free(
+ git_diff_patch *patch);
+
+/**
+ * Get the delta associated with a patch
+ */
+GIT_EXTERN(void) git_diff_patch_get_delta(
+ const git_diff_delta **delta,
+ git_diff_patch *patch);
+
+/**
+ * Get the number of hunks in a patch
+ */
+GIT_EXTERN(size_t) git_diff_patch_hunks(
+ git_diff_patch *patch);
+
+/**
+ * Get the information about a hunk in a patch
+ */
+GIT_EXTERN(int) git_diff_patch_get_hunk(
+ const git_diff_range **range,
+ const char **header,
+ size_t *header_len,
+ size_t *lines_in_hunk,
+ git_diff_patch *patch,
+ size_t hunk);
+
+/**
+ * Get the number of lines in a hunk
+ */
+GIT_EXTERN(size_t) git_diff_patch_lines_in_hunk(
+ git_diff_patch *patch,
+ size_t hunk);
+
+/**
+ * Get a line in a hunk of a patch
+ */
+GIT_EXTERN(int) git_diff_patch_get_line_in_hunk(
+ char *line_origin,
+ const char **content,
+ size_t *content_len,
+ git_diff_patch *patch,
+ size_t hunk,
+ size_t line_of_hunk);
/**@}*/