diff options
author | Russell Belfer <arrbee@arrbee.com> | 2012-02-07 12:14:28 -0800 |
---|---|---|
committer | Russell Belfer <arrbee@arrbee.com> | 2012-03-02 15:49:29 -0800 |
commit | a2e895be820a2fd77285ef4576afe53f68c96ca2 (patch) | |
tree | a086aaaad07d11d17bec91f3660b22a96250df65 /examples/diff.c | |
parent | 5a2f097fdc1408500cff9addf378f86046363665 (diff) | |
download | libgit2-a2e895be820a2fd77285ef4576afe53f68c96ca2.tar.gz |
Continue implementation of git-diff
* Implemented git_diff_index_to_tree
* Reworked git_diff_options structure to handle more options
* Made most of the options in git_diff_options actually work
* Reorganized code a bit to remove some redundancy
* Added option parsing to examples/diff.c to test most options
Diffstat (limited to 'examples/diff.c')
-rw-r--r-- | examples/diff.c | 117 |
1 files changed, 97 insertions, 20 deletions
diff --git a/examples/diff.c b/examples/diff.c index 9b696dad5..5eb0f3179 100644 --- a/examples/diff.c +++ b/examples/diff.c @@ -87,46 +87,123 @@ int printer(void *data, char usage, const char *line) return 0; } +int check_uint16_param(const char *arg, const char *pattern, uint16_t *val) +{ + size_t len = strlen(pattern); + uint16_t strval; + char *endptr = NULL; + if (strncmp(arg, pattern, len)) + return 0; + strval = strtoul(arg + len, &endptr, 0); + if (endptr == arg) + return 0; + *val = strval; + return 1; +} + +int check_str_param(const char *arg, const char *pattern, char **val) +{ + size_t len = strlen(pattern); + if (strncmp(arg, pattern, len)) + return 0; + *val = (char *)(arg + len); + return 1; +} + +void usage(const char *message, const char *arg) +{ + if (message && arg) + fprintf(stderr, "%s: %s\n", message, arg); + else if (message) + fprintf(stderr, "%s\n", message); + fprintf(stderr, "usage: diff <tree-oid> <tree-oid>\n"); + exit(1); +} + int main(int argc, char *argv[]) { char path[GIT_PATH_MAX]; git_repository *repo = NULL; - git_tree *a, *b; + git_tree *t1 = NULL, *t2 = NULL; git_diff_options opts = {0}; git_diff_list *diff; - char *dir = "."; - int color = -1; + int i, color = -1, compact = 0; + char *a, *dir = ".", *treeish1 = NULL, *treeish2 = NULL; - if (argc != 3) { - fprintf(stderr, "usage: diff <tree-oid> <tree-oid>\n"); - exit(1); + /* parse arguments as copied from git-diff */ + + for (i = 1; i < argc; ++i) { + a = argv[i]; + + if (a[0] != '-') { + if (treeish1 == NULL) + treeish1 = a; + else if (treeish2 == NULL) + treeish2 = a; + else + usage("Only one or two tree identifiers can be provided", NULL); + } + else if (!strcmp(a, "-p") || !strcmp(a, "-u") || + !strcmp(a, "--patch")) + compact = 0; + else if (!strcmp(a, "--name-status")) + compact = 1; + else if (!strcmp(a, "--color")) + color = 0; + else if (!strcmp(a, "--no-color")) + color = -1; + else if (!strcmp(a, "-R")) + opts.flags |= GIT_DIFF_REVERSE; + else if (!strcmp(a, "-a") || !strcmp(a, "--text")) + opts.flags |= GIT_DIFF_FORCE_TEXT; + else if (!strcmp(a, "--ignore-space-at-eol")) + opts.flags |= GIT_DIFF_IGNORE_WHITESPACE_EOL; + else if (!strcmp(a, "-b") || !strcmp(a, "--ignore-space-change")) + opts.flags |= GIT_DIFF_IGNORE_WHITESPACE_CHANGE; + else if (!strcmp(a, "-w") || !strcmp(a, "--ignore-all-space")) + opts.flags |= GIT_DIFF_IGNORE_WHITESPACE; + else if (!check_uint16_param(a, "-U", &opts.context_lines) && + !check_uint16_param(a, "--unified=", &opts.context_lines) && + !check_uint16_param(a, "--inter-hunk-context=", + &opts.interhunk_lines) && + !check_str_param(a, "--src-prefix=", &opts.src_prefix) && + !check_str_param(a, "--dst-prefix=", &opts.dst_prefix)) + usage("Unknown arg", a); } + if (!treeish1) + usage("Must provide at least one tree identifier (for now)", NULL); + + /* open repo */ + check(git_repository_discover(path, sizeof(path), dir, 0, "/"), "Could not discover repository"); check(git_repository_open(&repo, path), "Could not open repository"); - check(resolve_to_tree(repo, argv[1], &a), "Looking up first tree"); - check(resolve_to_tree(repo, argv[2], &b), "Looking up second tree"); - - check(git_diff_tree_to_tree(repo, &opts, a, b, &diff), "Generating diff"); - - fputs(colors[0], stdout); - - check(git_diff_print_compact(diff, &color, printer), "Displaying diff summary"); + check(resolve_to_tree(repo, treeish1, &t1), "Looking up first tree"); + if (treeish2) + check(resolve_to_tree(repo, treeish2, &t2), "Looking up second tree"); - fprintf(stdout, "--\n"); + if (!treeish2) + check(git_diff_index_to_tree(repo, &opts, t1, &diff), "Generating diff"); + else + check(git_diff_tree_to_tree(repo, &opts, t1, t2, &diff), "Generating diff"); - color = 0; + if (color >= 0) + fputs(colors[0], stdout); - check(git_diff_print_patch(diff, &color, printer), "Displaying diff"); + if (compact) + check(git_diff_print_compact(diff, &color, printer), "Displaying diff summary"); + else + check(git_diff_print_patch(diff, &color, printer), "Displaying diff"); - fputs(colors[0], stdout); + if (color >= 0) + fputs(colors[0], stdout); git_diff_list_free(diff); - git_tree_free(a); - git_tree_free(b); + git_tree_free(t1); + git_tree_free(t2); git_repository_free(repo); return 0; |