Skip to content

Commit 84054f7

Browse files
peffgitster
authored andcommitted
clone: accept config options on the command line
Clone does all of init, "remote add", fetch, and checkout without giving the user a chance to intervene and set any configuration. This patch allows you to set config options in the newly created repository after the clone, but before we do any other operations. In many cases, this is a minor convenience over something like: git clone git://... git config core.whatever true But in some cases, it can bring extra efficiency by changing how the fetch or checkout work. For example, setting line-ending config before the checkout avoids having to re-checkout all of the contents with the correct line endings. It also provides a mechanism for passing information to remote helpers during a clone; the helpers may read the git config to influence how they operate. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 2496844 commit 84054f7

File tree

3 files changed

+71
-1
lines changed

3 files changed

+71
-1
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

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

0 commit comments

Comments
 (0)