Hash :
ead10785
Author :
Date :
2019-01-24T11:31:49
examples: create common lg2 executable Inside of our networking example code, we have a git2 executable that acts as an entry point to all the different network examples. As such, it is kind of the same like the normal git(1) executable in that it simply arbitrates to the respective subcommands. Let's extend this approach and merge all examples into a single standalone lg2 executable. Instead of building an executable for all the existing examples we have, we now bundle them all inside of the lg2 one and let them be callable via subcommands. In the process, we can get rid of duplicated library initialization, deinitialization and repository discovery code. Instead of having each subcommand handle these on its own, we simply do it inside of the single main function now.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
/*
* libgit2 "rev-parse" example - shows how to parse revspecs
*
* Written by the libgit2 contributors
*
* To the extent possible under law, the author(s) have dedicated all copyright
* and related and neighboring rights to this software to the public domain
* worldwide. This software is distributed without any warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication along
* with this software. If not, see
* <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include "common.h"
/** Forward declarations for helpers. */
struct parse_state {
const char *repodir;
const char *spec;
int not;
};
static void parse_opts(struct parse_state *ps, int argc, char *argv[]);
static int parse_revision(git_repository *repo, struct parse_state *ps);
int lg2_rev_parse(git_repository *repo, int argc, char *argv[])
{
struct parse_state ps = {0};
parse_opts(&ps, argc, argv);
check_lg2(parse_revision(repo, &ps), "Parsing", NULL);
return 0;
}
static 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: rev-parse [ --option ] <args>...\n");
exit(1);
}
static void parse_opts(struct parse_state *ps, int argc, char *argv[])
{
struct args_info args = ARGS_INFO_INIT;
for (args.pos=1; args.pos < argc; ++args.pos) {
const char *a = argv[args.pos];
if (a[0] != '-') {
if (ps->spec)
usage("Too many specs", a);
ps->spec = a;
} else if (!strcmp(a, "--not"))
ps->not = !ps->not;
else if (!match_str_arg(&ps->repodir, &args, "--git-dir"))
usage("Cannot handle argument", a);
}
}
static int parse_revision(git_repository *repo, struct parse_state *ps)
{
git_revspec rs;
char str[GIT_OID_HEXSZ + 1];
check_lg2(git_revparse(&rs, repo, ps->spec), "Could not parse", ps->spec);
if ((rs.flags & GIT_REVPARSE_SINGLE) != 0) {
git_oid_tostr(str, sizeof(str), git_object_id(rs.from));
printf("%s\n", str);
git_object_free(rs.from);
}
else if ((rs.flags & GIT_REVPARSE_RANGE) != 0) {
git_oid_tostr(str, sizeof(str), git_object_id(rs.to));
printf("%s\n", str);
git_object_free(rs.to);
if ((rs.flags & GIT_REVPARSE_MERGE_BASE) != 0) {
git_oid base;
check_lg2(git_merge_base(&base, repo,
git_object_id(rs.from), git_object_id(rs.to)),
"Could not find merge base", ps->spec);
git_oid_tostr(str, sizeof(str), &base);
printf("%s\n", str);
}
git_oid_tostr(str, sizeof(str), git_object_id(rs.from));
printf("^%s\n", str);
git_object_free(rs.from);
}
else {
fatal("Invalid results from git_revparse", ps->spec);
}
return 0;
}