Fix comments and a minor bug This adds better header comments and also fixes a bug in one of simple APIs that tells the number of lines in the current hunk.
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
diff --git a/include/git2/diff.h b/include/git2/diff.h
index 7ac6994..d145506 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -327,28 +327,118 @@ GIT_EXTERN(int) git_diff_merge(
/**@{*/
/**
+ * Iterate over 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.
+ *
+ * The "hunk" and "line" callbacks are optional, and the text diff of the
+ * files will only be calculated if they are not NULL. Of course, these
+ * callbacks will not be invoked for binary files on the diff list or for
+ * files whose only changed is a file mode change.
+ *
+ * Returning a non-zero value from any of the callbacks will terminate
+ * the iteration and cause this return `GIT_EUSER`.
+ *
+ * @param diff A git_diff_list generated by one of the above functions.
+ * @param cb_data Reference pointer that will be passed to your callbacks.
+ * @param file_cb Callback function to make per file in the diff.
+ * @param hunk_cb Optional callback to make per hunk of text diff. This
+ * callback is called to describe a range of lines in the
+ * diff. It will not be issued for binary files.
+ * @param line_cb Optional callback to make per line of diff text. This
+ * same callback will be made for context lines, added, and
+ * removed lines, and even for a deleted trailing newline.
+ * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ */
+GIT_EXTERN(int) git_diff_foreach(
+ git_diff_list *diff,
+ void *cb_data,
+ git_diff_file_fn file_cb,
+ git_diff_hunk_fn hunk_cb,
+ 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);
-GIT_EXTERN(void) git_diff_iterator_free(git_diff_iterator *iter);
+/**
+ * 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 the number of files in the diff.
+ *
+ * Note that there is an uncommon scenario where this number might be too
+ * high -- if a file in the working directory has been "touched" on disk but
+ * the contents were then reverted, it might have been added to the
+ * `git_diff_list` as a MODIFIED file along with a note that the status
+ * needs to be confirmed when the file contents are loaded into memory. In
+ * that case, when the file is loaded, we will check the contents and might
+ * switch it back to UNMODIFIED. The loading of the file is deferred until
+ * as late as possible. As a result, this might return a value what was too
+ * high in those circumstances.
+ *
+ * This is true of `git_diff_foreach` as well, but the only implication
+ * there is that the `progress` value would not advance evenly.
+ *
+ * @param iterator The iterator object
+ * @return The maximum number of files to be iterated over
*/
GIT_EXTERN(int) git_diff_iterator_num_files(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.
+ * 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,
@@ -364,6 +454,10 @@ GIT_EXTERN(int) git_diff_iterator_next_file(
* 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 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,
@@ -373,6 +467,10 @@ GIT_EXTERN(int) git_diff_iterator_next_hunk(
/**
* Return the next line of the current hunk of diffs.
+ *
+ * @param iterator The iterator object
+ * @return 0 on success, GIT_ITEROVER when done with current hunk, other
+ * value < 0 on error
*/
GIT_EXTERN(int) git_diff_iterator_next_line(
char *line_origin, /**< GIT_DIFF_LINE_... value from above */
@@ -381,38 +479,6 @@ GIT_EXTERN(int) git_diff_iterator_next_line(
git_diff_iterator *iterator);
/**
- * Iterate over 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.
- *
- * The "hunk" and "line" callbacks are optional, and the text diff of the
- * files will only be calculated if they are not NULL. Of course, these
- * callbacks will not be invoked for binary files on the diff list or for
- * files whose only changed is a file mode change.
- *
- * Returning a non-zero value from any of the callbacks will terminate
- * the iteration and cause this return `GIT_EUSER`.
- *
- * @param diff A git_diff_list generated by one of the above functions.
- * @param cb_data Reference pointer that will be passed to your callbacks.
- * @param file_cb Callback function to make per file in the diff.
- * @param hunk_cb Optional callback to make per hunk of text diff. This
- * callback is called to describe a range of lines in the
- * diff. It will not be issued for binary files.
- * @param line_cb Optional callback to make per line of diff text. This
- * same callback will be made for context lines, added, and
- * removed lines, and even for a deleted trailing newline.
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
- */
-GIT_EXTERN(int) git_diff_foreach(
- git_diff_list *diff,
- void *cb_data,
- git_diff_file_fn file_cb,
- git_diff_hunk_fn hunk_cb,
- git_diff_data_fn line_cb);
-
-/**
* Iterate over a diff generating text output like "git diff --name-status".
*
* Returning a non-zero value from the callbacks will terminate the
diff --git a/src/diff_output.c b/src/diff_output.c
index 6992174..d715f9e 100644
--- a/src/diff_output.c
+++ b/src/diff_output.c
@@ -1023,7 +1023,6 @@ struct git_diff_iterator {
diffiter_hunk *hunk_curr;
char hunk_header[128];
git_pool lines;
- size_t line_count;
diffiter_line *line_curr;
};
@@ -1096,7 +1095,6 @@ static int diffiter_line_cb(
line->len = content_len;
info->last_hunk->line_count++;
- iter->line_count++;
if (info->last_hunk->line_head == NULL)
info->last_hunk->line_head = line;
@@ -1136,7 +1134,6 @@ static void diffiter_do_unload_file(git_diff_iterator *iter)
iter->ctxt.delta = NULL;
iter->hunk_head = NULL;
iter->hunk_count = 0;
- iter->line_count = 0;
}
int git_diff_iterator_new(
@@ -1202,7 +1199,9 @@ int git_diff_iterator_num_hunks_in_file(git_diff_iterator *iter)
int git_diff_iterator_num_lines_in_hunk(git_diff_iterator *iter)
{
int error = diffiter_do_diff_file(iter);
- return (error != 0) ? error : (int)iter->line_count;
+ if (!error && iter->hunk_curr)
+ error = iter->hunk_curr->line_count;
+ return error;
}
int git_diff_iterator_next_file(