@matheusbsbs / matheus-bagliano / commits / bc699afcce
Fork 0

clone: Add an option to set up a mirror

The command line $ git clone --mirror $URL is now a short-hand for $ git clone --bare $URL $ (cd $(basename $URL) && git remote add --mirror origin $URL) Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Aug 2, 2008 at 21:38 UTC bc699afcce3c45bb17aaca145d081992ed699a42
4 files changed +37 -6
Documentation/git-clone.txt
+4 -1
@@ -10,7 +10,7 @@ SYNOPSIS
10 --------
11 [verse]
12 'git clone' [--template=<template_directory>]
13 - [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare]
13 + [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
14 [-o <name>] [-u <upload-pack>] [--reference <repository>]
15 [--depth <depth>] [--] <repository> [<directory>]
16
@@ -106,6 +106,9 @@ then the cloned repository will become corrupt.
106 used, neither remote-tracking branches nor the related
107 configuration variables are created.
108
109 +--mirror::
110 + Set up a mirror of the remote repository. This implies --bare.
111 +
112 --origin <name>::
113 -o <name>::
114 Instead of using the remote name 'origin' to keep track
builtin-clone.c
+20 -4
@@ -33,7 +33,7 @@ static const char * const builtin_clone_usage[] = {
33 NULL
34 };
35
36 -static int option_quiet, option_no_checkout, option_bare;
36 +static int option_quiet, option_no_checkout, option_bare, option_mirror;
37 static int option_local, option_no_hardlinks, option_shared;
38 static char *option_template, *option_reference, *option_depth;
39 static char *option_origin = NULL;
@@ -45,6 +45,8 @@ static struct option builtin_clone_options[] = {
45 "don't create a checkout"),
46 OPT_BOOLEAN(0, "bare", &option_bare, "create a bare repository"),
47 OPT_BOOLEAN(0, "naked", &option_bare, "create a bare repository"),
48 + OPT_BOOLEAN(0, "mirror", &option_mirror,
49 + "create a mirror repository (implies bare)"),
50 OPT_BOOLEAN('l', "local", &option_local,
51 "to clone from a local repository"),
52 OPT_BOOLEAN(0, "no-hardlinks", &option_no_hardlinks,
@@ -345,6 +347,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
347 char branch_top[256], key[256], value[256];
348 struct strbuf reflog_msg;
349 struct transport *transport = NULL;
350 + char *src_ref_prefix = "refs/heads/";
351
352 struct refspec refspec;
353
@@ -359,6 +362,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
362 if (option_no_hardlinks)
363 use_local_hardlinks = 0;
364
365 + if (option_mirror)
366 + option_bare = 1;
367 +
368 if (option_bare) {
369 if (option_origin)
370 die("--bare and --origin %s options are incompatible.",
@@ -440,26 +446,36 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
446 git_config(git_default_config, NULL);
447
448 if (option_bare) {
443 - strcpy(branch_top, "refs/heads/");
449 + if (option_mirror)
450 + src_ref_prefix = "refs/";
451 + strcpy(branch_top, src_ref_prefix);
452
453 git_config_set("core.bare", "true");
454 } else {
455 snprintf(branch_top, sizeof(branch_top),
456 "refs/remotes/%s/", option_origin);
457 + }
458
459 + if (option_mirror || !option_bare) {
460 /* Configure the remote */
461 + if (option_mirror) {
462 + snprintf(key, sizeof(key),
463 + "remote.%s.mirror", option_origin);
464 + git_config_set(key, "true");
465 + }
466 +
467 snprintf(key, sizeof(key), "remote.%s.url", option_origin);
468 git_config_set(key, repo);
469
470 snprintf(key, sizeof(key), "remote.%s.fetch", option_origin);
471 snprintf(value, sizeof(value),
456 - "+refs/heads/*:%s*", branch_top);
472 + "+%s*:%s*", src_ref_prefix, branch_top);
473 git_config_set_multivar(key, value, "^$", 0);
474 }
475
476 refspec.force = 0;
477 refspec.pattern = 1;
462 - refspec.src = "refs/heads/";
478 + refspec.src = src_ref_prefix;
479 refspec.dst = branch_top;
480
481 if (path && !is_bundle)
builtin-remote.c
+1 -1
@@ -115,7 +115,7 @@ static int add(int argc, const char **argv)
115 if (mirror) {
116 strbuf_reset(&buf);
117 strbuf_addf(&buf, "remote.%s.mirror", name);
118 - if (git_config_set(buf.buf, "yes"))
118 + if (git_config_set(buf.buf, "true"))
119 return 1;
120 }
121
t/t5601-clone.sh
+12
@@ -70,4 +70,16 @@ test_expect_success 'clone creates intermediate directories for bare repo' '
70
71 '
72
73 +test_expect_success 'clone --mirror' '
74 +
75 + git clone --mirror src mirror &&
76 + test -f mirror/HEAD &&
77 + test ! -f mirror/file &&
78 + FETCH="$(cd mirror && git config remote.origin.fetch)" &&
79 + test "+refs/*:refs/*" = "$FETCH" &&
80 + MIRROR="$(cd mirror && git config --bool remote.origin.mirror)" &&
81 + test "$MIRROR" = true
82 +
83 +'
84 +
85 test_done