'git fetch' uses git transport to compress and transfer all the commits
even though they're on a local machine -- both very slow and space
consuming.
Setting 'alternates' before fetching solves the issue partially since
the commits no longer need to be transferred. The checkout is still slow
since git needs to recheck all of them.

Instead, just set 'alternates' and copy the refs manually. This is
pretty much what 'git clone --shared' does. And we can't use 'git clone'
because it refuses non-empty destinations.

This also makes it possible to use the same checkout method for shallow
clones with <git-1.9 (git-1.9 finally allows clones and fetches using
shallow repos).
---
 eclass/git-r3.eclass | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/eclass/git-r3.eclass b/eclass/git-r3.eclass
index c00b3a0..892ed07 100644
--- a/eclass/git-r3.eclass
+++ b/eclass/git-r3.eclass
@@ -458,13 +458,14 @@ git-r3_checkout() {
                # non-empty directories.
 
                git init --quiet || die
-               set -- git fetch --update-head-ok "${orig_repo}" \
-                       "refs/heads/*:refs/heads/*" \
-                       "refs/tags/*:refs/tags/*" \
-                       "refs/notes/*:refs/notes/*"
-
-               echo "${@}" >&2
-               "${@}" || die "git fetch into checkout dir failed"
+               # setup 'alternates' to avoid copying objects
+               echo "${orig_repo}/objects" > 
"${GIT_DIR}"/objects/info/alternates || die
+               # now copy the refs
+               # [htn]* safely catches heads, tags, notes without complaining
+               # on non-existing ones, and omits internal 'git-r3' ref
+               cp -R "${orig_repo}"/refs/[htn]* "${GIT_DIR}"/refs/ || die
+
+               # (no need to copy HEAD, we will set it via checkout)
 
                set -- git checkout --quiet
                if [[ ${remote_ref} ]]; then
-- 
1.8.3.2


Reply via email to