summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2012-09-18 15:13:07 -0700
committerRussell Belfer <rb@github.com>2012-09-25 16:35:05 -0700
commit9a12a6256efa7da4b4245d0f2b7df6f3b84edabd (patch)
tree16fd5aa10bc2d282bfb843f4e701746da9e16654
parent5942bd18bf557cc70873009c4303a421c83f0129 (diff)
downloadlibgit2-9a12a6256efa7da4b4245d0f2b7df6f3b84edabd.tar.gz
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.
-rw-r--r--include/git2/diff.h243
1 files changed, 100 insertions, 143 deletions
diff --git a/include/git2/diff.h b/include/git2/diff.h
index 05825c50d..2a5cdacc0 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);
/**@}*/