summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2012-08-30 16:39:05 -0700
committerRussell Belfer <rb@github.com>2012-09-05 15:17:24 -0700
commit510f1bac6b94ce19459498ae78f87fc4f4552305 (patch)
tree77793e2bf6c22eacb2c5194ea0b78ba145371b0f
parentf335ecd6e126aa9dea28786522c0e6ce71596e91 (diff)
downloadlibgit2-510f1bac6b94ce19459498ae78f87fc4f4552305.tar.gz
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.
-rw-r--r--include/git2/diff.h134
-rw-r--r--src/diff_output.c7
2 files changed, 103 insertions, 38 deletions
diff --git a/include/git2/diff.h b/include/git2/diff.h
index 7ac6994e..d1455061 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 69921741..d715f9ef 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(