Index: mercurial/context.py =================================================================== --- mercurial/context.py +++ mercurial/context.py @@ -2190,6 +2190,9 @@ def commit(self, text, parents=None, date=None, extra=None, editor=None, user=None, branch=None): + # We need to discard any keys that are actually clean before the empty + # commit check. + self._compact() allowemptycommit = (len(self._cache) or self._repo.ui.configbool('ui', 'allowemptycommit')) if not allowemptycommit: @@ -2211,6 +2214,29 @@ self._cache = {} self._writeorder = [] + def _compact(self): + """Removes keys from the cache that are actually clean, by comparing + them with the underlting context. + + This can occur during the merge process, e.g. by passing --tool :local + to resolve a conflict. + """ + keys = [] + for path in self._cache.keys(): + cache = self._cache[path] + try: + underlying = self._wrappedctx[path] + if (underlying.data() == cache['data'] and + underlying.flags() == cache['flags']): + keys.append(path) + except error.ManifestLookupError: + # Path not in the underlying manifest (created). + continue + + for path in keys: + del self._cache[path] + return keys + def _markdirty(self, path, exists, data=None, date=None, flags=''): if path not in self._cache: self._writeorder.append(path)