1. Henrik Stuart
  2. hg-renamebranch

Commits

Henrik Stuart  committed 7247f4f

Initial version

Missing full pushkey implementation of transfering branch alias information
between clients and servers.

  • Participants
  • Branches default

Comments (0)

Files changed (1)

File hg-renamebranch.py

View file
  • Ignore whitespace
+'''experimental branch alias extension'''
+
+from mercurial import extensions
+from mercurial import context
+from mercurial import util
+
+class branchalias(object):
+    def __init__(self, repo):
+        object.__init__(self)
+        self.repo = repo
+        self.aliases = self._parse()
+
+    def _readint(self, data, offset):
+        off = offset[0]
+        eoff = off
+        if not data[off].isdigit():
+            raise util.Abort('malform branchalias - expected integer at position %d, but got "%s"' % (off, data[off]))
+        while data[eoff].isdigit():
+            eoff += 1
+        num = data[off:eoff]
+        offset[0] = eoff
+        return int(num)
+
+    def _parse(self):
+        # entries are on form [branchlength] [aliaslength] [branch] [alias]\n
+        # note that branch names can be anything but tip, ., and null, so
+        # newlines, zero bytes, etc. are all "good to go"
+
+        if not self.repo.local():
+            return self.repo.listkeys('branchalias')
+
+        try:
+            ba = self.repo.opener.read('.branchalias')
+            offset = [0]
+            rv = {}
+            while offset[0] < len(ba):
+                srclen = self._readint(ba, offset)
+                offset[0] += 1
+                tgtlen = self._readint(ba, offset)
+                offset[0] += 1
+                srcname = ba[offset[0]:offset[0]+srclen]
+                offset[0] += srclen + 1
+                tgtname = ba[offset[0]:offset[0]+tgtlen]
+                offset[0] += tgtlen + 1
+                rv[srcname] = tgtname
+            return rv
+        except IOError:
+            return {}
+
+    def getname(self, branch):
+        return self.aliases.get(branch, branch)
+
+    def add(self, branch, alias):
+        self.aliases[branch] = alias
+
+    def write(self):
+        data = ''.join(['%d %d %s %s\n' % (len(x), len(y), x, y)
+            for x, y in self.aliases.iteritems()])
+        self.repo.opener.write('.branchalias', data)
+
+    def __iter__(self):
+        return self.aliases.iteritems()
+
+    def __len__(self):
+        return len(self.aliases)
+
+    def __bool__(self):
+        return len(self.aliases) != 0
+
+
+def _branch(orig, self):
+    retval = orig(self)
+    return self._repo.branchalias.getname(retval)
+
+def extsetup(ui):
+    extensions.wrapfunction(context.changectx, 'branch', _branch)
+
+def reposetup(ui, repo):
+    repo.branchalias = branchalias(repo)
+
+def _branchalias(ui, repo, *args, **opts):
+    '''shows or adds a branch alias for a named branch
+
+    This allows you to create named branches that are later converted into
+    anonymous branches by letting your Mercurial think that a branch name is
+    actually a different name.
+
+    Note that due to various caches, if you enable and disable this extension
+    you might not see the actual branch names of changesets.
+
+    Further, note that the extension must be enabled both on the client and
+    the server in order for the branch names to "go away".
+
+    This extension only renames branches in memory and caches, the original
+    branch names will stay part of the on-disk history, as per the design of
+    named branches.
+    '''
+
+    if opts.get('list'):
+        if not repo.branchalias:
+            ui.status('No branch aliases defined\n')
+            return
+
+        ui.status('Branch aliases:\n')
+        for src, tgt in repo.branchalias:
+            ui.status('  %s -> %s\n' % (src, tgt))
+        return
+
+    if len(args) != 2:
+        raise util.Abort('specify both branch source and target')
+
+    branches = repo.branchmap()
+    src, tgt = args
+    if src not in branches:
+        raise util.Abort('source branch not known')
+    if tgt not in branches:
+        raise util.Abort('target branch not known')
+
+    lock = repo.lock()
+    try:
+        repo.branchalias.add(*args)
+        repo.branchalias.write()
+        repo.invalidatecaches()
+    finally:
+        lock.release()
+
+cmdtable = {
+        'branchalias|balias': (_branchalias,
+            [('l', 'list', False, 'show branch aliases')],
+            'BRANCHNAME BRANCHALIAS'),
+        }