From e95ab1edf38a0747832330cfa66763c25af9ad62 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 6 Jul 2005 13:04:21 -0700 Subject: [PATCH] [PATCH] Short-circuit git-clone-pack while cloning locally (take 2). When we are cloning a repository on a local filesystem, it is faster to just create a hard linkfarm of .git/object hierarchy and copy the .git/refs files. By default, the script uses the clone-pack method, but it can be told with the -l flag to do the hard linkfarm (falling back on recursive file copy) to replicate the .git/object hierarchy. Signed-off-by: Junio C Hamano Signed-off-by: Linus Torvalds --- git-clone-script | 68 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/git-clone-script b/git-clone-script index 28a9321269..4f80ade21c 100755 --- a/git-clone-script +++ b/git-clone-script @@ -1,4 +1,70 @@ #!/bin/sh +# +# Copyright (c) 2005, Linus Torvalds +# Copyright (c) 2005, Junio C Hamano +# +# Clone a repository into a different directory that does not yet exist. + +usage() { + echo >&2 "* git clone [-l] " + exit 1 +} + +use_local=no +while + case "$#,$1" in + 0,*) break ;; + *,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local) use_local=yes ;; + *,-*) usage ;; + *) break ;; + esac +do + shift +done + repo="$1" dir="$2" -mkdir "$dir" && cd "$dir" && git-init-db && git-clone-pack "$repo" +mkdir "$dir" && +D=$( + (cd "$dir" && git-init-db && pwd) +) && +test -d "$D" || usage + +# We do local magic only when the user tells us to. +case "$use_local" in +yes) + ( cd "$repo/objects" ) || { + repo="$repo/.git" + ( cd "$repo/objects" ) || { + echo >&2 "-l flag seen but $repo is not local." + exit 1 + } + } + + # See if we can hardlink and drop "l" if not. + sample_file=$(cd "$repo" && \ + find objects -type f -print | sed -e 1q) + + # objects directory should not be empty since we are cloning! + test -f "$repo/$sample_file" || exit + + l= + if ln "$repo/$sample_file" "$D/.git/objects/sample" 2>/dev/null + then + l=l + fi && + rm -f "$D/.git/objects/sample" && + cp -r$l "$repo/objects" "$D/.git/" || exit 1 + + # Make a duplicate of refs and HEAD pointer + HEAD= + if test -f "$repo/HEAD" + then + HEAD=HEAD + fi + tar Ccf "$repo" - refs $HEAD | tar Cxf "$D/.git" - || exit 1 + exit 0 + ;; +esac + +cd "$D" && git clone-pack "$repo"