Re: [PATCH v3 13/28] fetch: support fetching from a shallow repository

2013-11-27 Thread Eric Sunshine
On Sun, Nov 24, 2013 at 10:55 PM, Nguyễn Thái Ngọc Duy
pclo...@gmail.com wrote:
 diff --git a/t/t5536-fetch-shallow.sh b/t/t5536-fetch-shallow.sh
 new file mode 100755
 index 000..41de74d
 --- /dev/null
 +++ b/t/t5536-fetch-shallow.sh
 @@ -0,0 +1,128 @@
 +#!/bin/sh
 +
 +test_description='fetch/clone from a shallow clone'
 +
 +. ./test-lib.sh
 +
 +commit() {
 +   echo $1 tracked 
 +   git add tracked 
 +   git commit -m $1
 +}
 +
 +test_expect_success 'fetch something upstream has but hidden by clients 
 shallow boundaries' '
 +   # the blob 1 is available in .git but hidden by the
 +   # shallow2/.git/shallow and it should be resent
 +   ! git --git-dir=shallow2/.git cat-file blob `echo 1|git hash-object 
 --stdin` /dev/null 
 +   echo 1  1.t 

s/ //

 +   git add 1.t 
 +   git commit -m add-1-back 
 +   (
 +   cd shallow2 
 +   git fetch ../.git +refs/heads/master:refs/remotes/top/master 
 +   git fsck 
 +   git log --format=%s top/master actual 
 +   cat EOF expect 
 +add-1-back
 +4
 +3
 +EOF
 +   test_cmp expect actual
 +   ) 
 +   git --git-dir=shallow2/.git cat-file blob `echo 1|git hash-object 
 --stdin` /dev/null
 +
 +'
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 13/28] fetch: support fetching from a shallow repository

2013-11-24 Thread Nguyễn Thái Ngọc Duy
This patch just put together pieces from the previous patches:

 - Before getting the new pack, we need to remove all new reachable
   shallow roots. The remaining roots may or may not be added to
   .git/shallow.

 - After getting the pack, walk all new refs until they connect to
   current refs, or hit the bottom of current repo, or hit new
   shallow roots.

Those refs that hit new shallow roots are rejected because by default
we do not allow to update .git/shallow (the only exception so far is
cloning from a shallow repo, which is more like creating .git/shallow
than updating it)

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/fetch.c   |   9 +++
 fetch-pack.c  |  35 ++-
 remote.h  |   1 +
 t/t5536-fetch-shallow.sh (new +x) | 128 ++
 transport.c   |  11 +++-
 5 files changed, 179 insertions(+), 5 deletions(-)
 create mode 100755 t/t5536-fetch-shallow.sh

diff --git a/builtin/fetch.c b/builtin/fetch.c
index bd7a101..7b41a7e 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -405,6 +405,8 @@ static int iterate_ref_map(void *cb_data, unsigned char 
sha1[20])
struct ref **rm = cb_data;
struct ref *ref = *rm;
 
+   while (ref  ref-status == REF_STATUS_REJECT_SHALLOW)
+   ref = ref-next;
if (!ref)
return -1; /* end of the list */
*rm = ref-next;
@@ -451,6 +453,13 @@ static int store_updated_refs(const char *raw_url, const 
char *remote_name,
struct ref *ref = NULL;
const char *merge_status_marker = ;
 
+   if (rm-status == REF_STATUS_REJECT_SHALLOW) {
+   if (want_status == FETCH_HEAD_MERGE)
+   warning(_(reject %s because shallow 
roots are not allowed to be updated),
+   rm-peer_ref ? 
rm-peer_ref-name : rm-name);
+   continue;
+   }
+
commit = lookup_commit_reference_gently(rm-old_sha1, 
1);
if (!commit)
rm-fetch_head_status = 
FETCH_HEAD_NOT_FOR_MERGE;
diff --git a/fetch-pack.c b/fetch-pack.c
index b76581a..64fa5d2 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -855,7 +855,17 @@ static struct ref *do_fetch_pack(struct fetch_pack_args 
*args,
NULL);
else if (args-cloning  shallow  shallow-nr)
alternate_shallow_file = setup_temporary_shallow(shallow);
-   else
+   else if (!args-cloning  shallow  shallow-nr) {
+   struct extra_have_objects extra;
+   memset(extra, 0, sizeof(extra));
+   remove_reachable_shallow_points(extra, shallow);
+   if (extra.nr) {
+   alternate_shallow_file = 
setup_temporary_shallow(extra);
+   free(shallow-array);
+   *shallow = extra;
+   } else
+   alternate_shallow_file = NULL;
+   } else
alternate_shallow_file = NULL;
if (get_pack(args, fd, pack_lockfile))
die(git fetch-pack: fetch failed.);
@@ -929,8 +939,11 @@ static int remove_duplicates_in_refs(struct ref **ref, int 
nr)
 }
 
 static void update_shallow(struct fetch_pack_args *args,
+  struct ref **sought, int nr_sought,
   struct extra_have_objects *shallow)
 {
+   struct extra_have_objects ref;
+   int *status;
int i;
 
if (args-depth  0  alternate_shallow_file) {
@@ -977,6 +990,24 @@ static void update_shallow(struct fetch_pack_args *args,
free(extra.array);
return;
}
+
+   memset(ref, 0, sizeof(ref));
+   for (i = 0; i  nr_sought; i++)
+   add_extra_have(ref, sought[i]-old_sha1);
+
+   status = xcalloc(nr_sought, sizeof(*status));
+
+   /*
+* remote is also shallow, check what ref is safe to update
+* without updating .git/shallow
+*/
+   if (mark_new_shallow_refs(ref, status, NULL, shallow)) {
+   for (i = 0; i  nr_sought; i++)
+   if (status[i])
+   sought[i]-status = REF_STATUS_REJECT_SHALLOW;
+   }
+   free(status);
+   free(ref.array);
 }
 
 struct ref *fetch_pack(struct fetch_pack_args *args,
@@ -1000,6 +1031,6 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought,
shallow, pack_lockfile);
reprepare_packed_git();
-   update_shallow(args, shallow);
+   update_shallow(args, sought, nr_sought, shallow);
return ref_cpy;
 }
diff --git a/remote.h b/remote.h
index ff604ff..e519c26 100644
--- a/remote.h
+++