Merge branch 'jk/clone-cmdline-config'

* jk/clone-cmdline-config:
  clone: accept config options on the command line
  config: make git_config_parse_parameter a public function
  remote: use new OPT_STRING_LIST
  parse-options: add OPT_STRING_LIST helper
This commit is contained in:
Junio C Hamano 2011-07-19 09:45:24 -07:00
Родитель fe01ef31b7 84054f79de
Коммит ff94409da9
10 изменённых файлов: 121 добавлений и 15 удалений

Просмотреть файл

@ -159,6 +159,17 @@ objects from the source repository into a pack in the cloned repository.
Specify the directory from which templates will be used;
(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
--config <key>=<value>::
-c <key>=<value>::
Set a configuration variable in the newly-created repository;
this takes effect immediately after the repository is
initialized, but before the remote history is fetched or any
files checked out. The key is in the same format as expected by
linkgit:git-config[1] (e.g., `core.eol=true`). If multiple
values are given for the same key, each value will be written to
the config file. This makes it safe, for example, to add
additional fetch refspecs to the origin remote.
--depth <depth>::
Create a 'shallow' clone with a history truncated to the
specified number of revisions. A shallow repository has a

Просмотреть файл

@ -46,6 +46,7 @@ static const char *real_git_dir;
static char *option_upload_pack = "git-upload-pack";
static int option_verbosity;
static int option_progress;
static struct string_list option_config;
static struct option builtin_clone_options[] = {
OPT__VERBOSITY(&option_verbosity),
@ -83,7 +84,8 @@ static struct option builtin_clone_options[] = {
"create a shallow clone of that depth"),
OPT_STRING(0, "separate-git-dir", &real_git_dir, "gitdir",
"separate git dir from working tree"),
OPT_STRING_LIST('c', "config", &option_config, "key=value",
"set config inside the new repository"),
OPT_END()
};
@ -364,6 +366,22 @@ static void write_remote_refs(const struct ref *local_refs)
clear_extra_refs();
}
static int write_one_config(const char *key, const char *value, void *data)
{
return git_config_set_multivar(key, value ? value : "true", "^$", 0);
}
static void write_config(struct string_list *config)
{
int i;
for (i = 0; i < config->nr; i++) {
if (git_config_parse_parameter(config->items[i].string,
write_one_config, NULL) < 0)
die("unable to write parameters to config file");
}
}
int cmd_clone(int argc, const char **argv, const char *prefix)
{
int is_bundle = 0, is_local;
@ -482,6 +500,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
printf(_("Cloning into %s...\n"), dir);
}
init_db(option_template, INIT_DB_QUIET);
write_config(&option_config);
/*
* At this point, the config exists, so we do not need the

Просмотреть файл

@ -88,16 +88,6 @@ static inline int postfixcmp(const char *string, const char *postfix)
return strcmp(string + len1 - len2, postfix);
}
static int opt_parse_track(const struct option *opt, const char *arg, int not)
{
struct string_list *list = opt->value;
if (not)
string_list_clear(list, 0);
else
string_list_append(list, arg);
return 0;
}
static int fetch_remote(const char *name)
{
const char *argv[] = { "fetch", name, NULL, NULL };
@ -176,8 +166,8 @@ static int add(int argc, const char **argv)
TAGS_SET),
OPT_SET_INT(0, NULL, &fetch_tags,
"or do not fetch any tag at all (--no-tags)", TAGS_UNSET),
OPT_CALLBACK('t', "track", &track, "branch",
"branch(es) to track", opt_parse_track),
OPT_STRING_LIST('t', "track", &track, "branch",
"branch(es) to track"),
OPT_STRING('m', "master", &master, "branch", "master branch"),
{ OPTION_CALLBACK, 0, "mirror", &mirror, "push|fetch",
"set up remote as a mirror to push to or fetch from",

Просмотреть файл

@ -1082,6 +1082,8 @@ extern int config_error_nonbool(const char *);
extern const char *get_log_output_encoding(void);
extern const char *get_commit_output_encoding(void);
extern int git_config_parse_parameter(const char *, config_fn_t fn, void *data);
extern const char *config_exclusive_filename;
#define MAX_GITNAME (1000)

Просмотреть файл

@ -47,8 +47,8 @@ void git_config_push_parameter(const char *text)
strbuf_release(&env);
}
static int git_config_parse_parameter(const char *text,
config_fn_t fn, void *data)
int git_config_parse_parameter(const char *text,
config_fn_t fn, void *data)
{
struct strbuf **pair;
pair = strbuf_split_str(text, '=', 2);

Просмотреть файл

@ -3,6 +3,7 @@
#include "cache.h"
#include "commit.h"
#include "color.h"
#include "string-list.h"
static int parse_options_usage(struct parse_opt_ctx_t *ctx,
const char * const *usagestr,
@ -687,3 +688,19 @@ int parse_options_concat(struct option *dst, size_t dst_size, struct option *src
}
return -1;
}
int parse_opt_string_list(const struct option *opt, const char *arg, int unset)
{
struct string_list *v = opt->value;
if (unset) {
string_list_clear(v, 0);
return 0;
}
if (!arg)
return -1;
string_list_append(v, xstrdup(arg));
return 0;
}

Просмотреть файл

@ -130,6 +130,9 @@ struct option {
(h), PARSE_OPT_NOARG, NULL, (p) }
#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), "n", (h) }
#define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) }
#define OPT_STRING_LIST(s, l, v, a, h) \
{ OPTION_CALLBACK, (s), (l), (v), (a), \
(h), 0, &parse_opt_string_list }
#define OPT_UYN(s, l, v, h) { OPTION_CALLBACK, (s), (l), (v), NULL, \
(h), PARSE_OPT_NOARG, &parse_opt_tertiary }
#define OPT_DATE(s, l, v, h) \
@ -204,6 +207,7 @@ extern int parse_opt_color_flag_cb(const struct option *, const char *, int);
extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
extern int parse_opt_with_commit(const struct option *, const char *, int);
extern int parse_opt_tertiary(const struct option *, const char *, int);
extern int parse_opt_string_list(const struct option *, const char *, int);
#define OPT__VERBOSE(var, h) OPT_BOOLEAN('v', "verbose", (var), (h))
#define OPT__QUIET(var, h) OPT_BOOLEAN('q', "quiet", (var), (h))

Просмотреть файл

@ -28,6 +28,7 @@ String options
--st <st> get another string (pervert ordering)
-o <str> get another string
--default-string set string to default
--list <str> add str to list
Magic arguments
--quux means --quux
@ -337,4 +338,20 @@ test_expect_success 'negation of OPT_NONEG flags is not ambiguous' '
test_cmp expect output
'
cat >>expect <<'EOF'
list: foo
list: bar
list: baz
EOF
test_expect_success '--list keeps list of strings' '
test-parse-options --list foo --list=bar --list=baz >output &&
test_cmp expect output
'
test_expect_success '--no-list resets list' '
test-parse-options --list=other --list=irrelevant --list=options \
--no-list --list=foo --list=bar --list=baz >output &&
test_cmp expect output
'
test_done

40
t/t5708-clone-config.sh Executable file
Просмотреть файл

@ -0,0 +1,40 @@
#!/bin/sh
test_description='tests for git clone -c key=value'
. ./test-lib.sh
test_expect_success 'clone -c sets config in cloned repo' '
rm -rf child &&
git clone -c core.foo=bar . child &&
echo bar >expect &&
git --git-dir=child/.git config core.foo >actual &&
test_cmp expect actual
'
test_expect_success 'clone -c can set multi-keys' '
rm -rf child &&
git clone -c core.foo=bar -c core.foo=baz . child &&
{ echo bar; echo baz; } >expect &&
git --git-dir=child/.git config --get-all core.foo >actual &&
test_cmp expect actual
'
test_expect_success 'clone -c without a value is boolean true' '
rm -rf child &&
git clone -c core.foo . child &&
echo true >expect &&
git --git-dir=child/.git config --bool core.foo >actual &&
test_cmp expect actual
'
test_expect_success 'clone -c config is available during clone' '
echo content >file &&
git add file &&
git commit -m one &&
rm -rf child &&
git clone -c core.autocrlf . child &&
printf "content\\r\\n" >expect &&
test_cmp expect child/file
'
test_done

Просмотреть файл

@ -1,5 +1,6 @@
#include "cache.h"
#include "parse-options.h"
#include "string-list.h"
static int boolean = 0;
static int integer = 0;
@ -9,6 +10,7 @@ static int verbose = 0, dry_run = 0, quiet = 0;
static char *string = NULL;
static char *file = NULL;
static int ambiguous;
static struct string_list list;
static int length_callback(const struct option *opt, const char *arg, int unset)
{
@ -54,6 +56,7 @@ int main(int argc, const char **argv)
OPT_STRING('o', NULL, &string, "str", "get another string"),
OPT_SET_PTR(0, "default-string", &string,
"set string to default", (unsigned long)"default"),
OPT_STRING_LIST(0, "list", &list, "str", "add str to list"),
OPT_GROUP("Magic arguments"),
OPT_ARGUMENT("quux", "means --quux"),
OPT_NUMBER_CALLBACK(&integer, "set integer to NUM",
@ -85,6 +88,9 @@ int main(int argc, const char **argv)
printf("dry run: %s\n", dry_run ? "yes" : "no");
printf("file: %s\n", file ? file : "(not set)");
for (i = 0; i < list.nr; i++)
printf("list: %s\n", list.items[i].string);
for (i = 0; i < argc; i++)
printf("arg %02d: %s\n", i, argv[i]);