[PATCH] add --remote option to git-clone.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



It is sometimes useful to track, and develop against, a single
topic branch from the remote repository.
Make this easier to do by adding a flag to git-clone.

Signed-off-by: Michael S. Tsirkin <mst@xxxxxxxxxxxxxx>

---

We have a repository with several long-lived topic branches.

I'm often annoyed by the fact that when I clone from this repository,
I get a copy of all topic branches and origin tracking master
by default, when I actually might only want to work on a different
topic. And getting all extra branches is annoying on a slow connection.

So here's the patch to only get a single branch on clone.
Other branches can be added later, on demand.

Junio, what do you think?
I would like very much for git to support this capability.

diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 707376f..f66a969 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -10,8 +10,8 @@ SYNOPSIS
 --------
 [verse]
 'git-clone' [--template=<template_directory>] [-l [-s]] [-q] [-n] [--bare]
-	  [-o <name>] [-u <upload-pack>] [--reference <repository>]
-	  [--depth=<depth>] <repository> [<directory>]
+	  [-o <name>] [-u <upload-pack>] [--remote <remote-branch>]
+	  [--reference <repository>] [--depth=<depth>] <repository> [<directory>]
 
 DESCRIPTION
 -----------
@@ -84,6 +84,10 @@ OPTIONS
 	Instead of using the remote name 'origin' to keep track
 	of the upstream repository, use <name> instead.
 
+--remote <remote-branch>::
+	When given, only the specified remote branch will be
+	tracked; if unset all remote branches are tracked.
+
 --upload-pack <upload-pack>::
 -u <upload-pack>::
 	When given, and the repository to clone from is handled
diff --git a/git-clone.sh b/git-clone.sh
index 4ddfa77..b0fe7d1 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -14,7 +14,7 @@ die() {
 }
 
 usage() {
-	die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] <repo> [<dir>]"
+	die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--remote <remote-branch>] [--origin <name>] [--depth <n>] [-n] <repo> [<dir>]"
 }
 
 get_repo_base() {
@@ -78,6 +78,8 @@ reference=
 origin=
 origin_override=
 use_separate_remote=t
+remote_branch=
+all_remote_branches="--all"
 depth=
 while
 	case "$#,$1" in
@@ -104,6 +106,10 @@ while
 		shift; reference="$1" ;;
 	*,--reference=*)
 		reference=`expr "z$1" : 'z--reference=\(.*\)'` ;;
+	*,--remote)
+		remote_branch="$2"
+		all_remote_branches=
+	       	shift ;;
 	*,-o|*,--or|*,--ori|*,--orig|*,--origi|*,--origin)
 		case "$2" in
 		'')
@@ -227,7 +233,7 @@ yes,yes)
 	    echo "$repo/objects" >> "$GIT_DIR/objects/info/alternates"
 	    ;;
 	esac
-	git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
+	git-ls-remote "$repo" $remote_branch >"$GIT_DIR/CLONE_HEAD" || exit 1
 	;;
 *)
 	case "$repo" in
@@ -261,7 +267,7 @@ yes,yes)
 		    done
 		    rm -f "$GIT_DIR/TMP_ALT"
 		fi
-		git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
+		git-ls-remote "$repo" $remote_branch >"$GIT_DIR/CLONE_HEAD" || exit 1
 		;;
 	https://*|http://*|ftp://*)
 		case "$depth" in
@@ -277,8 +283,8 @@ yes,yes)
 		;;
 	*)
 		case "$upload_pack" in
-		'') git-fetch-pack --all -k $quiet $depth "$repo" ;;
-		*) git-fetch-pack --all -k $quiet "$upload_pack" $depth "$repo" ;;
+		'') git-fetch-pack $all_remote_branches -k $quiet $depth "$repo" $remote_branch;;
+		*) git-fetch-pack $all_remote_branches -k $quiet "$upload_pack" $depth "$repo" $remote_branch;;
 		esac >"$GIT_DIR/CLONE_HEAD" ||
 			die "fetch-pack from '$repo' failed."
 		;;
@@ -304,6 +310,9 @@ then
 			continue ;;
 		HEAD)
 			destname="REMOTE_HEAD" ;;
+		refs/heads/$remote_branch)
+			git-update-ref -m "clone: from $repo" "REMOTE_HEAD" "$sha1" ""
+			destname="refs/$branch_top/${name#refs/heads/}" ;;
 		refs/heads/*)
 			destname="refs/$branch_top/${name#refs/heads/}" ;;
 		refs/tags/*)
@@ -334,25 +343,32 @@ then
 	esac
 
 	# The name under $remote_top the remote HEAD seems to point at.
-	head_points_at=$(
-		(
-			test -f "$GIT_DIR/$remote_top/master" && echo "master"
-			cd "$GIT_DIR/$remote_top" &&
-			find . -type f -print | sed -e 's/^\.\///'
-		) | (
-		done=f
-		while read name
-		do
-			test t = $done && continue
-			branch_tip=`cat "$GIT_DIR/$remote_top/$name"`
-			if test "$head_sha1" = "$branch_tip"
-			then
-				echo "$name"
-				done=t
-			fi
-		done
+	if
+		test $remote_branch
+	then
+		head_points_at=$remote_branch
+		head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"`
+	else
+		head_points_at=$(
+			(
+				test -f "$GIT_DIR/$remote_top/master" && echo "master"
+				cd "$GIT_DIR/$remote_top" &&
+				find . -type f -print | sed -e 's/^\.\///'
+			) | (
+			done=f
+			while read name
+			do
+				test t = $done && continue
+				branch_tip=`cat "$GIT_DIR/$remote_top/$name"`
+				if test "$head_sha1" = "$branch_tip"
+				then
+					echo "$name"
+					done=t
+				fi
+			done
+			)
 		)
-	)
+	fi
 
 	# Write out remote.$origin config, and update our "$head_points_at".
 	case "$head_points_at" in
@@ -368,11 +384,18 @@ then
 		git-config remote."$origin".url "$repo" &&
 
 		# Set up the mappings to track the remote branches.
-		git-config remote."$origin".fetch \
-			"+refs/heads/*:$remote_top/*" '^$' &&
-		rm -f "refs/remotes/$origin/HEAD"
-		git-symbolic-ref "refs/remotes/$origin/HEAD" \
-			"refs/remotes/$origin/$head_points_at" &&
+		(if
+			test $remote_branch
+		then
+			git-config remote."$origin".fetch \
+				"+refs/heads/$remote_branch:$remote_top/$remote_branch" '^$'
+		else
+			git-config remote."$origin".fetch \
+				"+refs/heads/*:$remote_top/*" '^$' &&
+			rm -f "refs/remotes/$origin/HEAD"
+			git-symbolic-ref "refs/remotes/$origin/HEAD" \
+				"refs/remotes/$origin/$head_points_at"
+		fi)
 
 		git-config branch."$head_points_at".remote "$origin" &&
 		git-config branch."$head_points_at".merge "refs/heads/$head_points_at"

-- 
MST
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]