[PATCH 18 of 19] commit: move commit preparation from localrepo.commit to workingctx
David Schleimer
dschleimer at fb.com
Sun Feb 10 23:30:08 UTC 2013
# HG changeset patch
# User David Schleimer <dschleimer at fb.com>
# Date 1360534411 28800
# Node ID 7a150f3cfd3ea54a11dbe5754671d3e82420d40b
# Parent 06702855099328ba716cd3096706357b379f6b50
commit: move commit preparation from localrepo.commit to workingctx
This moves the logic for change filtering, subrepo munging, and
subrepo-related validation out of localrepo and into workingcontext.
The long-term goal is to make this logic more accessible to other
code.
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -1213,6 +1213,60 @@
return subs
+ def preparecommit(self, match, force):
+ """Prepare this workingcontext for commit.
+
+ Includes validation, subrepo state munging, and change
+ filtering.
+ """
+ merge = len(self.parents()) > 1
+
+ def fail(f, msg):
+ raise util.Abort('%s: %s' % (f, msg))
+
+ if not match:
+ match = matchmod.always(self._repo.root, '')
+
+ if not force:
+ vdirs = []
+ match.dir = vdirs.append
+ match.bad = fail
+
+ if (not force and merge and match and
+ (match.files() or match.anypats())):
+ raise util.Abort(_('cannot partially commit a merge '
+ '(do not specify files or patterns)'))
+
+ self.status(match=match, clean=force)
+
+ if force:
+ # mq may commit unchanged files
+ self.modified().extend(self.clean())
+
+ subs = self.preparesubstate(match, force)
+
+ # make sure all explicit patterns are matched
+ if not force and match.files():
+ matched = set(self.files())
+
+ for f in match.files():
+ f = self._repo.dirstate.normalize(f)
+ if f == '.' or f in matched or f in self.substate:
+ continue
+ if f in self.deleted(): # missing
+ fail(f, _('file not found!'))
+ if f in vdirs: # visited directory
+ d = f + '/'
+ for mf in matched:
+ if mf.startswith(d):
+ break
+ else:
+ fail(f, _("no match under directory!"))
+ elif f not in self._repo.dirstate:
+ fail(f, _("file not tracked!"))
+
+ return subs
+
def commitablesubstate(self, match, force):
subs = []
commitsubs = set()
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1130,54 +1130,12 @@
supplied, it is called to get a commit message.
"""
- def fail(f, msg):
- raise util.Abort('%s: %s' % (f, msg))
-
- if not match:
- match = matchmod.always(self.root, '')
-
- if not force:
- vdirs = []
- match.dir = vdirs.append
- match.bad = fail
-
wlock = self.wlock()
try:
wctx = self[None]
merge = len(wctx.parents()) > 1
- if (not force and merge and match and
- (match.files() or match.anypats())):
- raise util.Abort(_('cannot partially commit a merge '
- '(do not specify files or patterns)'))
-
- wctx.status(match=match, clean=force)
- if force:
- # mq may commit unchanged files
- wctx.modified().extend(wctx.clean())
-
- subs = wctx.preparesubstate(match, force)
-
- # make sure all explicit patterns are matched
- if not force and match.files():
- matched = set(wctx.files())
-
- for f in match.files():
- f = self.dirstate.normalize(f)
- if f == '.' or f in matched or f in wctx.substate:
- continue
- if f in wctx.deleted(): # missing
- fail(f, _('file not found!'))
- if f in vdirs: # visited directory
- d = f + '/'
- for mf in matched:
- if mf.startswith(d):
- break
- else:
- fail(f, _("no match under directory!"))
- elif f not in self.dirstate:
- fail(f, _("file not tracked!"))
-
+ subs = wctx.preparecommit(match, force)
cctx = wctx
if (not force and not extra.get("close") and not merge
More information about the Mercurial-devel
mailing list