Skip to content

Commit

Permalink
Merge branch 'jk/clone-cmdline-config'
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Junio C Hamano committed Jul 19, 2011
2 parents fe01ef3 + 84054f7 commit ff94409
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 15 deletions.
11 changes: 11 additions & 0 deletions Documentation/git-clone.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 20 additions & 1 deletion builtin/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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()
};

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
14 changes: 2 additions & 12 deletions builtin/remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -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",
Expand Down
2 changes: 2 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
17 changes: 17 additions & 0 deletions parse-options.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}
4 changes: 4 additions & 0 deletions parse-options.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down Expand Up @@ -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))
Expand Down
17 changes: 17 additions & 0 deletions t/t0040-parse-options.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 changes: 40 additions & 0 deletions t/t5708-clone-config.sh
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions test-parse-options.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "cache.h"
#include "parse-options.h"
#include "string-list.h"

static int boolean = 0;
static int integer = 0;
Expand All @@ -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)
{
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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]);

Expand Down

0 comments on commit ff94409

Please sign in to comment.