Subject: [PATCH] branch: write branch properties

From: Santi Béjar <[email-masked]>
Date: Mon, 25 Sep 2006 00:42:02 +0200

If you want to work in the 'next' branch of git.git:

$ git clone --use-separate-remote git://git.kernel.org/pub/scm/git/git.git
$ cd git
$ git branch next origin next

Signed-off-by: Santi Béjar <[email-masked]>
---
 Documentation/git-branch.txt |    7 +++++--
 git-branch.sh                |   17 +++++++++++++++--
 git-parse-remote.sh          |   21 +++++++++++++++++++++
 3 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index d43ef1d..de2889d 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -9,7 +9,7 @@ SYNOPSIS
 --------
 [verse]
 'git-branch' [-r]
-'git-branch' [-l] [-f] <branchname> [<start-point>]
+'git-branch' [-l] [-f] <branchname> [<start-point> | <remote> <remotebranch>]
 'git-branch' (-d | -D) <branchname>...
 
 DESCRIPTION
@@ -18,9 +18,12 @@ With no arguments given (or just `-r`) a
 will be shown, the current branch will be highlighted with an asterisk.
 
 In its second form, a new branch named <branchname> will be created.
-It will start out with a head equal to the one given as <start-point>.
+It will start out with a head equal to the one given as <start-point>,
+or from branch <remotebranch> of the repository <remote>.
 If no <start-point> is given, the branch will be created with a head
 equal to that of the currently checked out branch.
+In the form <remote> <remotebranch> it will also record the branch
+properties `branch.<branchname>.remote` and `branch.<branchname>.merge`.
 
 With a `-d` or `-D` option, `<branchname>` will be deleted.  You may
 specify more than one branch for deletion.  If the branch currently
diff --git a/git-branch.sh b/git-branch.sh
index e0501ec..94dd157 100755
--- a/git-branch.sh
+++ b/git-branch.sh
@@ -1,9 +1,10 @@
 #!/bin/sh
 
-USAGE='[-l] [(-d | -D) <branchname>] | [[-f] <branchname> [<start-point>]] | -r'
+USAGE='[-l] [(-d | -D) <branchname>] | [[-f] <branchname> [<start-point> | <remote> <remotebranch>]] | -r'
 LONG_USAGE='If no arguments, show available branches and mark current branch with a star.
 If one argument, create a new branch <branchname> based off of current HEAD.
-If two arguments, create a new branch <branchname> based off of <start-point>.'
+If two arguments, create a new branch <branchname> based off of <start-point>.
+If three arguments, create a new branch <branchname> based off the branch <remotebranch> of the repository <remote>, writing the branch properties for fetch.'
 
 SUBDIRECTORY_OK='Yes'
 . git-sh-setup
@@ -104,6 +105,12 @@ case "$#" in
 	head=HEAD ;;
 2)
 	head="$2^0" ;;
+3)
+	remote="$2"
+	remote_branch="$3"
+	. ./git-parse-remote.sh
+	ref=$(get_ref_for_remote_branch "$2" "$3")
+	head="$ref^0";;
 esac
 branchname="$1"
 
@@ -128,3 +135,9 @@ then
 	touch "$GIT_DIR/logs/refs/heads/$branchname"
 fi
 git update-ref -m "branch: Created from $head" "refs/heads/$branchname" $rev
+
+if test -n "$ref"
+then
+	git repo-config branch."$branchname".remote "$remote"
+	git repo-config branch."$branchname".merge "$remote_branch"
+fi
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 187f088..51f3b9b 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -209,3 +209,24 @@ resolve_alternates () {
 		esac
 	done
 }
+
+get_ref_for_remote_branch (){
+	data_source=$(get_data_source "$1")
+	case "$data_source" in
+	'' | config-partial | branches | branches-partial)
+		;;
+	config)
+		ref=$(git-repo-config --get-all "remote.$1.fetch" |\
+			grep "^$2:")
+		expr "z$ref" : 'z[^:]*:\(.*\)'
+		;;
+	remotes)
+		ref=$(sed -ne '/^Pull: */{
+				s///p
+			}' "$GIT_DIR/remotes/$1" | grep "$2:")
+		expr "z$ref" : 'z[^:]*:\(.*\)'
+		;;
+	*)
+		die "internal error: get-ref-for-remote-branch $1 $2" ;;
+	esac
+}
-- 
1.4.2.1.g279b