diff options
author | Vicent Marti <vicent@github.com> | 2014-04-23 03:21:05 -0700 |
---|---|---|
committer | Vicent Marti <vicent@github.com> | 2014-04-23 03:21:05 -0700 |
commit | 5b58d6f78cf8346445374eaf5cde0f54be5c5796 (patch) | |
tree | efc60e0cbdf2ff1614fb1bcbfd7faedb09d758c4 | |
parent | a32d684f866e7710fd139d69ad5d1a8d0ae527c4 (diff) | |
parent | e60883c82f1c4d44be856e545b4cbeea27522416 (diff) | |
download | libgit2-5b58d6f78cf8346445374eaf5cde0f54be5c5796.tar.gz |
Merge pull request #2289 from libgit2/rb/note-git-diff-index-behavior
Some doc and examples/diff.c changes
-rw-r--r-- | examples/diff.c | 172 | ||||
-rw-r--r-- | include/git2/diff.h | 33 | ||||
-rw-r--r-- | src/diff.c | 3 | ||||
-rw-r--r-- | src/diff_print.c | 3 | ||||
-rw-r--r-- | src/diff_stats.c | 299 | ||||
-rw-r--r-- | tests/diff/format_email.c | 193 | ||||
-rw-r--r-- | tests/diff/stats.c | 357 |
7 files changed, 404 insertions, 656 deletions
diff --git a/examples/diff.c b/examples/diff.c index 6f68e8305..76ac2f311 100644 --- a/examples/diff.c +++ b/examples/diff.c @@ -33,14 +33,27 @@ static const char *colors[] = { "\033[36m" /* cyan */ }; +enum { + OUTPUT_DIFF = (1 << 0), + OUTPUT_STAT = (1 << 1), + OUTPUT_SHORTSTAT = (1 << 2), + OUTPUT_NUMSTAT = (1 << 3), + OUTPUT_SUMMARY = (1 << 4) +}; + +enum { + CACHE_NORMAL = 0, + CACHE_ONLY = 1, + CACHE_NONE = 2 +}; + /** The 'opts' struct captures all the various parsed command line options. */ struct opts { git_diff_options diffopts; git_diff_find_options findopts; int color; - int cached; - int numstat; - int shortstat; + int cache; + int output; git_diff_format_t format; const char *treeish1; const char *treeish2; @@ -48,11 +61,11 @@ struct opts { }; /** These functions are implemented at the end */ +static void usage(const char *message, const char *arg); static void parse_opts(struct opts *o, int argc, char *argv[]); static int color_printer( const git_diff_delta*, const git_diff_hunk*, const git_diff_line*, void*); -static void diff_print_numstat(git_diff *diff); -static void diff_print_shortstat(git_diff *diff); +static void diff_print_stats(git_diff *diff, struct opts *o); int main(int argc, char *argv[]) { @@ -61,7 +74,7 @@ int main(int argc, char *argv[]) git_diff *diff; struct opts o = { GIT_DIFF_OPTIONS_INIT, GIT_DIFF_FIND_OPTIONS_INIT, - -1, 0, 0, 0, GIT_DIFF_FORMAT_PATCH, NULL, NULL, "." + -1, 0, 0, GIT_DIFF_FORMAT_PATCH, NULL, NULL, "." }; git_threads_init(); @@ -78,6 +91,7 @@ int main(int argc, char *argv[]) * * <sha1> --cached * * <sha1> * * --cached + * * --nocache (don't use index data in diff at all) * * nothing * * Currently ranged arguments like <sha1>..<sha2> and <sha1>...<sha2> @@ -93,20 +107,23 @@ int main(int argc, char *argv[]) check_lg2( git_diff_tree_to_tree(&diff, repo, t1, t2, &o.diffopts), "diff trees", NULL); - else if (t1 && o.cached) - check_lg2( - git_diff_tree_to_index(&diff, repo, t1, NULL, &o.diffopts), - "diff tree to index", NULL); + else if (o.cache != CACHE_NORMAL) { + if (!t1) + treeish_to_tree(&t1, repo, "HEAD"); + + if (o.cache == CACHE_NONE) + check_lg2( + git_diff_tree_to_workdir(&diff, repo, t1, &o.diffopts), + "diff tree to working directory", NULL); + else + check_lg2( + git_diff_tree_to_index(&diff, repo, t1, NULL, &o.diffopts), + "diff tree to index", NULL); + } else if (t1) check_lg2( git_diff_tree_to_workdir_with_index(&diff, repo, t1, &o.diffopts), "diff tree to working directory", NULL); - else if (o.cached) { - treeish_to_tree(&t1, repo, "HEAD"); - check_lg2( - git_diff_tree_to_index(&diff, repo, t1, NULL, &o.diffopts), - "diff tree to index", NULL); - } else check_lg2( git_diff_index_to_workdir(&diff, repo, NULL, &o.diffopts), @@ -121,11 +138,13 @@ int main(int argc, char *argv[]) /** Generate simple output using libgit2 display helper. */ - if (o.numstat == 1) - diff_print_numstat(diff); - else if (o.shortstat == 1) - diff_print_shortstat(diff); - else { + if (!o.output) + o.output = OUTPUT_DIFF; + + if (o.output != OUTPUT_DIFF) + diff_print_stats(diff, &o); + + if ((o.output & OUTPUT_DIFF) != 0) { if (o.color >= 0) fputs(colors[0], stdout); @@ -210,16 +229,25 @@ static void parse_opts(struct opts *o, int argc, char *argv[]) usage("Only one or two tree identifiers can be provided", NULL); } else if (!strcmp(a, "-p") || !strcmp(a, "-u") || - !strcmp(a, "--patch")) + !strcmp(a, "--patch")) { + o->output |= OUTPUT_DIFF; o->format = GIT_DIFF_FORMAT_PATCH; + } else if (!strcmp(a, "--cached")) - o->cached = 1; - else if (!strcmp(a, "--name-only")) + o->cache = CACHE_ONLY; + else if (!strcmp(a, "--nocache")) + o->cache = CACHE_NONE; + else if (!strcmp(a, "--name-only") || !strcmp(a, "--format=name")) o->format = GIT_DIFF_FORMAT_NAME_ONLY; - else if (!strcmp(a, "--name-status")) + else if (!strcmp(a, "--name-status") || + !strcmp(a, "--format=name-status")) o->format = GIT_DIFF_FORMAT_NAME_STATUS; - else if (!strcmp(a, "--raw")) + else if (!strcmp(a, "--raw") || !strcmp(a, "--format=raw")) o->format = GIT_DIFF_FORMAT_RAW; + else if (!strcmp(a, "--format=diff-index")) { + o->format = GIT_DIFF_FORMAT_RAW; + o->diffopts.id_abbrev = 40; + } else if (!strcmp(a, "--color")) o->color = 0; else if (!strcmp(a, "--no-color")) @@ -242,10 +270,14 @@ static void parse_opts(struct opts *o, int argc, char *argv[]) o->diffopts.flags |= GIT_DIFF_PATIENCE; else if (!strcmp(a, "--minimal")) o->diffopts.flags |= GIT_DIFF_MINIMAL; + else if (!strcmp(a, "--stat")) + o->output |= OUTPUT_STAT; else if (!strcmp(a, "--numstat")) - o->numstat = 1; + o->output |= OUTPUT_NUMSTAT; else if (!strcmp(a, "--shortstat")) - o->shortstat = 1; + o->output |= OUTPUT_SHORTSTAT; + else if (!strcmp(a, "--summary")) + o->output |= OUTPUT_SUMMARY; else if (match_uint16_arg( &o->findopts.rename_threshold, &args, "-M") || match_uint16_arg( @@ -267,6 +299,8 @@ static void parse_opts(struct opts *o, int argc, char *argv[]) &o->diffopts.context_lines, &args, "--unified") && !match_uint16_arg( &o->diffopts.interhunk_lines, &args, "--inter-hunk-context") && + !match_uint16_arg( + &o->diffopts.id_abbrev, &args, "--abbrev") && !match_str_arg(&o->diffopts.old_prefix, &args, "--src-prefix") && !match_str_arg(&o->diffopts.new_prefix, &args, "--dst-prefix") && !match_str_arg(&o->dir, &args, "--git-dir")) @@ -274,72 +308,30 @@ static void parse_opts(struct opts *o, int argc, char *argv[]) } } -/** Display diff output with "--numstat".*/ -static void diff_print_numstat(git_diff *diff) +/** Display diff output with "--stat", "--numstat", or "--shortstat" */ +static void diff_print_stats(git_diff *diff, struct opts *o) { - git_patch *patch; - const git_diff_delta *delta; - size_t d, ndeltas = git_diff_num_deltas(diff); - size_t nadditions, ndeletions; + git_diff_stats *stats; + git_buf b = GIT_BUF_INIT_CONST(NULL, 0); + git_diff_stats_format_t format = 0; - for (d = 0; d < ndeltas; d++){ - check_lg2( - git_patch_from_diff(&patch, diff, d), - "generating patch from diff", NULL); + check_lg2( + git_diff_get_stats(&stats, diff), "generating stats for diff", NULL); - check_lg2( - git_patch_line_stats(NULL, &nadditions, &ndeletions, patch), - "generating the number of additions and deletions", NULL); + if (o->output & OUTPUT_STAT) + format |= GIT_DIFF_STATS_FULL; + if (o->output & OUTPUT_SHORTSTAT) + format |= GIT_DIFF_STATS_SHORT; + if (o->output & OUTPUT_NUMSTAT) + format |= GIT_DIFF_STATS_NUMBER; + if (o->output & OUTPUT_SUMMARY) + format |= GIT_DIFF_STATS_INCLUDE_SUMMARY; - delta = git_patch_get_delta(patch); + check_lg2( + git_diff_stats_to_buf(&b, stats, format, 80), "formatting stats", NULL); - printf("%ld\t%ld\t%s\n", - (long)nadditions, (long)ndeletions, delta->new_file.path); + fputs(b.ptr, stdout); - git_patch_free(patch); - } -} - -/** Display diff output with "--shortstat".*/ -static void diff_print_shortstat(git_diff *diff) -{ - git_patch *patch; - size_t d, ndeltas = git_diff_num_deltas(diff); - size_t nadditions, ndeletions; - long nadditions_sum, ndeletions_sum; - - nadditions_sum = 0; - ndeletions_sum = 0; - - for (d = 0; d < ndeltas; d++){ - check_lg2( - git_patch_from_diff(&patch, diff, d), - "generating patch from diff", NULL); - - check_lg2( - git_patch_line_stats(NULL, &nadditions, &ndeletions, patch), - "generating the number of additions and deletions", NULL); - - nadditions_sum += nadditions; - ndeletions_sum += ndeletions; - - git_patch_free(patch); - } - - if (ndeltas) { - - printf(" %ld ", (long)ndeltas); - printf("%s", 1==ndeltas ? "file changed" : "files changed"); - - if(nadditions_sum) { - printf(", %ld ",nadditions_sum); - printf("%s", 1==nadditions_sum ? "insertion(+)" : "insertions(+)"); - } - - if(ndeletions_sum) { - printf(", %ld ",ndeletions_sum); - printf("%s", 1==ndeletions_sum ? "deletion(-)" : "deletions(-)"); - } - printf("\n"); - } + git_buf_free(&b); + git_diff_stats_free(stats); } diff --git a/include/git2/diff.h b/include/git2/diff.h index a0cfbc918..e5e641a2a 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -725,24 +725,17 @@ GIT_EXTERN(int) git_diff_index_to_workdir( * The tree you provide will be used for the "old_file" side of the delta, * and the working directory will be used for the "new_file" side. * - * Please note: this is *NOT* the same as `git diff <treeish>`. Running - * `git diff HEAD` or the like actually uses information from the index, - * along with the tree and working directory info. - * - * This function returns strictly the differences between the tree and the - * files contained in the working directory, regardless of the state of - * files in the index. It may come as a surprise, but there is no direct - * equivalent in core git. - * - * To emulate `git diff <tree>`, use `git_diff_tree_to_workdir_with_index` - * (or `git_diff_tree_to_index` and `git_diff_index_to_workdir`, then call - * `git_diff_merge` on the results). That will yield a `git_diff` that - * matches the git output. - * - * If this seems confusing, take the case of a file with a staged deletion - * where the file has then been put back into the working dir and modified. - * The tree-to-workdir diff for that file is 'modified', but core git would - * show status 'deleted' since there is a pending deletion in the index. + * This is not the same as `git diff <treeish>` or `git diff-index + * <treeish>`. Those commands use information from the index, whereas this + * function strictly returns the differences between the tree and the files + * in the working directory, regardless of the state of the index. Use + * `git_diff_tree_to_workdir_with_index` to emulate those commands. + * + * To see difference between this and `git_diff_tree_to_workdir_with_index`, + * consider the example of a staged file deletion where the file has then + * been put back into the working dir and further modified. The + * tree-to-workdir diff for that file is 'modified', but `git diff` would + * show status 'deleted' since there is a staged delete. * * @param diff A pointer to a git_diff pointer that will be allocated. * @param repo The repository containing the tree. @@ -1143,12 +1136,14 @@ GIT_EXTERN(size_t) git_diff_stats_deletions( * @param out buffer to store the formatted diff statistics in. * @param stats A `git_diff_stats` generated by one of the above functions. * @param format Formatting option. + * @param width Target width for output (only affects GIT_DIFF_STATS_FULL) * @return 0 on success; non-zero on error */ GIT_EXTERN(int) git_diff_stats_to_buf( git_buf *out, const git_diff_stats *stats, - git_diff_stats_format_t format); + git_diff_stats_format_t format, + size_t width); /** * Deallocate a `git_diff_stats`. diff --git a/src/diff.c b/src/diff.c index 0d1aed4ad..fd881c6f6 100644 --- a/src/diff.c +++ b/src/diff.c @@ -1590,7 +1590,8 @@ int git_diff_format_email( if ((error = git_buf_puts(out, "---\n")) < 0 || (error = git_diff_get_stats(&stats, diff)) < 0 || - (error = git_diff_stats_to_buf(out, stats, format_flags)) < 0 || + (error = git_diff_stats_to_buf(out, stats, format_flags, 0)) < 0 || + (error = git_buf_putc(out, '\n')) < 0 || (error = git_diff_format_email__append_patches_tobuf(out, diff)) < 0) goto on_error; diff --git a/src/diff_print.c b/src/diff_print.c index a7f7b6fe8..ee5cd8dfb 100644 --- a/src/diff_print.c +++ b/src/diff_print.c @@ -175,7 +175,8 @@ static int diff_print_one_raw( git_oid_tostr(end_oid, pi->oid_strlen, &delta->new_file.id); git_buf_printf( - out, ":%06o %06o %s... %s... %c", + out, (pi->oid_strlen <= GIT_OID_HEXSZ) ? + ":%06o %06o %s... %s... %c" : ":%06o %06o %s %s %c", delta->old_file.mode, delta->new_file.mode, start_oid, end_oid, code); if (delta->similarity > 0) diff --git a/src/diff_stats.c b/src/diff_stats.c index bb436bf7b..6ad670c42 100644 --- a/src/diff_stats.c +++ b/src/diff_stats.c @@ -10,149 +10,134 @@ #include "diff_patch.h" #define DIFF_RENAME_FILE_SEPARATOR " => " +#define STATS_FULL_MIN_SCALE 7 + +typedef struct { + size_t insertions; + size_t deletions; +} diff_file_stats; struct git_diff_stats { - git_vector patches; + git_diff *diff; + diff_file_stats *filestats; size_t files_changed; size_t insertions; size_t deletions; + size_t renames; + + size_t max_name; + size_t max_filestat; + int max_digits; }; -static size_t diff_get_filename_padding( - int has_renames, - const git_diff_stats *stats) +static int digits_for_value(size_t val) { - const git_patch *patch = NULL; - size_t i, max_padding = 0; - - if (has_renames) { - git_vector_foreach(&stats->patches, i, patch) { - const git_diff_delta *delta = NULL; - size_t len; + int count = 1; + size_t placevalue = 10; - delta = git_patch_get_delta(patch); - if (strcmp(delta->old_file.path, delta->new_file.path) == 0) - continue; - - if ((len = strlen(delta->old_file.path) + strlen(delta->new_file.path)) > max_padding) - max_padding = len; - } + while (val >= placevalue) { + ++count; + placevalue *= 10; } - git_vector_foreach(&stats->patches, i, patch) { - const git_diff_delta *delta = NULL; - size_t len; - - delta = git_patch_get_delta(patch); - len = strlen(delta->new_file.path); - - if (strcmp(delta->old_file.path, delta->new_file.path) != 0) - continue; - - if (len > max_padding) - max_padding = len; - } - - return max_padding; + return count; } int git_diff_file_stats__full_to_buf( git_buf *out, - size_t max_padding, - int has_renames, - const git_patch *patch) + const git_diff_delta *delta, + const diff_file_stats *filestat, + const git_diff_stats *stats, + size_t width) { const char *old_path = NULL, *new_path = NULL; - const git_diff_delta *delta = NULL; size_t padding, old_size, new_size; - int error; - - delta = git_patch_get_delta(patch); old_path = delta->old_file.path; new_path = delta->new_file.path; old_size = delta->old_file.size; new_size = delta->new_file.size; - if ((error = git_buf_printf(out, " %s", old_path)) < 0) + if (git_buf_printf(out, " %s", old_path) < 0) goto on_error; if (strcmp(old_path, new_path) != 0) { - padding = max_padding - strlen(old_path) - strlen(new_path); + padding = stats->max_name - strlen(old_path) - strlen(new_path); - if ((error = git_buf_printf(out, DIFF_RENAME_FILE_SEPARATOR "%s", new_path)) < 0) + if (git_buf_printf(out, DIFF_RENAME_FILE_SEPARATOR "%s", new_path) < 0) goto on_error; - } - else { - padding = max_padding - strlen(old_path); + } else { + padding = stats->max_name - strlen(old_path); - if (has_renames) + if (stats->renames > 0) padding += strlen(DIFF_RENAME_FILE_SEPARATOR); } - if ((error = git_buf_putcn(out, ' ', padding)) < 0 || - (error = git_buf_puts(out, " | ")) < 0) - goto on_error; + if (git_buf_putcn(out, ' ', padding) < 0 || + git_buf_puts(out, " | ") < 0) + goto on_error; if (delta->flags & GIT_DIFF_FLAG_BINARY) { - if ((error = git_buf_printf(out, "Bin %" PRIuZ " -> %" PRIuZ " bytes", old_size, new_size)) < 0) + if (git_buf_printf(out, + "Bin %" PRIuZ " -> %" PRIuZ " bytes", old_size, new_size) < 0) goto on_error; } else { - size_t insertions, deletions; - - if ((error = git_patch_line_stats(NULL, &insertions, &deletions, patch)) < 0) + if (git_buf_printf(out, + "%*" PRIuZ, stats->max_digits, + filestat->insertions + filestat->deletions) < 0) goto on_error; - if ((error = git_buf_printf(out, "%" PRIuZ, insertions + deletions)) < 0) - goto on_error; + if (filestat->insertions || filestat->deletions) { + if (git_buf_putc(out, ' ') < 0) + goto on_error; - if (insertions || deletions) { - if ((error = git_buf_putc(out, ' ')) < 0 || - (error = git_buf_putcn(out, '+', insertions)) < 0 || - (error = git_buf_putcn(out, '-', deletions)) < 0) + if (!width) { + if (git_buf_putcn(out, '+', filestat->insertions) < 0 || + git_buf_putcn(out, '-', filestat->deletions) < 0) + goto on_error; + } else { + size_t total = filestat->insertions + filestat->deletions; + size_t full = (total * width + stats->max_filestat / 2) / + stats->max_filestat; + size_t plus = full * filestat->insertions / total; + size_t minus = full - plus; + + if (git_buf_putcn(out, '+', max(plus, 1)) < 0 || + git_buf_putcn(out, '-', max(minus, 1)) < 0) goto on_error; + } } } - error = git_buf_putc(out, '\n'); + git_buf_putc(out, '\n'); on_error: - return error; + return (git_buf_oom(out) ? -1 : 0); } int git_diff_file_stats__number_to_buf( git_buf *out, - const git_patch *patch) + const git_diff_delta *delta, + const diff_file_stats *filestats) { - const git_diff_delta *delta = NULL; - const char *path = NULL; - size_t insertions, deletions; int error; - - delta = git_patch_get_delta(patch); - path = delta->new_file.path; - - if ((error = git_patch_line_stats(NULL, &insertions, &deletions, patch)) < 0) - return error; + const char *path = delta->new_file.path; if (delta->flags & GIT_DIFF_FLAG_BINARY) error = git_buf_printf(out, "%-8c" "%-8c" "%s\n", '-', '-', path); else - error = git_buf_printf(out, "%-8" PRIuZ "%-8" PRIuZ "%s\n", insertions, deletions, path); + error = git_buf_printf(out, "%-8" PRIuZ "%-8" PRIuZ "%s\n", + filestats->insertions, filestats->deletions, path); return error; } int git_diff_file_stats__summary_to_buf( git_buf *out, - const git_patch *patch) + const git_diff_delta *delta) { - const git_diff_delta *delta = NULL; - - delta = git_patch_get_delta(patch); - if (delta->old_file.mode != delta->new_file.mode) { if (delta->old_file.mode == 0) { git_buf_printf(out, " create mode %06o %s\n", @@ -171,39 +156,6 @@ int git_diff_file_stats__summary_to_buf( return 0; } -int git_diff_stats__has_renames( - const git_diff_stats *stats) -{ - git_patch *patch = NULL; - size_t i; - - git_vector_foreach(&stats->patches, i, patch) { - const git_diff_delta *delta = git_patch_get_delta(patch); - - if (strcmp(delta->old_file.path, delta->new_file.path) != 0) { - return 1; - } - } - - return 0; -} - -int git_diff_stats__add_file_stats( - git_diff_stats *stats, - git_patch *patch) -{ - const git_diff_delta *delta = NULL; - int error = 0; - - if ((delta = git_patch_get_delta(patch)) == NULL) - return -1; - - if ((error = git_vector_insert(&stats->patches, patch)) < 0) - return error; - - return error; -} - int git_diff_get_stats( git_diff_stats **out, git_diff *diff) @@ -220,35 +172,60 @@ int git_diff_get_stats( deltas = git_diff_num_deltas(diff); - for (i = 0; i < deltas; ++i) { + stats->filestats = git__calloc(deltas, sizeof(diff_file_stats)); + if (!stats->filestats) { + git__free(stats); + return -1; + } + + stats->diff = diff; + GIT_REFCOUNT_INC(diff); + + for (i = 0; i < deltas && !error; ++i) { git_patch *patch = NULL; - size_t add, remove; + size_t add = 0, remove = 0, namelen; + const git_diff_delta *delta; if ((error = git_patch_from_diff(&patch, diff, i)) < 0) - goto on_error; + break; - if ((error = git_patch_line_stats(NULL, &add, &remove, patch)) < 0 || - (error = git_diff_stats__add_file_stats(stats, patch)) < 0) { - git_patch_free(patch); - goto on_error; + /* keep a count of renames because it will affect formatting */ + delta = git_patch_get_delta(patch); + + namelen = strlen(delta->new_file.path); + if (strcmp(delta->old_file.path, delta->new_file.path) != 0) { + namelen += strlen(delta->old_file.path); + stats->renames++; } + /* and, of course, count the line stats */ + error = git_patch_line_stats(NULL, &add, &remove, patch); + + git_patch_free(patch); + + stats->filestats[i].insertions = add; + stats->filestats[i].deletions = remove; + total_insertions += add; total_deletions += remove; + + if (stats->max_name < namelen) + stats->max_name = namelen; + if (stats->max_filestat < add + remove) + stats->max_filestat = add + remove; } stats->files_changed = deltas; stats->insertions = total_insertions; stats->deletions = total_deletions; + stats->max_digits = digits_for_value(stats->max_filestat + 1); - *out = stats; - - goto done; - -on_error: - git_diff_stats_free(stats); + if (error < 0) { + git_diff_stats_free(stats); + stats = NULL; + } -done: + *out = stats; return error; } @@ -279,48 +256,67 @@ size_t git_diff_stats_deletions( int git_diff_stats_to_buf( git_buf *out, const git_diff_stats *stats, - git_diff_stats_format_t format) + git_diff_stats_format_t format, + size_t width) { - git_patch *patch = NULL; + int error = 0; size_t i; - int has_renames = 0, error = 0; + const git_diff_delta *delta; assert(out && stats); - /* check if we have renames, it affects the padding */ - has_renames = git_diff_stats__has_renames(stats); - - git_vector_foreach(&stats->patches, i, patch) { - if (format & GIT_DIFF_STATS_FULL) { - size_t max_padding = diff_get_filename_padding(has_renames, stats); + if (format & GIT_DIFF_STATS_NUMBER) { + for (i = 0; i < stats->files_changed; ++i) { + if ((delta = git_diff_get_delta(stats->diff, i)) == NULL) + continue; - error = git_diff_file_stats__full_to_buf(out, max_padding, has_renames, patch); + error = git_diff_file_stats__number_to_buf( + out, delta, &stats->filestats[i]); + if (error < 0) + return error; } - else if (format & GIT_DIFF_STATS_NUMBER) { - error = git_diff_file_stats__number_to_buf(out, patch); + } + + if (format & GIT_DIFF_STATS_FULL) { + if (width > 0) { + if (width > stats->max_name + stats->max_digits + 5) + width -= (stats->max_name + stats->max_digits + 5); + if (width < STATS_FULL_MIN_SCALE) + width = STATS_FULL_MIN_SCALE; } - if (error < 0) - return error; + for (i = 0; i < stats->files_changed; ++i) { + if ((delta = git_diff_get_delta(stats->diff, i)) == NULL) + continue; + + error = git_diff_file_stats__full_to_buf( + out, delta, &stats->filestats[i], stats, width); + if (error < 0) + return error; + } } if (format & GIT_DIFF_STATS_FULL || format & GIT_DIFF_STATS_SHORT) { - error = git_buf_printf(out, " %" PRIuZ " file%s changed, %" PRIuZ " insertions(+), %" PRIuZ " deletions(-)\n", - stats->files_changed, stats->files_changed > 1 ? "s" : "", - stats->insertions, stats->deletions); + error = git_buf_printf( + out, " %" PRIuZ " file%s changed, %" PRIuZ + " insertion%s(+), %" PRIuZ " deletion%s(-)\n", + stats->files_changed, stats->files_changed != 1 ? "s" : "", + stats->insertions, stats->insertions != 1 ? "s" : "", + stats->deletions, stats->deletions != 1 ? "s" : ""); if (error < 0) return error; } if (format & GIT_DIFF_STATS_INCLUDE_SUMMARY) { - git_vector_foreach(&stats->patches, i, patch) { - if ((error = git_diff_file_stats__summary_to_buf(out, patch)) < 0) + for (i = 0; i < stats->files_changed; ++i) { + if ((delta = git_diff_get_delta(stats->diff, i)) == NULL) + continue; + + error = git_diff_file_stats__summary_to_buf(out, delta); + if (error < 0) return error; } - - if (git_vector_length(&stats->patches) > 0) - git_buf_putc(out, '\n'); } return error; @@ -328,16 +324,11 @@ int git_diff_stats_to_buf( void git_diff_stats_free(git_diff_stats *stats) { - size_t i; - git_patch *patch; - if (stats == NULL) return; - git_vector_foreach(&stats->patches, i, patch) - git_patch_free(patch); - - git_vector_free(&stats->patches); + git_diff_free(stats->diff); /* bumped refcount in constructor */ + git__free(stats->filestats); git__free(stats); } diff --git a/tests/diff/format_email.c b/tests/diff/format_email.c index 3260fdea8..18ad99bd5 100644 --- a/tests/diff/format_email.c +++ b/tests/diff/format_email.c @@ -17,15 +17,44 @@ void test_diff_format_email__cleanup(void) cl_git_sandbox_cleanup(); } -void test_diff_format_email__simple(void) +static void assert_email_match( + const char *expected, + const char *oidstr, + git_diff_format_email_options *opts) { git_oid oid; git_commit *commit = NULL; git_diff *diff = NULL; - git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; git_buf buf = GIT_BUF_INIT; - const char *email = + git_oid_fromstr(&oid, oidstr); + + cl_git_pass(git_commit_lookup(&commit, repo, &oid)); + + opts->id = git_commit_id(commit); + opts->author = git_commit_author(commit); + if (!opts->summary) + opts->summary = git_commit_summary(commit); + + cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); + cl_git_pass(git_diff_format_email(&buf, diff, opts)); + + cl_assert_equal_s(expected, git_buf_cstr(&buf)); + git_buf_clear(&buf); + + cl_git_pass(git_diff_commit_as_email( + &buf, repo, commit, 1, 1, opts->flags, NULL)); + cl_assert_equal_s(expected, git_buf_cstr(&buf)); + + git_diff_free(diff); + git_commit_free(commit); + git_buf_free(&buf); +} + +void test_diff_format_email__simple(void) +{ + git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; + const char *email = "From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001\n" \ "From: Jacques Germishuys <jacquesg@striata.com>\n" \ "Date: Wed, 9 Apr 2014 20:57:01 +0200\n" \ @@ -64,25 +93,8 @@ void test_diff_format_email__simple(void) "libgit2 " LIBGIT2_VERSION "\n" \ "\n"; - git_oid_fromstr(&oid, "9264b96c6d104d0e07ae33d3007b6a48246c6f92"); - - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - - opts.id = git_commit_id(commit); - opts.author = git_commit_author(commit); - opts.summary = git_commit_summary(commit); - - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - cl_git_pass(git_diff_format_email(&buf, diff, &opts)); - cl_assert(strcmp(git_buf_cstr(&buf), email) == 0); - - git_buf_clear(&buf); - cl_git_pass(git_diff_commit_as_email(&buf, repo, commit, 1, 1, 0, NULL)); - cl_assert(strcmp(git_buf_cstr(&buf), email) == 0); - - git_diff_free(diff); - git_commit_free(commit); - git_buf_free(&buf); + assert_email_match( + email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); } void test_diff_format_email__multiple(void) @@ -90,10 +102,10 @@ void test_diff_format_email__multiple(void) git_oid oid; git_commit *commit = NULL; git_diff *diff = NULL; - git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; + git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; git_buf buf = GIT_BUF_INIT; - const char *email = + const char *email = "From 10808fe9c9be5a190c0ba68d1a002233fb363508 Mon Sep 17 00:00:00 2001\n" \ "From: Jacques Germishuys <jacquesg@striata.com>\n" \ "Date: Thu, 10 Apr 2014 19:37:05 +0200\n" \ @@ -167,6 +179,7 @@ void test_diff_format_email__multiple(void) "libgit2 " LIBGIT2_VERSION "\n" \ "\n"; + git_oid_fromstr(&oid, "10808fe9c9be5a190c0ba68d1a002233fb363508"); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); @@ -196,7 +209,7 @@ void test_diff_format_email__multiple(void) cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); cl_git_pass(git_diff_format_email(&buf, diff, &opts)); - cl_assert(strcmp(git_buf_cstr(&buf), email) == 0); + cl_assert_equal_s(email, git_buf_cstr(&buf)); git_diff_free(diff); git_commit_free(commit); @@ -205,13 +218,8 @@ void test_diff_format_email__multiple(void) void test_diff_format_email__exclude_marker(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; - git_buf buf = GIT_BUF_INIT; - - const char *email = + const char *email = "From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001\n" \ "From: Jacques Germishuys <jacquesg@striata.com>\n" \ "Date: Wed, 9 Apr 2014 20:57:01 +0200\n" \ @@ -250,27 +258,10 @@ void test_diff_format_email__exclude_marker(void) "libgit2 " LIBGIT2_VERSION "\n" \ "\n"; - git_oid_fromstr(&oid, "9264b96c6d104d0e07ae33d3007b6a48246c6f92"); - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - - opts.id = git_commit_id(commit); - opts.author = git_commit_author(commit); - opts.summary = git_commit_summary(commit); - opts.flags |= GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER; - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - cl_git_pass(git_diff_format_email(&buf, diff, &opts)); - cl_assert(strcmp(git_buf_cstr(&buf), email) == 0); - - git_buf_clear(&buf); - cl_git_pass(git_diff_commit_as_email(&buf, repo, commit, 1, 1, - GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER, NULL)); - cl_assert(strcmp(git_buf_cstr(&buf), email) == 0); - - git_diff_free(diff); - git_commit_free(commit); - git_buf_free(&buf); + assert_email_match( + email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); } void test_diff_format_email__invalid_no(void) @@ -303,13 +294,8 @@ void test_diff_format_email__invalid_no(void) void test_diff_format_email__mode_change(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; - git_buf buf = GIT_BUF_INIT; - - const char *email = + const char *email = "From 7ade76dd34bba4733cf9878079f9fd4a456a9189 Mon Sep 17 00:00:00 2001\n" \ "From: Jacques Germishuys <jacquesg@striata.com>\n" \ "Date: Thu, 10 Apr 2014 10:05:03 +0200\n" \ @@ -330,36 +316,14 @@ void test_diff_format_email__mode_change(void) "libgit2 " LIBGIT2_VERSION "\n" \ "\n"; - git_oid_fromstr(&oid, "7ade76dd34bba4733cf9878079f9fd4a456a9189"); - - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - - opts.id = git_commit_id(commit); - opts.author = git_commit_author(commit); - opts.summary = git_commit_summary(commit); - - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - cl_git_pass(git_diff_format_email(&buf, diff, &opts)); - cl_assert(strcmp(git_buf_cstr(&buf), email) == 0); - - git_buf_clear(&buf); - cl_git_pass(git_diff_commit_as_email(&buf, repo, commit, 1, 1, 0, NULL)); - cl_assert(strcmp(git_buf_cstr(&buf), email) == 0); - - git_diff_free(diff); - git_commit_free(commit); - git_buf_free(&buf); + assert_email_match( + email, "7ade76dd34bba4733cf9878079f9fd4a456a9189", &opts); } void test_diff_format_email__rename_add_remove(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; - git_buf buf = GIT_BUF_INIT; - - const char *email = + const char *email = "From 6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d Mon Sep 17 00:00:00 2001\n" \ "From: Jacques Germishuys <jacquesg@striata.com>\n" \ "Date: Wed, 9 Apr 2014 21:15:56 +0200\n" \ @@ -422,35 +386,13 @@ void test_diff_format_email__rename_add_remove(void) "libgit2 " LIBGIT2_VERSION "\n" \ "\n"; - git_oid_fromstr(&oid, "6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d"); - - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - - opts.id = git_commit_id(commit); - opts.author = git_commit_author(commit); - opts.summary = git_commit_summary(commit); - - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - cl_git_pass(git_diff_format_email(&buf, diff, &opts)); - cl_assert(strcmp(git_buf_cstr(&buf), email) == 0); - - git_buf_clear(&buf); - cl_git_pass(git_diff_commit_as_email(&buf, repo, commit, 1, 1, 0, NULL)); - cl_assert(strcmp(git_buf_cstr(&buf), email) == 0); - - git_diff_free(diff); - git_commit_free(commit); - git_buf_free(&buf); + assert_email_match( + email, "6e05acc5a5dab507d91a0a0cc0fb05a3dd98892d", &opts); } void test_diff_format_email__multiline_summary(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; - git_buf buf = GIT_BUF_INIT; - const char *email = "From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001\n" \ "From: Jacques Germishuys <jacquesg@striata.com>\n" \ @@ -490,36 +432,15 @@ void test_diff_format_email__multiline_summary(void) "libgit2 " LIBGIT2_VERSION "\n" \ "\n"; - git_oid_fromstr(&oid, "9264b96c6d104d0e07ae33d3007b6a48246c6f92"); - - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - - opts.id = git_commit_id(commit); - opts.author = git_commit_author(commit); opts.summary = "Modify some content\nSome extra stuff here"; - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - cl_git_pass(git_diff_format_email(&buf, diff, &opts)); - cl_assert(strcmp(git_buf_cstr(&buf), email) == 0); - - git_buf_clear(&buf); - cl_git_pass(git_diff_commit_as_email(&buf, repo, commit, 1, 1, 0, NULL)); - cl_assert(strcmp(git_buf_cstr(&buf), email) == 0); - - git_diff_free(diff); - git_commit_free(commit); - git_buf_free(&buf); + assert_email_match( + email, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", &opts); } void test_diff_format_email__binary(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; - git_buf buf = GIT_BUF_INIT; - - /* TODO: Actually 0 bytes here should be 5!. Seems like we don't load the new content for binary files? */ const char *email = "From 8d7523f6fcb2404257889abe0d96f093d9f524f9 Mon Sep 17 00:00:00 2001\n" \ "From: Jacques Germishuys <jacquesg@striata.com>\n" \ @@ -536,21 +457,11 @@ void test_diff_format_email__binary(void) "--\n" \ "libgit2 " LIBGIT2_VERSION "\n" \ "\n"; + /* TODO: Actually 0 bytes here should be 5!. Seems like we don't load the new content for binary files? */ - git_oid_fromstr(&oid, "8d7523f6fcb2404257889abe0d96f093d9f524f9"); - - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - - opts.id = git_commit_id(commit); - opts.author = git_commit_author(commit); opts.summary = "Modified binary file"; - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - cl_git_pass(git_diff_format_email(&buf, diff, &opts)); - cl_assert(strcmp(git_buf_cstr(&buf), email) == 0); - - git_diff_free(diff); - git_commit_free(commit); - git_buf_free(&buf); + assert_email_match( + email, "8d7523f6fcb2404257889abe0d96f093d9f524f9", &opts); } diff --git a/tests/diff/stats.c b/tests/diff/stats.c index 131b7681d..055019f69 100644 --- a/tests/diff/stats.c +++ b/tests/diff/stats.c @@ -5,246 +5,173 @@ #include "commit.h" #include "diff.h" -static git_repository *repo; +static git_repository *_repo; +static git_diff_stats *_stats; void test_diff_stats__initialize(void) { - repo = cl_git_sandbox_init("diff_format_email"); + _repo = cl_git_sandbox_init("diff_format_email"); } void test_diff_stats__cleanup(void) { + git_diff_stats_free(_stats); _stats = NULL; cl_git_sandbox_cleanup(); } -void test_diff_stats__stat(void) +static void diff_stats_from_commit_oid( + git_diff_stats **stats, const char *oidstr, bool rename) { git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - git_diff_stats *stats = NULL; - git_buf buf = GIT_BUF_INIT; + git_commit *commit; + git_diff *diff; + + git_oid_fromstr(&oid, oidstr); + cl_git_pass(git_commit_lookup(&commit, _repo, &oid)); + cl_git_pass(git_diff__commit(&diff, _repo, commit, NULL)); + if (rename) + cl_git_pass(git_diff_find_similar(diff, NULL)); + cl_git_pass(git_diff_get_stats(stats, diff)); + + git_diff_free(diff); + git_commit_free(commit); +} +void test_diff_stats__stat(void) +{ + git_buf buf = GIT_BUF_INIT; const char *stat = " file1.txt | 8 +++++---\n" \ " 1 file changed, 5 insertions(+), 3 deletions(-)\n"; - git_oid_fromstr(&oid, "9264b96c6d104d0e07ae33d3007b6a48246c6f92"); + diff_stats_from_commit_oid( + &_stats, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", false); - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); + cl_assert_equal_sz(1, git_diff_stats_files_changed(_stats)); + cl_assert_equal_sz(5, git_diff_stats_insertions(_stats)); + cl_assert_equal_sz(3, git_diff_stats_deletions(_stats)); - cl_git_pass(git_diff_get_stats(&stats, diff)); - cl_assert(git_diff_stats_files_changed(stats) == 1); - cl_assert(git_diff_stats_insertions(stats) == 5); - cl_assert(git_diff_stats_deletions(stats) == 3); - - cl_git_pass(git_diff_stats_to_buf(&buf, stats, GIT_DIFF_STATS_FULL)); + cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); - - git_diff_stats_free(stats); - git_diff_free(diff); - git_commit_free(commit); git_buf_free(&buf); } void test_diff_stats__multiple_hunks(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - git_diff_stats *stats = NULL; git_buf buf = GIT_BUF_INIT; - const char *stat = " file2.txt | 5 +++--\n" \ " file3.txt | 6 ++++--\n" \ " 2 files changed, 7 insertions(+), 4 deletions(-)\n"; - git_oid_fromstr(&oid, "cd471f0d8770371e1bc78bcbb38db4c7e4106bd2"); - - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); + diff_stats_from_commit_oid( + &_stats, "cd471f0d8770371e1bc78bcbb38db4c7e4106bd2", false); - cl_git_pass(git_diff_get_stats(&stats, diff)); - cl_assert(git_diff_stats_files_changed(stats) == 2); - cl_assert(git_diff_stats_insertions(stats) == 7); - cl_assert(git_diff_stats_deletions(stats) == 4); + cl_assert_equal_sz(2, git_diff_stats_files_changed(_stats)); + cl_assert_equal_sz(7, git_diff_stats_insertions(_stats)); + cl_assert_equal_sz(4, git_diff_stats_deletions(_stats)); - cl_git_pass(git_diff_stats_to_buf(&buf, stats, GIT_DIFF_STATS_FULL)); - cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); - - git_diff_stats_free(stats); - git_diff_free(diff); - git_commit_free(commit); + cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); + cl_assert_equal_s(stat, git_buf_cstr(&buf)); git_buf_free(&buf); } void test_diff_stats__numstat(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - git_diff_stats *stats = NULL; git_buf buf = GIT_BUF_INIT; - const char *stat = "3 2 file2.txt\n" "4 2 file3.txt\n"; - git_oid_fromstr(&oid, "cd471f0d8770371e1bc78bcbb38db4c7e4106bd2"); - - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - - cl_git_pass(git_diff_get_stats(&stats, diff)); - - cl_git_pass(git_diff_stats_to_buf(&buf, stats, GIT_DIFF_STATS_NUMBER)); - cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); + diff_stats_from_commit_oid( + &_stats, "cd471f0d8770371e1bc78bcbb38db4c7e4106bd2", false); - git_diff_stats_free(stats); - git_diff_free(diff); - git_commit_free(commit); + cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_NUMBER, 0)); + cl_assert_equal_s(stat, git_buf_cstr(&buf)); git_buf_free(&buf); } void test_diff_stats__shortstat(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - git_diff_stats *stats = NULL; git_buf buf = GIT_BUF_INIT; - const char *stat = " 1 file changed, 5 insertions(+), 3 deletions(-)\n"; - git_oid_fromstr(&oid, "9264b96c6d104d0e07ae33d3007b6a48246c6f92"); - - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); + diff_stats_from_commit_oid( + &_stats, "9264b96c6d104d0e07ae33d3007b6a48246c6f92", false); - cl_git_pass(git_diff_get_stats(&stats, diff)); - cl_assert(git_diff_stats_files_changed(stats) == 1); - cl_assert(git_diff_stats_insertions(stats) == 5); - cl_assert(git_diff_stats_deletions(stats) == 3); + cl_assert_equal_sz(1, git_diff_stats_files_changed(_stats)); + cl_assert_equal_sz(5, git_diff_stats_insertions(_stats)); + cl_assert_equal_sz(3, git_diff_stats_deletions(_stats)); - cl_git_pass(git_diff_stats_to_buf(&buf, stats, GIT_DIFF_STATS_SHORT)); - cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); - - git_diff_stats_free(stats); - git_diff_free(diff); - git_commit_free(commit); + cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_SHORT, 0)); + cl_assert_equal_s(stat, git_buf_cstr(&buf)); git_buf_free(&buf); } void test_diff_stats__rename(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - git_diff_stats *stats = NULL; git_buf buf = GIT_BUF_INIT; - const char *stat = " file2.txt => file2.txt.renamed | 1 +\n" " file3.txt => file3.txt.renamed | 4 +++-\n" - " 2 files changed, 4 insertions(+), 1 deletions(-)\n"; - - git_oid_fromstr(&oid, "8947a46e2097638ca6040ad4877246f4186ec3bd"); + " 2 files changed, 4 insertions(+), 1 deletion(-)\n"; - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - cl_git_pass(git_diff_find_similar(diff, NULL)); + diff_stats_from_commit_oid( + &_stats, "8947a46e2097638ca6040ad4877246f4186ec3bd", true); - cl_git_pass(git_diff_get_stats(&stats, diff)); - cl_assert(git_diff_stats_files_changed(stats) == 2); - cl_assert(git_diff_stats_insertions(stats) == 4); - cl_assert(git_diff_stats_deletions(stats) == 1); + cl_assert_equal_sz(2, git_diff_stats_files_changed(_stats)); + cl_assert_equal_sz(4, git_diff_stats_insertions(_stats)); + cl_assert_equal_sz(1, git_diff_stats_deletions(_stats)); - cl_git_pass(git_diff_stats_to_buf(&buf, stats, GIT_DIFF_STATS_FULL)); - cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); - - git_diff_stats_free(stats); - git_diff_free(diff); - git_commit_free(commit); + cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); + cl_assert_equal_s(stat, git_buf_cstr(&buf)); git_buf_free(&buf); } void test_diff_stats__rename_nochanges(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - git_diff_stats *stats = NULL; git_buf buf = GIT_BUF_INIT; - const char *stat = " file2.txt.renamed => file2.txt.renamed2 | 0\n" " file3.txt.renamed => file3.txt.renamed2 | 0\n" " 2 files changed, 0 insertions(+), 0 deletions(-)\n"; - git_oid_fromstr(&oid, "3991dce9e71a0641ca49a6a4eea6c9e7ff402ed4"); - - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - cl_git_pass(git_diff_find_similar(diff, NULL)); + diff_stats_from_commit_oid( + &_stats, "3991dce9e71a0641ca49a6a4eea6c9e7ff402ed4", true); - cl_git_pass(git_diff_get_stats(&stats, diff)); - cl_assert(git_diff_stats_files_changed(stats) == 2); - cl_assert(git_diff_stats_insertions(stats) == 0); - cl_assert(git_diff_stats_deletions(stats) == 0); + cl_assert_equal_sz(2, git_diff_stats_files_changed(_stats)); + cl_assert_equal_sz(0, git_diff_stats_insertions(_stats)); + cl_assert_equal_sz(0, git_diff_stats_deletions(_stats)); - cl_git_pass(git_diff_stats_to_buf(&buf, stats, GIT_DIFF_STATS_FULL)); - cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); - - git_diff_stats_free(stats); - git_diff_free(diff); - git_commit_free(commit); + cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); + cl_assert_equal_s(stat, git_buf_cstr(&buf)); git_buf_free(&buf); } void test_diff_stats__rename_and_modifiy(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - git_diff_stats *stats = NULL; git_buf buf = GIT_BUF_INIT; - const char *stat = " file2.txt.renamed2 | 2 +-\n" " file3.txt.renamed2 => file3.txt.renamed | 0\n" - " 2 files changed, 1 insertions(+), 1 deletions(-)\n"; + " 2 files changed, 1 insertion(+), 1 deletion(-)\n"; - git_oid_fromstr(&oid, "4ca10087e696d2ba78d07b146a118e9a7096ed4f"); + diff_stats_from_commit_oid( + &_stats, "4ca10087e696d2ba78d07b146a118e9a7096ed4f", true); - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - cl_git_pass(git_diff_find_similar(diff, NULL)); + cl_assert_equal_sz(2, git_diff_stats_files_changed(_stats)); + cl_assert_equal_sz(1, git_diff_stats_insertions(_stats)); + cl_assert_equal_sz(1, git_diff_stats_deletions(_stats)); - cl_git_pass(git_diff_get_stats(&stats, diff)); - cl_assert(git_diff_stats_files_changed(stats) == 2); - cl_assert(git_diff_stats_insertions(stats) == 1); - cl_assert(git_diff_stats_deletions(stats) == 1); - - cl_git_pass(git_diff_stats_to_buf(&buf, stats, GIT_DIFF_STATS_FULL)); - cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); - - git_diff_stats_free(stats); - git_diff_free(diff); - git_commit_free(commit); + cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); + cl_assert_equal_s(stat, git_buf_cstr(&buf)); git_buf_free(&buf); } void test_diff_stats__rename_no_find(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - git_diff_stats *stats = NULL; git_buf buf = GIT_BUF_INIT; - const char *stat = " file2.txt | 5 -----\n" " file2.txt.renamed | 6 ++++++\n" @@ -252,33 +179,21 @@ void test_diff_stats__rename_no_find(void) " file3.txt.renamed | 7 +++++++\n" " 4 files changed, 13 insertions(+), 10 deletions(-)\n"; - git_oid_fromstr(&oid, "8947a46e2097638ca6040ad4877246f4186ec3bd"); + diff_stats_from_commit_oid( + &_stats, "8947a46e2097638ca6040ad4877246f4186ec3bd", false); - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); + cl_assert_equal_sz(4, git_diff_stats_files_changed(_stats)); + cl_assert_equal_sz(13, git_diff_stats_insertions(_stats)); + cl_assert_equal_sz(10, git_diff_stats_deletions(_stats)); - cl_git_pass(git_diff_get_stats(&stats, diff)); - cl_assert(git_diff_stats_files_changed(stats) == 4); - cl_assert(git_diff_stats_insertions(stats) == 13); - cl_assert(git_diff_stats_deletions(stats) == 10); - - cl_git_pass(git_diff_stats_to_buf(&buf, stats, GIT_DIFF_STATS_FULL)); - cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); - - git_diff_stats_free(stats); - git_diff_free(diff); - git_commit_free(commit); + cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); + cl_assert_equal_s(stat, git_buf_cstr(&buf)); git_buf_free(&buf); } void test_diff_stats__rename_nochanges_no_find(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - git_diff_stats *stats = NULL; git_buf buf = GIT_BUF_INIT; - const char *stat = " file2.txt.renamed | 6 ------\n" " file2.txt.renamed2 | 6 ++++++\n" @@ -286,143 +201,85 @@ void test_diff_stats__rename_nochanges_no_find(void) " file3.txt.renamed2 | 7 +++++++\n" " 4 files changed, 13 insertions(+), 13 deletions(-)\n"; - git_oid_fromstr(&oid, "3991dce9e71a0641ca49a6a4eea6c9e7ff402ed4"); - - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); + diff_stats_from_commit_oid( + &_stats, "3991dce9e71a0641ca49a6a4eea6c9e7ff402ed4", false); - cl_git_pass(git_diff_get_stats(&stats, diff)); - cl_assert(git_diff_stats_files_changed(stats) == 4); - cl_assert(git_diff_stats_insertions(stats) == 13); - cl_assert(git_diff_stats_deletions(stats) == 13); - - cl_git_pass(git_diff_stats_to_buf(&buf, stats, GIT_DIFF_STATS_FULL)); - cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); + cl_assert_equal_sz(4, git_diff_stats_files_changed(_stats)); + cl_assert_equal_sz(13, git_diff_stats_insertions(_stats)); + cl_assert_equal_sz(13, git_diff_stats_deletions(_stats)); - git_diff_stats_free(stats); - git_diff_free(diff); - git_commit_free(commit); + cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); + cl_assert_equal_s(stat, git_buf_cstr(&buf)); git_buf_free(&buf); } void test_diff_stats__rename_and_modifiy_no_find(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - git_diff_stats *stats = NULL; git_buf buf = GIT_BUF_INIT; - const char *stat = " file2.txt.renamed2 | 2 +-\n" " file3.txt.renamed | 7 +++++++\n" " file3.txt.renamed2 | 7 -------\n" " 3 files changed, 8 insertions(+), 8 deletions(-)\n"; - git_oid_fromstr(&oid, "4ca10087e696d2ba78d07b146a118e9a7096ed4f"); - - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - - cl_git_pass(git_diff_get_stats(&stats, diff)); - cl_assert(git_diff_stats_files_changed(stats) == 3); - cl_assert(git_diff_stats_insertions(stats) == 8); - cl_assert(git_diff_stats_deletions(stats) == 8); + diff_stats_from_commit_oid( + &_stats, "4ca10087e696d2ba78d07b146a118e9a7096ed4f", false); - cl_git_pass(git_diff_stats_to_buf(&buf, stats, GIT_DIFF_STATS_FULL)); - cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); + cl_assert_equal_sz(3, git_diff_stats_files_changed(_stats)); + cl_assert_equal_sz(8, git_diff_stats_insertions(_stats)); + cl_assert_equal_sz(8, git_diff_stats_deletions(_stats)); - git_diff_stats_free(stats); - git_diff_free(diff); - git_commit_free(commit); + cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); + cl_assert_equal_s(stat, git_buf_cstr(&buf)); git_buf_free(&buf); } void test_diff_stats__binary(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - git_diff_stats *stats = NULL; git_buf buf = GIT_BUF_INIT; - - /* TODO: Actually 0 bytes here should be 5!. Seems like we don't load the new content for binary files? */ const char *stat = " binary.bin | Bin 3 -> 0 bytes\n" " 1 file changed, 0 insertions(+), 0 deletions(-)\n"; + /* TODO: Actually 0 bytes here should be 5!. Seems like we don't load the new content for binary files? */ - git_oid_fromstr(&oid, "8d7523f6fcb2404257889abe0d96f093d9f524f9"); - - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - - cl_git_pass(git_diff_get_stats(&stats, diff)); - cl_assert(git_diff_stats_files_changed(stats) == 1); - cl_assert(git_diff_stats_insertions(stats) == 0); - cl_assert(git_diff_stats_deletions(stats) == 0); + diff_stats_from_commit_oid( + &_stats, "8d7523f6fcb2404257889abe0d96f093d9f524f9", false); - cl_git_pass(git_diff_stats_to_buf(&buf, stats, GIT_DIFF_STATS_FULL)); - cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); + cl_assert_equal_sz(1, git_diff_stats_files_changed(_stats)); + cl_assert_equal_sz(0, git_diff_stats_insertions(_stats)); + cl_assert_equal_sz(0, git_diff_stats_deletions(_stats)); - git_diff_stats_free(stats); - git_diff_free(diff); - git_commit_free(commit); + cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); + cl_assert_equal_s(stat, git_buf_cstr(&buf)); git_buf_free(&buf); } void test_diff_stats__binary_numstat(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - git_diff_stats *stats = NULL; git_buf buf = GIT_BUF_INIT; - const char *stat = "- - binary.bin\n"; - git_oid_fromstr(&oid, "8d7523f6fcb2404257889abe0d96f093d9f524f9"); - - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - - cl_git_pass(git_diff_get_stats(&stats, diff)); + diff_stats_from_commit_oid( + &_stats, "8d7523f6fcb2404257889abe0d96f093d9f524f9", false); - cl_git_pass(git_diff_stats_to_buf(&buf, stats, GIT_DIFF_STATS_NUMBER)); - cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); - - git_diff_stats_free(stats); - git_diff_free(diff); - git_commit_free(commit); + cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_NUMBER, 0)); + cl_assert_equal_s(stat, git_buf_cstr(&buf)); git_buf_free(&buf); } void test_diff_stats__mode_change(void) { - git_oid oid; - git_commit *commit = NULL; - git_diff *diff = NULL; - git_diff_stats *stats = NULL; git_buf buf = GIT_BUF_INIT; - const char *stat = " file1.txt.renamed | 0\n" \ " 1 file changed, 0 insertions(+), 0 deletions(-)\n" \ - " mode change 100644 => 100755 file1.txt.renamed\n" \ - "\n"; + " mode change 100644 => 100755 file1.txt.renamed\n"; - git_oid_fromstr(&oid, "7ade76dd34bba4733cf9878079f9fd4a456a9189"); + diff_stats_from_commit_oid( + &_stats, "7ade76dd34bba4733cf9878079f9fd4a456a9189", false); - cl_git_pass(git_commit_lookup(&commit, repo, &oid)); - cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); - - cl_git_pass(git_diff_get_stats(&stats, diff)); - - cl_git_pass(git_diff_stats_to_buf(&buf, stats, GIT_DIFF_STATS_FULL | GIT_DIFF_STATS_INCLUDE_SUMMARY)); - cl_assert(strcmp(git_buf_cstr(&buf), stat) == 0); - - git_diff_stats_free(stats); - git_diff_free(diff); - git_commit_free(commit); + cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL | GIT_DIFF_STATS_INCLUDE_SUMMARY, 0)); + cl_assert_equal_s(stat, git_buf_cstr(&buf)); git_buf_free(&buf); } |