Commit 2e4a9ea9 by Vicent Marti

Merge remote-tracking branch 'arrbee/diff-iterator' into development

parents 27730eef 510f1bac
......@@ -169,7 +169,7 @@ enum {
GIT_DIFF_LINE_CONTEXT = ' ',
GIT_DIFF_LINE_ADDITION = '+',
GIT_DIFF_LINE_DELETION = '-',
GIT_DIFF_LINE_ADD_EOFNL = '\n', /**< DEPRECATED */
GIT_DIFF_LINE_ADD_EOFNL = '\n', /**< DEPRECATED - will not be returned */
GIT_DIFF_LINE_DEL_EOFNL = '\0', /**< LF was removed at end of file */
/* The following values will only be sent to a `git_diff_data_fn` when
......@@ -197,6 +197,11 @@ typedef int (*git_diff_data_fn)(
const char *content,
size_t content_len);
/**
* The diff iterator object is used to scan a diff list.
*/
typedef struct git_diff_iterator git_diff_iterator;
/** @name Diff List Generator Functions
*
* These are the functions you would use to create (or destroy) a
......@@ -354,6 +359,126 @@ 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 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. 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.
*
* 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 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.
*
* @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 */
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
......
......@@ -28,7 +28,7 @@ enum {
GIT_EUSER = -7,
GIT_PASSTHROUGH = -30,
GIT_REVWALKOVER = -31,
GIT_ITEROVER = -31,
};
typedef struct {
......
......@@ -201,7 +201,7 @@ GIT_EXTERN(int) git_revwalk_hide_ref(git_revwalk *walk, const char *refname);
* @param oid Pointer where to store the oid of the next commit
* @param walk the walker to pop the commit from.
* @return 0 if the next commit was found;
* GIT_REVWALKOVER if there are no commits left to iterate
* GIT_ITEROVER if there are no commits left to iterate
*/
GIT_EXTERN(int) git_revwalk_next(git_oid *oid, git_revwalk *walk);
......
......@@ -188,6 +188,7 @@ int git_attr_foreach(
error = callback(assign->name, assign->value, payload);
if (error) {
giterr_clear();
error = GIT_EUSER;
goto cleanup;
}
......
......@@ -221,6 +221,7 @@ static int file_foreach(
/* abort iterator on non-zero return value */
if (fn(key, var->value, data)) {
giterr_clear();
result = GIT_EUSER;
goto cleanup;
}
......
......@@ -316,6 +316,7 @@ static git_diff_list *git_diff_list_alloc(
if (diff == NULL)
return NULL;
GIT_REFCOUNT_INC(diff);
diff->repo = repo;
if (git_vector_init(&diff->deltas, 0, diff_delta__cmp) < 0 ||
......@@ -391,15 +392,12 @@ fail:
return NULL;
}
void git_diff_list_free(git_diff_list *diff)
static void diff_list_free(git_diff_list *diff)
{
git_diff_delta *delta;
git_attr_fnmatch *match;
unsigned int i;
if (!diff)
return;
git_vector_foreach(&diff->deltas, i, delta) {
git__free(delta);
diff->deltas.contents[i] = NULL;
......@@ -416,6 +414,14 @@ void git_diff_list_free(git_diff_list *diff)
git__free(diff);
}
void git_diff_list_free(git_diff_list *diff)
{
if (!diff)
return;
GIT_REFCOUNT_DEC(diff, diff_list_free);
}
static int oid_for_workdir_item(
git_repository *repo,
const git_index_entry *item,
......
......@@ -26,6 +26,7 @@ enum {
};
struct git_diff_list {
git_refcount rc;
git_repository *repo;
git_diff_options opts;
git_vector pathspec;
......
......@@ -221,7 +221,7 @@ int git_fetch_negotiate(git_remote *remote)
}
}
if (error < 0 && error != GIT_REVWALKOVER)
if (error < 0 && error != GIT_ITEROVER)
goto on_error;
/* Tell the other end that we're done negotiating */
......
......@@ -76,6 +76,17 @@ extern void git_pool_swap(git_pool *a, git_pool *b);
extern void *git_pool_malloc(git_pool *pool, uint32_t items);
/**
* Allocate space and zero it out.
*/
GIT_INLINE(void *) git_pool_mallocz(git_pool *pool, uint32_t items)
{
void *ptr = git_pool_malloc(pool, items);
if (ptr)
memset(ptr, 0, (size_t)items * (size_t)pool->item_size);
return ptr;
}
/**
* Allocate space and duplicate string data into it.
*
* This is allowed only for pools with item_size == sizeof(char)
......
......@@ -1643,7 +1643,6 @@ int git_reference_normalize_name(
}
}
*buffer_out++ = *current++;
buffer_size--;
}
......
......@@ -493,7 +493,7 @@ static int walk_and_search(git_object **out, git_revwalk *walk, regex_t *regex)
git_object_free(obj);
}
if (error < 0 && error == GIT_REVWALKOVER)
if (error < 0 && error == GIT_ITEROVER)
error = GIT_ENOTFOUND;
return error;
......
......@@ -449,6 +449,7 @@ int git_merge_base(git_oid *out, git_repository *repo, git_oid *one, git_oid *tw
if (!result) {
git_revwalk_free(walk);
giterr_clear();
return GIT_ENOTFOUND;
}
......@@ -682,7 +683,8 @@ static int revwalk_next_timesort(commit_object **object_out, git_revwalk *walk)
}
}
return GIT_REVWALKOVER;
giterr_clear();
return GIT_ITEROVER;
}
static int revwalk_next_unsorted(commit_object **object_out, git_revwalk *walk)
......@@ -700,7 +702,8 @@ static int revwalk_next_unsorted(commit_object **object_out, git_revwalk *walk)
}
}
return GIT_REVWALKOVER;
giterr_clear();
return GIT_ITEROVER;
}
static int revwalk_next_toposort(commit_object **object_out, git_revwalk *walk)
......@@ -710,8 +713,10 @@ static int revwalk_next_toposort(commit_object **object_out, git_revwalk *walk)
for (;;) {
next = commit_list_pop(&walk->iterator_topo);
if (next == NULL)
return GIT_REVWALKOVER;
if (next == NULL) {
giterr_clear();
return GIT_ITEROVER;
}
if (next->in_degree > 0) {
next->topo_delay = 1;
......@@ -736,7 +741,7 @@ static int revwalk_next_toposort(commit_object **object_out, git_revwalk *walk)
static int revwalk_next_reverse(commit_object **object_out, git_revwalk *walk)
{
*object_out = commit_list_pop(&walk->iterator_reverse);
return *object_out ? 0 : GIT_REVWALKOVER;
return *object_out ? 0 : GIT_ITEROVER;
}
......@@ -751,8 +756,10 @@ static int prepare_walk(git_revwalk *walk)
* If walk->one is NULL, there were no positive references,
* so we know that the walk is already over.
*/
if (walk->one == NULL)
return GIT_REVWALKOVER;
if (walk->one == NULL) {
giterr_clear();
return GIT_ITEROVER;
}
/* first figure out what the merge bases are */
if (merge_bases_many(&bases, walk, walk->one, &walk->twos) < 0)
......@@ -780,7 +787,7 @@ static int prepare_walk(git_revwalk *walk)
return -1;
}
if (error != GIT_REVWALKOVER)
if (error != GIT_ITEROVER)
return error;
walk->get_next = &revwalk_next_toposort;
......@@ -792,7 +799,7 @@ static int prepare_walk(git_revwalk *walk)
if (commit_list_insert(next, &walk->iterator_reverse) == NULL)
return -1;
if (error != GIT_REVWALKOVER)
if (error != GIT_ITEROVER)
return error;
walk->get_next = &revwalk_next_reverse;
......@@ -891,9 +898,10 @@ int git_revwalk_next(git_oid *oid, git_revwalk *walk)
error = walk->get_next(&next, walk);
if (error == GIT_REVWALKOVER) {
if (error == GIT_ITEROVER) {
git_revwalk_reset(walk);
return GIT_REVWALKOVER;
giterr_clear();
return GIT_ITEROVER;
}
if (!error)
......
......@@ -151,6 +151,9 @@ cleanup:
git_diff_list_free(idx2head);
git_diff_list_free(wd2idx);
if (err == GIT_EUSER)
giterr_clear();
return err;
}
......
......@@ -163,6 +163,7 @@ int git_submodule_foreach(
}
if (callback(sm, sm->name, payload)) {
giterr_clear();
error = GIT_EUSER;
break;
}
......
......@@ -58,59 +58,59 @@ void test_diff_blob__can_compare_text_blobs(void)
cl_git_pass(git_diff_blobs(
a, b, &opts, &expected, diff_file_fn, diff_hunk_fn, diff_line_fn));
cl_assert(expected.files == 1);
cl_assert(expected.file_mods == 1);
cl_assert_equal_i(1, expected.files);
cl_assert_equal_i(1, expected.file_mods);
cl_assert(expected.at_least_one_of_them_is_binary == false);
cl_assert(expected.hunks == 1);
cl_assert(expected.lines == 6);
cl_assert(expected.line_ctxt == 1);
cl_assert(expected.line_adds == 5);
cl_assert(expected.line_dels == 0);
cl_assert_equal_i(1, expected.hunks);
cl_assert_equal_i(6, expected.lines);
cl_assert_equal_i(1, expected.line_ctxt);
cl_assert_equal_i(5, expected.line_adds);
cl_assert_equal_i(0, expected.line_dels);
/* diff on tests/resources/attr/root_test2 */
memset(&expected, 0, sizeof(expected));
cl_git_pass(git_diff_blobs(
b, c, &opts, &expected, diff_file_fn, diff_hunk_fn, diff_line_fn));
cl_assert(expected.files == 1);
cl_assert(expected.file_mods == 1);
cl_assert_equal_i(1, expected.files);
cl_assert_equal_i(1, expected.file_mods);
cl_assert(expected.at_least_one_of_them_is_binary == false);
cl_assert(expected.hunks == 1);
cl_assert(expected.lines == 15);
cl_assert(expected.line_ctxt == 3);
cl_assert(expected.line_adds == 9);
cl_assert(expected.line_dels == 3);
cl_assert_equal_i(1, expected.hunks);
cl_assert_equal_i(15, expected.lines);
cl_assert_equal_i(3, expected.line_ctxt);
cl_assert_equal_i(9, expected.line_adds);
cl_assert_equal_i(3, expected.line_dels);
/* diff on tests/resources/attr/root_test3 */
memset(&expected, 0, sizeof(expected));
cl_git_pass(git_diff_blobs(
a, c, &opts, &expected, diff_file_fn, diff_hunk_fn, diff_line_fn));
cl_assert(expected.files == 1);
cl_assert(expected.file_mods == 1);
cl_assert_equal_i(1, expected.files);
cl_assert_equal_i(1, expected.file_mods);
cl_assert(expected.at_least_one_of_them_is_binary == false);
cl_assert(expected.hunks == 1);
cl_assert(expected.lines == 13);
cl_assert(expected.line_ctxt == 0);
cl_assert(expected.line_adds == 12);
cl_assert(expected.line_dels == 1);
cl_assert_equal_i(1, expected.hunks);
cl_assert_equal_i(13, expected.lines);
cl_assert_equal_i(0, expected.line_ctxt);
cl_assert_equal_i(12, expected.line_adds);
cl_assert_equal_i(1, expected.line_dels);
memset(&expected, 0, sizeof(expected));
cl_git_pass(git_diff_blobs(
c, d, &opts, &expected, diff_file_fn, diff_hunk_fn, diff_line_fn));
cl_assert(expected.files == 1);
cl_assert(expected.file_mods == 1);
cl_assert_equal_i(1, expected.files);
cl_assert_equal_i(1, expected.file_mods);
cl_assert(expected.at_least_one_of_them_is_binary == false);
cl_assert(expected.hunks == 2);
cl_assert(expected.lines == 14);
cl_assert(expected.line_ctxt == 4);
cl_assert(expected.line_adds == 6);
cl_assert(expected.line_dels == 4);
cl_assert_equal_i(2, expected.hunks);
cl_assert_equal_i(14, expected.lines);
cl_assert_equal_i(4, expected.line_ctxt);
cl_assert_equal_i(6, expected.line_adds);
cl_assert_equal_i(4, expected.line_dels);
git_blob_free(a);
git_blob_free(b);
......@@ -124,14 +124,14 @@ void test_diff_blob__can_compare_against_null_blobs(void)
cl_git_pass(git_diff_blobs(
d, e, &opts, &expected, diff_file_fn, diff_hunk_fn, diff_line_fn));
cl_assert(expected.files == 1);
cl_assert(expected.file_dels == 1);
cl_assert_equal_i(1, expected.files);
cl_assert_equal_i(1, expected.file_dels);
cl_assert(expected.at_least_one_of_them_is_binary == false);
cl_assert(expected.hunks == 1);
cl_assert(expected.hunk_old_lines == 14);
cl_assert(expected.lines == 14);
cl_assert(expected.line_dels == 14);
cl_assert_equal_i(1, expected.hunks);
cl_assert_equal_i(14, expected.hunk_old_lines);
cl_assert_equal_i(14, expected.lines);
cl_assert_equal_i(14, expected.line_dels);
opts.flags |= GIT_DIFF_REVERSE;
memset(&expected, 0, sizeof(expected));
......@@ -139,14 +139,14 @@ void test_diff_blob__can_compare_against_null_blobs(void)
cl_git_pass(git_diff_blobs(
d, e, &opts, &expected, diff_file_fn, diff_hunk_fn, diff_line_fn));
cl_assert(expected.files == 1);
cl_assert(expected.file_adds == 1);
cl_assert_equal_i(1, expected.files);
cl_assert_equal_i(1, expected.file_adds);
cl_assert(expected.at_least_one_of_them_is_binary == false);
cl_assert(expected.hunks == 1);
cl_assert(expected.hunk_new_lines == 14);
cl_assert(expected.lines == 14);
cl_assert(expected.line_adds == 14);
cl_assert_equal_i(1, expected.hunks);
cl_assert_equal_i(14, expected.hunk_new_lines);
cl_assert_equal_i(14, expected.lines);
cl_assert_equal_i(14, expected.line_adds);
opts.flags ^= GIT_DIFF_REVERSE;
memset(&expected, 0, sizeof(expected));
......@@ -156,10 +156,10 @@ void test_diff_blob__can_compare_against_null_blobs(void)
cl_assert(expected.at_least_one_of_them_is_binary == true);
cl_assert(expected.files == 1);
cl_assert(expected.file_dels == 1);
cl_assert(expected.hunks == 0);
cl_assert(expected.lines == 0);
cl_assert_equal_i(1, expected.files);
cl_assert_equal_i(1, expected.file_dels);
cl_assert_equal_i(0, expected.hunks);
cl_assert_equal_i(0, expected.lines);
memset(&expected, 0, sizeof(expected));
......@@ -168,18 +168,18 @@ void test_diff_blob__can_compare_against_null_blobs(void)
cl_assert(expected.at_least_one_of_them_is_binary == true);
cl_assert(expected.files == 1);
cl_assert(expected.file_adds == 1);
cl_assert(expected.hunks == 0);
cl_assert(expected.lines == 0);
cl_assert_equal_i(1, expected.files);
cl_assert_equal_i(1, expected.file_adds);
cl_assert_equal_i(0, expected.hunks);
cl_assert_equal_i(0, expected.lines);
}
static void assert_identical_blobs_comparison(diff_expects expected)
{
cl_assert(expected.files == 1);
cl_assert(expected.file_unmodified == 1);
cl_assert(expected.hunks == 0);
cl_assert(expected.lines == 0);
cl_assert_equal_i(1, expected.files);
cl_assert_equal_i(1, expected.file_unmodified);
cl_assert_equal_i(0, expected.hunks);
cl_assert_equal_i(0, expected.lines);
}
void test_diff_blob__can_compare_identical_blobs(void)
......@@ -209,10 +209,10 @@ static void assert_binary_blobs_comparison(diff_expects expected)
{
cl_assert(expected.at_least_one_of_them_is_binary == true);
cl_assert(expected.files == 1);
cl_assert(expected.file_mods == 1);
cl_assert(expected.hunks == 0);
cl_assert(expected.lines == 0);
cl_assert_equal_i(1, expected.files);
cl_assert_equal_i(1, expected.file_mods);
cl_assert_equal_i(0, expected.hunks);
cl_assert_equal_i(0, expected.lines);
}
void test_diff_blob__can_compare_two_binary_blobs(void)
......@@ -292,7 +292,7 @@ void test_diff_blob__comparing_two_text_blobs_honors_interhunkcontext(void)
cl_git_pass(git_diff_blobs(
old_d, d, &opts, &expected, diff_file_fn, diff_hunk_fn, diff_line_fn));
cl_assert(expected.hunks == 2);
cl_assert_equal_i(2, expected.hunks);
/* Test with inter-hunk-context explicitly set to 0 */
opts.interhunk_lines = 0;
......@@ -300,7 +300,7 @@ void test_diff_blob__comparing_two_text_blobs_honors_interhunkcontext(void)
cl_git_pass(git_diff_blobs(
old_d, d, &opts, &expected, diff_file_fn, diff_hunk_fn, diff_line_fn));
cl_assert(expected.hunks == 2);
cl_assert_equal_i(2, expected.hunks);
/* Test with inter-hunk-context explicitly set to 1 */
opts.interhunk_lines = 1;
......@@ -308,7 +308,7 @@ void test_diff_blob__comparing_two_text_blobs_honors_interhunkcontext(void)
cl_git_pass(git_diff_blobs(
old_d, d, &opts, &expected, diff_file_fn, diff_hunk_fn, diff_line_fn));
cl_assert(expected.hunks == 1);
cl_assert_equal_i(1, expected.hunks);
git_blob_free(old_d);
}
......@@ -103,3 +103,74 @@ int diff_line_fn(
}
return 0;
}
int diff_foreach_via_iterator(
git_diff_list *diff,
void *data,
git_diff_file_fn file_cb,
git_diff_hunk_fn hunk_cb,
git_diff_data_fn line_cb)
{
int error, curr, total;
git_diff_iterator *iter;
git_diff_delta *delta;
if ((error = git_diff_iterator_new(&iter, diff)) < 0)
return error;
curr = 0;
total = git_diff_iterator_num_files(iter);
while (!(error = git_diff_iterator_next_file(&delta, iter))) {
git_diff_range *range;
const char *hdr;
size_t hdr_len;
/* call file_cb for this file */
if (file_cb != NULL && file_cb(data, delta, (float)curr / total) != 0)
goto abort;
if (!hunk_cb && !line_cb)
continue;
while (!(error = git_diff_iterator_next_hunk(
&range, &hdr, &hdr_len, iter))) {
char origin;
const char *line;
size_t line_len;
if (hunk_cb && hunk_cb(data, delta, range, hdr, hdr_len) != 0)
goto abort;
if (!line_cb)
continue;
while (!(error = git_diff_iterator_next_line(
&origin, &line, &line_len, iter))) {
if (line_cb(data, delta, range, origin, line, line_len) != 0)
goto abort;
}
if (error && error != GIT_ITEROVER)
goto done;
}
if (error && error != GIT_ITEROVER)
goto done;
}
done:
git_diff_iterator_free(iter);
if (error == GIT_ITEROVER)
error = 0;
return error;
abort:
git_diff_iterator_free(iter);
giterr_clear();
return GIT_EUSER;
}
......@@ -45,3 +45,9 @@ extern int diff_line_fn(
const char *content,
size_t content_len);
extern int diff_foreach_via_iterator(
git_diff_list *diff,
void *data,
git_diff_file_fn file_cb,
git_diff_hunk_fn hunk_cb,
git_diff_data_fn line_cb);
#include "clar_libgit2.h"
#include "diff_helpers.h"
void test_diff_diffiter__initialize(void)
{
}
void test_diff_diffiter__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_diff_diffiter__create(void)
{
git_repository *repo = cl_git_sandbox_init("attr");
git_diff_list *diff;
git_diff_iterator *iter;
cl_git_pass(git_diff_workdir_to_index(repo, NULL, &diff));
cl_git_pass(git_diff_iterator_new(&iter, diff));
git_diff_iterator_free(iter);
git_diff_list_free(diff);
}
void test_diff_diffiter__iterate_files(void)
{
git_repository *repo = cl_git_sandbox_init("attr");
git_diff_list *diff;
git_diff_iterator *iter;
git_diff_delta *delta;
int error, count = 0;
cl_git_pass(git_diff_workdir_to_index(repo, NULL, &diff));
cl_git_pass(git_diff_iterator_new(&iter, diff));
while ((error = git_diff_iterator_next_file(&delta, iter)) != GIT_ITEROVER) {
cl_assert_equal_i(0, error);
cl_assert(delta != NULL);
count++;
}
cl_assert_equal_i(GIT_ITEROVER, error);
cl_assert(delta == NULL);
cl_assert_equal_i(6, count);
git_diff_iterator_free(iter);
git_diff_list_free(diff);
}
void test_diff_diffiter__iterate_files_2(void)
{
git_repository *repo = cl_git_sandbox_init("status");
git_diff_list *diff;
git_diff_iterator *iter;
git_diff_delta *delta;
int error, count = 0;
cl_git_pass(git_diff_workdir_to_index(repo, NULL, &diff));
cl_git_pass(git_diff_iterator_new(&iter, diff));
while ((error = git_diff_iterator_next_file(&delta, iter)) != GIT_ITEROVER) {
cl_assert_equal_i(0, error);
cl_assert(delta != NULL);
count++;
}
cl_assert_equal_i(GIT_ITEROVER, error);
cl_assert(delta == NULL);
cl_assert_equal_i(8, count);
git_diff_iterator_free(iter);
git_diff_list_free(diff);
}
void test_diff_diffiter__iterate_files_and_hunks(void)
{
git_repository *repo = cl_git_sandbox_init("status");
git_diff_options opts = {0};
git_diff_list *diff = NULL;
git_diff_iterator *iter;
git_diff_delta *delta;
git_diff_range *range;
const char *header;
size_t header_len;
int error, file_count = 0, hunk_count = 0;
opts.context_lines = 3;
opts.interhunk_lines = 1;
opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
cl_git_pass(git_diff_workdir_to_index(repo, &opts, &diff));
cl_git_pass(git_diff_iterator_new(&iter, diff));
while ((error = git_diff_iterator_next_file(&delta, iter)) != GIT_ITEROVER) {
cl_assert_equal_i(0, error);
cl_assert(delta);
file_count++;
while ((error = git_diff_iterator_next_hunk(
&range, &header, &header_len, iter)) != GIT_ITEROVER) {
cl_assert_equal_i(0, error);
cl_assert(range);
hunk_count++;
}
}
cl_assert_equal_i(GIT_ITEROVER, error);
cl_assert(delta == NULL);
cl_assert_equal_i(13, file_count);
cl_assert_equal_i(8, hunk_count);
git_diff_iterator_free(iter);
git_diff_list_free(diff);
}
......@@ -44,17 +44,17 @@ void test_diff_index__0(void)
* - git diff -U1 --cached 26a125ee1bf
* - mv .git .gitted
*/
cl_assert(exp.files == 8);
cl_assert(exp.file_adds == 3);
cl_assert(exp.file_dels == 2);
cl_assert(exp.file_mods == 3);
cl_assert_equal_i(8, exp.files);
cl_assert_equal_i(3, exp.file_adds);
cl_assert_equal_i(2, exp.file_dels);
cl_assert_equal_i(3, exp.file_mods);
cl_assert(exp.hunks == 8);
cl_assert_equal_i(8, exp.hunks);
cl_assert(exp.lines == 11);
cl_assert(exp.line_ctxt == 3);
cl_assert(exp.line_adds == 6);
cl_assert(exp.line_dels == 2);
cl_assert_equal_i(11, exp.lines);
cl_assert_equal_i(3, exp.line_ctxt);
cl_assert_equal_i(6, exp.line_adds);
cl_assert_equal_i(2, exp.line_dels);
git_diff_list_free(diff);
diff = NULL;
......@@ -72,17 +72,17 @@ void test_diff_index__0(void)
* - git diff -U1 --cached 0017bd4ab1ec3
* - mv .git .gitted
*/
cl_assert(exp.files == 12);
cl_assert(exp.file_adds == 7);
cl_assert(exp.file_dels == 2);
cl_assert(exp.file_mods == 3);
cl_assert_equal_i(12, exp.files);
cl_assert_equal_i(7, exp.file_adds);
cl_assert_equal_i(2, exp.file_dels);
cl_assert_equal_i(3, exp.file_mods);
cl_assert(exp.hunks == 12);
cl_assert_equal_i(12, exp.hunks);
cl_assert(exp.lines == 16);
cl_assert(exp.line_ctxt == 3);
cl_assert(exp.line_adds == 11);
cl_assert(exp.line_dels == 2);
cl_assert_equal_i(16, exp.lines);
cl_assert_equal_i(3, exp.line_ctxt);
cl_assert_equal_i(11, exp.line_adds);
cl_assert_equal_i(2, exp.line_dels);
git_diff_list_free(diff);
diff = NULL;
......@@ -132,7 +132,7 @@ void test_diff_index__1(void)
git_diff_foreach(diff, &exp, diff_stop_after_2_files, NULL, NULL)
);
cl_assert(exp.files == 2);
cl_assert_equal_i(2, exp.files);
git_diff_list_free(diff);
diff = NULL;
......
......@@ -39,17 +39,17 @@ void test_diff_tree__0(void)
cl_git_pass(git_diff_foreach(
diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));
cl_assert(exp.files == 5);
cl_assert(exp.file_adds == 2);
cl_assert(exp.file_dels == 1);
cl_assert(exp.file_mods == 2);
cl_assert_equal_i(5, exp.files);
cl_assert_equal_i(2, exp.file_adds);
cl_assert_equal_i(1, exp.file_dels);
cl_assert_equal_i(2, exp.file_mods);
cl_assert(exp.hunks == 5);
cl_assert_equal_i(5, exp.hunks);
cl_assert(exp.lines == 7 + 24 + 1 + 6 + 6);
cl_assert(exp.line_ctxt == 1);
cl_assert(exp.line_adds == 24 + 1 + 5 + 5);
cl_assert(exp.line_dels == 7 + 1);
cl_assert_equal_i(7 + 24 + 1 + 6 + 6, exp.lines);
cl_assert_equal_i(1, exp.line_ctxt);
cl_assert_equal_i(24 + 1 + 5 + 5, exp.line_adds);
cl_assert_equal_i(7 + 1, exp.line_dels);
git_diff_list_free(diff);
diff = NULL;
......@@ -61,17 +61,17 @@ void test_diff_tree__0(void)
cl_git_pass(git_diff_foreach(
diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));
cl_assert(exp.files == 2);
cl_assert(exp.file_adds == 0);
cl_assert(exp.file_dels == 0);
cl_assert(exp.file_mods == 2);
cl_assert_equal_i(2, exp.files);
cl_assert_equal_i(0, exp.file_adds);
cl_assert_equal_i(0, exp.file_dels);
cl_assert_equal_i(2, exp.file_mods);
cl_assert(exp.hunks == 2);
cl_assert_equal_i(2, exp.hunks);
cl_assert(exp.lines == 8 + 15);
cl_assert(exp.line_ctxt == 1);
cl_assert(exp.line_adds == 1);
cl_assert(exp.line_dels == 7 + 14);
cl_assert_equal_i(8 + 15, exp.lines);
cl_assert_equal_i(1, exp.line_ctxt);
cl_assert_equal_i(1, exp.line_adds);
cl_assert_equal_i(7 + 14, exp.line_dels);
git_diff_list_free(diff);
......@@ -192,17 +192,17 @@ void test_diff_tree__bare(void)
cl_git_pass(git_diff_foreach(
diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));
cl_assert(exp.files == 3);
cl_assert(exp.file_adds == 2);
cl_assert(exp.file_dels == 0);
cl_assert(exp.file_mods == 1);
cl_assert_equal_i(3, exp.files);
cl_assert_equal_i(2, exp.file_adds);
cl_assert_equal_i(0, exp.file_dels);
cl_assert_equal_i(1, exp.file_mods);
cl_assert(exp.hunks == 3);
cl_assert_equal_i(3, exp.hunks);
cl_assert(exp.lines == 4);
cl_assert(exp.line_ctxt == 0);
cl_assert(exp.line_adds == 3);
cl_assert(exp.line_dels == 1);
cl_assert_equal_i(4, exp.lines);
cl_assert_equal_i(0, exp.line_ctxt);
cl_assert_equal_i(3, exp.line_adds);
cl_assert_equal_i(1, exp.line_dels);
git_diff_list_free(diff);
git_tree_free(a);
......@@ -242,17 +242,17 @@ void test_diff_tree__merge(void)
cl_git_pass(git_diff_foreach(
diff1, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));
cl_assert(exp.files == 6);
cl_assert(exp.file_adds == 2);
cl_assert(exp.file_dels == 1);
cl_assert(exp.file_mods == 3);
cl_assert_equal_i(6, exp.files);
cl_assert_equal_i(2, exp.file_adds);
cl_assert_equal_i(1, exp.file_dels);
cl_assert_equal_i(3, exp.file_mods);
cl_assert(exp.hunks == 6);
cl_assert_equal_i(6, exp.hunks);
cl_assert(exp.lines == 59);
cl_assert(exp.line_ctxt == 1);
cl_assert(exp.line_adds == 36);
cl_assert(exp.line_dels == 22);
cl_assert_equal_i(59, exp.lines);
cl_assert_equal_i(1, exp.line_ctxt);
cl_assert_equal_i(36, exp.line_adds);
cl_assert_equal_i(22, exp.line_dels);
git_diff_list_free(diff1);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment