# HG changeset patch # User Matt Mackall # Date 1161129277 18000 # Node ID 357b5589dc62a0037e8460d46456f531768c1c51 # Parent 2576b6731524789435d590df4868498cde24048c# Parent 5207cf649abe173239db83cabf68ea8dedddfd77 Merge with crew diff --git a/mercurial/changelog.py b/mercurial/changelog.py --- 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') diff --git a/mercurial/commands.py b/mercurial/commands.py --- 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] diff --git a/mercurial/context.py b/mercurial/context.py --- 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""" diff --git a/mercurial/hg.py b/mercurial/hg.py --- 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] diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- 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() diff --git a/tests/test-newbranch b/tests/test-newbranch 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 + + diff --git a/tests/test-newbranch.out b/tests/test-newbranch.out 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 +