Merge branch 'jc/checkout-local-track-report'
authorJunio C Hamano <gitster@pobox.com>
Wed, 7 Jan 2015 20:40:59 +0000 (12:40 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 7 Jan 2015 20:41:00 +0000 (12:41 -0800)
The report from "git checkout" on a branch that builds on another
local branch by setting its branch.*.merge to branch name (not a
full refname) incorrectly said that the upstream is gone.

* jc/checkout-local-track-report:
checkout: report upstream correctly even with loosely defined branch.*.merge

remote.c
t/t2024-checkout-dwim.sh
index ae4ecfa1163137f7372fd02a51dc8a93319d218f..5b9c6931c1e66adb03f5d505aa8dd57169452eae 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -1631,6 +1631,27 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror,
        }
 }
 
+static void set_merge(struct branch *ret)
+{
+       char *ref;
+       unsigned char sha1[20];
+       int i;
+
+       ret->merge = xcalloc(ret->merge_nr, sizeof(*ret->merge));
+       for (i = 0; i < ret->merge_nr; i++) {
+               ret->merge[i] = xcalloc(1, sizeof(**ret->merge));
+               ret->merge[i]->src = xstrdup(ret->merge_name[i]);
+               if (!remote_find_tracking(ret->remote, ret->merge[i]) ||
+                   strcmp(ret->remote_name, "."))
+                       continue;
+               if (dwim_ref(ret->merge_name[i], strlen(ret->merge_name[i]),
+                            sha1, &ref) == 1)
+                       ret->merge[i]->dst = ref;
+               else
+                       ret->merge[i]->dst = xstrdup(ret->merge_name[i]);
+       }
+}
+
 struct branch *branch_get(const char *name)
 {
        struct branch *ret;
@@ -1642,17 +1663,8 @@ struct branch *branch_get(const char *name)
                ret = make_branch(name, 0);
        if (ret && ret->remote_name) {
                ret->remote = remote_get(ret->remote_name);
-               if (ret->merge_nr) {
-                       int i;
-                       ret->merge = xcalloc(ret->merge_nr, sizeof(*ret->merge));
-                       for (i = 0; i < ret->merge_nr; i++) {
-                               ret->merge[i] = xcalloc(1, sizeof(**ret->merge));
-                               ret->merge[i]->src = xstrdup(ret->merge_name[i]);
-                               if (remote_find_tracking(ret->remote, ret->merge[i])
-                                   && !strcmp(ret->remote_name, "."))
-                                       ret->merge[i]->dst = xstrdup(ret->merge_name[i]);
-                       }
-               }
+               if (ret->merge_nr)
+                       set_merge(ret);
        }
        return ret;
 }
index 6ecb559465b43e528a5cb1511b758cc48d940e92..468a000e4bbb113d004ee8df8ef0db9b8260fdb5 100755 (executable)
@@ -185,4 +185,22 @@ test_expect_success 'checkout <branch> -- succeeds, even if a file with the same
        test_branch_upstream spam repo_c spam
 '
 
+test_expect_success 'loosely defined local base branch is reported correctly' '
+
+       git checkout master &&
+       git branch strict &&
+       git branch loose &&
+       git commit --allow-empty -m "a bit more" &&
+
+       test_config branch.strict.remote . &&
+       test_config branch.loose.remote . &&
+       test_config branch.strict.merge refs/heads/master &&
+       test_config branch.loose.merge master &&
+
+       git checkout strict | sed -e "s/strict/BRANCHNAME/g" >expect &&
+       git checkout loose | sed -e "s/loose/BRANCHNAME/g" >actual &&
+
+       test_cmp expect actual
+'
+
 test_done