builtin/clone.c: add --reject-shallow option
In some scenarios, users may want more history than the repository offered for cloning, which happens to be a shallow repository, can give them. But because users don't know it is a shallow repository until they download it to local, we may want to refuse to clone this kind of repository, without creating any unnecessary files. The '--depth=x' option cannot be used as a solution; the source may be deep enough to give us 'x' commits when cloned, but the user may later need to deepen the history to arbitrary depth. Teach '--reject-shallow' option to "git clone" to abort as soon as we find out that we are cloning from a shallow repository. Signed-off-by: Li Linchao <lilinchao@oschina.cn> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
84d06cdc06
commit
4fe788b1b0
@ -50,6 +50,8 @@ static int option_no_checkout, option_bare, option_mirror, option_single_branch
|
||||
static int option_local = -1, option_no_hardlinks, option_shared;
|
||||
static int option_no_tags;
|
||||
static int option_shallow_submodules;
|
||||
static int option_reject_shallow = -1; /* unspecified */
|
||||
static int config_reject_shallow = -1; /* unspecified */
|
||||
static int deepen;
|
||||
static char *option_template, *option_depth, *option_since;
|
||||
static char *option_origin = NULL;
|
||||
@ -90,6 +92,8 @@ static struct option builtin_clone_options[] = {
|
||||
OPT__VERBOSITY(&option_verbosity),
|
||||
OPT_BOOL(0, "progress", &option_progress,
|
||||
N_("force progress reporting")),
|
||||
OPT_BOOL(0, "reject-shallow", &option_reject_shallow,
|
||||
N_("don't clone shallow repository")),
|
||||
OPT_BOOL('n', "no-checkout", &option_no_checkout,
|
||||
N_("don't create a checkout")),
|
||||
OPT_BOOL(0, "bare", &option_bare, N_("create a bare repository")),
|
||||
@ -858,6 +862,9 @@ static int git_clone_config(const char *k, const char *v, void *cb)
|
||||
free(remote_name);
|
||||
remote_name = xstrdup(v);
|
||||
}
|
||||
if (!strcmp(k, "clone.rejectshallow"))
|
||||
config_reject_shallow = git_config_bool(k, v);
|
||||
|
||||
return git_default_config(k, v, cb);
|
||||
}
|
||||
|
||||
@ -963,6 +970,7 @@ static int path_exists(const char *path)
|
||||
int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int is_bundle = 0, is_local;
|
||||
int reject_shallow = 0;
|
||||
const char *repo_name, *repo, *work_tree, *git_dir;
|
||||
char *path, *dir, *display_repo = NULL;
|
||||
int dest_exists, real_dest_exists = 0;
|
||||
@ -1156,6 +1164,15 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
*/
|
||||
git_config(git_clone_config, NULL);
|
||||
|
||||
/*
|
||||
* If option_reject_shallow is specified from CLI option,
|
||||
* ignore config_reject_shallow from git_clone_config.
|
||||
*/
|
||||
if (config_reject_shallow != -1)
|
||||
reject_shallow = config_reject_shallow;
|
||||
if (option_reject_shallow != -1)
|
||||
reject_shallow = option_reject_shallow;
|
||||
|
||||
/*
|
||||
* apply the remote name provided by --origin only after this second
|
||||
* call to git_config, to ensure it overrides all config-based values.
|
||||
@ -1216,6 +1233,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
if (filter_options.choice)
|
||||
warning(_("--filter is ignored in local clones; use file:// instead."));
|
||||
if (!access(mkpath("%s/shallow", path), F_OK)) {
|
||||
if (reject_shallow)
|
||||
die(_("source repository is shallow, reject to clone."));
|
||||
if (option_local > 0)
|
||||
warning(_("source repository is shallow, ignoring --local"));
|
||||
is_local = 0;
|
||||
@ -1227,6 +1246,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
|
||||
transport_set_option(transport, TRANS_OPT_KEEP, "yes");
|
||||
|
||||
if (reject_shallow)
|
||||
transport_set_option(transport, TRANS_OPT_REJECT_SHALLOW, "1");
|
||||
if (option_depth)
|
||||
transport_set_option(transport, TRANS_OPT_DEPTH,
|
||||
option_depth);
|
||||
|
Reference in New Issue
Block a user