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() ...@@ -9,6 +9,8 @@ ENDIF()
FILE(GLOB SRC_EXAMPLE_APPS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c) FILE(GLOB SRC_EXAMPLE_APPS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c)
FOREACH(src_app ${SRC_EXAMPLE_APPS}) FOREACH(src_app ${SRC_EXAMPLE_APPS})
STRING(REPLACE ".c" "" app_name ${src_app}) STRING(REPLACE ".c" "" app_name ${src_app})
ADD_EXECUTABLE(${app_name} ${src_app}) IF(NOT ${app_name} STREQUAL "common")
TARGET_LINK_LIBRARIES(${app_name} git2) ADD_EXECUTABLE(${app_name} ${src_app} "common.c")
TARGET_LINK_LIBRARIES(${app_name} git2)
ENDIF()
ENDFOREACH() ENDFOREACH()
...@@ -8,7 +8,7 @@ APPS = general showindex diff rev-list cat-file status log rev-parse init ...@@ -8,7 +8,7 @@ APPS = general showindex diff rev-list cat-file status log rev-parse init
all: $(APPS) all: $(APPS)
% : %.c % : %.c
$(CC) -o $@ $(CFLAGS) $< $(LFLAGS) $(CC) -o $@ common.c $(CFLAGS) $< $(LFLAGS)
clean: clean:
$(RM) $(APPS) $(RM) $(APPS)
......
libgit2 examples libgit2 examples
================ ================
These examples are meant as thin, easy-to-read snippets for Docurium These examples are a mixture of basic emulation of core Git command line
(https://github.com/github/docurium) rather than full-blown functions and simple snippets demonstrating libgit2 API usage (for use
implementations of Git commands. They are not vetted as carefully with Docurium). As a whole, they are not vetted carefully for bugs, error
for bugs, error handling, or cross-platform compatibility as the handling, and cross-platform compatibility in the same manner as the rest
rest of the code in libgit2, so copy with some caution. 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> * Copyright (C) the libgit2 contributors. All rights reserved.
#include <string.h> *
* 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> #include <assert.h>
enum print_options { enum print_options {
...@@ -14,19 +19,49 @@ struct print_payload { ...@@ -14,19 +19,49 @@ struct print_payload {
git_repository *repo; 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; git_threads_init();
array->strings = malloc(sizeof(char*) * array->count);
assert(array->strings!=NULL);
for(i=0; i<array->count; i++) { parse_opts(&options, &count, argc, argv);
array->strings[i]=argv[i];
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) 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 ...@@ -55,36 +90,46 @@ int print_matched_cb(const char *path, const char *matched_pathspec, void *paylo
return ret; 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) void print_usage(void)
{ {
fprintf(stderr, "usage: add [options] [--] file-spec [file-spec] [...]\n\n"); fprintf(stderr, "usage: add [options] [--] file-spec [file-spec] [...]\n\n");
fprintf(stderr, "\t-n, --dry-run dry run\n"); fprintf(stderr, "\t-n, --dry-run dry run\n");
fprintf(stderr, "\t-v, --verbose be verbose\n"); fprintf(stderr, "\t-v, --verbose be verbose\n");
fprintf(stderr, "\t-u, --update update tracked files\n"); fprintf(stderr, "\t-u, --update update tracked files\n");
exit(1);
} }
static void parse_opts(int *options, int *count, int argc, char *argv[])
int main (int argc, char** argv)
{ {
git_index_matched_path_cb matched_cb = NULL; int i;
git_repository *repo = NULL;
git_index *index;
git_strarray array = {0};
int i, options = 0;
struct print_payload payload = {0};
for (i = 1; i < argc; ++i) { for (i = 1; i < argc; ++i) {
if (argv[i][0] != '-') { if (argv[i][0] != '-') {
break; break;
} }
else if(!strcmp(argv[i], "--verbose") || !strcmp(argv[i], "-v")) { 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")) { 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")) { else if(!strcmp(argv[i], "--update") || !strcmp(argv[i], "-u")) {
options |= UPDATE; *options |= UPDATE;
} }
else if(!strcmp(argv[i], "-h")) { else if(!strcmp(argv[i], "-h")) {
print_usage(); print_usage();
...@@ -97,47 +142,11 @@ int main (int argc, char** argv) ...@@ -97,47 +142,11 @@ int main (int argc, char** argv)
else { else {
fprintf(stderr, "Unsupported option %s.\n", argv[i]); fprintf(stderr, "Unsupported option %s.\n", argv[i]);
print_usage(); print_usage();
return 1;
} }
} }
if (argc<=i) { if (argc<=i)
print_usage(); print_usage();
return 1;
}
git_threads_init(); *count = i;
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;
} }
#include <stdio.h> /*
#include <git2.h> * Copyright (C) the libgit2 contributors. All rights reserved.
#include <stdlib.h> *
#include <string.h> * 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; #include "common.h"
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;
}
static void print_signature(const char *header, const git_signature *sig) 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) ...@@ -57,12 +31,14 @@ static void print_signature(const char *header, const git_signature *sig)
sign, hours, minutes); sign, hours, minutes);
} }
/** Printing out a blob is simple, get the contents and print */
static void show_blob(const git_blob *blob) static void show_blob(const git_blob *blob)
{ {
/* ? Does this need crlf filtering? */ /* ? Does this need crlf filtering? */
fwrite(git_blob_rawcontent(blob), git_blob_rawsize(blob), 1, stdout); 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) static void show_tree(const git_tree *tree)
{ {
size_t i, max_i = (int)git_tree_entrycount(tree); size_t i, max_i = (int)git_tree_entrycount(tree);
...@@ -81,6 +57,9 @@ static void show_tree(const git_tree *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) static void show_commit(const git_commit *commit)
{ {
unsigned int i, max_i; unsigned int i, max_i;
...@@ -123,53 +102,34 @@ enum { ...@@ -123,53 +102,34 @@ enum {
SHOW_PRETTY = 4 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[]) int main(int argc, char *argv[])
{ {
const char *dir = ".", *rev = NULL; git_repository *repo;
int i, action = 0, verbose = 0; struct opts o = { ".", NULL, 0, 0 };
git_object *obj = NULL; git_object *obj = NULL;
char oidstr[GIT_OID_HEXSZ + 1]; char oidstr[GIT_OID_HEXSZ + 1];
git_threads_init(); git_threads_init();
for (i = 1; i < argc; ++i) { parse_opts(&o, argc, argv);
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);
check(git_repository_open_ext(&g_repo, dir, 0, NULL), check_lg2(git_repository_open_ext(&repo, o.dir, 0, NULL),
"Could not open repository"); "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) { if (o.verbose) {
fprintf(stderr, "Could not resolve '%s'\n", rev);
exit(1);
}
if (verbose) {
char oidstr[GIT_OID_HEXSZ + 1]; char oidstr[GIT_OID_HEXSZ + 1];
git_oid_tostr(oidstr, sizeof(oidstr), git_object_id(obj)); git_oid_tostr(oidstr, sizeof(oidstr), git_object_id(obj));
...@@ -177,7 +137,7 @@ int main(int argc, char *argv[]) ...@@ -177,7 +137,7 @@ int main(int argc, char *argv[])
git_object_type2string(git_object_type(obj)), oidstr); git_object_type2string(git_object_type(obj)), oidstr);
} }
switch (action) { switch (o.action) {
case SHOW_TYPE: case SHOW_TYPE:
printf("%s\n", git_object_type2string(git_object_type(obj))); printf("%s\n", git_object_type2string(git_object_type(obj)));
break; break;
...@@ -185,9 +145,9 @@ int main(int argc, char *argv[]) ...@@ -185,9 +145,9 @@ int main(int argc, char *argv[])
git_odb *odb; git_odb *odb;
git_odb_object *odbobj; git_odb_object *odbobj;
check(git_repository_odb(&odb, g_repo), "Could not open ODB"); check_lg2(git_repository_odb(&odb, repo), "Could not open ODB", NULL);
check(git_odb_read(&odbobj, odb, git_object_id(obj)), check_lg2(git_odb_read(&odbobj, odb, git_object_id(obj)),
"Could not find obj"); "Could not find obj", NULL);
printf("%ld\n", (long)git_odb_object_size(odbobj)); printf("%ld\n", (long)git_odb_object_size(odbobj));
...@@ -221,9 +181,59 @@ int main(int argc, char *argv[]) ...@@ -221,9 +181,59 @@ int main(int argc, char *argv[])
} }
git_object_free(obj); git_object_free(obj);
git_repository_free(g_repo); git_repository_free(repo);
git_threads_shutdown(); git_threads_shutdown();
return 0; 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: ...@@ -47,6 +47,11 @@ exit:
return &data->ret; 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) 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]; 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 ...@@ -66,6 +71,7 @@ static int update_cb(const char *refname, const git_oid *a, const git_oid *b, vo
return 0; return 0;
} }
/** Entry point for this command */
int fetch(git_repository *repo, int argc, char **argv) int fetch(git_repository *repo, int argc, char **argv)
{ {
git_remote *remote = NULL; git_remote *remote = NULL;
...@@ -130,6 +136,11 @@ int fetch(git_repository *repo, int argc, char **argv) ...@@ -130,6 +136,11 @@ int fetch(git_repository *repo, int argc, char **argv)
pthread_join(worker, NULL); pthread_join(worker, NULL);
#endif #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) { if (stats->local_objects > 0) {
printf("\rReceived %d/%d objects in %zu bytes (used %d local objects)\n", 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); stats->indexed_objects, stats->total_objects, stats->received_bytes, stats->local_objects);
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <string.h> #include <string.h>
#include "common.h" #include "common.h"
/** Callback to show each item */
static int show_ref__cb(git_remote_head *head, void *payload) static int show_ref__cb(git_remote_head *head, void *payload)
{ {
char oid[GIT_OID_HEXSZ + 1] = {0}; char oid[GIT_OID_HEXSZ + 1] = {0};
...@@ -28,6 +29,10 @@ static int use_remote(git_repository *repo, char *name) ...@@ -28,6 +29,10 @@ static int use_remote(git_repository *repo, char *name)
goto cleanup; goto cleanup;
} }
/**
* Connect to the remote and call the printing function for
* each of the remote references.
*/
callbacks.credentials = cred_acquire_cb; callbacks.credentials = cred_acquire_cb;
git_remote_set_callbacks(remote, &callbacks); git_remote_set_callbacks(remote, &callbacks);
...@@ -42,9 +47,7 @@ cleanup: ...@@ -42,9 +47,7 @@ cleanup:
return error; return error;
} }
// This gets called to do the work. The remote can be given either as /** Entry point for this command */
// the name of a configured remote or an URL.
int ls_remote(git_repository *repo, int argc, char **argv) int ls_remote(git_repository *repo, int argc, char **argv)
{ {
int error; 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) git_repository *repo;
return; git_revwalk *walk;
git_oid oid;
char buf[41];
git_threads_init();
const git_error *error = giterr_last(); check_lg2(git_repository_open_ext(&repo, ".", 0, NULL), "opening repository", NULL);
fprintf(stderr, "Error %d %s: %s\n", -error_code, action, check_lg2(git_revwalk_new(&walk, repo), "allocating revwalk", NULL);
(error && error->message) ? error->message : "???"); check_lg2(revwalk_parseopts(repo, walk, argc-1, argv+1), "parsing options", NULL);
exit(1);
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) 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, ...@@ -93,27 +111,3 @@ static int revwalk_parseopts(git_repository *repo, git_revwalk *walk, int nopts,
return 0; 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> * Copyright (C) the libgit2 contributors. All rights reserved.
#include <stdlib.h> *
#include <string.h> * 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) struct parse_state ps = {0};
return;
if (arg) git_threads_init();
fprintf(stderr, "%s %s (%d)\n", message, arg, error); parse_opts(&ps, argc, argv);
else
fprintf(stderr, "%s(%d)\n", message, error); check_lg2(parse_revision(&ps), "Parsing", NULL);
exit(1);
git_repository_free(ps.repo);
git_threads_shutdown();
return 0;
} }
static void usage(const char *message, const char *arg) static void usage(const char *message, const char *arg)
...@@ -24,13 +43,25 @@ static void usage(const char *message, const char *arg) ...@@ -24,13 +43,25 @@ static void usage(const char *message, const char *arg)
exit(1); exit(1);
} }
struct parse_state { static void parse_opts(struct parse_state *ps, int argc, char *argv[])
git_repository *repo; {
const char *repodir; struct args_info args = ARGS_INFO_INIT;
int not;
};
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; git_revspec rs;
char str[GIT_OID_HEXSZ + 1]; char str[GIT_OID_HEXSZ + 1];
...@@ -38,11 +69,11 @@ static int parse_revision(struct parse_state *ps, const char *revstr) ...@@ -38,11 +69,11 @@ static int parse_revision(struct parse_state *ps, const char *revstr)
if (!ps->repo) { if (!ps->repo) {
if (!ps->repodir) if (!ps->repodir)
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); "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) { if ((rs.flags & GIT_REVPARSE_SINGLE) != 0) {
git_oid_tostr(str, sizeof(str), git_object_id(rs.from)); 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) ...@@ -56,9 +87,9 @@ static int parse_revision(struct parse_state *ps, const char *revstr)
if ((rs.flags & GIT_REVPARSE_MERGE_BASE) != 0) { if ((rs.flags & GIT_REVPARSE_MERGE_BASE) != 0) {
git_oid base; git_oid base;
check(git_merge_base(&base, ps->repo, check_lg2(git_merge_base(&base, ps->repo,
git_object_id(rs.from), git_object_id(rs.to)), git_object_id(rs.from), git_object_id(rs.to)),
"Could not find merge base", revstr); "Could not find merge base", ps->spec);
git_oid_tostr(str, sizeof(str), &base); git_oid_tostr(str, sizeof(str), &base);
printf("%s\n", str); printf("%s\n", str);
...@@ -69,38 +100,9 @@ static int parse_revision(struct parse_state *ps, const char *revstr) ...@@ -69,38 +100,9 @@ static int parse_revision(struct parse_state *ps, const char *revstr)
git_object_free(rs.from); git_object_free(rs.from);
} }
else { else {
check(0, "Invalid results from git_revparse", revstr); fatal("Invalid results from git_revparse", ps->spec);
} }
return 0; 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> * Copyright (C) the libgit2 contributors. All rights reserved.
#include <string.h> *
* 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) int main (int argc, char** argv)
{ {
git_repository *repo = NULL;
git_index *index; git_index *index;
unsigned int i, ecount; unsigned int i, ecount;
char *dir = "."; char *dir = ".";
...@@ -14,28 +18,19 @@ int main (int argc, char** argv) ...@@ -14,28 +18,19 @@ int main (int argc, char** argv)
git_threads_init(); git_threads_init();
if (argc > 2)
fatal("usage: showindex [<repo-dir>]", NULL);
if (argc > 1) if (argc > 1)
dir = argv[1]; dir = argv[1];
if (!dir || argc > 2) {
fprintf(stderr, "usage: showindex [<repo-dir>]\n");
return 1;
}
dirlen = strlen(dir); dirlen = strlen(dir);
if (dirlen > 5 && strcmp(dir + dirlen - 5, "index") == 0) { if (dirlen > 5 && strcmp(dir + dirlen - 5, "index") == 0) {
if (git_index_open(&index, dir) < 0) { check_lg2(git_index_open(&index, dir), "could not open index", dir);
fprintf(stderr, "could not open index: %s\n", dir);
return 1;
}
} else { } else {
if (git_repository_open_ext(&repo, dir, 0, NULL) < 0) { git_repository *repo;
fprintf(stderr, "could not open repository: %s\n", dir); check_lg2(git_repository_open_ext(&repo, dir, 0, NULL), "could not open repository", dir);
return 1; check_lg2(git_repository_index(&index, repo), "could not open repository index", NULL);
} git_repository_free(repo);
if (git_repository_index(&index, repo) < 0) {
fprintf(stderr, "could not open repository index\n");
return 1;
}
} }
git_index_read(index); git_index_read(index);
...@@ -62,10 +57,7 @@ int main (int argc, char** argv) ...@@ -62,10 +57,7 @@ int main (int argc, char** argv)
} }
git_index_free(index); git_index_free(index);
git_repository_free(repo);
git_threads_shutdown(); git_threads_shutdown();
return 0; 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