clone: implement optional references
In a later patch we want to try to create alternates for submodules, but they might not exist in the referenced superproject. So add a way to skip the non existing references and report them. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Stefan Beller committed
Aug 15, 2016 at 14:53 UTC
f7415b4d71150d5c2d52f87c8792591237aaf00e
2 files changed
+29
-11
Documentation/git-clone.txt
+4
-1
@@ -90,13 +90,16 @@ If you want to break the dependency of a repository cloned with `-s` on
90
its source repository, you can simply run `git repack -a` to copy all
91
objects from the source repository into a pack in the cloned repository.
92
93
---reference <repository>::
93
+--reference[-if-able] <repository>::
94
If the reference repository is on the local machine,
95
automatically setup `.git/objects/info/alternates` to
96
obtain objects from the reference repository. Using
97
an already existing repository as an alternate will
98
require fewer objects to be copied from the repository
99
being cloned, reducing network and local storage costs.
100
+ When using the `--reference-if-able`, a non existing
101
+ directory is skipped with a warning instead of aborting
102
+ the clone.
103
+
104
*NOTE*: see the NOTE for the `--shared` option, and also the
105
`--dissociate` option.
builtin/clone.c
+25
-10
@@ -51,6 +51,7 @@ static int option_progress = -1;
51
static enum transport_family family;
52
static struct string_list option_config = STRING_LIST_INIT_NODUP;
53
static struct string_list option_required_reference = STRING_LIST_INIT_NODUP;
54
+static struct string_list option_optional_reference = STRING_LIST_INIT_NODUP;
55
static int option_dissociate;
56
static int max_jobs = -1;
57
@@ -81,6 +82,8 @@ static struct option builtin_clone_options[] = {
82
N_("directory from which templates will be used")),
83
OPT_STRING_LIST(0, "reference", &option_required_reference, N_("repo"),
84
N_("reference repository")),
85
+ OPT_STRING_LIST(0, "reference-if-able", &option_optional_reference,
86
+ N_("repo"), N_("reference repository")),
87
OPT_BOOL(0, "dissociate", &option_dissociate,
88
N_("use --reference only while cloning")),
89
OPT_STRING('o', "origin", &option_origin, N_("name"),
@@ -283,24 +286,36 @@ static void strip_trailing_slashes(char *dir)
286
static int add_one_reference(struct string_list_item *item, void *cb_data)
287
{
288
struct strbuf err = STRBUF_INIT;
286
- struct strbuf sb = STRBUF_INIT;
289
+ int *required = cb_data;
290
char *ref_git = compute_alternate_path(item->string, &err);
291
289
- if (!ref_git)
290
- die("%s", err.buf);
291
-
292
- strbuf_addf(&sb, "%s/objects", ref_git);
293
- add_to_alternates_file(sb.buf);
292
+ if (!ref_git) {
293
+ if (*required)
294
+ die("%s", err.buf);
295
+ else
296
+ fprintf(stderr,
297
+ _("info: Could not add alternate for '%s': %s\n"),
298
+ item->string, err.buf);
299
+ } else {
300
+ struct strbuf sb = STRBUF_INIT;
301
+ strbuf_addf(&sb, "%s/objects", ref_git);
302
+ add_to_alternates_file(sb.buf);
303
+ strbuf_release(&sb);
304
+ }
305
295
- free(ref_git);
306
strbuf_release(&err);
297
- strbuf_release(&sb);
307
+ free(ref_git);
308
return 0;
309
}
310
311
static void setup_reference(void)
312
{
303
- for_each_string_list(&option_required_reference, add_one_reference, NULL);
313
+ int required = 1;
314
+ for_each_string_list(&option_required_reference,
315
+ add_one_reference, &required);
316
+ required = 0;
317
+ for_each_string_list(&option_optional_reference,
318
+ add_one_reference, &required);
319
}
320
321
static void copy_alternates(struct strbuf *src, struct strbuf *dst,
@@ -952,7 +967,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
967
git_config_set(key.buf, repo);
968
strbuf_reset(&key);
969
955
- if (option_required_reference.nr)
970
+ if (option_required_reference.nr || option_optional_reference.nr)
971
setup_reference();
972
973
fetch_pattern = value.buf;