Merge branch 'nd/shallow-clone'
authorJunio C Hamano <gitster@pobox.com>
Fri, 17 Jan 2014 20:21:14 +0000 (12:21 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 17 Jan 2014 20:21:20 +0000 (12:21 -0800)
Fetching from a shallow-cloned repository used to be forbidden,
primarily because the codepaths involved were not carefully vetted
and we did not bother supporting such usage. This attempts to allow
object transfer out of a shallow-cloned repository in a controlled
way (i.e. the receiver become a shallow repository with truncated
history).

* nd/shallow-clone: (31 commits)
t5537: fix incorrect expectation in test case 10
shallow: remove unused code
send-pack.c: mark a file-local function static
git-clone.txt: remove shallow clone limitations
prune: clean .git/shallow after pruning objects
clone: use git protocol for cloning shallow repo locally
send-pack: support pushing from a shallow clone via http
receive-pack: support pushing to a shallow clone via http
smart-http: support shallow fetch/clone
remote-curl: pass ref SHA-1 to fetch-pack as well
send-pack: support pushing to a shallow clone
receive-pack: allow pushes that update .git/shallow
connected.c: add new variant that runs with --shallow-file
add GIT_SHALLOW_FILE to propagate --shallow-file to subprocesses
receive/send-pack: support pushing from a shallow clone
receive-pack: reorder some code in unpack()
fetch: add --update-shallow to accept refs that update .git/shallow
upload-pack: make sure deepening preserves shallow roots
fetch: support fetching from a shallow repository
clone: support remote shallow repository
...

25 files changed:
1  2 
Documentation/config.txt
Documentation/fetch-options.txt
builtin/clone.c
builtin/fetch-pack.c
builtin/fetch.c
builtin/gc.c
builtin/prune.c
builtin/receive-pack.c
builtin/send-pack.c
cache.h
commit.h
connect.c
connected.c
environment.c
fetch-pack.c
fetch-pack.h
git.c
remote-curl.c
remote.h
send-pack.c
shallow.c
t/t5601-clone.sh
transport-helper.c
transport.c
upload-pack.c
Simple merge
Simple merge
diff --cc builtin/clone.c
Simple merge
index 8b8978a25287bce6c4f937ff52df6cb7ae8e429e,81fae380e8ad8a3c2b32b023fce54cb126b81392..1262b405f8212e71d088f4e090b8121fa304699a
@@@ -150,18 -163,14 +167,18 @@@ int cmd_fetch_pack(int argc, const cha
                fd[0] = 0;
                fd[1] = 1;
        } else {
 +              int flags = args.verbose ? CONNECT_VERBOSE : 0;
 +              if (args.diag_url)
 +                      flags |= CONNECT_DIAG_URL;
                conn = git_connect(fd, dest, args.uploadpack,
 -                                 args.verbose ? CONNECT_VERBOSE : 0);
 +                                 flags);
 +              if (!conn)
 +                      return args.diag_url ? 0 : 1;
        }
-       get_remote_heads(fd[0], NULL, 0, &ref, 0, NULL);
 -
+       get_remote_heads(fd[0], NULL, 0, &ref, 0, NULL, &shallow);
  
-       ref = fetch_pack(&args, fd, conn, ref, dest,
-                        sought, nr_sought, pack_lockfile_ptr);
+       ref = fetch_pack(&args, fd, conn, ref, dest, sought, nr_sought,
+                        &shallow, pack_lockfile_ptr);
        if (pack_lockfile) {
                printf("lock %s\n", pack_lockfile);
                fflush(stdout);
diff --cc builtin/fetch.c
Simple merge
diff --cc builtin/gc.c
Simple merge
diff --cc builtin/prune.c
Simple merge
index e09994f4dfa3a50ea285ad20d61dd845f4bea357,bc4f5dc4632350c39972a0c1c589f10f90b120df..85bba356fab7743506f00bb0c5ca955eb9112bd5
@@@ -766,6 -852,14 +852,14 @@@ static struct command *read_head_info(s
                line = packet_read_line(0, &len);
                if (!line)
                        break;
 -              if (len == 48 && !prefixcmp(line, "shallow ")) {
++              if (len == 48 && starts_with(line, "shallow ")) {
+                       if (get_sha1_hex(line + 8, old_sha1))
+                               die("protocol error: expected shallow sha, got '%s'", line + 8);
+                       sha1_array_append(shallow, old_sha1);
+                       continue;
+               }
                if (len < 83 ||
                    line[40] != ' ' ||
                    line[81] != ' ' ||
Simple merge
diff --cc cache.h
Simple merge
diff --cc commit.h
Simple merge
diff --cc connect.c
index c763eeda863d62093a9f37d281e8b1afc1a1e254,efadd3cbeb0c95f00c7ffd3d1d8d01eae0d9e483..4150412e2c0ebf6129137baf41c9d268d50c60bd
+++ b/connect.c
@@@ -145,9 -140,18 +140,18 @@@ struct ref **get_remote_heads(int in, c
                if (!len)
                        break;
  
 -              if (len > 4 && !prefixcmp(buffer, "ERR "))
 +              if (len > 4 && starts_with(buffer, "ERR "))
                        die("remote error: %s", buffer + 4);
  
 -              if (len == 48 && !prefixcmp(buffer, "shallow ")) {
++              if (len == 48 && starts_with(buffer, "shallow ")) {
+                       if (get_sha1_hex(buffer + 8, old_sha1))
+                               die("protocol error: expected shallow sha-1, got '%s'", buffer + 8);
+                       if (!shallow_points)
+                               die("repository on the other end cannot be shallow");
+                       sha1_array_append(shallow_points, old_sha1);
+                       continue;
+               }
                if (len < 42 || get_sha1_hex(buffer, old_sha1) || buffer[40] != ' ')
                        die("protocol error: expected sha/ref, got '%s'", buffer);
                name = buffer + 41;
diff --cc connected.c
Simple merge
diff --cc environment.c
Simple merge
diff --cc fetch-pack.c
Simple merge
diff --cc fetch-pack.h
index 20ccc12e57b9499b0716c8295b4adea38d8d2a86,ada02f51c162a72d58782f315e648f2de8340d61..bb7fd76e5939d812f1f89b787324ae6ec519ca15
@@@ -8,19 -10,20 +10,21 @@@ struct fetch_pack_args 
        const char *uploadpack;
        int unpacklimit;
        int depth;
-       unsigned quiet:1,
-               keep_pack:1,
-               lock_pack:1,
-               use_thin_pack:1,
-               fetch_all:1,
-               stdin_refs:1,
-               diag_url:1,
-               verbose:1,
-               no_progress:1,
-               include_tag:1,
-               stateless_rpc:1,
-               check_self_contained_and_connected:1,
-               self_contained_and_connected:1;
+       unsigned quiet:1;
+       unsigned keep_pack:1;
+       unsigned lock_pack:1;
+       unsigned use_thin_pack:1;
+       unsigned fetch_all:1;
+       unsigned stdin_refs:1;
++      unsigned diag_url:1;
+       unsigned verbose:1;
+       unsigned no_progress:1;
+       unsigned include_tag:1;
+       unsigned stateless_rpc:1;
+       unsigned check_self_contained_and_connected:1;
+       unsigned self_contained_and_connected:1;
+       unsigned cloning:1;
+       unsigned update_shallow:1;
  };
  
  /*
diff --cc git.c
Simple merge
diff --cc remote-curl.c
Simple merge
diff --cc remote.h
Simple merge
diff --cc send-pack.c
Simple merge
diff --cc shallow.c
index 961cf6f02480e04d1baebb8f508aa17c5fea6355,e483780d4916a817e5256ec325e6cbcf31eb9328..bbc98b55c07969474b0afb01d9c4da70455f1903
+++ b/shallow.c
@@@ -90,9 -99,13 +99,12 @@@ struct commit_list *get_shallow_commits
                                cur_depth = *(int *)commit->util;
                        }
                }
 -              if (parse_commit(commit))
 -                      die("invalid commit");
 +              parse_commit_or_die(commit);
                cur_depth++;
-               if (cur_depth >= depth) {
+               if ((depth != INFINITE_DEPTH && cur_depth >= depth) ||
+                   (is_repository_shallow() && !commit->parents &&
+                    (graft = lookup_commit_graft(commit->object.sha1)) != NULL &&
+                    graft->nr_parent < 0)) {
                        commit_list_insert(commit, &result);
                        commit->object.flags |= shallow_flag;
                        commit = NULL;
Simple merge
Simple merge
diff --cc transport.c
Simple merge
diff --cc upload-pack.c
Simple merge