1. Stefan Saasen
  2. git

Commits

Gerrit Pape  committed 5274ba6

git-clone.sh: properly configure remote even if remote's head is dangling

When cloning a remote repository which's HEAD refers to a nonexistent
ref, git-clone cloned all existing refs, but failed to write the
configuration for 'remote'. Now it detects the dangling remote HEAD,
refuses to checkout any local branch since HEAD refers to nowhere, but
properly writes the configuration for 'remote', so that subsequent
'git fetch's don't fail.

The problem was reported by Daniel Jacobowitz through
http://bugs.debian.org/466581

Signed-off-by: Gerrit Pape <pape@smarden.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

  • Participants
  • Parent commits fbd538c
  • Branches master

Comments (0)

Files changed (2)

File git-clone.sh

View file
  • Ignore whitespace
 	cd "$D" || exit
 fi
 
-if test -z "$bare" && test -f "$GIT_DIR/REMOTE_HEAD"
+if test -z "$bare"
 then
 	# a non-bare repository is always in separate-remote layout
 	remote_top="refs/remotes/$origin"
-	head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"`
+	head_sha1=
+	test ! -r "$GIT_DIR/REMOTE_HEAD" || head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"`
 	case "$head_sha1" in
 	'ref: refs/'*)
 		# Uh-oh, the remote told us (http transport done against
 		git config branch."$head_points_at".merge "refs/heads/$head_points_at"
 		;;
 	'')
-		# Source had detached HEAD pointing nowhere
-		git update-ref --no-deref HEAD "$head_sha1" &&
-		rm -f "refs/remotes/$origin/HEAD"
+		if test -z "$head_sha1"
+		then
+			# Source had nonexistent ref in HEAD
+			echo >&2 "Warning: Remote HEAD refers to nonexistent ref, unable to checkout."
+			no_checkout=t
+		else
+			# Source had detached HEAD pointing nowhere
+			git update-ref --no-deref HEAD "$head_sha1" &&
+			rm -f "refs/remotes/$origin/HEAD"
+		fi
 		;;
 	esac
 

File t/t5701-clone-local.sh

View file
  • Ignore whitespace
 	test 0 = $copied
 '
 
+test_expect_success 'local clone of repo with nonexistent ref in HEAD' '
+	cd "$D" &&
+	echo "ref: refs/heads/nonexistent" > a.git/HEAD &&
+	git clone a d &&
+	cd d &&
+	git fetch &&
+	test ! -e .git/refs/remotes/origin/HEAD'
+
 test_done