Commit 567649f2 by Vicent Martí

Merge pull request #1916 from libgit2/simplify-examples

Fix examples to make the important stuff more obvious
parents 948f00b4 4f62d559
......@@ -9,6 +9,8 @@ ENDIF()
FILE(GLOB SRC_EXAMPLE_APPS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c)
FOREACH(src_app ${SRC_EXAMPLE_APPS})
STRING(REPLACE ".c" "" app_name ${src_app})
ADD_EXECUTABLE(${app_name} ${src_app})
TARGET_LINK_LIBRARIES(${app_name} git2)
IF(NOT ${app_name} STREQUAL "common")
ADD_EXECUTABLE(${app_name} ${src_app} "common.c")
TARGET_LINK_LIBRARIES(${app_name} git2)
ENDIF()
ENDFOREACH()
......@@ -8,7 +8,7 @@ APPS = general showindex diff rev-list cat-file status log rev-parse init
all: $(APPS)
% : %.c
$(CC) -o $@ $(CFLAGS) $< $(LFLAGS)
$(CC) -o $@ common.c $(CFLAGS) $< $(LFLAGS)
clean:
$(RM) $(APPS)
......
libgit2 examples
================
These examples are meant as thin, easy-to-read snippets for Docurium
(https://github.com/github/docurium) rather than full-blown
implementations of Git commands. They are not vetted as carefully
for bugs, error handling, or cross-platform compatibility as the
rest of the code in libgit2, so copy with some caution.
These examples are a mixture of basic emulation of core Git command line
functions and simple snippets demonstrating libgit2 API usage (for use
with Docurium). As a whole, they are not vetted carefully for bugs, error
handling, and cross-platform compatibility in the same manner as the rest
of the code in libgit2, so copy with caution.
For HTML versions, check "Examples" at http://libgit2.github.com/libgit2
That being said, you are welcome to copy code from these examples as
desired when using libgit2.
For annotated HTML versions, see the "Examples" section of:
http://libgit2.github.com/libgit2
such as:
http://libgit2.github.com/libgit2/ex/HEAD/general.html
#include <git2.h>
#include <stdio.h>
#include <string.h>
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "common.h"
#include <assert.h>
enum print_options {
......@@ -14,19 +19,49 @@ struct print_payload {
git_repository *repo;
};
void init_array(git_strarray *array, int argc, char **argv)
/* Forward declarations for helpers */
static void parse_opts(int *options, int *count, int argc, char *argv[]);
void init_array(git_strarray *array, int argc, char **argv);
int print_matched_cb(const char *path, const char *matched_pathspec, void *payload);
int main (int argc, char** argv)
{
unsigned int i;
git_index_matched_path_cb matched_cb = NULL;
git_repository *repo = NULL;
git_index *index;
git_strarray array = {0};
int options = 0, count = 0;
struct print_payload payload = {0};
array->count = argc;
array->strings = malloc(sizeof(char*) * array->count);
assert(array->strings!=NULL);
git_threads_init();
for(i=0; i<array->count; i++) {
array->strings[i]=argv[i];
parse_opts(&options, &count, argc, argv);
init_array(&array, argc-count, argv+count);
check_lg2(git_repository_open(&repo, "."), "No git repository", NULL);
check_lg2(git_repository_index(&index, repo), "Could not open repository index", NULL);
if (options&VERBOSE || options&SKIP) {
matched_cb = &print_matched_cb;
}
return;
payload.options = options;
payload.repo = repo;
if (options&UPDATE) {
git_index_update_all(index, &array, matched_cb, &payload);
} else {
git_index_add_all(index, &array, 0, matched_cb, &payload);
}
git_index_write(index);
git_index_free(index);
git_repository_free(repo);
git_threads_shutdown();
return 0;
}
int print_matched_cb(const char *path, const char *matched_pathspec, void *payload)
......@@ -55,36 +90,46 @@ int print_matched_cb(const char *path, const char *matched_pathspec, void *paylo
return ret;
}
void init_array(git_strarray *array, int argc, char **argv)
{
unsigned int i;
array->count = argc;
array->strings = malloc(sizeof(char*) * array->count);
assert(array->strings!=NULL);
for(i=0; i<array->count; i++) {
array->strings[i]=argv[i];
}
return;
}
void print_usage(void)
{
fprintf(stderr, "usage: add [options] [--] file-spec [file-spec] [...]\n\n");
fprintf(stderr, "\t-n, --dry-run dry run\n");
fprintf(stderr, "\t-v, --verbose be verbose\n");
fprintf(stderr, "\t-u, --update update tracked files\n");
exit(1);
}
int main (int argc, char** argv)
static void parse_opts(int *options, int *count, int argc, char *argv[])
{
git_index_matched_path_cb matched_cb = NULL;
git_repository *repo = NULL;
git_index *index;
git_strarray array = {0};
int i, options = 0;
struct print_payload payload = {0};
int i;
for (i = 1; i < argc; ++i) {
if (argv[i][0] != '-') {
break;
}
else if(!strcmp(argv[i], "--verbose") || !strcmp(argv[i], "-v")) {
options |= VERBOSE;
*options |= VERBOSE;
}
else if(!strcmp(argv[i], "--dry-run") || !strcmp(argv[i], "-n")) {
options |= SKIP;
*options |= SKIP;
}
else if(!strcmp(argv[i], "--update") || !strcmp(argv[i], "-u")) {
options |= UPDATE;
*options |= UPDATE;
}
else if(!strcmp(argv[i], "-h")) {
print_usage();
......@@ -97,47 +142,11 @@ int main (int argc, char** argv)
else {
fprintf(stderr, "Unsupported option %s.\n", argv[i]);
print_usage();
return 1;
}
}
if (argc<=i) {
if (argc<=i)
print_usage();
return 1;
}
git_threads_init();
init_array(&array, argc-i, argv+i);
if (git_repository_open(&repo, ".") < 0) {
fprintf(stderr, "No git repository\n");
return 1;
}
if (git_repository_index(&index, repo) < 0) {
fprintf(stderr, "Could not open repository index\n");
return 1;
}
if (options&VERBOSE || options&SKIP) {
matched_cb = &print_matched_cb;
}
payload.options = options;
payload.repo = repo;
if (options&UPDATE) {
git_index_update_all(index, &array, matched_cb, &payload);
} else {
git_index_add_all(index, &array, 0, matched_cb, &payload);
}
git_index_write(index);
git_index_free(index);
git_repository_free(repo);
git_threads_shutdown();
return 0;
*count = i;
}
#include <stdio.h>
#include <git2.h>
#include <stdlib.h>
#include <string.h>
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
static git_repository *g_repo;
static void check(int error, const char *message)
{
if (error) {
fprintf(stderr, "%s (%d)\n", message, error);
exit(1);
}
}
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: cat-file (-t | -s | -e | -p) [<options>] <object>\n");
exit(1);
}
static int check_str_param(
const char *arg, const char *pattern, const char **val)
{
size_t len = strlen(pattern);
if (strncmp(arg, pattern, len))
return 0;
*val = (const char *)(arg + len);
return 1;
}
#include "common.h"
static void print_signature(const char *header, const git_signature *sig)
{
......@@ -57,12 +31,14 @@ static void print_signature(const char *header, const git_signature *sig)
sign, hours, minutes);
}
/** Printing out a blob is simple, get the contents and print */
static void show_blob(const git_blob *blob)
{
/* ? Does this need crlf filtering? */
fwrite(git_blob_rawcontent(blob), git_blob_rawsize(blob), 1, stdout);
}
/** Show each entry with its type, id and attributes */
static void show_tree(const git_tree *tree)
{
size_t i, max_i = (int)git_tree_entrycount(tree);
......@@ -81,6 +57,9 @@ static void show_tree(const git_tree *tree)
}
}
/**
* Commits and tags have a few interesting fields in their header.
*/
static void show_commit(const git_commit *commit)
{
unsigned int i, max_i;
......@@ -123,53 +102,34 @@ enum {
SHOW_PRETTY = 4
};
/* Forward declarations for option-parsing helper */
struct opts {
const char *dir;
const char *rev;
int action;
int verbose;
};
static void parse_opts(struct opts *o, int argc, char *argv[]);
/** Entry point for this command */
int main(int argc, char *argv[])
{
const char *dir = ".", *rev = NULL;
int i, action = 0, verbose = 0;
git_repository *repo;
struct opts o = { ".", NULL, 0, 0 };
git_object *obj = NULL;
char oidstr[GIT_OID_HEXSZ + 1];
git_threads_init();
for (i = 1; i < argc; ++i) {
char *a = argv[i];
if (a[0] != '-') {
if (rev != NULL)
usage("Only one rev should be provided", NULL);
else
rev = a;
}
else if (!strcmp(a, "-t"))
action = SHOW_TYPE;
else if (!strcmp(a, "-s"))
action = SHOW_SIZE;
else if (!strcmp(a, "-e"))
action = SHOW_NONE;
else if (!strcmp(a, "-p"))
action = SHOW_PRETTY;
else if (!strcmp(a, "-q"))
verbose = 0;
else if (!strcmp(a, "-v"))
verbose = 1;
else if (!strcmp(a, "--help") || !strcmp(a, "-h"))
usage(NULL, NULL);
else if (!check_str_param(a, "--git-dir=", &dir))
usage("Unknown option", a);
}
if (!action || !rev)
usage(NULL, NULL);
parse_opts(&o, argc, argv);
check(git_repository_open_ext(&g_repo, dir, 0, NULL),
"Could not open repository");
check_lg2(git_repository_open_ext(&repo, o.dir, 0, NULL),
"Could not open repository", NULL);
check_lg2(git_revparse_single(&obj, repo, o.rev),
"Could not resolve", o.rev);
if (git_revparse_single(&obj, g_repo, rev) < 0) {
fprintf(stderr, "Could not resolve '%s'\n", rev);
exit(1);
}
if (verbose) {
if (o.verbose) {
char oidstr[GIT_OID_HEXSZ + 1];
git_oid_tostr(oidstr, sizeof(oidstr), git_object_id(obj));
......@@ -177,7 +137,7 @@ int main(int argc, char *argv[])
git_object_type2string(git_object_type(obj)), oidstr);
}
switch (action) {
switch (o.action) {
case SHOW_TYPE:
printf("%s\n", git_object_type2string(git_object_type(obj)));
break;
......@@ -185,9 +145,9 @@ int main(int argc, char *argv[])
git_odb *odb;
git_odb_object *odbobj;
check(git_repository_odb(&odb, g_repo), "Could not open ODB");
check(git_odb_read(&odbobj, odb, git_object_id(obj)),
"Could not find obj");
check_lg2(git_repository_odb(&odb, repo), "Could not open ODB", NULL);
check_lg2(git_odb_read(&odbobj, odb, git_object_id(obj)),
"Could not find obj", NULL);
printf("%ld\n", (long)git_odb_object_size(odbobj));
......@@ -221,9 +181,59 @@ int main(int argc, char *argv[])
}
git_object_free(obj);
git_repository_free(g_repo);
git_repository_free(repo);
git_threads_shutdown();
return 0;
}
/** Print out usage information */
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: cat-file (-t | -s | -e | -p) [-v] [-q] "
"[-h|--help] [--git-dir=<dir>] <object>\n");
exit(1);
}
/** Parse the command-line options taken from git */
static void parse_opts(struct opts *o, int argc, char *argv[])
{
struct args_info args = ARGS_INFO_INIT;
for (args.pos = 1; args.pos < argc; ++args.pos) {
char *a = argv[args.pos];
if (a[0] != '-') {
if (o->rev != NULL)
usage("Only one rev should be provided", NULL);
else
o->rev = a;
}
else if (!strcmp(a, "-t"))
o->action = SHOW_TYPE;
else if (!strcmp(a, "-s"))
o->action = SHOW_SIZE;
else if (!strcmp(a, "-e"))
o->action = SHOW_NONE;
else if (!strcmp(a, "-p"))
o->action = SHOW_PRETTY;
else if (!strcmp(a, "-q"))
o->verbose = 0;
else if (!strcmp(a, "-v"))
o->verbose = 1;
else if (!strcmp(a, "--help") || !strcmp(a, "-h"))
usage(NULL, NULL);
else if (!match_str_arg(&o->dir, &args, "--git-dir"))
usage("Unknown option", a);
}
if (!o->action || !o->rev)
usage(NULL, NULL);
}
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "common.h"
void check_lg2(int error, const char *message, const char *extra)
{
const git_error *lg2err;
const char *lg2msg = "", *lg2spacer = "";
if (!error)
return;
if ((lg2err = giterr_last()) != NULL && lg2err->message != NULL) {
lg2msg = lg2err->message;
lg2spacer = " - ";
}
if (extra)
fprintf(stderr, "%s '%s' [%d]%s%s\n",
message, extra, error, lg2spacer, lg2msg);
else
fprintf(stderr, "%s [%d]%s%s\n",
message, error, lg2spacer, lg2msg);
exit(1);
}
void fatal(const char *message, const char *extra)
{
if (extra)
fprintf(stderr, "%s %s\n", message, extra);
else
fprintf(stderr, "%s\n", message);
exit(1);
}
size_t is_prefixed(const char *str, const char *pfx)
{
size_t len = strlen(pfx);
return strncmp(str, pfx, len) ? 0 : len;
}
int match_str_arg(
const char **out, struct args_info *args, const char *opt)
{
const char *found = args->argv[args->pos];
size_t len = is_prefixed(found, opt);
if (!len)
return 0;
if (!found[len]) {
if (args->pos + 1 == args->argc)
fatal("expected value following argument", opt);
args->pos += 1;
*out = args->argv[args->pos];
return 1;
}
if (found[len] == '=') {
*out = found + len + 1;
return 1;
}
return 0;
}
static const char *match_numeric_arg(struct args_info *args, const char *opt)
{
const char *found = args->argv[args->pos];
size_t len = is_prefixed(found, opt);
if (!len)
return NULL;
if (!found[len]) {
if (args->pos + 1 == args->argc)
fatal("expected numeric value following argument", opt);
args->pos += 1;
found = args->argv[args->pos];
} else {
found = found + len;
if (*found == '=')
found++;
}
return found;
}
int match_uint16_arg(
uint16_t *out, struct args_info *args, const char *opt)
{
const char *found = match_numeric_arg(args, opt);
uint16_t val;
char *endptr = NULL;
if (!found)
return 0;
val = (uint16_t)strtoul(found, &endptr, 0);
if (!endptr || *endptr != '\0')
fatal("expected number after argument", opt);
if (out)
*out = val;
return 1;
}
static int match_int_internal(
int *out, const char *str, int allow_negative, const char *opt)
{
char *endptr = NULL;
int val = (int)strtol(str, &endptr, 10);
if (!endptr || *endptr != '\0')
fatal("expected number", opt);
else if (val < 0 && !allow_negative)
fatal("negative values are not allowed", opt);
if (out)
*out = val;
return 1;
}
int is_integer(int *out, const char *str, int allow_negative)
{
return match_int_internal(out, str, allow_negative, NULL);
}
int match_int_arg(
int *out, struct args_info *args, const char *opt, int allow_negative)
{
const char *found = match_numeric_arg(args, opt);
if (!found)
return 0;
return match_int_internal(out, found, allow_negative, opt);
}
int diff_output(
const git_diff_delta *d,
const git_diff_hunk *h,
const git_diff_line *l,
void *p)
{
FILE *fp = p;
(void)d; (void)h;
if (!fp)
fp = stdout;
if (l->origin == GIT_DIFF_LINE_CONTEXT ||
l->origin == GIT_DIFF_LINE_ADDITION ||
l->origin == GIT_DIFF_LINE_DELETION)
fputc(l->origin, fp);
fwrite(l->content, 1, l->content_len, fp);
return 0;
}
void treeish_to_tree(
git_tree **out, git_repository *repo, const char *treeish)
{
git_object *obj = NULL;
check_lg2(
git_revparse_single(&obj, repo, treeish),
"looking up object", treeish);
check_lg2(
git_object_peel((git_object **)out, obj, GIT_OBJ_TREE),
"resolving object to tree", treeish);
git_object_free(obj);
}
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <git2.h>
/**
* Check libgit2 error code, printing error to stderr on failure and
* exiting the program.
*/
extern void check_lg2(int error, const char *message, const char *extra);
/**
* Exit the program, printing error to stderr
*/
extern void fatal(const char *message, const char *extra);
/**
* Check if a string has the given prefix. Returns 0 if not prefixed
* or the length of the prefix if it is.
*/
extern size_t is_prefixed(const char *str, const char *pfx);
/**
* Match an integer string, returning 1 if matched, 0 if not.
*/
extern int is_integer(int *out, const char *str, int allow_negative);
struct args_info {
int argc;
char **argv;
int pos;
};
#define ARGS_INFO_INIT { argc, argv, 0 }
/**
* Check current `args` entry against `opt` string. If it matches
* exactly, take the next arg as a string; if it matches as a prefix with
* an equal sign, take the remainder as a string; otherwise return 0.
*/
extern int match_str_arg(
const char **out, struct args_info *args, const char *opt);
/**
* Check current `args` entry against `opt` string parsing as uint16. If
* `opt` matches exactly, take the next arg as a uint16_t value; if `opt`
* is a prefix (equal sign optional), take the remainder of the arg as a
* uint16_t value; otherwise return 0.
*/
extern int match_uint16_arg(
uint16_t *out, struct args_info *args, const char *opt);
/**
* Check current `args` entry against `opt` string parsing as int. If
* `opt` matches exactly, take the next arg as an int value; if it matches
* as a prefix (equal sign optional), take the remainder of the arg as a
* int value; otherwise return 0.
*/
extern int match_int_arg(
int *out, struct args_info *args, const char *opt, int allow_negative);
/**
* Basic output function for plain text diff output
* Pass `FILE*` such as `stdout` or `stderr` as payload (or NULL == `stdout`)
*/
extern int diff_output(
const git_diff_delta*, const git_diff_hunk*, const git_diff_line*, void*);
/**
* Convert a treeish argument to an actual tree; this will call check_lg2
* and exit the program if `treeish` cannot be resolved to a tree
*/
extern void treeish_to_tree(
git_tree **out, git_repository *repo, const char *treeish);
......@@ -47,6 +47,11 @@ exit:
return &data->ret;
}
/**
* This function gets called for each remote-tracking branch that gets
* updated. The message we output depends on whether it's a new one or
* an update.
*/
static int update_cb(const char *refname, const git_oid *a, const git_oid *b, void *data)
{
char a_str[GIT_OID_HEXSZ+1], b_str[GIT_OID_HEXSZ+1];
......@@ -66,6 +71,7 @@ static int update_cb(const char *refname, const git_oid *a, const git_oid *b, vo
return 0;
}
/** Entry point for this command */
int fetch(git_repository *repo, int argc, char **argv)
{
git_remote *remote = NULL;
......@@ -130,6 +136,11 @@ int fetch(git_repository *repo, int argc, char **argv)
pthread_join(worker, NULL);
#endif
/**
* If there are local objects (we got a thin pack), then tell
* the user how many objects we saved from having to cross the
* network.
*/
if (stats->local_objects > 0) {
printf("\rReceived %d/%d objects in %zu bytes (used %d local objects)\n",
stats->indexed_objects, stats->total_objects, stats->received_bytes, stats->local_objects);
......
......@@ -4,6 +4,7 @@
#include <string.h>
#include "common.h"
/** Callback to show each item */
static int show_ref__cb(git_remote_head *head, void *payload)
{
char oid[GIT_OID_HEXSZ + 1] = {0};
......@@ -28,6 +29,10 @@ static int use_remote(git_repository *repo, char *name)
goto cleanup;
}
/**
* Connect to the remote and call the printing function for
* each of the remote references.
*/
callbacks.credentials = cred_acquire_cb;
git_remote_set_callbacks(remote, &callbacks);
......@@ -42,9 +47,7 @@ cleanup:
return error;
}
// This gets called to do the work. The remote can be given either as
// the name of a configured remote or an URL.
/** Entry point for this command */
int ls_remote(git_repository *repo, int argc, char **argv)
{
int error;
......
#include <stdio.h>
#include <string.h>
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include <git2.h>
#include "common.h"
static void check_error(int error_code, const char *action)
static int revwalk_parseopts(git_repository *repo, git_revwalk *walk, int nopts, char **opts);
int main (int argc, char **argv)
{
if (!error_code)
return;
git_repository *repo;
git_revwalk *walk;
git_oid oid;
char buf[41];
git_threads_init();
const git_error *error = giterr_last();
fprintf(stderr, "Error %d %s: %s\n", -error_code, action,
(error && error->message) ? error->message : "???");
exit(1);
check_lg2(git_repository_open_ext(&repo, ".", 0, NULL), "opening repository", NULL);
check_lg2(git_revwalk_new(&walk, repo), "allocating revwalk", NULL);
check_lg2(revwalk_parseopts(repo, walk, argc-1, argv+1), "parsing options", NULL);
while (!git_revwalk_next(&oid, walk)) {
git_oid_fmt(buf, &oid);
buf[40] = '\0';
printf("%s\n", buf);
}
git_threads_shutdown();
return 0;
}
static int push_commit(git_revwalk *walk, const git_oid *oid, int hide)
......@@ -93,27 +111,3 @@ static int revwalk_parseopts(git_repository *repo, git_revwalk *walk, int nopts,
return 0;
}
int main (int argc, char **argv)
{
int error;
git_repository *repo;
git_revwalk *walk;
git_oid oid;
char buf[41];
error = git_repository_open_ext(&repo, ".", 0, NULL);
check_error(error, "opening repository");
error = git_revwalk_new(&walk, repo);
check_error(error, "allocating revwalk");
error = revwalk_parseopts(repo, walk, argc-1, argv+1);
check_error(error, "parsing options");
while (!git_revwalk_next(&oid, walk)) {
git_oid_fmt(buf, &oid);
buf[40] = '\0';
printf("%s\n", buf);
}
return 0;
}
#include <stdio.h>
#include <git2.h>
#include <stdlib.h>
#include <string.h>
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
static void check(int error, const char *message, const char *arg)
#include "common.h"
/** Forward declarations for helpers. */
struct parse_state {
git_repository *repo;
const char *repodir;
const char *spec;
int not;
};
static void parse_opts(struct parse_state *ps, int argc, char *argv[]);
static int parse_revision(struct parse_state *ps);
int main(int argc, char *argv[])
{
if (!error)
return;
if (arg)
fprintf(stderr, "%s %s (%d)\n", message, arg, error);
else
fprintf(stderr, "%s(%d)\n", message, error);
exit(1);
struct parse_state ps = {0};
git_threads_init();
parse_opts(&ps, argc, argv);
check_lg2(parse_revision(&ps), "Parsing", NULL);
git_repository_free(ps.repo);
git_threads_shutdown();
return 0;
}
static void usage(const char *message, const char *arg)
......@@ -24,13 +43,25 @@ static void usage(const char *message, const char *arg)
exit(1);
}
struct parse_state {
git_repository *repo;
const char *repodir;
int not;
};
static void parse_opts(struct parse_state *ps, int argc, char *argv[])
{
struct args_info args = ARGS_INFO_INIT;
static int parse_revision(struct parse_state *ps, const char *revstr)
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(struct parse_state *ps)
{
git_revspec rs;
char str[GIT_OID_HEXSZ + 1];
......@@ -38,11 +69,11 @@ static int parse_revision(struct parse_state *ps, const char *revstr)
if (!ps->repo) {
if (!ps->repodir)
ps->repodir = ".";
check(git_repository_open_ext(&ps->repo, ps->repodir, 0, NULL),
check_lg2(git_repository_open_ext(&ps->repo, ps->repodir, 0, NULL),
"Could not open repository from", ps->repodir);
}
check(git_revparse(&rs, ps->repo, revstr), "Could not parse", revstr);
check_lg2(git_revparse(&rs, ps->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));
......@@ -56,9 +87,9 @@ static int parse_revision(struct parse_state *ps, const char *revstr)
if ((rs.flags & GIT_REVPARSE_MERGE_BASE) != 0) {
git_oid base;
check(git_merge_base(&base, ps->repo,
git_object_id(rs.from), git_object_id(rs.to)),
"Could not find merge base", revstr);
check_lg2(git_merge_base(&base, ps->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);
......@@ -69,38 +100,9 @@ static int parse_revision(struct parse_state *ps, const char *revstr)
git_object_free(rs.from);
}
else {
check(0, "Invalid results from git_revparse", revstr);
fatal("Invalid results from git_revparse", ps->spec);
}
return 0;
}
int main(int argc, char *argv[])
{
int i;
char *a;
struct parse_state ps;
git_threads_init();
memset(&ps, 0, sizeof(ps));
for (i = 1; i < argc; ++i) {
a = argv[i];
if (a[0] != '-') {
if (parse_revision(&ps, a) != 0)
break;
} else if (!strcmp(a, "--not"))
ps.not = !ps.not;
else if (!strncmp(a, "--git-dir=", strlen("--git-dir=")))
ps.repodir = a + strlen("--git-dir=");
else
usage("Cannot handle argument", a);
}
git_repository_free(ps.repo);
git_threads_shutdown();
return 0;
}
#include <git2.h>
#include <stdio.h>
#include <string.h>
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "common.h"
int main (int argc, char** argv)
{
git_repository *repo = NULL;
git_index *index;
unsigned int i, ecount;
char *dir = ".";
......@@ -14,28 +18,19 @@ int main (int argc, char** argv)
git_threads_init();
if (argc > 2)
fatal("usage: showindex [<repo-dir>]", NULL);
if (argc > 1)
dir = argv[1];
if (!dir || argc > 2) {
fprintf(stderr, "usage: showindex [<repo-dir>]\n");
return 1;
}
dirlen = strlen(dir);
if (dirlen > 5 && strcmp(dir + dirlen - 5, "index") == 0) {
if (git_index_open(&index, dir) < 0) {
fprintf(stderr, "could not open index: %s\n", dir);
return 1;
}
check_lg2(git_index_open(&index, dir), "could not open index", dir);
} else {
if (git_repository_open_ext(&repo, dir, 0, NULL) < 0) {
fprintf(stderr, "could not open repository: %s\n", dir);
return 1;
}
if (git_repository_index(&index, repo) < 0) {
fprintf(stderr, "could not open repository index\n");
return 1;
}
git_repository *repo;
check_lg2(git_repository_open_ext(&repo, dir, 0, NULL), "could not open repository", dir);
check_lg2(git_repository_index(&index, repo), "could not open repository index", NULL);
git_repository_free(repo);
}
git_index_read(index);
......@@ -62,10 +57,7 @@ int main (int argc, char** argv)
}
git_index_free(index);
git_repository_free(repo);
git_threads_shutdown();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment