mirror of
https://github.com/libgit2/libgit2.git
synced 2026-06-22 06:26:26 +00:00
Merge pull request #5272 from tiennou/examples/cli-ification
Various examples shape-ups
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES})
|
||||
INCLUDE_DIRECTORIES(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES})
|
||||
|
||||
FILE(GLOB LG2_SOURCES *.c)
|
||||
FILE(GLOB LG2_SOURCES *.c *.h)
|
||||
ADD_EXECUTABLE(lg2 ${LG2_SOURCES})
|
||||
SET_TARGET_PROPERTIES(lg2 PROPERTIES C_STANDARD 90)
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* The following example demonstrates how to add files with libgit2.
|
||||
@@ -27,48 +26,50 @@
|
||||
* -u/--update: update the index instead of adding to it.
|
||||
*/
|
||||
|
||||
enum print_options {
|
||||
SKIP = 1,
|
||||
VERBOSE = 2,
|
||||
UPDATE = 4,
|
||||
enum index_mode {
|
||||
INDEX_NONE,
|
||||
INDEX_ADD,
|
||||
};
|
||||
|
||||
struct print_payload {
|
||||
enum print_options options;
|
||||
struct index_options {
|
||||
int dry_run;
|
||||
int verbose;
|
||||
git_repository *repo;
|
||||
enum index_mode mode;
|
||||
int add_update;
|
||||
};
|
||||
|
||||
/* 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);
|
||||
static void parse_opts(const char **repo_path, struct index_options *opts, struct args_info *args);
|
||||
int print_matched_cb(const char *path, const char *matched_pathspec, void *payload);
|
||||
|
||||
int lg2_add(git_repository *repo, int argc, char** argv)
|
||||
int lg2_add(git_repository *repo, int argc, char **argv)
|
||||
{
|
||||
git_index_matched_path_cb matched_cb = NULL;
|
||||
git_index *index;
|
||||
git_strarray array = {0};
|
||||
int options = 0, count = 0;
|
||||
struct print_payload payload = {0};
|
||||
struct index_options options;
|
||||
struct args_info args = ARGS_INFO_INIT;
|
||||
|
||||
parse_opts(&options, &count, argc, argv);
|
||||
init_array(&array, argc-count, argv+count);
|
||||
/* Parse the options & arguments. */
|
||||
parse_opts(NULL, &options, &args);
|
||||
strarray_from_args(&array, &args);
|
||||
|
||||
/* Grab the repository's index. */
|
||||
check_lg2(git_repository_index(&index, repo), "Could not open repository index", NULL);
|
||||
|
||||
/* Setup a callback if the requested options need it */
|
||||
if ((options & VERBOSE) || (options & SKIP)) {
|
||||
if (options.verbose || options.dry_run) {
|
||||
matched_cb = &print_matched_cb;
|
||||
}
|
||||
|
||||
/* Perform the requested action with the index and files */
|
||||
payload.options = options;
|
||||
payload.repo = repo;
|
||||
options.repo = repo;
|
||||
|
||||
if (options & UPDATE) {
|
||||
git_index_update_all(index, &array, matched_cb, &payload);
|
||||
/* Perform the requested action with the index and files */
|
||||
if (options.add_update) {
|
||||
git_index_update_all(index, &array, matched_cb, &options);
|
||||
} else {
|
||||
git_index_add_all(index, &array, 0, matched_cb, &payload);
|
||||
git_index_add_all(index, &array, 0, matched_cb, &options);
|
||||
}
|
||||
|
||||
/* Cleanup memory */
|
||||
@@ -85,15 +86,14 @@ int lg2_add(git_repository *repo, int argc, char** argv)
|
||||
*/
|
||||
int print_matched_cb(const char *path, const char *matched_pathspec, void *payload)
|
||||
{
|
||||
struct print_payload p = *(struct print_payload*)(payload);
|
||||
struct index_options *opts = (struct index_options *)(payload);
|
||||
int ret;
|
||||
unsigned status;
|
||||
(void)matched_pathspec;
|
||||
|
||||
/* Get the file status */
|
||||
if (git_status_file(&status, p.repo, path)) {
|
||||
if (git_status_file(&status, opts->repo, path) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((status & GIT_STATUS_WT_MODIFIED) || (status & GIT_STATUS_WT_NEW)) {
|
||||
printf("add '%s'\n", path);
|
||||
@@ -102,9 +102,8 @@ int print_matched_cb(const char *path, const char *matched_pathspec, void *paylo
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if ((p.options & SKIP)) {
|
||||
if (opts->dry_run)
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -133,33 +132,39 @@ void print_usage(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void parse_opts(int *options, int *count, int argc, char *argv[])
|
||||
static void parse_opts(const char **repo_path, struct index_options *opts, struct args_info *args)
|
||||
{
|
||||
int i;
|
||||
if (args->argc <= 1)
|
||||
print_usage();
|
||||
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (argv[i][0] != '-')
|
||||
break;
|
||||
else if (!strcmp(argv[i], "--verbose") || !strcmp(argv[i], "-v"))
|
||||
*options |= VERBOSE;
|
||||
else if (!strcmp(argv[i], "--dry-run") || !strcmp(argv[i], "-n"))
|
||||
*options |= SKIP;
|
||||
else if (!strcmp(argv[i], "--update") || !strcmp(argv[i], "-u"))
|
||||
*options |= UPDATE;
|
||||
else if (!strcmp(argv[i], "-h")) {
|
||||
for (args->pos = 1; args->pos < args->argc; ++args->pos) {
|
||||
const char *curr = args->argv[args->pos];
|
||||
|
||||
if (curr[0] != '-') {
|
||||
if (!strcmp("add", curr)) {
|
||||
opts->mode = INDEX_ADD;
|
||||
continue;
|
||||
} else if (opts->mode == INDEX_NONE) {
|
||||
fprintf(stderr, "missing command: %s", curr);
|
||||
print_usage();
|
||||
break;
|
||||
} else {
|
||||
/* We might be looking at a filename */
|
||||
break;
|
||||
}
|
||||
} else if (match_bool_arg(&opts->verbose, args, "--verbose") ||
|
||||
match_bool_arg(&opts->dry_run, args, "--dry-run") ||
|
||||
match_str_arg(repo_path, args, "--git-dir") ||
|
||||
(opts->mode == INDEX_ADD && match_bool_arg(&opts->add_update, args, "--update"))) {
|
||||
continue;
|
||||
} else if (match_bool_arg(NULL, args, "--help")) {
|
||||
print_usage();
|
||||
break;
|
||||
} else if (!strcmp(argv[i], "--")) {
|
||||
i++;
|
||||
} else if (match_arg_separator(args)) {
|
||||
break;
|
||||
} else {
|
||||
fprintf(stderr, "Unsupported option %s.\n", argv[i]);
|
||||
fprintf(stderr, "Unsupported option %s.\n", curr);
|
||||
print_usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (argc <= i)
|
||||
print_usage();
|
||||
|
||||
*count = i;
|
||||
}
|
||||
|
||||
197
examples/args.c
Normal file
197
examples/args.c
Normal file
@@ -0,0 +1,197 @@
|
||||
#include "common.h"
|
||||
#include "args.h"
|
||||
|
||||
size_t is_prefixed(const char *str, const char *pfx)
|
||||
{
|
||||
size_t len = strlen(pfx);
|
||||
return strncmp(str, pfx, len) ? 0 : len;
|
||||
}
|
||||
|
||||
int optional_str_arg(
|
||||
const char **out, struct args_info *args, const char *opt, const char *def)
|
||||
{
|
||||
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) {
|
||||
*out = def;
|
||||
return 1;
|
||||
}
|
||||
args->pos += 1;
|
||||
*out = args->argv[args->pos];
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (found[len] == '=') {
|
||||
*out = found + len + 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int match_uint32_arg(
|
||||
uint32_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 = (uint32_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 match_bool_arg(int *out, struct args_info *args, const char *opt)
|
||||
{
|
||||
const char *found = args->argv[args->pos];
|
||||
|
||||
if (!strcmp(found, opt)) {
|
||||
*out = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strncmp(found, "--no-", strlen("--no-")) &&
|
||||
!strcmp(found + strlen("--no-"), opt + 2)) {
|
||||
*out = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
*out = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 match_arg_separator(struct args_info *args)
|
||||
{
|
||||
if (args->opts_done)
|
||||
return 1;
|
||||
|
||||
if (strcmp(args->argv[args->pos], "--") != 0)
|
||||
return 0;
|
||||
|
||||
args->opts_done = 1;
|
||||
args->pos++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void strarray_from_args(git_strarray *array, struct args_info *args)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
array->count = args->argc - args->pos;
|
||||
array->strings = calloc(array->count, sizeof(char *));
|
||||
assert(array->strings != NULL);
|
||||
|
||||
for (i = 0; args->pos < args->argc; ++args->pos) {
|
||||
array->strings[i++] = args->argv[args->pos];
|
||||
}
|
||||
args->pos = args->argc;
|
||||
}
|
||||
90
examples/args.h
Normal file
90
examples/args.h
Normal file
@@ -0,0 +1,90 @@
|
||||
#ifndef INCLUDE_examples_args_h__
|
||||
#define INCLUDE_examples_args_h__
|
||||
|
||||
/**
|
||||
* Argument-processing helper structure
|
||||
*/
|
||||
struct args_info {
|
||||
int argc;
|
||||
char **argv;
|
||||
int pos;
|
||||
int opts_done : 1; /**< Did we see a -- separator */
|
||||
};
|
||||
#define ARGS_INFO_INIT { argc, argv, 0, 0 }
|
||||
#define ARGS_CURRENT(args) args->argv[args->pos]
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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; if value not supplied,
|
||||
* default value `def` will be given. otherwise return 0.
|
||||
*/
|
||||
extern int optional_str_arg(
|
||||
const char **out, struct args_info *args, const char *opt, const char *def);
|
||||
|
||||
/**
|
||||
* 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 uint32. 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
|
||||
* uint32_t value; otherwise return 0.
|
||||
*/
|
||||
extern int match_uint32_arg(
|
||||
uint32_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);
|
||||
|
||||
/**
|
||||
* Check current `args` entry against a "bool" `opt` (ie. --[no-]progress).
|
||||
* If `opt` matches positively, out will be set to 1, or if `opt` matches
|
||||
* negatively, out will be set to 0, and in both cases 1 will be returned.
|
||||
* If neither the positive or the negative form of opt matched, out will be -1,
|
||||
* and 0 will be returned.
|
||||
*/
|
||||
extern int match_bool_arg(int *out, struct args_info *args, const char *opt);
|
||||
|
||||
/**
|
||||
* Check if we're processing past the single -- separator
|
||||
*/
|
||||
extern int match_arg_separator(struct args_info *args);
|
||||
|
||||
/**
|
||||
* Consume all remaining arguments in a git_strarray
|
||||
*/
|
||||
extern void strarray_from_args(git_strarray *array, struct args_info *args);
|
||||
|
||||
#endif
|
||||
@@ -19,7 +19,7 @@
|
||||
* simulate the output of `git blame` and a few of its command line arguments.
|
||||
*/
|
||||
|
||||
struct opts {
|
||||
struct blame_opts {
|
||||
char *path;
|
||||
char *commitspec;
|
||||
int C;
|
||||
@@ -28,14 +28,14 @@ struct opts {
|
||||
int end_line;
|
||||
int F;
|
||||
};
|
||||
static void parse_opts(struct opts *o, int argc, char *argv[]);
|
||||
static void parse_opts(struct blame_opts *o, int argc, char *argv[]);
|
||||
|
||||
int lg2_blame(git_repository *repo, int argc, char *argv[])
|
||||
{
|
||||
int line, break_on_null_hunk;
|
||||
git_object_size_t i, rawsize;
|
||||
char spec[1024] = {0};
|
||||
struct opts o = {0};
|
||||
struct blame_opts o = {0};
|
||||
const char *rawdata;
|
||||
git_revspec revspec = {0};
|
||||
git_blame_options blameopts = GIT_BLAME_OPTIONS_INIT;
|
||||
@@ -143,7 +143,7 @@ static void usage(const char *msg, const char *arg)
|
||||
}
|
||||
|
||||
/** Parse the arguments. */
|
||||
static void parse_opts(struct opts *o, int argc, char *argv[])
|
||||
static void parse_opts(struct blame_opts *o, int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
char *bare_args[3] = {0};
|
||||
|
||||
@@ -102,27 +102,28 @@ static void show_tag(const git_tag *tag)
|
||||
printf("\n%s\n", git_tag_message(tag));
|
||||
}
|
||||
|
||||
enum {
|
||||
typedef enum {
|
||||
SHOW_TYPE = 1,
|
||||
SHOW_SIZE = 2,
|
||||
SHOW_NONE = 3,
|
||||
SHOW_PRETTY = 4
|
||||
};
|
||||
} catfile_mode;
|
||||
|
||||
/* Forward declarations for option-parsing helper */
|
||||
struct opts {
|
||||
struct catfile_options {
|
||||
const char *dir;
|
||||
const char *rev;
|
||||
int action;
|
||||
catfile_mode action;
|
||||
int verbose;
|
||||
};
|
||||
static void parse_opts(struct opts *o, int argc, char *argv[]);
|
||||
|
||||
static void parse_opts(struct catfile_options *o, int argc, char *argv[]);
|
||||
|
||||
|
||||
/** Entry point for this command */
|
||||
int lg2_cat_file(git_repository *repo, int argc, char *argv[])
|
||||
{
|
||||
struct opts o = { ".", NULL, 0, 0 };
|
||||
struct catfile_options o = { ".", NULL, 0, 0 };
|
||||
git_object *obj = NULL;
|
||||
char oidstr[GIT_OID_HEXSZ + 1];
|
||||
|
||||
@@ -201,7 +202,7 @@ static void usage(const char *message, const char *arg)
|
||||
}
|
||||
|
||||
/** Parse the command-line options taken from git */
|
||||
static void parse_opts(struct opts *o, int argc, char *argv[])
|
||||
static void parse_opts(struct catfile_options *o, int argc, char *argv[])
|
||||
{
|
||||
struct args_info args = ARGS_INFO_INIT;
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <assert.h>
|
||||
|
||||
/* Define the printf format specifer to use for size_t output */
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
@@ -66,7 +65,7 @@ static void parse_options(const char **repo_path, checkout_options *opts, struct
|
||||
const char *curr = args->argv[args->pos];
|
||||
int bool_arg;
|
||||
|
||||
if (strcmp(curr, "--") == 0) {
|
||||
if (match_arg_separator(args)) {
|
||||
break;
|
||||
} else if (!strcmp(curr, "--force")) {
|
||||
opts->force = 1;
|
||||
@@ -191,11 +190,7 @@ int lg2_checkout(git_repository *repo, int argc, char **argv)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (args.pos >= args.argc) {
|
||||
fprintf(stderr, "unhandled\n");
|
||||
err = -1;
|
||||
goto cleanup;
|
||||
} else if (!strcmp("--", args.argv[args.pos])) {
|
||||
if (match_arg_separator(&args)) {
|
||||
/**
|
||||
* Try to checkout the given path
|
||||
*/
|
||||
|
||||
@@ -12,21 +12,14 @@
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef _WIN32
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <fcntl.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
void check_lg2(int error, const char *message, const char *extra)
|
||||
{
|
||||
const git_error *lg2err;
|
||||
@@ -60,174 +53,6 @@ void fatal(const char *message, const char *extra)
|
||||
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 optional_str_arg(
|
||||
const char **out, struct args_info *args, const char *opt, const char *def)
|
||||
{
|
||||
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) {
|
||||
*out = def;
|
||||
return 1;
|
||||
}
|
||||
args->pos += 1;
|
||||
*out = args->argv[args->pos];
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (found[len] == '=') {
|
||||
*out = found + len + 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int match_uint32_arg(
|
||||
uint32_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 = (uint32_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 match_bool_arg(int *out, struct args_info *args, const char *opt)
|
||||
{
|
||||
const char *found = args->argv[args->pos];
|
||||
|
||||
if (!strcmp(found, opt)) {
|
||||
*out = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strncmp(found, "--no-", strlen("--no-")) &&
|
||||
!strcmp(found + strlen("--no-"), opt + 2)) {
|
||||
*out = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
*out = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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,
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
* with this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#ifndef INCLUDE_examples_common_h__
|
||||
#define INCLUDE_examples_common_h__
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
@@ -49,6 +52,8 @@
|
||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x))
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
#include "args.h"
|
||||
|
||||
extern int lg2_add(git_repository *repo, int argc, char **argv);
|
||||
extern int lg2_blame(git_repository *repo, int argc, char **argv);
|
||||
extern int lg2_cat_file(git_repository *repo, int argc, char **argv);
|
||||
@@ -93,77 +98,6 @@ extern char *read_file(const char *path);
|
||||
*/
|
||||
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; if value not supplied,
|
||||
* default value `def` will be given. otherwise return 0.
|
||||
*/
|
||||
extern int optional_str_arg(
|
||||
const char **out, struct args_info *args, const char *opt, const char *def);
|
||||
|
||||
/**
|
||||
* 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 uint32. 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
|
||||
* uint32_t value; otherwise return 0.
|
||||
*/
|
||||
extern int match_uint32_arg(
|
||||
uint32_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);
|
||||
|
||||
/**
|
||||
* Check current `args` entry against a "bool" `opt` (ie. --[no-]progress).
|
||||
* If `opt` matches positively, out will be set to 1, or if `opt` matches
|
||||
* negatively, out will be set to 0, and in both cases 1 will be returned.
|
||||
* If neither the positive or the negative form of opt matched, out will be -1,
|
||||
* and 0 will be returned.
|
||||
*/
|
||||
extern int match_bool_arg(int *out, struct args_info *args, const char *opt);
|
||||
|
||||
/**
|
||||
* Basic output function for plain text diff output
|
||||
* Pass `FILE*` such as `stdout` or `stderr` as payload (or NULL == `stdout`)
|
||||
@@ -196,3 +130,5 @@ extern int cred_acquire_cb(git_cred **out,
|
||||
const char *username_from_url,
|
||||
unsigned int allowed_types,
|
||||
void *payload);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* The following example partially reimplements the `git describe` command
|
||||
@@ -38,16 +37,14 @@
|
||||
*/
|
||||
|
||||
/** describe_options represents the parsed command line options */
|
||||
typedef struct {
|
||||
struct describe_options {
|
||||
const char **commits;
|
||||
size_t commit_count;
|
||||
git_describe_options describe_options;
|
||||
git_describe_format_options format_options;
|
||||
} describe_options;
|
||||
};
|
||||
|
||||
typedef struct args_info args_info;
|
||||
|
||||
static void opts_add_commit(describe_options *opts, const char *commit)
|
||||
static void opts_add_commit(struct describe_options *opts, const char *commit)
|
||||
{
|
||||
size_t sz;
|
||||
|
||||
@@ -58,7 +55,7 @@ static void opts_add_commit(describe_options *opts, const char *commit)
|
||||
opts->commits[opts->commit_count - 1] = commit;
|
||||
}
|
||||
|
||||
static void do_describe_single(git_repository *repo, describe_options *opts, const char *rev)
|
||||
static void do_describe_single(git_repository *repo, struct describe_options *opts, const char *rev)
|
||||
{
|
||||
git_object *commit;
|
||||
git_describe_result *describe_result;
|
||||
@@ -81,7 +78,7 @@ static void do_describe_single(git_repository *repo, describe_options *opts, con
|
||||
printf("%s\n", buf.ptr);
|
||||
}
|
||||
|
||||
static void do_describe(git_repository *repo, describe_options *opts)
|
||||
static void do_describe(git_repository *repo, struct describe_options *opts)
|
||||
{
|
||||
if (opts->commit_count == 0)
|
||||
do_describe_single(repo, opts, NULL);
|
||||
@@ -100,9 +97,9 @@ static void print_usage(void)
|
||||
}
|
||||
|
||||
/** Parse command line arguments */
|
||||
static void parse_options(describe_options *opts, int argc, char **argv)
|
||||
static void parse_options(struct describe_options *opts, int argc, char **argv)
|
||||
{
|
||||
args_info args = ARGS_INFO_INIT;
|
||||
struct args_info args = ARGS_INFO_INIT;
|
||||
|
||||
for (args.pos = 1; args.pos < argc; ++args.pos) {
|
||||
const char *curr = argv[args.pos];
|
||||
@@ -142,7 +139,7 @@ static void parse_options(describe_options *opts, int argc, char **argv)
|
||||
}
|
||||
|
||||
/** Initialize describe_options struct */
|
||||
static void describe_options_init(describe_options *opts)
|
||||
static void describe_options_init(struct describe_options *opts)
|
||||
{
|
||||
memset(opts, 0, sizeof(*opts));
|
||||
|
||||
@@ -154,7 +151,7 @@ static void describe_options_init(describe_options *opts)
|
||||
|
||||
int lg2_describe(git_repository *repo, int argc, char **argv)
|
||||
{
|
||||
describe_options opts;
|
||||
struct describe_options opts;
|
||||
|
||||
describe_options_init(&opts);
|
||||
parse_options(&opts, argc, argv);
|
||||
|
||||
@@ -47,8 +47,8 @@ enum {
|
||||
CACHE_NONE = 2
|
||||
};
|
||||
|
||||
/** The 'opts' struct captures all the various parsed command line options. */
|
||||
struct opts {
|
||||
/** The 'diff_options' struct captures all the various parsed command line options. */
|
||||
struct diff_options {
|
||||
git_diff_options diffopts;
|
||||
git_diff_find_options findopts;
|
||||
int color;
|
||||
@@ -63,18 +63,17 @@ struct opts {
|
||||
|
||||
/** These functions are implemented at the end */
|
||||
static void usage(const char *message, const char *arg);
|
||||
static void parse_opts(struct opts *o, int argc, char *argv[]);
|
||||
static void parse_opts(struct diff_options *o, int argc, char *argv[]);
|
||||
static int color_printer(
|
||||
const git_diff_delta*, const git_diff_hunk*, const git_diff_line*, void*);
|
||||
static void diff_print_stats(git_diff *diff, struct opts *o);
|
||||
static void compute_diff_no_index(git_diff **diff, struct opts *o);
|
||||
static void diff_print_stats(git_diff *diff, struct diff_options *o);
|
||||
static void compute_diff_no_index(git_diff **diff, struct diff_options *o);
|
||||
|
||||
int lg2_diff(git_repository *repo, int argc, char *argv[])
|
||||
{
|
||||
git_tree *t1 = NULL, *t2 = NULL;
|
||||
git_diff *diff;
|
||||
|
||||
struct opts o = {
|
||||
struct diff_options o = {
|
||||
GIT_DIFF_OPTIONS_INIT, GIT_DIFF_FIND_OPTIONS_INIT,
|
||||
-1, -1, 0, 0, GIT_DIFF_FORMAT_PATCH, NULL, NULL, "."
|
||||
};
|
||||
@@ -166,7 +165,7 @@ int lg2_diff(git_repository *repo, int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void compute_diff_no_index(git_diff **diff, struct opts *o) {
|
||||
static void compute_diff_no_index(git_diff **diff, struct diff_options *o) {
|
||||
git_patch *patch = NULL;
|
||||
char *file1_str = NULL;
|
||||
char *file2_str = NULL;
|
||||
@@ -242,11 +241,10 @@ static int color_printer(
|
||||
}
|
||||
|
||||
/** Parse arguments as copied from git-diff. */
|
||||
static void parse_opts(struct opts *o, int argc, char *argv[])
|
||||
static void parse_opts(struct diff_options *o, 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];
|
||||
|
||||
@@ -343,7 +341,7 @@ static void parse_opts(struct opts *o, int argc, char *argv[])
|
||||
}
|
||||
|
||||
/** Display diff output with "--stat", "--numstat", or "--shortstat" */
|
||||
static void diff_print_stats(git_diff *diff, struct opts *o)
|
||||
static void diff_print_stats(git_diff *diff, struct diff_options *o)
|
||||
{
|
||||
git_diff_stats *stats;
|
||||
git_buf b = GIT_BUF_INIT_CONST(NULL, 0);
|
||||
|
||||
@@ -3,42 +3,42 @@
|
||||
|
||||
static int show_ref(git_reference *ref, void *data)
|
||||
{
|
||||
git_repository *repo = data;
|
||||
git_reference *resolved = NULL;
|
||||
char hex[GIT_OID_HEXSZ+1];
|
||||
const git_oid *oid;
|
||||
git_object *obj;
|
||||
|
||||
if (git_reference_type(ref) == GIT_REFERENCE_SYMBOLIC)
|
||||
check_lg2(git_reference_resolve(&resolved, ref),
|
||||
"Unable to resolve symbolic reference",
|
||||
git_reference_name(ref));
|
||||
|
||||
oid = git_reference_target(resolved ? resolved : ref);
|
||||
git_oid_fmt(hex, oid);
|
||||
hex[GIT_OID_HEXSZ] = 0;
|
||||
check_lg2(git_object_lookup(&obj, repo, oid, GIT_OBJECT_ANY),
|
||||
"Unable to lookup object", hex);
|
||||
|
||||
printf("%s %-6s\t%s\n",
|
||||
hex,
|
||||
git_object_type2string(git_object_type(obj)),
|
||||
git_reference_name(ref));
|
||||
|
||||
if (resolved)
|
||||
git_reference_free(resolved);
|
||||
return 0;
|
||||
git_repository *repo = data;
|
||||
git_reference *resolved = NULL;
|
||||
char hex[GIT_OID_HEXSZ+1];
|
||||
const git_oid *oid;
|
||||
git_object *obj;
|
||||
|
||||
if (git_reference_type(ref) == GIT_REFERENCE_SYMBOLIC)
|
||||
check_lg2(git_reference_resolve(&resolved, ref),
|
||||
"Unable to resolve symbolic reference",
|
||||
git_reference_name(ref));
|
||||
|
||||
oid = git_reference_target(resolved ? resolved : ref);
|
||||
git_oid_fmt(hex, oid);
|
||||
hex[GIT_OID_HEXSZ] = 0;
|
||||
check_lg2(git_object_lookup(&obj, repo, oid, GIT_OBJECT_ANY),
|
||||
"Unable to lookup object", hex);
|
||||
|
||||
printf("%s %-6s\t%s\n",
|
||||
hex,
|
||||
git_object_type2string(git_object_type(obj)),
|
||||
git_reference_name(ref));
|
||||
|
||||
if (resolved)
|
||||
git_reference_free(resolved);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lg2_for_each_ref(git_repository *repo, int argc, char **argv)
|
||||
{
|
||||
UNUSED(argv);
|
||||
|
||||
if (argc != 1)
|
||||
fatal("Sorry, no for-each-ref options supported yet", NULL);
|
||||
|
||||
check_lg2(git_reference_foreach(repo, show_ref, repo),
|
||||
"Could not iterate over references", NULL);
|
||||
|
||||
return 0;
|
||||
|
||||
if (argc != 1)
|
||||
fatal("Sorry, no for-each-ref options supported yet", NULL);
|
||||
|
||||
check_lg2(git_reference_foreach(repo, show_ref, repo),
|
||||
"Could not iterate over references", NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
*/
|
||||
|
||||
/** Forward declarations of helpers */
|
||||
struct opts {
|
||||
struct init_opts {
|
||||
int no_options;
|
||||
int quiet;
|
||||
int bare;
|
||||
@@ -38,11 +38,11 @@ struct opts {
|
||||
const char *dir;
|
||||
};
|
||||
static void create_initial_commit(git_repository *repo);
|
||||
static void parse_opts(struct opts *o, int argc, char *argv[]);
|
||||
static void parse_opts(struct init_opts *o, int argc, char *argv[]);
|
||||
|
||||
int lg2_init(git_repository *repo, int argc, char *argv[])
|
||||
{
|
||||
struct opts o = { 1, 0, 0, 0, GIT_REPOSITORY_INIT_SHARED_UMASK, 0, 0, 0 };
|
||||
struct init_opts o = { 1, 0, 0, 0, GIT_REPOSITORY_INIT_SHARED_UMASK, 0, 0, 0 };
|
||||
|
||||
parse_opts(&o, argc, argv);
|
||||
|
||||
@@ -210,7 +210,7 @@ static uint32_t parse_shared(const char *shared)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void parse_opts(struct opts *o, int argc, char *argv[])
|
||||
static void parse_opts(struct init_opts *o, int argc, char *argv[])
|
||||
{
|
||||
struct args_info args = ARGS_INFO_INIT;
|
||||
const char *sharedarg;
|
||||
|
||||
@@ -84,8 +84,7 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
} else if (optional_str_arg(&git_dir, &args, "--git-dir", ".git")) {
|
||||
continue;
|
||||
} else if (!strcmp(a, "--")) {
|
||||
/* arg separator */
|
||||
} else if (match_arg_separator(&args)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,8 +424,7 @@ static int parse_options(
|
||||
else
|
||||
/** Try failed revision parse as filename. */
|
||||
break;
|
||||
} else if (!strcmp(a, "--")) {
|
||||
++args.pos;
|
||||
} else if (!match_arg_separator(&args)) {
|
||||
break;
|
||||
}
|
||||
else if (!strcmp(a, "--date-order"))
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
* This currently supports the default behavior and the `--error-unmatch` option.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
struct ls_options {
|
||||
int error_unmatch;
|
||||
char *files[1024];
|
||||
size_t file_count;
|
||||
} ls_options;
|
||||
};
|
||||
|
||||
static void usage(const char *message, const char *arg)
|
||||
{
|
||||
@@ -41,12 +41,12 @@ static void usage(const char *message, const char *arg)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int parse_options(ls_options *opts, int argc, char *argv[])
|
||||
static int parse_options(struct ls_options *opts, int argc, char *argv[])
|
||||
{
|
||||
int parsing_files = 0;
|
||||
int i;
|
||||
|
||||
memset(opts, 0, sizeof(ls_options));
|
||||
memset(opts, 0, sizeof(struct ls_options));
|
||||
|
||||
if (argc < 2)
|
||||
return 0;
|
||||
@@ -78,7 +78,7 @@ static int parse_options(ls_options *opts, int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int print_paths(ls_options *opts, git_index *index)
|
||||
static int print_paths(struct ls_options *opts, git_index *index)
|
||||
{
|
||||
size_t i;
|
||||
const git_index_entry *entry;
|
||||
@@ -113,7 +113,7 @@ static int print_paths(ls_options *opts, git_index *index)
|
||||
int lg2_ls_files(git_repository *repo, int argc, char *argv[])
|
||||
{
|
||||
git_index *index = NULL;
|
||||
ls_options opts;
|
||||
struct ls_options opts;
|
||||
int error;
|
||||
|
||||
if ((error = parse_options(&opts, argc, argv)) < 0)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <assert.h>
|
||||
|
||||
/** The following example demonstrates how to do merges with libgit2.
|
||||
*
|
||||
@@ -24,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
struct merge_options {
|
||||
const char **heads;
|
||||
size_t heads_count;
|
||||
|
||||
@@ -32,7 +31,7 @@ typedef struct {
|
||||
size_t annotated_count;
|
||||
|
||||
int no_commit : 1;
|
||||
} merge_options;
|
||||
};
|
||||
|
||||
static void print_usage(void)
|
||||
{
|
||||
@@ -40,7 +39,7 @@ static void print_usage(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void merge_options_init(merge_options *opts)
|
||||
static void merge_options_init(struct merge_options *opts)
|
||||
{
|
||||
memset(opts, 0, sizeof(*opts));
|
||||
|
||||
@@ -50,7 +49,7 @@ static void merge_options_init(merge_options *opts)
|
||||
opts->annotated_count = 0;
|
||||
}
|
||||
|
||||
static void opts_add_refish(merge_options *opts, const char *refish)
|
||||
static void opts_add_refish(struct merge_options *opts, const char *refish)
|
||||
{
|
||||
size_t sz;
|
||||
|
||||
@@ -61,7 +60,7 @@ static void opts_add_refish(merge_options *opts, const char *refish)
|
||||
opts->heads[opts->heads_count - 1] = refish;
|
||||
}
|
||||
|
||||
static void parse_options(const char **repo_path, merge_options *opts, int argc, char **argv)
|
||||
static void parse_options(const char **repo_path, struct merge_options *opts, int argc, char **argv)
|
||||
{
|
||||
struct args_info args = ARGS_INFO_INIT;
|
||||
|
||||
@@ -83,7 +82,7 @@ static void parse_options(const char **repo_path, merge_options *opts, int argc,
|
||||
}
|
||||
}
|
||||
|
||||
static int resolve_heads(git_repository *repo, merge_options *opts)
|
||||
static int resolve_heads(git_repository *repo, struct merge_options *opts)
|
||||
{
|
||||
git_annotated_commit **annotated = calloc(opts->heads_count, sizeof(git_annotated_commit *));
|
||||
size_t annotated_count = 0, i;
|
||||
@@ -201,7 +200,7 @@ static void output_conflicts(git_index *index)
|
||||
git_index_conflict_iterator_free(conflicts);
|
||||
}
|
||||
|
||||
static int create_merge_commit(git_repository *repo, git_index *index, merge_options *opts)
|
||||
static int create_merge_commit(git_repository *repo, git_index *index, struct merge_options *opts)
|
||||
{
|
||||
git_oid tree_oid, commit_oid;
|
||||
git_tree *tree;
|
||||
@@ -277,7 +276,7 @@ cleanup:
|
||||
|
||||
int lg2_merge(git_repository *repo, int argc, char **argv)
|
||||
{
|
||||
merge_options opts;
|
||||
struct merge_options opts;
|
||||
git_index *index;
|
||||
git_repository_state_t state;
|
||||
git_merge_analysis_t analysis;
|
||||
|
||||
@@ -30,7 +30,7 @@ enum subcmd {
|
||||
subcmd_show,
|
||||
};
|
||||
|
||||
struct opts {
|
||||
struct remote_opts {
|
||||
enum subcmd cmd;
|
||||
|
||||
/* for command-specific args */
|
||||
@@ -38,20 +38,20 @@ struct opts {
|
||||
char **argv;
|
||||
};
|
||||
|
||||
static int cmd_add(git_repository *repo, struct opts *o);
|
||||
static int cmd_remove(git_repository *repo, struct opts *o);
|
||||
static int cmd_rename(git_repository *repo, struct opts *o);
|
||||
static int cmd_seturl(git_repository *repo, struct opts *o);
|
||||
static int cmd_show(git_repository *repo, struct opts *o);
|
||||
static int cmd_add(git_repository *repo, struct remote_opts *o);
|
||||
static int cmd_remove(git_repository *repo, struct remote_opts *o);
|
||||
static int cmd_rename(git_repository *repo, struct remote_opts *o);
|
||||
static int cmd_seturl(git_repository *repo, struct remote_opts *o);
|
||||
static int cmd_show(git_repository *repo, struct remote_opts *o);
|
||||
|
||||
static void parse_subcmd(
|
||||
struct opts *opt, int argc, char **argv);
|
||||
struct remote_opts *opt, int argc, char **argv);
|
||||
static void usage(const char *msg, const char *arg);
|
||||
|
||||
int lg2_remote(git_repository *repo, int argc, char *argv[])
|
||||
{
|
||||
int retval = 0;
|
||||
struct opts opt = {0};
|
||||
struct remote_opts opt = {0};
|
||||
|
||||
parse_subcmd(&opt, argc, argv);
|
||||
|
||||
@@ -77,7 +77,7 @@ int lg2_remote(git_repository *repo, int argc, char *argv[])
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int cmd_add(git_repository *repo, struct opts *o)
|
||||
static int cmd_add(git_repository *repo, struct remote_opts *o)
|
||||
{
|
||||
char *name, *url;
|
||||
git_remote *remote = {0};
|
||||
@@ -94,7 +94,7 @@ static int cmd_add(git_repository *repo, struct opts *o)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_remove(git_repository *repo, struct opts *o)
|
||||
static int cmd_remove(git_repository *repo, struct remote_opts *o)
|
||||
{
|
||||
char *name;
|
||||
|
||||
@@ -109,7 +109,7 @@ static int cmd_remove(git_repository *repo, struct opts *o)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_rename(git_repository *repo, struct opts *o)
|
||||
static int cmd_rename(git_repository *repo, struct remote_opts *o)
|
||||
{
|
||||
int i, retval;
|
||||
char *old, *new;
|
||||
@@ -134,7 +134,7 @@ static int cmd_rename(git_repository *repo, struct opts *o)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int cmd_seturl(git_repository *repo, struct opts *o)
|
||||
static int cmd_seturl(git_repository *repo, struct remote_opts *o)
|
||||
{
|
||||
int i, retval, push = 0;
|
||||
char *name = NULL, *url = NULL;
|
||||
@@ -166,7 +166,7 @@ static int cmd_seturl(git_repository *repo, struct opts *o)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_show(git_repository *repo, struct opts *o)
|
||||
static int cmd_show(git_repository *repo, struct remote_opts *o)
|
||||
{
|
||||
int i;
|
||||
const char *arg, *name, *fetch, *push;
|
||||
@@ -213,7 +213,7 @@ static int cmd_show(git_repository *repo, struct opts *o)
|
||||
}
|
||||
|
||||
static void parse_subcmd(
|
||||
struct opts *opt, int argc, char **argv)
|
||||
struct remote_opts *opt, int argc, char **argv)
|
||||
{
|
||||
char *arg = argv[1];
|
||||
enum subcmd cmd = 0;
|
||||
|
||||
@@ -15,16 +15,24 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static int revwalk_parseopts(git_repository *repo, git_revwalk *walk, int nopts, char **opts);
|
||||
#include <assert.h>
|
||||
|
||||
static int revwalk_parse_options(git_sort_t *sort, struct args_info *args);
|
||||
static int revwalk_parse_revs(git_repository *repo, git_revwalk *walk, struct args_info *args);
|
||||
|
||||
int lg2_rev_list(git_repository *repo, int argc, char **argv)
|
||||
{
|
||||
struct args_info args = ARGS_INFO_INIT;
|
||||
git_revwalk *walk;
|
||||
git_oid oid;
|
||||
git_sort_t sort;
|
||||
char buf[GIT_OID_HEXSZ+1];
|
||||
|
||||
check_lg2(revwalk_parse_options(&sort, &args), "parsing options", NULL);
|
||||
|
||||
check_lg2(git_revwalk_new(&walk, repo), "allocating revwalk", NULL);
|
||||
check_lg2(revwalk_parseopts(repo, walk, argc-1, argv+1), "parsing options", NULL);
|
||||
git_revwalk_sorting(walk, sort);
|
||||
check_lg2(revwalk_parse_revs(repo, walk, &args), "parsing revs", NULL);
|
||||
|
||||
while (!git_revwalk_next(&oid, walk)) {
|
||||
git_oid_fmt(buf, &oid);
|
||||
@@ -32,6 +40,7 @@ int lg2_rev_list(git_repository *repo, int argc, char **argv)
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
|
||||
git_revwalk_free(walk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -80,33 +89,60 @@ out:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int revwalk_parseopts(git_repository *repo, git_revwalk *walk, int nopts, char **opts)
|
||||
static void print_usage(void)
|
||||
{
|
||||
int hide, i, error;
|
||||
unsigned int sorting = GIT_SORT_NONE;
|
||||
fprintf(stderr, "rev-list [--git-dir=dir] [--topo-order|--date-order] [--reverse] <revspec>\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
static int revwalk_parse_options(git_sort_t *sort, struct args_info *args)
|
||||
{
|
||||
assert(sort && args);
|
||||
*sort = GIT_SORT_NONE;
|
||||
|
||||
if (args->argc < 1)
|
||||
print_usage();
|
||||
|
||||
for (args->pos = 1; args->pos < args->argc; ++args->pos) {
|
||||
const char *curr = args->argv[args->pos];
|
||||
|
||||
if (!strcmp(curr, "--topo-order")) {
|
||||
*sort |= GIT_SORT_TOPOLOGICAL;
|
||||
} else if (!strcmp(curr, "--date-order")) {
|
||||
*sort |= GIT_SORT_TIME;
|
||||
} else if (!strcmp(curr, "--reverse")) {
|
||||
*sort |= (*sort & ~GIT_SORT_REVERSE) ^ GIT_SORT_REVERSE;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int revwalk_parse_revs(git_repository *repo, git_revwalk *walk, struct args_info *args)
|
||||
{
|
||||
int hide, error;
|
||||
git_oid oid;
|
||||
|
||||
hide = 0;
|
||||
for (i = 0; i < nopts; i++) {
|
||||
if (!strcmp(opts[i], "--topo-order")) {
|
||||
sorting = GIT_SORT_TOPOLOGICAL | (sorting & GIT_SORT_REVERSE);
|
||||
git_revwalk_sorting(walk, sorting);
|
||||
} else if (!strcmp(opts[i], "--date-order")) {
|
||||
sorting = GIT_SORT_TIME | (sorting & GIT_SORT_REVERSE);
|
||||
git_revwalk_sorting(walk, sorting);
|
||||
} else if (!strcmp(opts[i], "--reverse")) {
|
||||
sorting = (sorting & ~GIT_SORT_REVERSE)
|
||||
| ((sorting & GIT_SORT_REVERSE) ? 0 : GIT_SORT_REVERSE);
|
||||
git_revwalk_sorting(walk, sorting);
|
||||
} else if (!strcmp(opts[i], "--not")) {
|
||||
for (; args->pos < args->argc; ++args->pos) {
|
||||
const char *curr = args->argv[args->pos];
|
||||
|
||||
if (!strcmp(curr, "--not")) {
|
||||
hide = !hide;
|
||||
} else if (opts[i][0] == '^') {
|
||||
if ((error = push_spec(repo, walk, opts[i] + 1, !hide)))
|
||||
} else if (curr[0] == '^') {
|
||||
if ((error = push_spec(repo, walk, curr + 1, !hide)))
|
||||
return error;
|
||||
} else if (strstr(opts[i], "..")) {
|
||||
if ((error = push_range(repo, walk, opts[i], hide)))
|
||||
} else if (strstr(curr, "..")) {
|
||||
if ((error = push_range(repo, walk, curr, hide)))
|
||||
return error;
|
||||
} else {
|
||||
if ((error = push_spec(repo, walk, opts[i], hide)))
|
||||
if (push_spec(repo, walk, curr, hide) == 0)
|
||||
continue;
|
||||
|
||||
if ((error = git_oid_fromstr(&oid, curr)))
|
||||
return error;
|
||||
if ((error = push_commit(walk, &oid, hide)))
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
int lg2_show_index(git_repository *repo, int argc, char** argv)
|
||||
int lg2_show_index(git_repository *repo, int argc, char **argv)
|
||||
{
|
||||
git_index *index;
|
||||
size_t i, ecount;
|
||||
|
||||
@@ -43,7 +43,7 @@ enum {
|
||||
|
||||
#define MAX_PATHSPEC 8
|
||||
|
||||
struct opts {
|
||||
struct status_opts {
|
||||
git_status_options statusopt;
|
||||
char *repodir;
|
||||
char *pathspec[MAX_PATHSPEC];
|
||||
@@ -55,7 +55,7 @@ struct opts {
|
||||
int repeat;
|
||||
};
|
||||
|
||||
static void parse_opts(struct opts *o, int argc, char *argv[]);
|
||||
static void parse_opts(struct status_opts *o, int argc, char *argv[]);
|
||||
static void show_branch(git_repository *repo, int format);
|
||||
static void print_long(git_status_list *status);
|
||||
static void print_short(git_repository *repo, git_status_list *status);
|
||||
@@ -64,7 +64,7 @@ static int print_submod(git_submodule *sm, const char *name, void *payload);
|
||||
int lg2_status(git_repository *repo, int argc, char *argv[])
|
||||
{
|
||||
git_status_list *status;
|
||||
struct opts o = { GIT_STATUS_OPTIONS_INIT, "." };
|
||||
struct status_opts o = { GIT_STATUS_OPTIONS_INIT, "." };
|
||||
|
||||
o.statusopt.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
|
||||
o.statusopt.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
|
||||
@@ -435,7 +435,7 @@ static int print_submod(git_submodule *sm, const char *name, void *payload)
|
||||
/**
|
||||
* Parse options that git's status command supports.
|
||||
*/
|
||||
static void parse_opts(struct opts *o, int argc, char *argv[])
|
||||
static void parse_opts(struct status_opts *o, int argc, char *argv[])
|
||||
{
|
||||
struct args_info args = ARGS_INFO_INIT;
|
||||
|
||||
|
||||
@@ -31,19 +31,19 @@
|
||||
*/
|
||||
|
||||
/** tag_options represents the parsed command line options */
|
||||
typedef struct {
|
||||
struct tag_options {
|
||||
const char *message;
|
||||
const char *pattern;
|
||||
const char *tag_name;
|
||||
const char *target;
|
||||
int num_lines;
|
||||
int force;
|
||||
} tag_options;
|
||||
};
|
||||
|
||||
/** tag_state represents the current program state for dragging around */
|
||||
typedef struct {
|
||||
git_repository *repo;
|
||||
tag_options *opts;
|
||||
struct tag_options *opts;
|
||||
} tag_state;
|
||||
|
||||
/** An action to execute based on the command line arguments */
|
||||
@@ -167,7 +167,7 @@ static void action_list_tags(tag_state *state)
|
||||
|
||||
static void action_delete_tag(tag_state *state)
|
||||
{
|
||||
tag_options *opts = state->opts;
|
||||
struct tag_options *opts = state->opts;
|
||||
git_object *obj;
|
||||
git_buf abbrev_oid = {0};
|
||||
|
||||
@@ -191,7 +191,7 @@ static void action_delete_tag(tag_state *state)
|
||||
static void action_create_lighweight_tag(tag_state *state)
|
||||
{
|
||||
git_repository *repo = state->repo;
|
||||
tag_options *opts = state->opts;
|
||||
struct tag_options *opts = state->opts;
|
||||
git_oid oid;
|
||||
git_object *target;
|
||||
|
||||
@@ -213,7 +213,7 @@ static void action_create_lighweight_tag(tag_state *state)
|
||||
static void action_create_tag(tag_state *state)
|
||||
{
|
||||
git_repository *repo = state->repo;
|
||||
tag_options *opts = state->opts;
|
||||
struct tag_options *opts = state->opts;
|
||||
git_signature *tagger;
|
||||
git_oid oid;
|
||||
git_object *target;
|
||||
@@ -243,7 +243,7 @@ static void print_usage(void)
|
||||
}
|
||||
|
||||
/** Parse command line arguments and choose action to run when done */
|
||||
static void parse_options(tag_action *action, tag_options *opts, int argc, char **argv)
|
||||
static void parse_options(tag_action *action, struct tag_options *opts, int argc, char **argv)
|
||||
{
|
||||
args_info args = ARGS_INFO_INIT;
|
||||
*action = &action_list_tags;
|
||||
@@ -281,7 +281,7 @@ static void parse_options(tag_action *action, tag_options *opts, int argc, char
|
||||
}
|
||||
|
||||
/** Initialize tag_options struct */
|
||||
static void tag_options_init(tag_options *opts)
|
||||
static void tag_options_init(struct tag_options *opts)
|
||||
{
|
||||
memset(opts, 0, sizeof(*opts));
|
||||
|
||||
@@ -295,7 +295,7 @@ static void tag_options_init(tag_options *opts)
|
||||
|
||||
int lg2_tag(git_repository *repo, int argc, char **argv)
|
||||
{
|
||||
tag_options opts;
|
||||
struct tag_options opts;
|
||||
tag_action action;
|
||||
tag_state state;
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#include "apply.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "git2/apply.h"
|
||||
#include "git2/patch.h"
|
||||
#include "git2/filter.h"
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#include "checkout.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "git2/repository.h"
|
||||
#include "git2/refs.h"
|
||||
#include "git2/tree.h"
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#include "clone.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "git2/clone.h"
|
||||
#include "git2/remote.h"
|
||||
#include "git2/revparse.h"
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "tree.h"
|
||||
#include "refdb.h"
|
||||
|
||||
Reference in New Issue
Block a user