mirror of
https://github.com/libgit2/libgit2.git
synced 2026-06-22 06:26:26 +00:00
Some doc and examples/diff.c changes
I was playing with "git diff-index" and wanted to be able to emulate that behavior a little more closely with the diff example. Also, I wanted to play with running `git_diff_tree_to_workdir` directly even though core Git doesn't exactly have the equivalent, so I added a command line option for that and tweaked some other things in the example code. This changes a minor output thing in that the "raw" print helper function will no longer add ellipses (...) if the OID is not actually abbreviated.
This commit is contained in:
151
examples/diff.c
151
examples/diff.c
@@ -33,14 +33,26 @@ static const char *colors[] = {
|
||||
"\033[36m" /* cyan */
|
||||
};
|
||||
|
||||
enum {
|
||||
OUTPUT_DIFF = 0,
|
||||
OUTPUT_STAT = 1,
|
||||
OUTPUT_SHORTSTAT = 2,
|
||||
OUTPUT_NUMSTAT = 3
|
||||
};
|
||||
|
||||
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 +60,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 +73,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 +90,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 +106,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 +137,14 @@ 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 {
|
||||
switch (o.output) {
|
||||
case OUTPUT_STAT:
|
||||
case OUTPUT_NUMSTAT:
|
||||
case OUTPUT_SHORTSTAT:
|
||||
diff_print_stats(diff, &o);
|
||||
break;
|
||||
|
||||
case OUTPUT_DIFF:
|
||||
if (o.color >= 0)
|
||||
fputs(colors[0], stdout);
|
||||
|
||||
@@ -135,6 +154,10 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (o.color >= 0)
|
||||
fputs(colors[0], stdout);
|
||||
break;
|
||||
|
||||
default:
|
||||
usage("Unknown output format", "programmer error");
|
||||
}
|
||||
|
||||
/** Cleanup before exiting. */
|
||||
@@ -213,13 +236,20 @@ static void parse_opts(struct opts *o, int argc, char *argv[])
|
||||
!strcmp(a, "--patch"))
|
||||
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 +272,12 @@ 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 (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,34 +308,8 @@ static void parse_opts(struct opts *o, int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
/** Display diff output with "--numstat".*/
|
||||
static void diff_print_numstat(git_diff *diff)
|
||||
{
|
||||
git_patch *patch;
|
||||
const git_diff_delta *delta;
|
||||
size_t d, ndeltas = git_diff_num_deltas(diff);
|
||||
size_t nadditions, ndeletions;
|
||||
|
||||
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);
|
||||
|
||||
delta = git_patch_get_delta(patch);
|
||||
|
||||
printf("%ld\t%ld\t%s\n",
|
||||
(long)nadditions, (long)ndeletions, delta->new_file.path);
|
||||
|
||||
git_patch_free(patch);
|
||||
}
|
||||
}
|
||||
|
||||
/** Display diff output with "--shortstat".*/
|
||||
static void diff_print_shortstat(git_diff *diff)
|
||||
/** Display diff output with "--numstat" or "--shortstat" */
|
||||
static void diff_print_stats(git_diff *diff, struct opts *o)
|
||||
{
|
||||
git_patch *patch;
|
||||
size_t d, ndeltas = git_diff_num_deltas(diff);
|
||||
@@ -320,26 +328,39 @@ static void diff_print_shortstat(git_diff *diff)
|
||||
git_patch_line_stats(NULL, &nadditions, &ndeletions, patch),
|
||||
"generating the number of additions and deletions", NULL);
|
||||
|
||||
if (o->output == OUTPUT_NUMSTAT) {
|
||||
const git_diff_delta *delta = git_patch_get_delta(patch);
|
||||
printf("%ld\t%ld\t%s\n",
|
||||
(long)nadditions, (long)ndeletions, delta->new_file.path);
|
||||
}
|
||||
else if (o->output == OUTPUT_STAT) {
|
||||
const git_diff_delta *delta = git_patch_get_delta(patch);
|
||||
printf(" %s\t| %ld\t(%ld+ %ld-)\n",
|
||||
delta->new_file.path, (long)nadditions + (long)ndeletions,
|
||||
(long)nadditions, (long)ndeletions);
|
||||
}
|
||||
|
||||
nadditions_sum += nadditions;
|
||||
ndeletions_sum += ndeletions;
|
||||
|
||||
git_patch_free(patch);
|
||||
}
|
||||
|
||||
if (ndeltas) {
|
||||
if (o->output != OUTPUT_NUMSTAT && ndeltas > 0) {
|
||||
printf(" %ld %s", (long)ndeltas,
|
||||
1 == ndeltas ? "file changed" : "files changed");
|
||||
|
||||
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 (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(-)");
|
||||
if (ndeletions_sum) {
|
||||
printf(", %ld ",ndeletions_sum);
|
||||
printf("%s", 1 == ndeletions_sum ? "deletion(-)" : "deletions(-)");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user