Merge branch 'sb/branch-attributes'
authorJunio C Hamano <junkio@cox.net>
Mon, 25 Sep 2006 02:20:26 +0000 (19:20 -0700)
committerJunio C Hamano <junkio@cox.net>
Mon, 25 Sep 2006 02:20:26 +0000 (19:20 -0700)
* sb/branch-attributes:
Add test for the default merges in fetch.
fetch: get the remote branches to merge from the branch properties
Add t5510 to test per branch configuration affecting git-fetch.
Fetch: default remote repository from branch properties

Documentation/config.txt
git-fetch.sh
git-parse-remote.sh
t/t5510-fetch.sh [new file with mode: 0755]
index bb2fbc324e6fa93a639b31668a7a030ece7787f0..98c1f3e2e32e71047d6f0f6cf982e207117c64e2 100644 (file)
@@ -119,6 +119,13 @@ 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 fetch` the default remote branch
+       to be merged.
+
 pager.color::
        A boolean to enable/disable colored output when the pager is in
        use (default is true).
index 09a5d6ceab7875f2344f84d684ea5cc250786c64..50ad101e89500af01edde00b047b91fc16fdcb81 100755 (executable)
@@ -68,11 +68,10 @@ 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 ;;
+       origin=$(get_default_remote)
+       test -n "$(get_remote_url ${origin})" ||
+               die "Where do you want to fetch from today?"
+       set x $origin ; shift ;;
 esac
 
 remote_nick="$1"
index 187f0883c9136772677088ddf61228291d4b41d1..c325ef761e4c558ab5c7c560da942e127e1be040 100755 (executable)
@@ -68,6 +68,12 @@ get_remote_url () {
        esac
 }
 
+get_default_remote () {
+       curr_branch=$(git-symbolic-ref HEAD | sed -e 's|^refs/heads/||')
+       origin=$(git-repo-config --get "branch.$curr_branch.remote")
+       echo ${origin:-origin}
+}
+
 get_remote_default_refs_for_push () {
        data_source=$(get_data_source "$1")
        case "$data_source" in
@@ -86,9 +92,22 @@ get_remote_default_refs_for_push () {
 
 # Subroutine to canonicalize remote:local notation.
 canon_refs_list_for_fetch () {
-       # Leave only the first one alone; add prefix . to the rest
+       # If called from get_remote_default_refs_for_fetch
+       # leave the branches in branch.${curr_branch}.merge alone,
+       # or the first one otherwise; add prefix . to the rest
        # to prevent the secondary branches to be merged by default.
-       dot_prefix=
+       merge_branches=
+       if test "$1" = "-d"
+       then
+               shift ; remote="$1" ; shift
+               if test "$remote" = "$(get_default_remote)"
+               then
+                       curr_branch=$(git-symbolic-ref HEAD | \
+                           sed -e 's|^refs/heads/||')
+                       merge_branches=$(git-repo-config \
+                           --get-all "branch.${curr_branch}.merge")
+               fi
+       fi
        for ref
        do
                force=
@@ -101,6 +120,18 @@ canon_refs_list_for_fetch () {
                expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
                remote=$(expr "z$ref" : 'z\([^:]*\):')
                local=$(expr "z$ref" : 'z[^:]*:\(.*\)')
+               dot_prefix=.
+               if test -z "$merge_branches"
+               then
+                       merge_branches=$remote
+                       dot_prefix=
+               else
+                       for merge_branch in $merge_branches
+                       do
+                           [ "$remote" = "$merge_branch" ] &&
+                           dot_prefix= && break
+                       done
+               fi
                case "$remote" in
                '') remote=HEAD ;;
                refs/heads/* | refs/tags/* | refs/remotes/*) ;;
@@ -120,7 +151,6 @@ canon_refs_list_for_fetch () {
                   die "* refusing to create funny ref '$local_ref_name' locally"
                fi
                echo "${dot_prefix}${force}${remote}:${local}"
-               dot_prefix=.
        done
 }
 
@@ -131,7 +161,7 @@ get_remote_default_refs_for_fetch () {
        '' | config-partial | branches-partial)
                echo "HEAD:" ;;
        config)
-               canon_refs_list_for_fetch \
+               canon_refs_list_for_fetch -d "$1" \
                        $(git-repo-config --get-all "remote.$1.fetch") ;;
        branches)
                remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
@@ -139,10 +169,7 @@ get_remote_default_refs_for_fetch () {
                echo "refs/heads/${remote_branch}:refs/heads/$1"
                ;;
        remotes)
-               # This prefixes the second and later default refspecs
-               # with a '.', to signal git-fetch to mark them
-               # not-for-merge.
-               canon_refs_list_for_fetch $(sed -ne '/^Pull: */{
+               canon_refs_list_for_fetch -d "$1" $(sed -ne '/^Pull: */{
                                                s///p
                                        }' "$GIT_DIR/remotes/$1")
                ;;
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
new file mode 100755 (executable)
index 0000000..df0ae48
--- /dev/null
@@ -0,0 +1,69 @@
+#!/bin/sh
+# Copyright (c) 2006, Junio C Hamano.
+
+test_description='Per branch config variables affects "git fetch".
+
+'
+
+. ./test-lib.sh
+
+D=`pwd`
+
+test_expect_success setup '
+       echo >file original &&
+       git add file &&
+       git commit -a -m original'
+
+test_expect_success "clone and setup child repos" '
+       git clone . one &&
+       cd one &&
+       echo >file updated by one &&
+       git commit -a -m "updated by one" &&
+       cd .. &&
+       git clone . two &&
+       cd two &&
+       git repo-config branch.master.remote one &&
+       {
+               echo "URL: ../one/.git/"
+               echo "Pull: refs/heads/master:refs/heads/one"
+       } >.git/remotes/one
+       cd .. &&
+       git clone . three &&
+       cd three &&
+       git repo-config branch.master.remote two &&
+       git repo-config branch.master.merge refs/heads/one &&
+       {
+               echo "URL: ../two/.git/"
+               echo "Pull: refs/heads/master:refs/heads/two"
+               echo "Pull: refs/heads/one:refs/heads/one"
+       } >.git/remotes/two
+'
+
+test_expect_success "fetch test" '
+       cd "$D" &&
+       echo >file updated by origin &&
+       git commit -a -m "updated by origin" &&
+       cd two &&
+       git fetch &&
+       test -f .git/refs/heads/one &&
+       mine=`git rev-parse refs/heads/one` &&
+       his=`cd ../one && git rev-parse refs/heads/master` &&
+       test "z$mine" = "z$his"
+'
+
+test_expect_success "fetch test for-merge" '
+       cd "$D" &&
+       cd three &&
+       git fetch &&
+       test -f .git/refs/heads/two &&
+       test -f .git/refs/heads/one &&
+       master_in_two=`cd ../two && git rev-parse master` &&
+       one_in_two=`cd ../two && git rev-parse one` &&
+       {
+               echo "$master_in_two    not-for-merge"
+               echo "$one_in_two       "
+       } >expected &&
+       cut -f -2 .git/FETCH_HEAD >actual &&
+       diff expected actual'
+
+test_done