diff options
| author | Ben Straub <bs@github.com> | 2013-10-30 05:38:12 -0700 |
|---|---|---|
| committer | Ben Straub <bs@github.com> | 2013-10-30 05:38:12 -0700 |
| commit | a8422f9202e6a177750c105260dd5bbf82a0778f (patch) | |
| tree | 0360ca42e98fdc2d9e188768eb476d062bbf47e6 /examples/init.c | |
| parent | 66902d47737da1100de5e24498cf8c7260b183df (diff) | |
| download | libgit2-a8422f9202e6a177750c105260dd5bbf82a0778f.tar.gz | |
init example: deploy helpers, reorg
Diffstat (limited to 'examples/init.c')
| -rw-r--r-- | examples/init.c | 249 |
1 files changed, 122 insertions, 127 deletions
diff --git a/examples/init.c b/examples/init.c index 4a379c6e3..d05788e10 100644 --- a/examples/init.c +++ b/examples/init.c @@ -15,164 +15,84 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include <stdio.h> -#include <git2.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -/* not actually good error handling */ -static void fail(const char *msg, const char *arg) -{ - if (arg) - fprintf(stderr, "%s %s\n", msg, arg); - else - fprintf(stderr, "%s\n", msg); - exit(1); -} - -static void usage(const char *error, const char *arg) -{ - fprintf(stderr, "error: %s '%s'\n", error, arg); - fprintf(stderr, "usage: init [-q | --quiet] [--bare] " - "[--template=<dir>] [--shared[=perms]] <directory>\n"); - exit(1); -} - -/* simple string prefix test used in argument parsing */ -static size_t is_prefixed(const char *arg, const char *pfx) -{ - size_t len = strlen(pfx); - return !strncmp(arg, pfx, len) ? len : 0; -} - -/* parse the tail of the --shared= argument */ -static uint32_t parse_shared(const char *shared) -{ - if (!strcmp(shared, "false") || !strcmp(shared, "umask")) - return GIT_REPOSITORY_INIT_SHARED_UMASK; - - else if (!strcmp(shared, "true") || !strcmp(shared, "group")) - return GIT_REPOSITORY_INIT_SHARED_GROUP; - - else if (!strcmp(shared, "all") || !strcmp(shared, "world") || - !strcmp(shared, "everybody")) - return GIT_REPOSITORY_INIT_SHARED_ALL; - - else if (shared[0] == '0') { - long val; - char *end = NULL; - val = strtol(shared + 1, &end, 8); - if (end == shared + 1 || *end != 0) - usage("invalid octal value for --shared", shared); - return (uint32_t)val; - } - - else - usage("unknown value for --shared", shared); - - return 0; -} - -/* forward declaration of helper to make an empty parent-less commit */ +#include "common.h" + +/* forward declarations of helpers */ +struct opts { + int no_options; + int quiet; + int bare; + int initial_commit; + uint32_t shared; + const char *template; + const char *gitdir; + const char *dir; +}; static void create_initial_commit(git_repository *repo); +static void parse_opts(struct opts *o, int argc, char *argv[]); int main(int argc, char *argv[]) { git_repository *repo = NULL; - int no_options = 1, quiet = 0, bare = 0, initial_commit = 0, i; - uint32_t shared = GIT_REPOSITORY_INIT_SHARED_UMASK; - const char *template = NULL, *gitdir = NULL, *dir = NULL; - size_t pfxlen; + struct opts o = { 1, 0, 0, 0, GIT_REPOSITORY_INIT_SHARED_UMASK, 0, 0, 0 }; git_threads_init(); - /* Process arguments */ - - for (i = 1; i < argc; ++i) { - char *a = argv[i]; - - if (a[0] == '-') - no_options = 0; - - if (a[0] != '-') { - if (dir != NULL) - usage("extra argument", a); - dir = a; - } - else if (!strcmp(a, "-q") || !strcmp(a, "--quiet")) - quiet = 1; - else if (!strcmp(a, "--bare")) - bare = 1; - else if ((pfxlen = is_prefixed(a, "--template=")) > 0) - template = a + pfxlen; - else if (!strcmp(a, "--separate-git-dir")) - gitdir = argv[++i]; - else if ((pfxlen = is_prefixed(a, "--separate-git-dir=")) > 0) - gitdir = a + pfxlen; - else if (!strcmp(a, "--shared")) - shared = GIT_REPOSITORY_INIT_SHARED_GROUP; - else if ((pfxlen = is_prefixed(a, "--shared=")) > 0) - shared = parse_shared(a + pfxlen); - else if (!strcmp(a, "--initial-commit")) - initial_commit = 1; - else - usage("unknown option", a); - } - - if (!dir) - usage("must specify directory to init", NULL); + parse_opts(&o, argc, argv); /* Initialize repository */ - if (no_options) { + if (o.no_options) { /* No options were specified, so let's demonstrate the default * simple case of git_repository_init() API usage... */ - if (git_repository_init(&repo, dir, 0) < 0) - fail("Could not initialize repository", dir); + if (git_repository_init(&repo, o.dir, 0) < 0) + fatal("Could not initialize repository", o.dir); } else { /* Some command line options were specified, so we'll use the * extended init API to handle them */ - git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; + git_repository_init_options initopts = GIT_REPOSITORY_INIT_OPTIONS_INIT; + initopts.flags = GIT_REPOSITORY_INIT_MKPATH; - if (bare) - opts.flags |= GIT_REPOSITORY_INIT_BARE; + if (o.bare) + initopts.flags |= GIT_REPOSITORY_INIT_BARE; - if (template) { - opts.flags |= GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; - opts.template_path = template; + if (o.template) { + initopts.flags |= GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; + initopts.template_path = o.template; } - if (gitdir) { + if (o.gitdir) { /* if you specified a separate git directory, then initialize * the repository at that path and use the second path as the * working directory of the repository (with a git-link file) */ - opts.workdir_path = dir; - dir = gitdir; + initopts.workdir_path = o.dir; + o.dir = o.gitdir; } - if (shared != 0) - opts.mode = shared; + if (o.shared != 0) + initopts.mode = o.shared; - if (git_repository_init_ext(&repo, dir, &opts) < 0) - fail("Could not initialize repository", dir); + if (git_repository_init_ext(&repo, o.dir, &initopts) < 0) { + const git_error *err = giterr_last(); + fatal("Could not initialize repository:", err->message); + } } /* Print a message to stdout like "git init" does */ - if (!quiet) { - if (bare || gitdir) - dir = git_repository_path(repo); + if (!o.quiet) { + if (o.bare || o.gitdir) + o.dir = git_repository_path(repo); else - dir = git_repository_workdir(repo); + o.dir = git_repository_workdir(repo); - printf("Initialized empty Git repository in %s\n", dir); + printf("Initialized empty Git repository in %s\n", o.dir); } /* As an extension to the basic "git init" command, this example @@ -180,7 +100,7 @@ int main(int argc, char *argv[]) * mostly to demonstrate what it takes to do that, but also some * people like to have that empty base commit in their repo. */ - if (initial_commit) { + if (o.initial_commit) { create_initial_commit(repo); printf("Created empty initial commit\n"); } @@ -205,13 +125,13 @@ static void create_initial_commit(git_repository *repo) /* First use the config to initialize a commit signature for the user */ if (git_signature_default(&sig, repo) < 0) - fail("Unable to create a commit signature.", - "Perhaps 'user.name' and 'user.email' are not set"); + fatal("Unable to create a commit signature.", + "Perhaps 'user.name' and 'user.email' are not set"); /* Now let's create an empty tree for this commit */ if (git_repository_index(&index, repo) < 0) - fail("Could not open repository index", NULL); + fatal("Could not open repository index", NULL); /* Outside of this example, you could call git_index_add_bypath() * here to put actual files into the index. For our purposes, we'll @@ -219,12 +139,12 @@ static void create_initial_commit(git_repository *repo) */ if (git_index_write_tree(&tree_id, index) < 0) - fail("Unable to write initial tree from index", NULL); + fatal("Unable to write initial tree from index", NULL); git_index_free(index); if (git_tree_lookup(&tree, repo, &tree_id) < 0) - fail("Could not look up initial tree", NULL); + fatal("Could not look up initial tree", NULL); /* Ready to create the initial commit * @@ -236,10 +156,85 @@ static void create_initial_commit(git_repository *repo) if (git_commit_create_v( &commit_id, repo, "HEAD", sig, sig, NULL, "Initial commit", tree, 0) < 0) - fail("Could not create the initial commit", NULL); + fatal("Could not create the initial commit", NULL); /* Clean up so we don't leak memory */ git_tree_free(tree); git_signature_free(sig); } + +static void usage(const char *error, const char *arg) +{ + fprintf(stderr, "error: %s '%s'\n", error, arg); + fprintf(stderr, + "usage: init [-q | --quiet] [--bare] [--template=<dir>]\n" + " [--shared[=perms]] [--initial-commit]\n" + " [--separate-git-dir] <directory>\n"); + exit(1); +} + +/* parse the tail of the --shared= argument */ +static uint32_t parse_shared(const char *shared) +{ + if (!strcmp(shared, "false") || !strcmp(shared, "umask")) + return GIT_REPOSITORY_INIT_SHARED_UMASK; + + else if (!strcmp(shared, "true") || !strcmp(shared, "group")) + return GIT_REPOSITORY_INIT_SHARED_GROUP; + + else if (!strcmp(shared, "all") || !strcmp(shared, "world") || + !strcmp(shared, "everybody")) + return GIT_REPOSITORY_INIT_SHARED_ALL; + + else if (shared[0] == '0') { + long val; + char *end = NULL; + val = strtol(shared + 1, &end, 8); + if (end == shared + 1 || *end != 0) + usage("invalid octal value for --shared", shared); + return (uint32_t)val; + } + + else + usage("unknown value for --shared", shared); + + return 0; +} + +static void parse_opts(struct opts *o, int argc, char *argv[]) +{ + struct args_info args = ARGS_INFO_INIT; + const char *sharedarg; + + /* Process arguments */ + + for (args.pos = 1; args.pos < argc; ++args.pos) { + char *a = argv[args.pos]; + + if (a[0] == '-') + o->no_options = 0; + + if (a[0] != '-') { + if (o->dir != NULL) + usage("extra argument", a); + o->dir = a; + } + else if (!strcmp(a, "-q") || !strcmp(a, "--quiet")) + o->quiet = 1; + else if (!strcmp(a, "--bare")) + o->bare = 1; + else if (!strcmp(a, "--shared")) + o->shared = GIT_REPOSITORY_INIT_SHARED_GROUP; + else if (!strcmp(a, "--initial-commit")) + o->initial_commit = 1; + else if (match_str_arg(&sharedarg, &args, "--shared")) + o->shared = parse_shared(sharedarg); + else if (!match_str_arg(&o->template, &args, "--template") || + !match_str_arg(&o->gitdir, &args, "--separate-git-dir")) + usage("unknown option", a); + } + + if (!o->dir) + usage("must specify directory to init", NULL); +} |
