Patchwork [2,of,8,RFC] localrepo: provide working context by integer revision next to tip (crazy idea)

login
register
mail settings
Submitter Yuya Nishihara
Date Aug. 19, 2014, 10:56 p.m.
Message ID <c14c51bf90582e64114b.1408488976@mimosa>
Download mbox | patch
Permalink /patch/5525/
State Changes Requested
Headers show

Comments

Yuya Nishihara - Aug. 19, 2014, 10:56 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1408163145 -32400
#      Sat Aug 16 13:25:45 2014 +0900
# Node ID c14c51bf90582e64114bf5b274d1871558699c6a
# Parent  0e8b104fd419419ddf9ec3c9df4df1991e9ba3a5
localrepo: provide working context by integer revision next to tip (crazy idea)

This will be used to implement revision specifier for workingctx.

It might sounds crazy to map both len(repo) and None to workingctx, but None
can't be used because it messes up integer comparison in scmutil.revpair()
and revset.  On the other hand, rev=None is sometimes useful in context where
optional "rev" argument is mapped to workingctx by default, e.g. "node" of
hg.update().

This patch does not provide command-level interface to specify rev=len(repo),
so there's no test yet.

Patch

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -963,9 +963,14 @@  class committablectx(basectx):
     """A committablectx object provides common functionality for a context that
     wants the ability to commit, e.g. workingctx or memctx."""
     def __init__(self, repo, text="", user=None, date=None, extra=None,
-                 changes=None):
+                 changes=None, changeid=None):
         self._repo = repo
-        self._rev = None
+        # optional changeid can be used to place uncommitted revision virtually
+        # on top of changelog. node is None even if changeid is specified until
+        # we can determine the correct value for uncommitted context.
+        assert (changeid is None
+                or isinstance(changeid, int) and changeid >= len(repo))
+        self._rev = changeid
         self._node = None
         self._text = text
         if date:
@@ -1187,8 +1192,9 @@  class workingctx(committablectx):
                or None to use the repository status.
     """
     def __init__(self, repo, text="", user=None, date=None, extra=None,
-                 changes=None):
-        super(workingctx, self).__init__(repo, text, user, date, extra, changes)
+                 changes=None, changeid=None):
+        super(workingctx, self).__init__(repo, text, user, date, extra, changes,
+                                         changeid)
 
     def __iter__(self):
         d = self._repo.dirstate
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -445,6 +445,8 @@  class localrepository(object):
     def __getitem__(self, changeid):
         if changeid is None:
             return context.workingctx(self)
+        if changeid == len(self):
+            return context.workingctx(self, changeid=len(self))
         return context.changectx(self, changeid)
 
     def __contains__(self, changeid):