{"thread":{"id":"6675","subject":"[PATCH] git-clone --reference: saner handling of borrowed symrefs.","startedAt":"2007-02-04T11:25:12Z","lastAt":"2007-02-04T11:25:12Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"33568","messageId":"7v64airwpz.fsf@assigned-by-dhcp.cox.net","threadId":"6675","inReplyTo":null,"subject":"[PATCH] git-clone --reference: saner handling of borrowed symrefs.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-04T11:25:12Z","receivedAt":"2007-02-04T11:25:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"When using --reference to borrow objects from a neighbouring\nrepository while cloning, we copy the entire set of refs under\ntemporary \"refs/reference-tmp/refs\" space and set up the object\nalternates.  However, a textual symref copied this way would not\npoint at the right place, and later steps emit error messages\n(which is harmless but still alarming and annoying).  This is\nmost visible when using a clone created with the separate-remote\nlayout as a reference, as such a repository would have\nrefs/remotes/origin/HEAD with 'ref: refs/remotes/origin/master'\nas its contents.\n\nAlthough we do not create symbolic-link based refs anymore, they\nhave the problem because they are always supposed to be relative\nto refs/ hierarchy (we dereference by hand, so it only is good\nfor HEAD and nothing else).\n\nIn either case, the solution is simply to remove them after\ncopying under refs/reference-tmp; if a symref points at a true\nref, that true ref itself is enough to ensure that objects\nreachable from it do not needlessly get fetched.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n git-clone.sh               |   29 ++++++++++++++++++++++++++++-\n t/t5700-clone-reference.sh |   40 +++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 67 insertions(+), 2 deletions(-)\n\ndiff --git a/git-clone.sh b/git-clone.sh\nindex 4ddfa77..1710996 100755\n--- a/git-clone.sh\n+++ b/git-clone.sh\n@@ -190,7 +190,34 @@ then\n \t\t(cd \"$GIT_DIR/refs\" &&\n \t\t mkdir reference-tmp &&\n \t\t cd reference-tmp &&\n-\t\t tar xf -)\n+\t\t tar xf - &&\n+\t\t find refs ! -type d -print |\n+\t\t while read ref\n+\t\t do\n+\t\t\tif test -h \"$ref\"\n+\t\t\tthen\n+\t\t\t\t# Old-style symbolic link ref.  Not likely\n+\t\t\t\t# to appear under refs/ but we might as well\n+\t\t\t\t# deal with them.\n+\t\t\t\t:\n+\t\t\telif test -f \"$ref\"\n+\t\t\tthen\n+\t\t\t\tpoint=$(cat \"$ref\") &&\n+\t\t\t\t\tcase \"$point\" in\n+\t\t\t\t\t'ref: '*) ;;\n+\t\t\t\t\t*) continue ;;\n+\t\t\t\t\tesac\n+\t\t\tfi\n+\t\t\t# The above makes true ref to 'continue' and\n+\t\t\t# we will come here when we are looking at\n+\t\t\t# symbolic link ref or a textual symref (or\n+\t\t\t# garbage, like fifo).\n+\t\t\t# The true ref pointed at by it is enough to\n+\t\t\t# ensure that we do not fetch objects reachable\n+\t\t\t# from it.\n+\t\t\trm -f \"$ref\"\n+\t\t done\n+\t\t)\n \telse\n \t\tdie \"reference repository '$reference' is not a local directory.\"\n \tfi\ndiff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh\nindex dd9caad..6d43252 100755\n--- a/t/t5700-clone-reference.sh\n+++ b/t/t5700-clone-reference.sh\n@@ -26,7 +26,7 @@ git prune'\n \n cd \"$base_dir\"\n \n-test_expect_success 'cloning with reference' \\\n+test_expect_success 'cloning with reference (-l -s)' \\\n 'git clone -l -s --reference B A C'\n \n cd \"$base_dir\"\n@@ -50,6 +50,28 @@ diff expected current'\n \n cd \"$base_dir\"\n \n+test_expect_success 'cloning with reference (no -l -s)' \\\n+'git clone --reference B A D'\n+\n+cd \"$base_dir\"\n+\n+test_expect_success 'existence of info/alternates' \\\n+'test `wc -l <D/.git/objects/info/alternates` = 1'\n+\n+cd \"$base_dir\"\n+\n+test_expect_success 'pulling from reference' \\\n+'cd D && git pull ../B'\n+\n+cd \"$base_dir\"\n+\n+test_expect_success 'that reference gets used' \\\n+'cd D && echo \"0 objects, 0 kilobytes\" > expected &&\n+git count-objects > current &&\n+diff expected current'\n+\n+cd \"$base_dir\"\n+\n test_expect_success 'updating origin' \\\n 'cd A &&\n echo third > file3 &&\n@@ -75,4 +97,20 @@ diff expected current'\n \n cd \"$base_dir\"\n \n+test_expect_success 'pulling changes from origin' \\\n+'cd D &&\n+git pull origin'\n+\n+cd \"$base_dir\"\n+\n+# the 5 local objects are expected; file3 blob, commit in A to add it\n+# and its tree, and 2 are our tree and the merge commit.\n+test_expect_success 'check objects expected to exist locally' \\\n+'cd D &&\n+echo \"5 objects\" > expected &&\n+git count-objects | cut -d, -f1 > current &&\n+diff expected current'\n+\n+cd \"$base_dir\"\n+\n test_done\n-- \n1.5.0.rc3.40.g2a08d-dirty\n"}]}