Skip to content

Commit

Permalink
fetch: add --unshallow for turning shallow repo into complete one
Browse files Browse the repository at this point in the history
The user can do --depth=2147483647 (*) for restoring complete repo
now. But it's hard to remember. Any other numbers larger than the
longest commit chain in the repository would also do, but some
guessing may be involved. Make easy-to-remember --unshallow an alias
for --depth=2147483647.

Make upload-pack recognize this special number as infinite depth. The
effect is essentially the same as before, except that upload-pack is
more efficient because it does not have to traverse to the bottom
anymore.

The chance of a user actually wanting exactly 2147483647 commits
depth, not infinite, on a repository with a history that long, is
probably too small to consider. The client can learn to add or
subtract one commit to avoid the special treatment when that actually
happens.

(*) This is the largest positive number a 32-bit signed integer can
    contain. JGit and older C Git store depth as "int" so both are OK
    with this number. Dulwich does not support shallow clone.

Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
pclouds authored and gitster committed Jan 11, 2013
1 parent 1599999 commit 4dcb167
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 4 deletions.
4 changes: 4 additions & 0 deletions Documentation/fetch-options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions Documentation/git-fetch-pack.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions Documentation/technical/shallow.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
17 changes: 16 additions & 1 deletion builtin/fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions commit.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down
20 changes: 20 additions & 0 deletions t/t5500-fetch-pack.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
'
Expand Down
13 changes: 10 additions & 3 deletions upload-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))) {
Expand Down

0 comments on commit 4dcb167

Please sign in to comment.