Skip to content

Commit ff94409

Browse files
committed
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
2 parents fe01ef3 + 84054f7 commit ff94409

File tree

10 files changed

+121
-15
lines changed

10 files changed

+121
-15
lines changed

Documentation/git-clone.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,17 @@ objects from the source repository into a pack in the cloned repository.
159159
Specify the directory from which templates will be used;
160160
(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
161161

162+
--config <key>=<value>::
163+
-c <key>=<value>::
164+
Set a configuration variable in the newly-created repository;
165+
this takes effect immediately after the repository is
166+
initialized, but before the remote history is fetched or any
167+
files checked out. The key is in the same format as expected by
168+
linkgit:git-config[1] (e.g., `core.eol=true`). If multiple
169+
values are given for the same key, each value will be written to
170+
the config file. This makes it safe, for example, to add
171+
additional fetch refspecs to the origin remote.
172+
162173
--depth <depth>::
163174
Create a 'shallow' clone with a history truncated to the
164175
specified number of revisions. A shallow repository has a

builtin/clone.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static const char *real_git_dir;
4646
static char *option_upload_pack = "git-upload-pack";
4747
static int option_verbosity;
4848
static int option_progress;
49+
static struct string_list option_config;
4950

5051
static struct option builtin_clone_options[] = {
5152
OPT__VERBOSITY(&option_verbosity),
@@ -83,7 +84,8 @@ static struct option builtin_clone_options[] = {
8384
"create a shallow clone of that depth"),
8485
OPT_STRING(0, "separate-git-dir", &real_git_dir, "gitdir",
8586
"separate git dir from working tree"),
86-
87+
OPT_STRING_LIST('c', "config", &option_config, "key=value",
88+
"set config inside the new repository"),
8789
OPT_END()
8890
};
8991

@@ -364,6 +366,22 @@ static void write_remote_refs(const struct ref *local_refs)
364366
clear_extra_refs();
365367
}
366368

369+
static int write_one_config(const char *key, const char *value, void *data)
370+
{
371+
return git_config_set_multivar(key, value ? value : "true", "^$", 0);
372+
}
373+
374+
static void write_config(struct string_list *config)
375+
{
376+
int i;
377+
378+
for (i = 0; i < config->nr; i++) {
379+
if (git_config_parse_parameter(config->items[i].string,
380+
write_one_config, NULL) < 0)
381+
die("unable to write parameters to config file");
382+
}
383+
}
384+
367385
int cmd_clone(int argc, const char **argv, const char *prefix)
368386
{
369387
int is_bundle = 0, is_local;
@@ -482,6 +500,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
482500
printf(_("Cloning into %s...\n"), dir);
483501
}
484502
init_db(option_template, INIT_DB_QUIET);
503+
write_config(&option_config);
485504

486505
/*
487506
* At this point, the config exists, so we do not need the

builtin/remote.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,6 @@ static inline int postfixcmp(const char *string, const char *postfix)
8888
return strcmp(string + len1 - len2, postfix);
8989
}
9090

91-
static int opt_parse_track(const struct option *opt, const char *arg, int not)
92-
{
93-
struct string_list *list = opt->value;
94-
if (not)
95-
string_list_clear(list, 0);
96-
else
97-
string_list_append(list, arg);
98-
return 0;
99-
}
100-
10191
static int fetch_remote(const char *name)
10292
{
10393
const char *argv[] = { "fetch", name, NULL, NULL };
@@ -176,8 +166,8 @@ static int add(int argc, const char **argv)
176166
TAGS_SET),
177167
OPT_SET_INT(0, NULL, &fetch_tags,
178168
"or do not fetch any tag at all (--no-tags)", TAGS_UNSET),
179-
OPT_CALLBACK('t', "track", &track, "branch",
180-
"branch(es) to track", opt_parse_track),
169+
OPT_STRING_LIST('t', "track", &track, "branch",
170+
"branch(es) to track"),
181171
OPT_STRING('m', "master", &master, "branch", "master branch"),
182172
{ OPTION_CALLBACK, 0, "mirror", &mirror, "push|fetch",
183173
"set up remote as a mirror to push to or fetch from",

cache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,8 @@ extern int config_error_nonbool(const char *);
10821082
extern const char *get_log_output_encoding(void);
10831083
extern const char *get_commit_output_encoding(void);
10841084

1085+
extern int git_config_parse_parameter(const char *, config_fn_t fn, void *data);
1086+
10851087
extern const char *config_exclusive_filename;
10861088

10871089
#define MAX_GITNAME (1000)

config.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ void git_config_push_parameter(const char *text)
4747
strbuf_release(&env);
4848
}
4949

50-
static int git_config_parse_parameter(const char *text,
51-
config_fn_t fn, void *data)
50+
int git_config_parse_parameter(const char *text,
51+
config_fn_t fn, void *data)
5252
{
5353
struct strbuf **pair;
5454
pair = strbuf_split_str(text, '=', 2);

parse-options.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "cache.h"
44
#include "commit.h"
55
#include "color.h"
6+
#include "string-list.h"
67

78
static int parse_options_usage(struct parse_opt_ctx_t *ctx,
89
const char * const *usagestr,
@@ -687,3 +688,19 @@ int parse_options_concat(struct option *dst, size_t dst_size, struct option *src
687688
}
688689
return -1;
689690
}
691+
692+
int parse_opt_string_list(const struct option *opt, const char *arg, int unset)
693+
{
694+
struct string_list *v = opt->value;
695+
696+
if (unset) {
697+
string_list_clear(v, 0);
698+
return 0;
699+
}
700+
701+
if (!arg)
702+
return -1;
703+
704+
string_list_append(v, xstrdup(arg));
705+
return 0;
706+
}

parse-options.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ struct option {
130130
(h), PARSE_OPT_NOARG, NULL, (p) }
131131
#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), "n", (h) }
132132
#define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) }
133+
#define OPT_STRING_LIST(s, l, v, a, h) \
134+
{ OPTION_CALLBACK, (s), (l), (v), (a), \
135+
(h), 0, &parse_opt_string_list }
133136
#define OPT_UYN(s, l, v, h) { OPTION_CALLBACK, (s), (l), (v), NULL, \
134137
(h), PARSE_OPT_NOARG, &parse_opt_tertiary }
135138
#define OPT_DATE(s, l, v, h) \
@@ -204,6 +207,7 @@ extern int parse_opt_color_flag_cb(const struct option *, const char *, int);
204207
extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
205208
extern int parse_opt_with_commit(const struct option *, const char *, int);
206209
extern int parse_opt_tertiary(const struct option *, const char *, int);
210+
extern int parse_opt_string_list(const struct option *, const char *, int);
207211

208212
#define OPT__VERBOSE(var, h) OPT_BOOLEAN('v', "verbose", (var), (h))
209213
#define OPT__QUIET(var, h) OPT_BOOLEAN('q', "quiet", (var), (h))

t/t0040-parse-options.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ String options
2828
--st <st> get another string (pervert ordering)
2929
-o <str> get another string
3030
--default-string set string to default
31+
--list <str> add str to list
3132
3233
Magic arguments
3334
--quux means --quux
@@ -337,4 +338,20 @@ test_expect_success 'negation of OPT_NONEG flags is not ambiguous' '
337338
test_cmp expect output
338339
'
339340

341+
cat >>expect <<'EOF'
342+
list: foo
343+
list: bar
344+
list: baz
345+
EOF
346+
test_expect_success '--list keeps list of strings' '
347+
test-parse-options --list foo --list=bar --list=baz >output &&
348+
test_cmp expect output
349+
'
350+
351+
test_expect_success '--no-list resets list' '
352+
test-parse-options --list=other --list=irrelevant --list=options \
353+
--no-list --list=foo --list=bar --list=baz >output &&
354+
test_cmp expect output
355+
'
356+
340357
test_done

t/t5708-clone-config.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/sh
2+
3+
test_description='tests for git clone -c key=value'
4+
. ./test-lib.sh
5+
6+
test_expect_success 'clone -c sets config in cloned repo' '
7+
rm -rf child &&
8+
git clone -c core.foo=bar . child &&
9+
echo bar >expect &&
10+
git --git-dir=child/.git config core.foo >actual &&
11+
test_cmp expect actual
12+
'
13+
14+
test_expect_success 'clone -c can set multi-keys' '
15+
rm -rf child &&
16+
git clone -c core.foo=bar -c core.foo=baz . child &&
17+
{ echo bar; echo baz; } >expect &&
18+
git --git-dir=child/.git config --get-all core.foo >actual &&
19+
test_cmp expect actual
20+
'
21+
22+
test_expect_success 'clone -c without a value is boolean true' '
23+
rm -rf child &&
24+
git clone -c core.foo . child &&
25+
echo true >expect &&
26+
git --git-dir=child/.git config --bool core.foo >actual &&
27+
test_cmp expect actual
28+
'
29+
30+
test_expect_success 'clone -c config is available during clone' '
31+
echo content >file &&
32+
git add file &&
33+
git commit -m one &&
34+
rm -rf child &&
35+
git clone -c core.autocrlf . child &&
36+
printf "content\\r\\n" >expect &&
37+
test_cmp expect child/file
38+
'
39+
40+
test_done

test-parse-options.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "cache.h"
22
#include "parse-options.h"
3+
#include "string-list.h"
34

45
static int boolean = 0;
56
static int integer = 0;
@@ -9,6 +10,7 @@ static int verbose = 0, dry_run = 0, quiet = 0;
910
static char *string = NULL;
1011
static char *file = NULL;
1112
static int ambiguous;
13+
static struct string_list list;
1214

1315
static int length_callback(const struct option *opt, const char *arg, int unset)
1416
{
@@ -54,6 +56,7 @@ int main(int argc, const char **argv)
5456
OPT_STRING('o', NULL, &string, "str", "get another string"),
5557
OPT_SET_PTR(0, "default-string", &string,
5658
"set string to default", (unsigned long)"default"),
59+
OPT_STRING_LIST(0, "list", &list, "str", "add str to list"),
5760
OPT_GROUP("Magic arguments"),
5861
OPT_ARGUMENT("quux", "means --quux"),
5962
OPT_NUMBER_CALLBACK(&integer, "set integer to NUM",
@@ -85,6 +88,9 @@ int main(int argc, const char **argv)
8588
printf("dry run: %s\n", dry_run ? "yes" : "no");
8689
printf("file: %s\n", file ? file : "(not set)");
8790

91+
for (i = 0; i < list.nr; i++)
92+
printf("list: %s\n", list.items[i].string);
93+
8894
for (i = 0; i < argc; i++)
8995
printf("arg %02d: %s\n", i, argv[i]);
9096

0 commit comments

Comments
 (0)