--- a/mercurial/context.py Wed Jun 18 23:16:51 2008 +0200
+++ b/mercurial/context.py Wed Jun 18 23:45:49 2008 +0200
@@ -444,11 +444,46 @@
class workingctx(changectx):
"""A workingctx object makes access to data related to
- the current working directory convenient."""
- def __init__(self, repo):
+ the current working directory convenient.
+ parents - a pair of parent nodeids, or None to use the dirstate.
+ date - any valid date string or (unixtime, offset), or None.
+ user - username string, or None.
+ extra - a dictionary of extra values, or None.
+ changes - a list of file lists as returned by localrepo.status()
+ or None to use the repository status.
+ """
+ def __init__(self, repo, parents=None, text="", user=None, date=None,
+ extra=None, changes=None):
self._repo = repo
self._rev = None
self._node = None
+ self._text = text
+ if date is not None:
+ self._date = util.parsedate(date)
+ else:
+ self._date = util.makedate()
+ if user:
+ self._user = user
+ else:
+ self._user = self._repo.ui.username()
+ if parents:
+ p1, p2 = parents
+ self._parents = [self._repo.changectx(p) for p in (p1, p2)]
+ if changes:
+ self._status = list(changes)
+
+ self._extra = {}
+ if extra:
+ self._extra = extra.copy()
+ if 'branch' not in self._extra:
+ branch = self._repo.dirstate.branch()
+ try:
+ branch = branch.decode('UTF-8').encode('UTF-8')
+ except UnicodeDecodeError:
+ raise util.Abort(_('branch name not in UTF-8!'))
+ self._extra['branch'] = branch
+ if self._extra['branch'] == '':
+ self._extra['branch'] = 'default'
def __str__(self):
return str(self._parents[0]) + "+"
@@ -495,9 +530,9 @@
def manifest(self): return self._manifest
- def user(self): return self._repo.ui.username()
- def date(self): return util.makedate()
- def description(self): return ""
+ def user(self): return self._user
+ def date(self): return self._date
+ def description(self): return self._text
def files(self):
f = self.modified() + self.added() + self.removed()
f.sort()
@@ -509,7 +544,8 @@
def deleted(self): return self._status[3]
def unknown(self): return self._status[4]
def clean(self): return self._status[5]
- def branch(self): return self._repo.dirstate.branch()
+ def branch(self): return self._extra['branch']
+ def extra(self): return self._extra
def tags(self):
t = []
--- a/mercurial/localrepo.py Wed Jun 18 23:16:51 2008 +0200
+++ b/mercurial/localrepo.py Wed Jun 18 23:45:49 2008 +0200
@@ -683,19 +683,21 @@
self._wlockref = weakref.ref(l)
return l
- def filecommit(self, fn, manifest1, manifest2, linkrev, tr, changelist):
+ def filecommit(self, fctx, manifest1, manifest2, linkrev, tr, changelist):
"""
commit an individual file as part of a larger transaction
"""
- t = self.wread(fn)
+ fn = fctx.path()
+ t = fctx.data()
fl = self.file(fn)
fp1 = manifest1.get(fn, nullid)
fp2 = manifest2.get(fn, nullid)
meta = {}
- cp = self.dirstate.copied(fn)
- if cp and cp != fn:
+ cp = fctx.renamed()
+ if cp and cp[0] != fn:
+ cp = cp[0]
# Mark the new revision of this file as a copy of another
# file. This copy data will effectively act as a parent
# of this new revision. If this is a merge, the first
@@ -754,36 +756,13 @@
def commit(self, files=None, text="", user=None, date=None,
match=None, force=False, force_editor=False,
p1=None, p2=None, extra={}, empty_ok=False):
- wlock = lock = tr = None
- valid = 0 # don't save the dirstate if this isn't set
+ wlock = lock = None
if files:
files = util.unique(files)
try:
wlock = self.wlock()
lock = self.lock()
- commit = []
- remove = []
- changed = []
use_dirstate = (p1 is None) # not rawcommit
- extra = extra.copy()
-
- if use_dirstate:
- if files:
- for f in files:
- s = self.dirstate[f]
- if s in 'nma':
- commit.append(f)
- elif s == 'r':
- remove.append(f)
- else:
- self.ui.warn(_("%s not tracked!\n") % f)
- else:
- changes = self.status(match=match)[:5]
- modified, added, removed, deleted, unknown = changes
- commit = modified + added
- remove = removed
- else:
- commit = files
if use_dirstate:
p1, p2 = self.dirstate.parents()
@@ -793,25 +772,51 @@
(match and (match.files() or match.anypats()))):
raise util.Abort(_('cannot partially commit a merge '
'(do not specify files or patterns)'))
+
+ if files:
+ modified, removed = [], []
+ for f in files:
+ s = self.dirstate[f]
+ if s in 'nma':
+ modified.append(f)
+ elif s == 'r':
+ removed.append(f)
+ else:
+ self.ui.warn(_("%s not tracked!\n") % f)
+ changes = [modified, [], removed, [], []]
+ else:
+ changes = self.status(match=match)
else:
p1, p2 = p1, p2 or nullid
update_dirstate = (self.dirstate.parents()[0] == p1)
+ changes = [files, [], [], [], []]
+ wctx = context.workingctx(self, (p1, p2), text, user, date,
+ extra, changes)
+ return self._commitctx(wctx, force, force_editor, empty_ok,
+ use_dirstate, update_dirstate)
+ finally:
+ del lock, wlock
+
+ def _commitctx(self, wctx, force=False, force_editor=False, empty_ok=False,
+ use_dirstate=True, update_dirstate=True):
+ tr = None
+ valid = 0 # don't save the dirstate if this isn't set
+ try:
+ commit = wctx.modified() + wctx.added()
+ remove = wctx.removed()
+ extra = wctx.extra().copy()
+ branchname = extra['branch']
+ user = wctx.user()
+ text = wctx.description()
+
+ p1, p2 = [p.node() for p in wctx.parents()]
c1 = self.changelog.read(p1)
c2 = self.changelog.read(p2)
m1 = self.manifest.read(c1[0]).copy()
m2 = self.manifest.read(c2[0])
if use_dirstate:
- branchname = self.workingctx().branch()
- try:
- branchname = branchname.decode('UTF-8').encode('UTF-8')
- except UnicodeDecodeError:
- raise util.Abort(_('branch name not in UTF-8!'))
- else:
- branchname = ""
-
- if use_dirstate:
oldname = c1[5].get("branch") # stored in UTF-8
if (not commit and not remove and not force and p2 == nullid
and branchname == oldname):
@@ -829,16 +834,16 @@
# check in files
new = {}
+ changed = []
linkrev = self.changelog.count()
commit.sort()
- is_exec = util.execfunc(self.root, m1.execf)
- is_link = util.linkfunc(self.root, m1.linkf)
for f in commit:
self.ui.note(f + "\n")
try:
- new[f] = self.filecommit(f, m1, m2, linkrev, trp, changed)
- new_exec = is_exec(f)
- new_link = is_link(f)
+ fctx = wctx.filectx(f)
+ new[f] = self.filecommit(fctx, m1, m2, linkrev, trp, changed)
+ new_exec = fctx.isexec()
+ new_link = fctx.islink()
if ((not changed or changed[-1] != f) and
m2.get(f) != new[f]):
# mention the file in the changelog if some
@@ -874,7 +879,6 @@
(new, removed))
# add changeset
- user = user or self.ui.username()
if (not empty_ok and not text) or force_editor:
edittext = []
if text:
@@ -899,9 +903,6 @@
text = self.ui.edit("\n".join(edittext), user)
os.chdir(olddir)
- if branchname:
- extra["branch"] = branchname
-
lines = [line.rstrip() for line in text.rstrip().splitlines()]
while lines and not lines[0]:
del lines[0]
@@ -910,7 +911,7 @@
text = '\n'.join(lines)
n = self.changelog.add(mn, changed + removed, text, trp, p1, p2,
- user, date, extra)
+ user, wctx.date(), extra)
self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
parent2=xp2)
tr.close()
@@ -930,7 +931,7 @@
finally:
if not valid: # don't save our updated dirstate
self.dirstate.invalidate()
- del tr, lock, wlock
+ del tr
def walk(self, match, node=None):
'''