# HG changeset patch # User FUJIWARA Katsunori # Date 1420016143 -32400 # Node ID 1e6fb8db666ebe09f62cc2abfc08cdb8e8109aa0 # Parent 745e3b48563247f040943d8acff654df21736c53 context: avoid breaking already fixed self._status at ctx.status() Before this patch, "status()" on "workingcommitctx" with "always match" object causes breaking "self._status" in "workingctx._buildstatus()", because "workingctx._buildstatus()" caches the result of "dirstate.status()" into "self._status" for efficiency, even though it should be fixed at construction for committing. For example, template function "diff()" without any patterns in "committemplate" implies "status()" on "workingcommitctx" with "always match" object, via "basectx.diff()" and "patch.diff()". Then, broken "self._status" causes committing unexpected files. To avoid breaking already fixed "self._status" at "ctx.status()", this patch overrides "_buildstatus" in "workingcommitctx". This patch doesn't write out the result of template function "diff()" in "committemplate" in "test-commit.t", because matching against files to be committed still has an issue fixed in subsequent patch. diff -r 745e3b485632 -r 1e6fb8db666e mercurial/context.py --- a/mercurial/context.py Wed Dec 31 17:55:43 2014 +0900 +++ b/mercurial/context.py Wed Dec 31 17:55:43 2014 +0900 @@ -1634,6 +1634,18 @@ super(workingctx, self).__init__(repo, text, user, date, extra, changes) + def _buildstatus(self, other, s, match, + listignored, listclean, listunknown): + """Prevent ``workingctx._buildstatus`` from changing ``self._status`` + """ + s = self._dirstatestatus(match, listignored, listclean, listunknown) + if other != self._repo['.']: + # workingctx._buildstatus doesn't change self._status in this case + superself = super(workingcommitctx, self) + s = superself._buildstatus(other, s, match, + listignored, listclean, listunknown) + return s + class memctx(committablectx): """Use memctx to perform in-memory commits via localrepo.commitctx(). diff -r 745e3b485632 -r 1e6fb8db666e tests/test-commit.t --- a/tests/test-commit.t Wed Dec 31 17:55:43 2014 +0900 +++ b/tests/test-commit.t Wed Dec 31 17:55:43 2014 +0900 @@ -430,6 +430,34 @@ [255] $ cat >> .hg/hgrc < [committemplate] + > changeset = {desc} + > HG: files={files} + > HG: + > {splitlines(diff()) % '' + > }HG: + > HG: files={files}\n + > EOF + $ hg status -amr + M changed + A added + R removed + $ HGEDITOR=cat hg commit -q -e -m "foo bar" changed + foo bar + HG: files=changed + HG: + HG: + HG: files=changed + $ hg status -amr + A added + R removed + $ hg parents --template "M {file_mods}\nA {file_adds}\nR {file_dels}\n" + M changed + A + R + $ hg rollback -q + + $ cat >> .hg/hgrc < # disable customizing for subsequent tests > [committemplate] > changeset = diff -r 745e3b485632 -r 1e6fb8db666e tests/test-context.py --- a/tests/test-context.py Wed Dec 31 17:55:43 2014 +0900 +++ b/tests/test-context.py Wed Dec 31 17:55:43 2014 +0900 @@ -96,3 +96,25 @@ print 'wctx._status=%s' % (str(wctx._status)) print actx2.status(other=wctx, listclean=True) print 'wctx._status=%s' % (str(wctx._status)) + +print "== checking workingcommitctx.status:" + +wcctx = context.workingcommitctx(repo, + scmutil.status(['bar-m'], + ['bar-a'], + [], + [], [], [], []), + text='', date='0 0') +print 'wcctx._status=%s' % (str(wcctx._status)) + +print '=== with "always match":' +actx1.status(other=wcctx) +print 'wcctx._status=%s' % (str(wcctx._status)) +actx2.status(other=wcctx) +print 'wcctx._status=%s' % (str(wcctx._status)) + +print '=== with "always match" and "listclean=True":' +actx1.status(other=wcctx, listclean=True) +print 'wcctx._status=%s' % (str(wcctx._status)) +actx2.status(other=wcctx, listclean=True) +print 'wcctx._status=%s' % (str(wcctx._status)) diff -r 745e3b485632 -r 1e6fb8db666e tests/test-context.py.out --- a/tests/test-context.py.out Wed Dec 31 17:55:43 2014 +0900 +++ b/tests/test-context.py.out Wed Dec 31 17:55:43 2014 +0900 @@ -24,3 +24,11 @@ wctx._status= wctx._status= +== checking workingcommitctx.status: +wcctx._status= +=== with "always match": +wcctx._status= +wcctx._status= +=== with "always match" and "listclean=True": +wcctx._status= +wcctx._status=