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>
This commit is contained in:
parent
372c767610
commit
bc699afcce
@ -10,7 +10,7 @@ SYNOPSIS
|
|||||||
--------
|
--------
|
||||||
[verse]
|
[verse]
|
||||||
'git clone' [--template=<template_directory>]
|
'git clone' [--template=<template_directory>]
|
||||||
[-l] [-s] [--no-hardlinks] [-q] [-n] [--bare]
|
[-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
|
||||||
[-o <name>] [-u <upload-pack>] [--reference <repository>]
|
[-o <name>] [-u <upload-pack>] [--reference <repository>]
|
||||||
[--depth <depth>] [--] <repository> [<directory>]
|
[--depth <depth>] [--] <repository> [<directory>]
|
||||||
|
|
||||||
@ -106,6 +106,9 @@ then the cloned repository will become corrupt.
|
|||||||
used, neither remote-tracking branches nor the related
|
used, neither remote-tracking branches nor the related
|
||||||
configuration variables are created.
|
configuration variables are created.
|
||||||
|
|
||||||
|
--mirror::
|
||||||
|
Set up a mirror of the remote repository. This implies --bare.
|
||||||
|
|
||||||
--origin <name>::
|
--origin <name>::
|
||||||
-o <name>::
|
-o <name>::
|
||||||
Instead of using the remote name 'origin' to keep track
|
Instead of using the remote name 'origin' to keep track
|
||||||
|
@ -33,7 +33,7 @@ static const char * const builtin_clone_usage[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static int option_quiet, option_no_checkout, option_bare;
|
static int option_quiet, option_no_checkout, option_bare, option_mirror;
|
||||||
static int option_local, option_no_hardlinks, option_shared;
|
static int option_local, option_no_hardlinks, option_shared;
|
||||||
static char *option_template, *option_reference, *option_depth;
|
static char *option_template, *option_reference, *option_depth;
|
||||||
static char *option_origin = NULL;
|
static char *option_origin = NULL;
|
||||||
@ -45,6 +45,8 @@ static struct option builtin_clone_options[] = {
|
|||||||
"don't create a checkout"),
|
"don't create a checkout"),
|
||||||
OPT_BOOLEAN(0, "bare", &option_bare, "create a bare repository"),
|
OPT_BOOLEAN(0, "bare", &option_bare, "create a bare repository"),
|
||||||
OPT_BOOLEAN(0, "naked", &option_bare, "create a bare repository"),
|
OPT_BOOLEAN(0, "naked", &option_bare, "create a bare repository"),
|
||||||
|
OPT_BOOLEAN(0, "mirror", &option_mirror,
|
||||||
|
"create a mirror repository (implies bare)"),
|
||||||
OPT_BOOLEAN('l', "local", &option_local,
|
OPT_BOOLEAN('l', "local", &option_local,
|
||||||
"to clone from a local repository"),
|
"to clone from a local repository"),
|
||||||
OPT_BOOLEAN(0, "no-hardlinks", &option_no_hardlinks,
|
OPT_BOOLEAN(0, "no-hardlinks", &option_no_hardlinks,
|
||||||
@ -345,6 +347,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||||||
char branch_top[256], key[256], value[256];
|
char branch_top[256], key[256], value[256];
|
||||||
struct strbuf reflog_msg;
|
struct strbuf reflog_msg;
|
||||||
struct transport *transport = NULL;
|
struct transport *transport = NULL;
|
||||||
|
char *src_ref_prefix = "refs/heads/";
|
||||||
|
|
||||||
struct refspec refspec;
|
struct refspec refspec;
|
||||||
|
|
||||||
@ -359,6 +362,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||||||
if (option_no_hardlinks)
|
if (option_no_hardlinks)
|
||||||
use_local_hardlinks = 0;
|
use_local_hardlinks = 0;
|
||||||
|
|
||||||
|
if (option_mirror)
|
||||||
|
option_bare = 1;
|
||||||
|
|
||||||
if (option_bare) {
|
if (option_bare) {
|
||||||
if (option_origin)
|
if (option_origin)
|
||||||
die("--bare and --origin %s options are incompatible.",
|
die("--bare and --origin %s options are incompatible.",
|
||||||
@ -440,26 +446,36 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||||||
git_config(git_default_config, NULL);
|
git_config(git_default_config, NULL);
|
||||||
|
|
||||||
if (option_bare) {
|
if (option_bare) {
|
||||||
strcpy(branch_top, "refs/heads/");
|
if (option_mirror)
|
||||||
|
src_ref_prefix = "refs/";
|
||||||
|
strcpy(branch_top, src_ref_prefix);
|
||||||
|
|
||||||
git_config_set("core.bare", "true");
|
git_config_set("core.bare", "true");
|
||||||
} else {
|
} else {
|
||||||
snprintf(branch_top, sizeof(branch_top),
|
snprintf(branch_top, sizeof(branch_top),
|
||||||
"refs/remotes/%s/", option_origin);
|
"refs/remotes/%s/", option_origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option_mirror || !option_bare) {
|
||||||
/* Configure the remote */
|
/* Configure the remote */
|
||||||
|
if (option_mirror) {
|
||||||
|
snprintf(key, sizeof(key),
|
||||||
|
"remote.%s.mirror", option_origin);
|
||||||
|
git_config_set(key, "true");
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(key, sizeof(key), "remote.%s.url", option_origin);
|
snprintf(key, sizeof(key), "remote.%s.url", option_origin);
|
||||||
git_config_set(key, repo);
|
git_config_set(key, repo);
|
||||||
|
|
||||||
snprintf(key, sizeof(key), "remote.%s.fetch", option_origin);
|
snprintf(key, sizeof(key), "remote.%s.fetch", option_origin);
|
||||||
snprintf(value, sizeof(value),
|
snprintf(value, sizeof(value),
|
||||||
"+refs/heads/*:%s*", branch_top);
|
"+%s*:%s*", src_ref_prefix, branch_top);
|
||||||
git_config_set_multivar(key, value, "^$", 0);
|
git_config_set_multivar(key, value, "^$", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
refspec.force = 0;
|
refspec.force = 0;
|
||||||
refspec.pattern = 1;
|
refspec.pattern = 1;
|
||||||
refspec.src = "refs/heads/";
|
refspec.src = src_ref_prefix;
|
||||||
refspec.dst = branch_top;
|
refspec.dst = branch_top;
|
||||||
|
|
||||||
if (path && !is_bundle)
|
if (path && !is_bundle)
|
||||||
|
@ -115,7 +115,7 @@ static int add(int argc, const char **argv)
|
|||||||
if (mirror) {
|
if (mirror) {
|
||||||
strbuf_reset(&buf);
|
strbuf_reset(&buf);
|
||||||
strbuf_addf(&buf, "remote.%s.mirror", name);
|
strbuf_addf(&buf, "remote.%s.mirror", name);
|
||||||
if (git_config_set(buf.buf, "yes"))
|
if (git_config_set(buf.buf, "true"))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,4 +70,16 @@ test_expect_success 'clone creates intermediate directories for bare repo' '
|
|||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'clone --mirror' '
|
||||||
|
|
||||||
|
git clone --mirror src mirror &&
|
||||||
|
test -f mirror/HEAD &&
|
||||||
|
test ! -f mirror/file &&
|
||||||
|
FETCH="$(cd mirror && git config remote.origin.fetch)" &&
|
||||||
|
test "+refs/*:refs/*" = "$FETCH" &&
|
||||||
|
MIRROR="$(cd mirror && git config --bool remote.origin.mirror)" &&
|
||||||
|
test "$MIRROR" = true
|
||||||
|
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user