--- a/mercurial/changelog.py
+++ b/mercurial/changelog.py
@@ -59,7 +59,7 @@ class changelog(revlog):
changelog v0 doesn't use extra
"""
if not text:
- return (nullid, "", (0, 0), [], "")
+ return (nullid, "", (0, 0), [], "", {})
last = text.index("\n\n")
desc = text[last + 2:]
l = text[:last].split('\n')
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -326,6 +326,7 @@ class changeset_printer(object):
changes = log.read(changenode)
date = util.datestr(changes[2])
+ branch = changes[5].get("branch")
hexfunc = self.ui.debugflag and hex or short
@@ -337,6 +338,8 @@ class changeset_printer(object):
self.ui.write(_("changeset: %d:%s\n") % (rev, hexfunc(changenode)))
+ if branch:
+ self.ui.status(_("branch: %s\n") % branch)
for tag in self.repo.nodetags(changenode):
self.ui.status(_("tag: %s\n") % tag)
for parent in parents:
@@ -1574,6 +1577,11 @@ def identify(ui, repo):
(modified or added or removed or deleted) and "+" or "")]
if not ui.quiet:
+
+ branch = repo.workingctx().branch()
+ if branch:
+ output.append("(%s)" % branch)
+
# multiple tags for a single parent separated by '/'
parenttags = ['/'.join(tags)
for tags in map(repo.nodetags, parents) if tags]
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -64,6 +64,7 @@ class changectx(object):
def date(self): return self._changeset[2]
def files(self): return self._changeset[3]
def description(self): return self._changeset[4]
+ def branch(self): return self._changeset[5].get("branch", "")
def parents(self):
"""return contexts for each parent changeset"""
@@ -192,6 +193,7 @@ class filectx(object):
def date(self): return self._changectx.date()
def files(self): return self._changectx.files()
def description(self): return self._changectx.description()
+ def branch(self): return self._changectx.branch()
def manifest(self): return self._changectx.manifest()
def changectx(self): return self._changectx
@@ -394,6 +396,11 @@ class workingctx(changectx):
def deleted(self): return self._status[3]
def unknown(self): return self._status[4]
def clean(self): return self._status[5]
+ def branch(self):
+ try:
+ return self._repo.opener("branch").read().strip()
+ except IOError:
+ return ""
def parents(self):
"""return contexts for each parent changeset"""
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -221,6 +221,8 @@ def update(repo, node):
"""update the working directory to node, merging linear changes"""
stats = _merge.update(repo, node, False, False, None, None)
_showstats(repo, stats)
+ branch = repo.changectx(node).branch()
+ repo.opener("branch", "w").write(branch + "\n")
if stats[3]:
repo.ui.status(_("There are unresolved merges with"
" locally modified files.\n"))
@@ -229,6 +231,8 @@ def update(repo, node):
def clean(repo, node, wlock=None, show_stats=True):
"""forcibly switch the working directory to node, clobbering changes"""
stats = _merge.update(repo, node, False, True, None, wlock)
+ branch = repo.changectx(node).branch()
+ repo.opener("branch", "w").write(branch + "\n")
if show_stats: _showstats(repo, stats)
return stats[3]
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -79,6 +79,7 @@ class localrepository(repo.repository):
self.revlogversion = v
self.tagscache = None
+ self.branchcache = None
self.nodetagscache = None
self.encodepats = None
self.decodepats = None
@@ -288,18 +289,57 @@ class localrepository(repo.repository):
self.nodetagscache.setdefault(n, []).append(t)
return self.nodetagscache.get(node, [])
+ def branchtags(self):
+ if self.branchcache != None:
+ return self.branchcache
+
+ self.branchcache = {}
+
+ try:
+ f = self.opener("branches.cache")
+ last, lrev = f.readline().rstrip().split(" ", 1)
+ last, lrev = bin(last), int(lrev)
+ if self.changelog.node(lrev) == last: # sanity check
+ for l in f:
+ node, label = l.rstrip().split(" ", 1)
+ self.branchcache[label] = bin(node)
+ f.close()
+ except IOError:
+ last, lrev = nullid, -1
+ lrev = self.changelog.rev(last)
+
+ tip = self.changelog.count() - 1
+ if lrev != tip:
+ for r in range(lrev + 1, tip + 1):
+ n = self.changelog.node(r)
+ c = self.changelog.read(n)
+ b = c[5].get("branch")
+ if b:
+ self.branchcache[b] = n
+ self._writebranchcache()
+
+ return self.branchcache
+
+ def _writebranchcache(self):
+ f = self.opener("branches.cache", "w")
+ t = self.changelog.tip()
+ f.write("%s %s\n" % (hex(t), self.changelog.count() - 1))
+ for label, node in self.branchcache.iteritems():
+ f.write("%s %s\n" % (hex(node), label))
+
def lookup(self, key):
- try:
+ if key == '.':
+ key = self.dirstate.parents()[0]
+ if key == nullid:
+ raise repo.RepoError(_("no revision checked out"))
+ if key in self.tags():
return self.tags()[key]
- except KeyError:
- if key == '.':
- key = self.dirstate.parents()[0]
- if key == nullid:
- raise repo.RepoError(_("no revision checked out"))
- try:
- return self.changelog.lookup(key)
- except:
- raise repo.RepoError(_("unknown revision '%s'") % key)
+ if key in self.branchtags():
+ return self.branchtags()[key]
+ try:
+ return self.changelog.lookup(key)
+ except:
+ raise repo.RepoError(_("unknown revision '%s'") % key)
def dev(self):
return os.lstat(self.path).st_dev
@@ -571,7 +611,14 @@ class localrepository(repo.repository):
m1 = self.manifest.read(c1[0]).copy()
m2 = self.manifest.read(c2[0])
- if not commit and not remove and not force and p2 == nullid:
+ try:
+ branchname = self.opener("branch").read().rstrip()
+ except IOError:
+ branchname = ""
+ oldname = c1[5].get("branch", "")
+
+ if not commit and not remove and not force and p2 == nullid and \
+ branchname == oldname:
self.ui.status(_("nothing changed\n"))
return None
@@ -636,7 +683,11 @@ class localrepository(repo.repository):
if not lines:
return None
text = '\n'.join(lines)
- n = self.changelog.add(mn, changed + remove, text, tr, p1, p2, user, date)
+ extra = {}
+ if branchname:
+ extra["branch"] = branchname
+ n = self.changelog.add(mn, changed + remove, text, tr, p1, p2,
+ user, date, extra)
self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
parent2=xp2)
tr.close()
new file mode 100755
--- /dev/null
+++ b/tests/test-newbranch
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+hg init t
+cd t
+
+echo foo > a
+hg add a
+hg ci -m "initial" -d "0 0"
+echo foo > .hg/branch
+hg ci -m "add branch name" -d "0 0"
+echo bar > .hg/branch
+hg ci -m "change branch name" -d "0 0"
+rm .hg/branch
+hg ci -m "clear branch name" -d "0 0"
+
+hg co foo
+cat .hg/branch
+echo bleah > a
+hg ci -m "modify a branch" -d "0 0"
+
+hg merge
+cat .hg/branch
+HG_MERGE=true hg ci -m "merge" -d "0 0"
+hg log
+
+
new file mode 100644
--- /dev/null
+++ b/tests/test-newbranch.out
@@ -0,0 +1,43 @@
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+foo
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+foo
+changeset: 5:dc140083783b
+branch: foo
+tag: tip
+parent: 4:98d14f698afe
+parent: 3:9d567d0b51f9
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: merge
+
+changeset: 4:98d14f698afe
+branch: foo
+parent: 1:0079f24813e2
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: modify a branch
+
+changeset: 3:9d567d0b51f9
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: clear branch name
+
+changeset: 2:ed2bbf4e0102
+branch: bar
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: change branch name
+
+changeset: 1:0079f24813e2
+branch: foo
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: add branch name
+
+changeset: 0:db01e8ea3388
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: initial
+