summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/fetch-options.txt4
-rw-r--r--Documentation/git-fetch-pack.txt2
-rw-r--r--Documentation/technical/shallow.txt3
-rw-r--r--builtin/fetch.c17
-rw-r--r--commit.h3
-rwxr-xr-xt/t5500-fetch-pack.sh20
-rw-r--r--upload-pack.c13
7 files changed, 58 insertions, 4 deletions
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 6e98bdf149..7fea9a8ecd 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -13,6 +13,10 @@
to the specified number of commits from the tip of each remote
branch history. Tags for the deepened commits are not fetched.
+--unshallow::
+ Convert a shallow repository to a complete one, removing all
+ the limitations imposed by shallow repositories.
+
ifndef::git-pull[]
--dry-run::
Show what would be done, without making any changes.
diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt
index 8c751202d7..b81e90d8e7 100644
--- a/Documentation/git-fetch-pack.txt
+++ b/Documentation/git-fetch-pack.txt
@@ -84,6 +84,8 @@ be in a separate packet, and the list must end with a flush packet.
--depth=<n>::
Limit fetching to ancestor-chains not longer than n.
+ 'git-upload-pack' treats the special depth 2147483647 as
+ infinite even if there is an ancestor-chain that long.
--no-progress::
Do not show the progress.
diff --git a/Documentation/technical/shallow.txt b/Documentation/technical/shallow.txt
index 0502a5471e..ea2f69faf5 100644
--- a/Documentation/technical/shallow.txt
+++ b/Documentation/technical/shallow.txt
@@ -53,3 +53,6 @@ It also writes an appropriate $GIT_DIR/shallow.
You can deepen a shallow repository with "git-fetch --depth 20
repo branch", which will fetch branch from repo, but stop at depth
20, updating $GIT_DIR/shallow.
+
+The special depth 2147483647 (or 0x7fffffff, the largest positive
+number a signed 32-bit integer can contain) means infinite depth.
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 4b5a89839b..3b97fc9bc6 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -32,7 +32,7 @@ enum {
static int all, append, dry_run, force, keep, multiple, prune, update_head_ok, verbosity;
static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
-static int tags = TAGS_DEFAULT;
+static int tags = TAGS_DEFAULT, unshallow;
static const char *depth;
static const char *upload_pack;
static struct strbuf default_rla = STRBUF_INIT;
@@ -82,6 +82,9 @@ static struct option builtin_fetch_options[] = {
OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
OPT_STRING(0, "depth", &depth, N_("depth"),
N_("deepen history of shallow clone")),
+ { OPTION_SET_INT, 0, "unshallow", &unshallow, NULL,
+ N_("convert to a complete repository"),
+ PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1 },
{ OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, N_("dir"),
N_("prepend this to submodule path output"), PARSE_OPT_HIDDEN },
{ OPTION_STRING, 0, "recurse-submodules-default",
@@ -970,6 +973,18 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix,
builtin_fetch_options, builtin_fetch_usage, 0);
+ if (unshallow) {
+ if (depth)
+ die(_("--depth and --unshallow cannot be used together"));
+ else if (!is_repository_shallow())
+ die(_("--unshallow on a complete repository does not make sense"));
+ else {
+ static char inf_depth[12];
+ sprintf(inf_depth, "%d", INFINITE_DEPTH);
+ depth = inf_depth;
+ }
+ }
+
if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
if (recurse_submodules_default) {
int arg = parse_fetch_recurse_submodules_arg("--recurse-submodules-default", recurse_submodules_default);
diff --git a/commit.h b/commit.h
index 9f2131318d..0adfce96e4 100644
--- a/commit.h
+++ b/commit.h
@@ -163,6 +163,9 @@ extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *r
extern struct commit_list *get_merge_bases_many(struct commit *one, int n, struct commit **twos, int cleanup);
extern struct commit_list *get_octopus_merge_bases(struct commit_list *in);
+/* largest postive number a signed 32-bit integer can contain */
+#define INFINITE_DEPTH 0x7fffffff
+
extern int register_shallow(const unsigned char *sha1);
extern int unregister_shallow(const unsigned char *sha1);
extern int for_each_commit_graft(each_commit_graft_fn, void *);
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 6322e8ade8..426027ee92 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -264,6 +264,26 @@ test_expect_success 'clone shallow object count' '
grep "^count: 52" count.shallow
'
+test_expect_success 'fetch --no-shallow on full repo' '
+ test_must_fail git fetch --noshallow
+'
+
+test_expect_success 'fetch --depth --no-shallow' '
+ (
+ cd shallow &&
+ test_must_fail git fetch --depth=1 --noshallow
+ )
+'
+
+test_expect_success 'turn shallow to complete repository' '
+ (
+ cd shallow &&
+ git fetch --unshallow &&
+ ! test -f .git/shallow &&
+ git fsck --full
+ )
+'
+
test_expect_success 'clone shallow without --no-single-branch' '
git clone --depth 1 "file://$(pwd)/." shallow2
'
diff --git a/upload-pack.c b/upload-pack.c
index 2e90ccb74f..8740002817 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -670,10 +670,17 @@ static void receive_needs(void)
if (depth == 0 && shallows.nr == 0)
return;
if (depth > 0) {
- struct commit_list *result, *backup;
+ struct commit_list *result = NULL, *backup = NULL;
int i;
- backup = result = get_shallow_commits(&want_obj, depth,
- SHALLOW, NOT_SHALLOW);
+ if (depth == INFINITE_DEPTH)
+ for (i = 0; i < shallows.nr; i++) {
+ struct object *object = shallows.objects[i].item;
+ object->flags |= NOT_SHALLOW;
+ }
+ else
+ backup = result =
+ get_shallow_commits(&want_obj, depth,
+ SHALLOW, NOT_SHALLOW);
while (result) {
struct object *object = &result->item->object;
if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {