Unverified Commit 8ffdc5a9 by Edward Thomson Committed by GitHub

Merge pull request #6616 from libgit2/ethomson/config_cmd

cli: add a `git config` command
parents 45647b72 929ec754
/*
* 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.
*/
#ifndef CLI_cli_h__
#define CLI_cli_h__
#define PROGRAM_NAME "git2"
#include "git2_util.h"
#include "error.h"
#include "opt.h"
#include "opt_usage.h"
#include "sighandler.h"
#endif /* CLI_cli_h__ */
......@@ -5,7 +5,7 @@
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "cli.h"
#include "common.h"
#include "cmd.h"
const cli_cmd_spec *cli_cmd_spec_byname(const char *name)
......
......@@ -27,6 +27,7 @@ extern const cli_cmd_spec *cli_cmd_spec_byname(const char *name);
/* Commands */
extern int cmd_cat_file(int argc, char **argv);
extern int cmd_clone(int argc, char **argv);
extern int cmd_config(int argc, char **argv);
extern int cmd_hash_object(int argc, char **argv);
extern int cmd_help(int argc, char **argv);
......
......@@ -6,7 +6,7 @@
*/
#include <git2.h>
#include "cli.h"
#include "common.h"
#include "cmd.h"
#define COMMAND_NAME "cat-file"
......@@ -24,9 +24,7 @@ static int display = DISPLAY_CONTENT;
static char *type_name, *object_spec;
static const cli_opt_spec opts[] = {
{ CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1,
CLI_OPT_USAGE_HIDDEN | CLI_OPT_USAGE_STOP_PARSING, NULL,
"display help about the " COMMAND_NAME " command" },
CLI_COMMON_OPT,
{ CLI_OPT_TYPE_SWITCH, NULL, 't', &display, DISPLAY_TYPE,
CLI_OPT_USAGE_REQUIRED, NULL, "display the type of the object" },
......@@ -139,6 +137,7 @@ static int print_pretty(git_object *object)
int cmd_cat_file(int argc, char **argv)
{
cli_repository_open_options open_opts = { argv + 1, argc - 1};
git_repository *repo = NULL;
git_object *object = NULL;
git_object_t type;
......@@ -153,7 +152,7 @@ int cmd_cat_file(int argc, char **argv)
return 0;
}
if (git_repository_open_ext(&repo, ".", GIT_REPOSITORY_OPEN_FROM_ENV, NULL) < 0)
if (cli_repository_open(&repo, &open_opts) < 0)
return cli_error_git();
if ((giterr = git_revparse_single(&object, repo, object_spec)) < 0) {
......
......@@ -7,7 +7,7 @@
#include <stdio.h>
#include <git2.h>
#include "cli.h"
#include "common.h"
#include "cmd.h"
#include "error.h"
#include "sighandler.h"
......@@ -24,9 +24,7 @@ static bool local_path_exists;
static cli_progress progress = CLI_PROGRESS_INIT;
static const cli_opt_spec opts[] = {
{ CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1,
CLI_OPT_USAGE_HIDDEN | CLI_OPT_USAGE_STOP_PARSING, NULL,
"display help about the " COMMAND_NAME " command" },
CLI_COMMON_OPT,
{ CLI_OPT_TYPE_SWITCH, "quiet", 'q', &quiet, 1,
CLI_OPT_USAGE_DEFAULT, NULL, "display the type of the object" },
......
/*
* 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"
#include "cmd.h"
#define COMMAND_NAME "config"
typedef enum {
ACTION_NONE = 0,
ACTION_GET,
ACTION_ADD,
ACTION_REPLACE_ALL,
ACTION_LIST
} action_t;
static action_t action = ACTION_NONE;
static int show_origin;
static int show_scope;
static int show_help;
static int null_separator;
static int config_level;
static char *config_filename;
static char *name, *value, *value_pattern;
static const cli_opt_spec opts[] = {
CLI_COMMON_OPT, \
{ CLI_OPT_TYPE_SWITCH, "null", 'z', &null_separator, 1,
0, NULL, "use NUL as a separator" },
{ CLI_OPT_TYPE_SWITCH, "system", 0, &config_level, GIT_CONFIG_LEVEL_SYSTEM,
0, NULL, "read/write to system configuration" },
{ CLI_OPT_TYPE_SWITCH, "global", 0, &config_level, GIT_CONFIG_LEVEL_GLOBAL,
CLI_OPT_USAGE_CHOICE, NULL, "read/write to global configuration" },
{ CLI_OPT_TYPE_SWITCH, "local", 0, &config_level, GIT_CONFIG_LEVEL_LOCAL,
CLI_OPT_USAGE_CHOICE, NULL, "read/write to local configuration" },
{ CLI_OPT_TYPE_VALUE, "file", 0, &config_filename, 0,
CLI_OPT_USAGE_CHOICE, "filename", "read/write to specified configuration file" },
{ CLI_OPT_TYPE_SWITCH, "get", 0, &action, ACTION_GET,
CLI_OPT_USAGE_REQUIRED, NULL, "get a configuration value" },
{ CLI_OPT_TYPE_SWITCH, "add", 0, &action, ACTION_ADD,
CLI_OPT_USAGE_CHOICE, NULL, "add a configuration value" },
{ CLI_OPT_TYPE_SWITCH, "replace-all", 0, &action, ACTION_REPLACE_ALL,
CLI_OPT_USAGE_CHOICE, NULL, "add a configuration value, replacing any old values" },
{ CLI_OPT_TYPE_SWITCH, "list", 'l', &action, ACTION_LIST,
CLI_OPT_USAGE_CHOICE | CLI_OPT_USAGE_SHOW_LONG,
NULL, "list all configuration entries" },
{ CLI_OPT_TYPE_SWITCH, "show-origin", 0, &show_origin, 1,
0, NULL, "show origin of configuration" },
{ CLI_OPT_TYPE_SWITCH, "show-scope", 0, &show_scope, 1,
0, NULL, "show scope of configuration" },
{ CLI_OPT_TYPE_ARG, "name", 0, &name, 0,
0, "name", "name of configuration entry" },
{ CLI_OPT_TYPE_ARG, "value", 0, &value, 0,
0, "value", "value of configuration entry" },
{ CLI_OPT_TYPE_ARG, "regexp", 0, &value_pattern, 0,
0, "regexp", "regular expression of values to replace" },
{ 0 },
};
static void print_help(void)
{
cli_opt_usage_fprint(stdout, PROGRAM_NAME, COMMAND_NAME, opts);
printf("\n");
printf("Query and set configuration options.\n");
printf("\n");
printf("Options:\n");
cli_opt_help_fprint(stdout, opts);
}
static int get_config(git_config *config)
{
git_buf value = GIT_BUF_INIT;
char sep = null_separator ? '\0' : '\n';
int error;
error = git_config_get_string_buf(&value, config, name);
if (error && error != GIT_ENOTFOUND)
return cli_error_git();
else if (error == GIT_ENOTFOUND)
return 1;
printf("%s%c", value.ptr, sep);
return 0;
}
static int add_config(git_config *config)
{
if (git_config_set_multivar(config, name, "$^", value) < 0)
return cli_error_git();
return 0;
}
static int replace_all_config(git_config *config)
{
if (git_config_set_multivar(config, name, value_pattern ? value_pattern : ".*", value) < 0)
return cli_error_git();
return 0;
}
static const char *level_name(git_config_level_t level)
{
switch (level) {
case GIT_CONFIG_LEVEL_PROGRAMDATA:
return "programdata";
case GIT_CONFIG_LEVEL_SYSTEM:
return "system";
case GIT_CONFIG_LEVEL_XDG:
return "global";
case GIT_CONFIG_LEVEL_GLOBAL:
return "global";
case GIT_CONFIG_LEVEL_LOCAL:
return "local";
case GIT_CONFIG_LEVEL_APP:
return "command";
default:
return "unknown";
}
}
static int list_config(git_config *config)
{
git_config_iterator *iterator;
git_config_entry *entry;
char data_separator = null_separator ? '\0' : '\t';
char kv_separator = null_separator ? '\n' : '=';
char entry_separator = null_separator ? '\0' : '\n';
int error;
if (git_config_iterator_new(&iterator, config) < 0)
return cli_error_git();
while ((error = git_config_next(&entry, iterator)) == 0) {
if (show_scope)
printf("%s%c",
level_name(entry->level),
data_separator);
if (show_origin)
printf("%s%s%s%c",
entry->backend_type ? entry->backend_type : "",
entry->backend_type && entry->origin_path ? ":" : "",
entry->origin_path ? entry->origin_path : "",
data_separator);
printf("%s%c%s%c", entry->name, kv_separator, entry->value,
entry_separator);
}
if (error != GIT_ITEROVER)
return cli_error_git();
git_config_iterator_free(iterator);
return 0;
}
int cmd_config(int argc, char **argv)
{
git_repository *repo = NULL;
git_config *config = NULL;
cli_repository_open_options open_opts = { argv + 1, argc - 1};
cli_opt invalid_opt;
int ret = 0;
if (cli_opt_parse(&invalid_opt, opts, argv + 1, argc - 1, CLI_OPT_PARSE_GNU))
return cli_opt_usage_error(COMMAND_NAME, opts, &invalid_opt);
if (show_help) {
print_help();
return 0;
}
if (config_filename) {
if (git_config_new(&config) < 0 ||
git_config_add_file_ondisk(config, config_filename,
GIT_CONFIG_LEVEL_APP, NULL, 0) < 0) {
ret = cli_error_git();
goto done;
}
} else {
if (cli_repository_open(&repo, &open_opts) < 0 ||
git_repository_config(&config, repo) < 0) {
ret = cli_error_git();
goto done;
}
if (config_level &&
git_config_open_level(&config, config, config_level) < 0) {
ret = cli_error_git();
goto done;
}
}
switch (action) {
case ACTION_ADD:
if (!name || !value || value_pattern)
ret = cli_error_usage("%s --add requires two arguments", COMMAND_NAME);
else
ret = add_config(config);
break;
case ACTION_REPLACE_ALL:
if (!name || !value)
ret = cli_error_usage("%s --replace-all requires two or three arguments", COMMAND_NAME);
else
ret = replace_all_config(config);
break;
case ACTION_GET:
if (!name)
ret = cli_error_usage("%s --get requires an argument", COMMAND_NAME);
else
ret = get_config(config);
break;
case ACTION_LIST:
if (name)
ret = cli_error_usage("%s --list does not take an argument", COMMAND_NAME);
else
ret = list_config(config);
break;
default:
ret = cli_error_usage("unknown action");
}
done:
git_config_free(config);
git_repository_free(repo);
return ret;
}
......@@ -6,7 +6,7 @@
*/
#include <git2.h>
#include "cli.h"
#include "common.h"
#include "cmd.h"
#include "futils.h"
......@@ -19,9 +19,7 @@ static int write_object, read_stdin, literally;
static char **filenames;
static const cli_opt_spec opts[] = {
{ CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1,
CLI_OPT_USAGE_HIDDEN | CLI_OPT_USAGE_STOP_PARSING, NULL,
"display help about the " COMMAND_NAME " command" },
CLI_COMMON_OPT,
{ CLI_OPT_TYPE_VALUE, NULL, 't', &type_name, 0,
CLI_OPT_USAGE_DEFAULT, "type", "the type of object to hash (default: \"blob\")" },
......@@ -92,6 +90,7 @@ static int hash_buf(
int cmd_hash_object(int argc, char **argv)
{
cli_repository_open_options open_opts = { argv + 1, argc - 1};
git_repository *repo = NULL;
git_odb *odb = NULL;
git_oid_t oid_type;
......@@ -113,7 +112,7 @@ int cmd_hash_object(int argc, char **argv)
return cli_error_usage("invalid object type '%s'", type_name);
if (write_object &&
(git_repository_open_ext(&repo, ".", GIT_REPOSITORY_OPEN_FROM_ENV, NULL) < 0 ||
(cli_repository_open(&repo, &open_opts) < 0 ||
git_repository_odb(&odb, repo) < 0)) {
ret = cli_error_git();
goto done;
......
......@@ -7,7 +7,7 @@
#include <stdio.h>
#include <git2.h>
#include "cli.h"
#include "common.h"
#include "cmd.h"
#define COMMAND_NAME "help"
......@@ -16,8 +16,8 @@ static char *command;
static int show_help;
static const cli_opt_spec opts[] = {
{ CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1,
CLI_OPT_USAGE_HIDDEN, NULL, "display help about the help command" },
CLI_COMMON_OPT,
{ CLI_OPT_TYPE_ARG, "command", 0, &command, 0,
CLI_OPT_USAGE_DEFAULT, "command", "the command to show help for" },
{ 0 },
......
/*
* 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 <git2/sys/config.h>
#include "git2_util.h"
#include "vector.h"
#include "common.h"
#include "error.h"
static int parse_option(cli_opt *opt, void *data)
{
git_str kv = GIT_STR_INIT, env = GIT_STR_INIT;
git_vector *cmdline_config = data;
int error = 0;
if (opt->spec && opt->spec->alias == 'c') {
if (git_str_puts(&kv, opt->value) < 0) {
error = cli_error_git();
goto done;
}
}
else if (opt->spec && !strcmp(opt->spec->name, "config-env")) {
char *val = strchr(opt->value, '=');
if (val == NULL || *(val + 1) == '\0') {
error = cli_error("invalid config format: '%s'", opt->value);
goto done;
}
if (git_str_put(&kv, opt->value, (val - opt->value)) < 0) {
error = cli_error_git();
goto done;
}
val++;
if ((error = git__getenv(&env, val)) == GIT_ENOTFOUND) {
error = cli_error("missing environment variable '%s' for configuration '%s'", val, kv.ptr);
goto done;
} else if (error) {
error = cli_error_git();
goto done;
}
if (git_str_putc(&kv, '=') < 0 ||
git_str_puts(&kv, env.ptr) < 0) {
error = cli_error_git();
goto done;
}
}
if (kv.size > 0 &&
git_vector_insert(cmdline_config, git_str_detach(&kv)) < 0)
error = cli_error_git();
done:
git_str_dispose(&env);
git_str_dispose(&kv);
return error;
}
static int parse_common_options(
git_repository *repo,
cli_repository_open_options *opts)
{
cli_opt_spec common_opts[] = {
{ CLI_COMMON_OPT_CONFIG },
{ CLI_COMMON_OPT_CONFIG_ENV },
{ 0 }
};
git_config_backend_memory_options config_opts =
GIT_CONFIG_BACKEND_MEMORY_OPTIONS_INIT;
git_vector cmdline = GIT_VECTOR_INIT;
git_config *config = NULL;
git_config_backend *backend = NULL;
int error = 0;
config_opts.backend_type = "command line";
if ((error = cli_opt_foreach(common_opts, opts->args,
opts->args_len, CLI_OPT_PARSE_GNU, parse_option,
&cmdline)) < 0)
goto done;
if (git_vector_length(&cmdline) == 0)
goto done;
if (git_repository_config(&config, repo) < 0 ||
git_config_backend_from_values(&backend,
(const char **)cmdline.contents, cmdline.length,
&config_opts) < 0 ||
git_config_add_backend(config, backend, GIT_CONFIG_LEVEL_APP,
repo, 0) < 0)
error = cli_error_git();
done:
if (error && backend)
backend->free(backend);
git_config_free(config);
git_vector_free_deep(&cmdline);
return error;
}
int cli_repository_open(
git_repository **out,
cli_repository_open_options *opts)
{
git_repository *repo;
if (git_repository_open_ext(&repo, ".", GIT_REPOSITORY_OPEN_FROM_ENV, NULL) < 0)
return -1;
if (opts && parse_common_options(repo, opts) < 0)
return -1;
*out = repo;
return 0;
}
/*
* 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.
*/
#ifndef CLI_common_h__
#define CLI_common_h__
#define PROGRAM_NAME "git2"
#include "git2_util.h"
#include "error.h"
#include "opt.h"
#include "opt_usage.h"
/*
* Common command arguments.
*/
#define CLI_COMMON_OPT_HELP \
CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1, \
CLI_OPT_USAGE_HIDDEN | CLI_OPT_USAGE_STOP_PARSING
#define CLI_COMMON_OPT_CONFIG \
CLI_OPT_TYPE_VALUE, NULL, 'c', NULL, 0, \
CLI_OPT_USAGE_HIDDEN
#define CLI_COMMON_OPT_CONFIG_ENV \
CLI_OPT_TYPE_VALUE, "config-env", 0, NULL, 0, \
CLI_OPT_USAGE_HIDDEN
#define CLI_COMMON_OPT \
{ CLI_COMMON_OPT_HELP }, \
{ CLI_COMMON_OPT_CONFIG }, \
{ CLI_COMMON_OPT_CONFIG_ENV }
typedef struct {
char **args;
int args_len;
} cli_repository_open_options;
extern int cli_repository_open(
git_repository **out,
cli_repository_open_options *opts);
/*
* Common command arguments.
*/
#define CLI_COMMON_OPT_HELP \
CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1, \
CLI_OPT_USAGE_HIDDEN | CLI_OPT_USAGE_STOP_PARSING
#define CLI_COMMON_OPT_CONFIG \
CLI_OPT_TYPE_VALUE, NULL, 'c', NULL, 0, \
CLI_OPT_USAGE_HIDDEN
#define CLI_COMMON_OPT_CONFIG_ENV \
CLI_OPT_TYPE_VALUE, "config-env", 0, NULL, 0, \
CLI_OPT_USAGE_HIDDEN
#define CLI_COMMON_OPT \
{ CLI_COMMON_OPT_HELP }, \
{ CLI_COMMON_OPT_CONFIG }, \
{ CLI_COMMON_OPT_CONFIG_ENV }
#endif /* CLI_common_h__ */
......@@ -8,7 +8,7 @@
#ifndef CLI_error_h__
#define CLI_error_h__
#include "cli.h"
#include "common.h"
#include <stdio.h>
#define CLI_EXIT_OK 0
......
......@@ -7,7 +7,7 @@
#include <stdio.h>
#include <git2.h>
#include "cli.h"
#include "common.h"
#include "cmd.h"
static int show_help = 0;
......@@ -16,8 +16,12 @@ static char *command = NULL;
static char **args = NULL;
const cli_opt_spec cli_common_opts[] = {
{ CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1,
CLI_OPT_USAGE_DEFAULT, NULL, "display help information" },
{ CLI_OPT_TYPE_SWITCH, "help", 0, &show_help, 1,
CLI_OPT_USAGE_DEFAULT, NULL, "display help information" },
{ CLI_OPT_TYPE_VALUE, NULL, 'c', NULL, 0,
CLI_OPT_USAGE_DEFAULT, "key=value", "add configuration value" },
{ CLI_OPT_TYPE_VALUE, "config-env", 0, NULL, 0,
CLI_OPT_USAGE_DEFAULT, "key=value", "set configuration value to environment variable" },
{ CLI_OPT_TYPE_SWITCH, "version", 0, &show_version, 1,
CLI_OPT_USAGE_DEFAULT, NULL, "display the version" },
{ CLI_OPT_TYPE_ARG, "command", 0, &command, 0,
......@@ -30,19 +34,39 @@ const cli_opt_spec cli_common_opts[] = {
const cli_cmd_spec cli_cmds[] = {
{ "cat-file", cmd_cat_file, "Display an object in the repository" },
{ "clone", cmd_clone, "Clone a repository into a new directory" },
{ "config", cmd_config, "View or set configuration values " },
{ "hash-object", cmd_hash_object, "Hash a raw object and product its object ID" },
{ "help", cmd_help, "Display help information" },
{ NULL }
};
/*
* Reorder the argv as it was given, since git has the notion of global
* options (like `--help` or `-c key=val`) that we want to pass to the
* subcommand, and that can appear early in the arguments, before the
* command name. Put the command-name in argv[1] to allow easier parsing.
*/
static void reorder_args(char **argv, size_t first)
{
char *tmp;
size_t i;
if (first == 1)
return;
tmp = argv[first];
for (i = first; i > 1; i--)
argv[i] = argv[i - 1];
argv[1] = tmp;
}
int main(int argc, char **argv)
{
const cli_cmd_spec *cmd;
cli_opt_parser optparser;
cli_opt opt;
char *help_args[3] = { NULL };
int help_args_len;
int args_len = 0;
int ret = 0;
if (git_libgit2_init() < 0) {
......@@ -66,8 +90,7 @@ int main(int argc, char **argv)
* remaining arguments as args for the command itself.
*/
if (command) {
args = &argv[optparser.idx];
args_len = (int)(argc - optparser.idx);
reorder_args(argv, optparser.idx);
break;
}
}
......@@ -77,28 +100,13 @@ int main(int argc, char **argv)
goto done;
}
/*
* If `--help <command>` is specified, delegate to that command's
* `--help` option. If no command is specified, run the `help`
* command. Do this by updating the args to emulate that behavior.
*/
if (!command || show_help) {
help_args[0] = command ? (char *)command : "help";
help_args[1] = command ? "--help" : NULL;
help_args_len = command ? 2 : 1;
command = help_args[0];
args = help_args;
args_len = help_args_len;
}
if ((cmd = cli_cmd_spec_byname(command)) == NULL) {
ret = cli_error("'%s' is not a %s command. See '%s help'.",
command, PROGRAM_NAME, PROGRAM_NAME);
goto done;
}
ret = cmd->fn(args_len, args);
ret = cmd->fn(argc - 1, &argv[1]);
done:
git_libgit2_shutdown();
......
......@@ -19,7 +19,7 @@
#include <limits.h>
#include <assert.h>
#include "cli.h"
#include "common.h"
#include "opt.h"
#ifdef _WIN32
......@@ -73,7 +73,7 @@ GIT_INLINE(const cli_opt_spec *) spec_for_long(
/* Handle --option=value arguments */
if (spec->type == CLI_OPT_TYPE_VALUE &&
eql &&
spec->name && eql &&
strncmp(arg, spec->name, eql_pos) == 0 &&
spec->name[eql_pos] == '\0') {
*has_value = 1;
......@@ -575,6 +575,28 @@ cli_opt_status_t cli_opt_parse(
return validate_required(opt, specs, given_specs);
}
int cli_opt_foreach(
const cli_opt_spec specs[],
char **args,
size_t args_len,
unsigned int flags,
int (*callback)(cli_opt *, void *),
void *callback_data)
{
cli_opt_parser parser;
cli_opt opt;
int ret;
cli_opt_parser_init(&parser, specs, args, args_len, flags);
while (cli_opt_parser_next(&opt, &parser)) {
if ((ret = callback(&opt, callback_data)) != 0)
return ret;
}
return 0;
}
static int spec_name_fprint(FILE *file, const cli_opt_spec *spec)
{
int error;
......
......@@ -300,6 +300,14 @@ cli_opt_status_t cli_opt_parse(
size_t args_len,
unsigned int flags);
int cli_opt_foreach(
const cli_opt_spec specs[],
char **args,
size_t args_len,
unsigned int flags,
int (*callback)(cli_opt *, void *),
void *callback_data);
/**
* Initializes a parser that parses the given arguments according to the
* given specifications.
......
......@@ -5,7 +5,7 @@
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "cli.h"
#include "common.h"
#include "str.h"
static int print_spec_name(git_str *out, const cli_opt_spec *spec)
......
......@@ -8,7 +8,8 @@
#include <stdint.h>
#include <signal.h>
#include "git2_util.h"
#include "cli.h"
#include "common.h"
#include "sighandler.h"
static void (*interrupt_handler)(void) = NULL;
......
#include <git2.h>
#include "cli.h"
#include "common.h"
......@@ -8,7 +8,7 @@
#include "git2_util.h"
#include <windows.h>
#include "cli.h"
#include "sighandler.h"
static void (*interrupt_handler)(void) = NULL;
......
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