[PATCH] Per branch properties for pull and fetch

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

 



It allows to specify on a per branch basis the following:
.- default repository to fetch
.- default branches to merge on a per repository basis
.- default pull.{octopus,twohead}

So if you have this in the config:
[branch "my"]
	remote=yours
	merge=master
	merge=our from theirs
	merge=mine from .

and you are in the branch "my":

"git pull": fetch the remote yours and merge the branch master.
"git pull theirs": fetch the remote theirs and merge the branch our.
"git pull .": merge the branch mine from the local repository.
---
 Documentation/config.txt |   14 +++++++++++
 git-fetch.sh             |   13 ++++++----
 git-parse-remote.sh      |   57 ++++++++++++++++++++++++++++++++++++++++++++++
 git-pull.sh              |   29 ++++++++++++++++++++---
 4 files changed, 104 insertions(+), 9 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 465eb13..f12b595 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -116,6 +116,20 @@ apply.whitespace::
 	Tells `git-apply` how to handle whitespaces, in the same way
 	as the '--whitespace' option. See gitlink:git-apply[1].
 
+branch.<name>.remote::
+	When in branch <name>, it tells `git-fetch` which remote to fetch.
+
+branch.<name>.merge::
+	When in branch <name>, it tells `git-pull` to merge this remote
+	branch of the repository branch.<name>.remote. To specify a different
+	remote repository use the from `<branch> from <repo>`.
+
+branch.<name>.octopus::
+	When in branch <name>, the same as pull.octopus.
+
+branch.<name>.twohead::
+	When in branch <name>, the same as pull.twohead.
+
 diff.color::
 	When true (or `always`), always use colors in patch.
 	When false (or `never`), never.  When set to `auto`, use
diff --git a/git-fetch.sh b/git-fetch.sh
index c2eebee..8129d8a 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -68,11 +68,13 @@ done
 
 case "$#" in
 0)
-	test -f "$GIT_DIR/branches/origin" ||
-		test -f "$GIT_DIR/remotes/origin" ||
-			git-repo-config --get remote.origin.url >/dev/null ||
-				die "Where do you want to fetch from today?"
-	set origin ;;
+	curr_branch=$(git-symbolic-ref HEAD)
+	curr_branch=${curr_branch##refs/heads/}
+	origin=$(git-repo-config --get "branch.$curr_branch.remote")
+	origin=${origin:-origin}
+	test -n "$(get_remote_url $origin)" ||
+		die "Where do you want to fetch from today?"
+	set $origin ;;
 esac
 
 remote_nick="$1"
@@ -446,3 +448,4 @@ case ",$update_head_ok,$orig_head," in
 	fi
 	;;
 esac
+echo $remote_nick >"$GIT_DIR/FETCH_REMOTE"
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 187f088..fe6c713 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -209,3 +209,60 @@ resolve_alternates () {
 		esac
 	done
 }
+
+get_head_for_remote_branch () {
+	if [ "$1" == "." ];
+	then
+		git-rev-parse $2 2>/dev/null||
+			die "error: no such ref $2"
+		return
+	fi
+	data_source=$(get_data_source "$1")
+	case "$data_source" in
+	config)
+		refspec=$(git-repo-config --get "remote.$1.fetch" ^$2:) ;;
+	branches)
+		remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
+		case "$remote_branch" in '') remote_branch=master ;; esac
+		[ $remote_branch == $2 ] &&
+		refspec="refs/heads/${remote_branch}:refs/heads/$1"
+		;;
+	remotes)
+		refspec=$(grep "^Pull: $2:" $GIT_DIR/remotes/$1)
+		refspec=${refspec##Pull: }
+		;;
+	*)
+		die "internal error: get-head_for_remote_branch" ;;
+	esac
+	[ "$refspec" ] || die "Branch $2 does not exist in the repository: $1."
+	git-rev-parse $(expr "z$refspec" : 'z[^:]*:\(.*\)')
+}
+
+get_heads_to_merge_in_branch () {
+ 	case "$#" in
+	2)
+		default=$(git repo-config --get-all "branch.$1.remote")
+		: >"$GIT_DIR/HEADS_TO_MERGE"
+		git repo-config --get-all "branch.$1.merge" |
+		while read ref ; do
+			case $ref in
+			?*' 'from' '?*)
+				remote=$(expr "z$ref" : 'z.* from \(.*\)')
+				branch=$(expr "z$ref" : 'z\(.*\) from .*');;
+			*)
+				remote=$default
+				branch=$ref;;
+			esac
+			[ "$remote" != "$2" ] && continue
+			headm=$(get_head_for_remote_branch $remote $branch) || exit 1
+			echo $headm
+			remoteurl=$(get_remote_url $remote)
+			remoteurl_1=$(expr "z$remoteurl" : 'z\(.*\)\.git/*$') &&
+				remoteurl=$remoteurl_1
+			echo "$headm		branch '$branch' of $remoteurl" \
+				>>"$GIT_DIR/HEADS_TO_MERGE"
+		done
+		;;
+	*) exit 1
+	esac
+}
diff --git a/git-pull.sh b/git-pull.sh
index f380437..467d9c0 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -7,6 +7,7 @@ # Fetch one or more remote refs and merg
 USAGE='[-n | --no-summary] [--no-commit] [-s strategy]... [<fetch-options>] <repo> <head>...'
 LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEAD.'
 . git-sh-setup
+. git-parse-remote
 
 strategy_args= no_summary= no_commit= squash=
 while case "$#,$1" in 0) break ;; *,-*) ;; *) break ;; esac
@@ -47,6 +48,8 @@ done
 orig_head=$(git-rev-parse --verify HEAD) || die "Pulling into a black hole?"
 git-fetch --update-head-ok --reflog-action=pull "$@" || exit 1
 
+curr_branch=$(git-symbolic-ref HEAD)
+curr_branch=${curr_branch##refs/heads/}
 curr_head=$(git-rev-parse --verify HEAD)
 if test "$curr_head" != "$orig_head"
 then
@@ -70,9 +73,18 @@ to recover.'
 
 fi
 
-merge_head=$(sed -e '/	not-for-merge	/d' \
-	-e 's/	.*//' "$GIT_DIR"/FETCH_HEAD | \
-	tr '\012' ' ')
+remote=$(cat "$GIT_DIR/FETCH_REMOTE")
+merge_head=$(get_heads_to_merge_in_branch "$curr_branch" "$remote" ) || exit
+
+if [ -n "$merge_head" ];
+then
+	merge_name=$(git-fmt-merge-msg <"$GIT_DIR/HEADS_TO_MERGE") || exit
+else
+	merge_head=$(sed -e '/	not-for-merge	/d' \
+		-e 's/	.*//' "$GIT_DIR"/FETCH_HEAD | \
+		tr '\012' ' ')
+	merge_name=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD") || exit
+fi
 
 case "$merge_head" in
 '')
@@ -85,6 +97,11 @@ case "$merge_head" in
 	then
 		strategy_default_args="-s $var"
 	fi
+	var=`git-repo-config --get branch.$curr_branch.octopus`
+	if test -n "$var"
+	then
+		strategy_default_args="-s $var"
+	fi
 	;;
 *)
 	var=`git-repo-config --get pull.twohead`
@@ -92,6 +109,11 @@ case "$merge_head" in
         then
 		strategy_default_args="-s $var"
 	fi
+	var=`git-repo-config --get branch.$curr_branch.twohead`
+	if test -n "$var"
+        then
+		strategy_default_args="-s $var"
+	fi
 	;;
 esac
 
@@ -101,7 +123,6 @@ case "$strategy_args" in
 	;;
 esac
 
-merge_name=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD") || exit
 git-merge "--reflog-action=pull $*" \
 	$no_summary $no_commit $squash $strategy_args \
 	"$merge_name" HEAD $merge_head
-- 
1.4.2.rc2.g1728

-
: 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]