changeset 13150:8617b8b74fae

subrepo: use low-level git-for-each-ref command in branchmap This command's output doesn't change across versions, and it also disambiguates cases where there are slashes in local branch names.
author Eric Eisner <ede@mit.edu>
date Tue, 14 Dec 2010 21:53:40 -0500
parents 735dd8e8a208
children 519ac79d680b
files mercurial/subrepo.py
diffstat 1 files changed, 22 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/subrepo.py	Wed Dec 15 10:55:14 2010 -0600
+++ b/mercurial/subrepo.py	Tue Dec 14 21:53:40 2010 -0500
@@ -649,7 +649,7 @@
         if p.returncode != 0 and p.returncode != 1:
             # there are certain error codes that are ok
             command = commands[0]
-            if command == 'cat-file':
+            if command in ('cat-file', 'symbolic-ref'):
                 return retdata, p.returncode
             # for all others, abort
             raise util.Abort('git %s error %d in %s' %
@@ -675,22 +675,20 @@
         a map from revision to branches'''
         branch2rev = {}
         rev2branch = {}
-        current = None
-        out = self._gitcommand(['branch', '-a', '--no-color',
-                                '--verbose', '--no-abbrev'])
+        current, err = self._gitdir(['symbolic-ref', 'HEAD', '--quiet'])
+        if err:
+            current = None
+
+        out = self._gitcommand(['for-each-ref', '--format',
+                                '%(objectname) %(refname)'])
         for line in out.split('\n'):
-            if line[2:].startswith('(no branch)'):
+            revision, ref = line.split(' ')
+            if ref.startswith('refs/tags/'):
                 continue
-            branch, revision = line[2:].split()[:2]
-            if revision == '->' or branch.endswith('/HEAD'):
+            if ref.startswith('refs/remotes/') and ref.endswith('/HEAD'):
                 continue # ignore remote/HEAD redirects
-            if '/' in branch and not branch.startswith('remotes/'):
-                # old git compatability
-                branch = 'remotes/' + branch
-            if line[0] == '*':
-                current = branch
-            branch2rev[branch] = revision
-            rev2branch.setdefault(revision, []).append(branch)
+            branch2rev[ref] = revision
+            rev2branch.setdefault(revision, []).append(ref)
         return current, branch2rev, rev2branch
 
     def _gittracking(self, branches):
@@ -698,12 +696,13 @@
         # assumes no more than one local tracking branch for each remote
         tracking = {}
         for b in branches:
-            if b.startswith('remotes/'):
+            if b.startswith('refs/remotes/'):
                 continue
             remote = self._gitcommand(['config', 'branch.%s.remote' % b])
             if remote:
                 ref = self._gitcommand(['config', 'branch.%s.merge' % b])
-                tracking['remotes/%s/%s' % (remote, ref.split('/')[-1])] = b
+                tracking['refs/remotes/%s/%s' %
+                         (remote, ref.split('/', 2)[2])] = b
         return tracking
 
     def _fetch(self, source, revision):
@@ -758,11 +757,11 @@
         branches = rev2branch[revision]
         firstlocalbranch = None
         for b in branches:
-            if b == 'master':
+            if b == 'refs/heads/master':
                 # master trumps all other branches
-                self._gitcommand(['checkout', 'master'])
+                self._gitcommand(['checkout', 'refs/heads/master'])
                 return
-            if not firstlocalbranch and not b.startswith('remotes/'):
+            if not firstlocalbranch and not b.startswith('refs/remotes/'):
                 firstlocalbranch = b
         if firstlocalbranch:
             self._gitcommand(['checkout', firstlocalbranch])
@@ -779,7 +778,7 @@
 
         if remote not in tracking:
             # create a new local tracking branch
-            local = remote.split('/')[-1]
+            local = remote.split('/', 2)[2]
             self._gitcommand(['checkout', '-b', local, remote])
         elif self._gitisancestor(branch2rev[tracking[remote]], remote):
             # When updating to a tracked remote branch,
@@ -824,10 +823,10 @@
         current, branch2rev, rev2branch = self._gitbranchmap()
         if self._state[1] in rev2branch:
             for b in rev2branch[self._state[1]]:
-                if b.startswith('remotes/origin/'):
+                if b.startswith('refs/remotes/origin/'):
                     return True
         for b, revision in branch2rev.iteritems():
-            if b.startswith('remotes/origin/'):
+            if b.startswith('refs/remotes/origin/'):
                 if self._gitisancestor(self._state[1], revision):
                     return True
         # otherwise, try to push the currently checked out branch
@@ -841,7 +840,7 @@
                                 'in subrepo %s\n') % self._relpath)
                 return False
             self._ui.status(_('pushing branch %s of subrepo %s\n') %
-                            (current, self._relpath))
+                            (current.split('/', 2)[2], self._relpath))
             self._gitcommand(cmd + ['origin', current])
             return True
         else: