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

Re: Why is git-clone --reference so slow?

From
Junio C Hamano <junkio@cox.net>
Date
Feb 7, 2007, 10:03 UTC
Message-ID
<7vhcty8eui.fsf@assigned-by-dhcp.cox.net>
In-Reply-To
<1170676004.29759.767.camel@pmac.infradead.org>
David Woodhouse <dwmw2@infradead.org> writes:
> My DSL line sucks; I know this. But why is git-clone so bad at using it?
I did the same and it initially got 45MB pack (14.5k objects).

For my case, the reason was because the repository I used as the reference was pruned and packed its refs, and git-clone was not fully using the refs from the reference repository.

The following patch made it to be almost instantaneous. The resulting clone has 600kB pack (0.5k objects).

diff --git a/git-clone.sh b/git-clone.sh
index 1710996..1bd54de 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
Previous: David Woodhouse
Message 4 of 4 in “Why is git-clone --reference so slow?”
  1. David WoodhouseFeb 5, 2007
  2. Johannes SchindelinFeb 5, 2007
  3. David WoodhouseFeb 5, 2007
  4. Junio C HamanoFeb 7, 2007

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.