summaryrefslogtreecommitdiff
path: root/examples/diff.c
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2014-04-21 16:08:05 -0700
committerRussell Belfer <rb@github.com>2014-04-22 09:17:29 -0700
commit12e422a0562de2aebb05f5f414dbcde7caf85886 (patch)
treecf679a3ce25ec6e9c58efe1324fdc5eb628fbd1c /examples/diff.c
parenta32d684f866e7710fd139d69ad5d1a8d0ae527c4 (diff)
downloadlibgit2-12e422a0562de2aebb05f5f414dbcde7caf85886.tar.gz
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.
Diffstat (limited to 'examples/diff.c')
-rw-r--r--examples/diff.c151
1 files changed, 86 insertions, 65 deletions
diff --git a/examples/diff.c b/examples/diff.c
index 6f68e8305..1dbf85f61 100644
--- a/examples/diff.c
+++ b/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[])
* * &lt;sha1&gt; --cached
* * &lt;sha1&gt;
* * --cached
+ * * --nocache (don't use index data in diff at all)
* * nothing
*
* Currently ranged arguments like &lt;sha1&gt;..&lt;sha2&gt; and &lt;sha1&gt;...&lt;sha2&gt;
@@ -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) {
-
- printf(" %ld ", (long)ndeltas);
- printf("%s", 1==ndeltas ? "file changed" : "files changed");
+ if (o->output != OUTPUT_NUMSTAT && ndeltas > 0) {
+ printf(" %ld %s", (long)ndeltas,
+ 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");
}
}
+