diff options
-rw-r--r-- | Documentation/fetch-options.txt | 4 | ||||
-rw-r--r-- | Documentation/git-fetch-pack.txt | 2 | ||||
-rw-r--r-- | Documentation/technical/shallow.txt | 3 | ||||
-rw-r--r-- | builtin/fetch.c | 17 | ||||
-rw-r--r-- | commit.h | 3 | ||||
-rwxr-xr-x | t/t5500-fetch-pack.sh | 20 | ||||
-rw-r--r-- | upload-pack.c | 13 |
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); @@ -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))) { |