aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2007-02-07 02:10:56 -0800
committerJunio C Hamano <junkio@cox.net>2007-02-07 02:10:56 -0800
commit099c7837678361985ca9df1240cdaf6a42fc89f9 (patch)
treed0e384b03f958f3007a1593e8bf4f6b521e5db09
parent563b43ee45b87cf1e4bba99d3d0216f396d5c873 (diff)
downloadgit-099c7837678361985ca9df1240cdaf6a42fc89f9.tar.gz
git-099c7837678361985ca9df1240cdaf6a42fc89f9.tar.xz
git-clone --reference: work well with pack-ref'ed reference repository
Earlier we only used loose refs to anchor already existing objects. When cloning from a repository that forked relatively long time ago from the reference repository, this made the want/have exchange by fetch-pack to do unnecessary work. Signed-off-by: Junio C Hamano <junkio@cox.net>
-rwxr-xr-xgit-clone.sh56
1 files changed, 21 insertions, 35 deletions
diff --git a/git-clone.sh b/git-clone.sh
index 171099674..1bd54ded3 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -178,46 +178,32 @@ esac && export GIT_DIR && git-init ${template+"$template"} || usage
if test -n "$reference"
then
+ ref_git=
if test -d "$reference"
then
if test -d "$reference/.git/objects"
then
- reference="$reference/.git"
+ ref_git="$reference/.git"
+ elif test -d "$reference/objects"
+ then
+ ref_git="$reference"
fi
- reference=$(cd "$reference" && pwd)
- echo "$reference/objects" >"$GIT_DIR/objects/info/alternates"
- (cd "$reference" && tar cf - refs) |
- (cd "$GIT_DIR/refs" &&
- mkdir reference-tmp &&
- cd reference-tmp &&
- tar xf - &&
- find refs ! -type d -print |
- while read ref
- do
- if test -h "$ref"
- then
- # Old-style symbolic link ref. Not likely
- # to appear under refs/ but we might as well
- # deal with them.
- :
- elif test -f "$ref"
- then
- point=$(cat "$ref") &&
- case "$point" in
- 'ref: '*) ;;
- *) continue ;;
- esac
- fi
- # The above makes true ref to 'continue' and
- # we will come here when we are looking at
- # symbolic link ref or a textual symref (or
- # garbage, like fifo).
- # The true ref pointed at by it is enough to
- # ensure that we do not fetch objects reachable
- # from it.
- rm -f "$ref"
- done
- )
+ fi
+ if test -n "$ref_git"
+ then
+ ref_git=$(cd "$ref_git" && pwd)
+ echo "$ref_git/objects" >"$GIT_DIR/objects/info/alternates"
+ (
+ GIT_DIR="$ref_git" git for-each-ref \
+ --format='%(objectname) %(*objectname)'
+ ) |
+ while read a b
+ do
+ test -z "$a" ||
+ git update-ref "refs/reference-tmp/$a" "$a"
+ test -z "$b" ||
+ git update-ref "refs/reference-tmp/$b" "$b"
+ done
else
die "reference repository '$reference' is not a local directory."
fi