git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] Short-circuit git-clone-pack while cloning locally.

From
Junio C Hamano <junkio@cox.net>
Date
Jul 6, 2005, 08:14 UTC
Message-ID
<7v8y0kxsfq.fsf_-_@assigned-by-dhcp.cox.net>
In-Reply-To
<Pine.LNX.4.58.0507051721450.3570@g5.osdl.org>
>>>>> "LT" == Linus Torvalds <torvalds@osdl.org> writes:

LT> Anyway, as mentioned, you can certainly do a local clone a lot faster with LT> "cp -rl" (and yes, I'll apply Junio's patch if he makes it available LT> against the new version, and adds a flag to make it conditional),...

By invitation.

------------ 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 with -l and -c parameters it can be told to do the hard linkfarm and recursive file copy to replicate .git/object hierarchy.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 git-clone-script |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 79 insertions(+), 1 deletions(-)
1eb81b1791a751ca0fd1c3e7c1d4a4baacdd042a
diff --git a/git-clone-script b/git-clone-script
--- a/git-clone-script
+++ b/git-clone-script
@@ -1,4 +1,81 @@
 #!/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|-c|-p] <repo> <dir>"
+	exit 1
+}
+
+# what to do when running locally
+local_use=default
+while
+	case "$#,$1" in
+	0,*) break ;;
+	*,-l) local_use=link ;;
+	*,-c) local_use=copy ;;
+	*,-p) local_use=pack ;;
+	*,-*) 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)
+) || exit 1
+
+# See if repo is a local directory.
+is_local=f
+if (
+	cd "$repo/objects" 2>/dev/null
+)
+then
+	is_local=t
+fi
+
+case "$local_use,$is_local" in
+default,f)
+	;;
+*,f)	echo >&2 "-l|-c|-p flag can be used only when cloning a local repo"
+	exit 1
+	;;
+copy,t | link,t)
+	l=
+	case "$local_use" in
+	link)
+	    # 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
+
+	    if ln "$repo/$sample_file" "$D/.git/objects/sample" 2>/dev/null
+	    then
+		    l=l
+	    fi &&
+	    rm -f "$D/.git/objects/sample"
+	    ;;
+	esac &&
+	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
+	;;
+*)
+	cd "$D" && git clone-pack "$repo"
+	;;
+esac
Previous: Linus TorvaldsNext: Linus Torvalds
Message 11 of 14 in “expensive local git clone”
  1. David S. MillerJul 4, 2005
  2. Linus TorvaldsJul 4, 2005
  3. Petr BaudisJul 4, 2005
  4. David S. MillerJul 4, 2005
  5. Junio C HamanoJul 4, 2005
  6. David S. MillerJul 4, 2005
  7. Junio C HamanoJul 4, 2005
  8. Linus TorvaldsJul 4, 2005
  9. Short-cut git-fetch-pack while cloning locally.Junio C Hamano, Jul 5, 2005
  10. Linus TorvaldsJul 6, 2005
  11. Short-circuit git-clone-pack while cloning locally.Junio C Hamano, Jul 6, 2005
  12. Linus TorvaldsJul 6, 2005
  13. Junio C HamanoJul 6, 2005
  14. Short-circuit git-clone-pack while cloning locally (take 2).Junio C Hamano, Jul 6, 2005

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.