Merge branch 'jk/branch-shortening-funny-symrefs'
authorJunio C Hamano <gitster@pobox.com>
Mon, 18 Apr 2016 17:49:14 +0000 (10:49 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 18 Apr 2016 17:49:14 +0000 (10:49 -0700)
A change back in version 2.7 to "git branch" broke display of a
symbolic ref in a non-standard place in the refs/ hierarchy (we
expect symbolic refs to appear in refs/remotes/*/HEAD to point at
the primary branch the remote has, and as .git/HEAD to point at the
branch we locally checked out).

* jk/branch-shortening-funny-symrefs:
branch: fix shortening of non-remote symrefs

1  2 
builtin/branch.c
diff --combined builtin/branch.c
index de6df09ed30df11ea853b5d815f22d9859ac24cc,f6c23bf5dd600cd8f1bc7029de757d577abdfd02..0adba629d2ae35a4db74fb9d1450b54bb11e51e3
@@@ -20,7 -20,6 +20,7 @@@
  #include "utf8.h"
  #include "wt-status.h"
  #include "ref-filter.h"
 +#include "worktree.h"
  
  static const char * const builtin_branch_usage[] = {
        N_("git branch [<options>] [-r | -a] [--merged | --no-merged]"),
@@@ -216,21 -215,16 +216,21 @@@ static int delete_branches(int argc, co
                int flags = 0;
  
                strbuf_branchname(&bname, argv[i]);
 -              if (kinds == FILTER_REFS_BRANCHES && !strcmp(head, bname.buf)) {
 -                      error(_("Cannot delete the branch '%s' "
 -                            "which you are currently on."), bname.buf);
 -                      ret = 1;
 -                      continue;
 -              }
 -
                free(name);
 -
                name = mkpathdup(fmt, bname.buf);
 +
 +              if (kinds == FILTER_REFS_BRANCHES) {
 +                      char *worktree = find_shared_symref("HEAD", name);
 +                      if (worktree) {
 +                              error(_("Cannot delete branch '%s' "
 +                                      "checked out at '%s'"),
 +                                    bname.buf, worktree);
 +                              free(worktree);
 +                              ret = 1;
 +                              continue;
 +                      }
 +              }
 +
                target = resolve_ref_unsafe(name,
                                            RESOLVE_REF_READING
                                            | RESOLVE_REF_NO_RECURSE
@@@ -399,22 -393,25 +399,25 @@@ static void format_and_print_ref_item(s
        int current = 0;
        int color;
        struct strbuf out = STRBUF_INIT, name = STRBUF_INIT;
-       const char *prefix = "";
+       const char *prefix_to_show = "";
+       const char *prefix_to_skip = NULL;
        const char *desc = item->refname;
        char *to_free = NULL;
  
        switch (item->kind) {
        case FILTER_REFS_BRANCHES:
-               skip_prefix(desc, "refs/heads/", &desc);
+               prefix_to_skip = "refs/heads/";
+               skip_prefix(desc, prefix_to_skip, &desc);
                if (!filter->detached && !strcmp(desc, head))
                        current = 1;
                else
                        color = BRANCH_COLOR_LOCAL;
                break;
        case FILTER_REFS_REMOTES:
-               skip_prefix(desc, "refs/remotes/", &desc);
+               prefix_to_skip = "refs/remotes/";
+               skip_prefix(desc, prefix_to_skip, &desc);
                color = BRANCH_COLOR_REMOTE;
-               prefix = remote_prefix;
+               prefix_to_show = remote_prefix;
                break;
        case FILTER_REFS_DETACHED_HEAD:
                desc = to_free = get_head_description();
                color = BRANCH_COLOR_CURRENT;
        }
  
-       strbuf_addf(&name, "%s%s", prefix, desc);
+       strbuf_addf(&name, "%s%s", prefix_to_show, desc);
        if (filter->verbose) {
                int utf8_compensation = strlen(name.buf) - utf8_strwidth(name.buf);
                strbuf_addf(&out, "%c %s%-*s%s", c, branch_get_color(color),
                            name.buf, branch_get_color(BRANCH_COLOR_RESET));
  
        if (item->symref) {
-               skip_prefix(item->symref, "refs/remotes/", &desc);
-               strbuf_addf(&out, " -> %s", desc);
+               const char *symref = item->symref;
+               if (prefix_to_skip)
+                       skip_prefix(symref, prefix_to_skip, &symref);
+               strbuf_addf(&out, " -> %s", symref);
        }
        else if (filter->verbose)
                /* " f7c0c00 [ahead 58, behind 197] vcs-svn: drop obj_pool.h" */
@@@ -558,7 -557,8 +563,7 @@@ static void rename_branch(const char *o
        if (recovery)
                warning(_("Renamed a misnamed branch '%s' away"), oldref.buf + 11);
  
 -      /* no need to pass logmsg here as HEAD didn't really move */
 -      if (!strcmp(oldname, head) && create_symref("HEAD", newref.buf, NULL))
 +      if (replace_each_worktree_head_symref(oldref.buf, newref.buf))
                die(_("Branch renamed to %s, but HEAD is not updated!"), newname);
  
        strbuf_addf(&oldsection, "branch.%s", oldref.buf + 11);