@@ -4,4 +4,5 @@ clone.defaultRemoteName::
option to linkgit:git-clone[1].
clone.rejectshallow::
- Reject to clone a repository if it is a shallow one.
+ Reject to clone a repository if it is a shallow one, can be overridden by
+ passing option `--reject-shallow` in command line. See linkgit:git-clone[1]
@@ -15,7 +15,7 @@ SYNOPSIS
[--dissociate] [--separate-git-dir <git dir>]
[--depth <depth>] [--[no-]single-branch] [--no-tags]
[--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules]
- [--[no-]remote-submodules] [--jobs <n>] [--sparse] [--no-shallow]
+ [--[no-]remote-submodules] [--jobs <n>] [--sparse] [--reject-shallow]
[--filter=<filter>] [--] <repository>
[<directory>]
@@ -149,11 +149,23 @@ objects from the source repository into a pack in the cloned repository.
--no-checkout::
No checkout of HEAD is performed after the clone is complete.
---no-shallow::
- Don't clone a shallow source repository. In some scenariors, clients
+--reject-shallow::
+ Don't clone a shallow source repository. In some scenarios, clients
want the cloned repository information to be complete. Otherwise,
the cloning process should end immediately without creating any files,
- which can save some disk space.
+ which can save some disk space. This can override `clone.rejectshallow`
+ from the configuration:
+
+ --------------------------------------------------------------------
+ $ git -c clone.rejectshallow=false clone --reject-shallow source out
+ --------------------------------------------------------------------
+
+ While there is a way to countermand a configured "I always refuse to
+ clone from a shallow repository" with "but let's allow it only this time":
+
+ ----------------------------------------------------------------------
+ $ git -c clone.rejectshallow=true clone --no-reject-shallow source out
+ ----------------------------------------------------------------------
--bare::
Make a 'bare' Git repository. That is, instead of
old mode 100755
new mode 100644
@@ -50,7 +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_no_shallow;
+static int option_no_shallow = -1; /* unspecified */
+static int config_shallow = -1; /* unspecified */
static int deepen;
static char *option_template, *option_depth, *option_since;
static char *option_origin = NULL;
@@ -91,7 +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, "no-shallow", &option_no_shallow, N_("don't clone shallow repository")),
+ OPT_BOOL(0, "reject-shallow", &option_no_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")),
@@ -861,7 +863,7 @@ static int git_clone_config(const char *k, const char *v, void *cb)
remote_name = xstrdup(v);
}
if (!strcmp(k, "clone.rejectshallow")) {
- option_no_shallow = 1;
+ config_shallow = git_config_bool(k, v);
}
return git_default_config(k, v, cb);
}
@@ -1211,6 +1213,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
path = get_repo_path(remote->url[0], &is_bundle);
is_local = option_local != 0 && path && !is_bundle;
+
+ /* Detect if the remote repository is shallow */
+ if (!access(mkpath("%s/shallow", path), F_OK)) {
+ is_shallow = 1;
+ }
+
if (is_local) {
if (option_depth)
warning(_("--depth is ignored in local clones; use file:// instead."));
@@ -1220,8 +1228,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
warning(_("--shallow-exclude is ignored in local clones; use file:// instead."));
if (filter_options.choice)
warning(_("--filter is ignored in local clones; use file:// instead."));
- if (!access(mkpath("%s/shallow", path), F_OK)) {
- is_shallow = 1;
+ if (is_shallow) {
if (option_local > 0)
warning(_("source repository is shallow, ignoring --local"));
is_local = 0;
@@ -1231,8 +1238,21 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
warning(_("--local is ignored"));
if (is_shallow) {
- if (option_no_shallow)
+ int reject = 0;
+
+ /* If option_no_shallow is specified from CLI option,
+ * ignore config_shallow from git_clone_config.
+ */
+
+ if (config_shallow != -1) {
+ reject = config_shallow;
+ }
+ if (option_no_shallow != -1) {
+ reject = option_no_shallow;
+ }
+ if (reject) {
die(_("source repository is shallow, reject to clone."));
+ }
}
transport->cloning = 1;
@@ -45,13 +45,42 @@ test_expect_success 'disallows --bare with --separate-git-dir' '
'
-test_expect_success 'reject clone shallow repository' '
+test_expect_success 'fail to clone shallow repository' '
git clone --depth=1 --no-local parent shallow-repo &&
- test_must_fail git clone --no-shallow shallow-repo out 2>err &&
+ test_must_fail git clone --reject-shallow shallow-repo out 2>err &&
test_i18ngrep -e "source repository is shallow, reject to clone." err
'
+test_expect_success 'fail to clone non-local shallow repository' '
+ rm -rf shallow-repo &&
+ git clone --depth=1 --no-local parent shallow-repo &&
+ test_must_fail git clone --reject-shallow --no-local shallow-repo out 2>err &&
+ test_i18ngrep -e "source repository is shallow, reject to clone." err
+
+'
+
+test_expect_success 'clone shallow repository with --no-reject-shallow' '
+ rm -rf shallow-repo &&
+ git clone --depth=1 --no-local parent shallow-repo &&
+ git clone --no-reject-shallow --no-local shallow-repo clone-repo
+
+'
+
+test_expect_success 'clone normal repository with --reject-shallow' '
+ rm -rf clone-repo &&
+ git clone --no-local parent normal-repo &&
+ git clone --reject-shallow --no-local normal-repo clone-repo
+
+'
+
+test_expect_success 'unspecified any configs or options' '
+ rm -rf shallow-repo clone-repo &&
+ git clone --depth=1 --no-local parent shallow-repo &&
+ git clone shallow-repo clone-repo
+
+'
+
test_expect_success 'uses "origin" for default remote name' '
git clone parent clone-default-origin &&
@@ -95,13 +95,38 @@ test_expect_success 'clone -c remote.<remote>.fetch=<refspec> --origin=<name>' '
test_cmp expect actual
'
-test_expect_success 'clone -c clone.rejectshallow' '
+test_expect_success 'clone.rejectshallow=true should fail to clone' '
rm -rf child &&
git clone --depth=1 --no-local . child &&
- test_must_fail git clone -c clone.rejectshallow child out 2>err &&
+ test_must_fail git -c clone.rejectshallow=true clone --no-local child out 2>err &&
test_i18ngrep -e "source repository is shallow, reject to clone." err
'
+test_expect_success 'clone.rejectshallow=false should succeed cloning' '
+ rm -rf child &&
+ git clone --depth=1 --no-local . child &&
+ git -c clone.rejectshallow=false clone --no-local child out
+'
+
+test_expect_success 'clone.rejectshallow=true should succeed cloning normal repo' '
+ rm -rf child out &&
+ git clone --no-local . child &&
+ git -c clone.rejectshallow=true clone --no-local child out
+'
+
+test_expect_success 'option --reject-shallow override clone.rejectshallow' '
+ rm -rf child out &&
+ git clone --depth=1 --no-local . child &&
+ test_must_fail git clone -c clone.rejectshallow=false --reject-shallow --no-local child out 2>err &&
+ test_i18ngrep -e "source repository is shallow, reject to clone." err
+'
+
+test_expect_success ' option --no-reject-shallow override clone.rejectshallow' '
+ rm -rf child &&
+ git clone --depth=1 --no-local . child &&
+ git -c clone.rejectshallow=true clone --no-reject-shallow --no-local child out
+'
+
test_expect_success MINGW 'clone -c core.hideDotFiles' '
test_commit attributes .gitattributes "" &&
rm -rf child &&