Mercurial > hg
diff mercurial/localrepo.py @ 39111:46da52f4b820
commit: try hard to reuse p1 manifest if nothing changed
This is all for commit reproducibility on "hg convert".
With this change, p1 manifest is reused if ctx.files() *to be committed* is
empty, and if new manifest entry is identical to p1. This is important
property for "hg convert" since memctx.files() built from a convert source
may be either a) more narrowed thanks to a committed ctx.files() which
provides more accurate status, or b) containing redundant files because of
sloppy filtering on e.g. octopus merge.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 07 Jul 2018 22:40:39 +0900 |
parents | a915db9a5e77 |
children | 7a9f15ed3b96 |
line wrap: on
line diff
--- a/mercurial/localrepo.py Sun Aug 12 18:44:42 2018 +0900 +++ b/mercurial/localrepo.py Sat Jul 07 22:40:39 2018 +0900 @@ -2039,6 +2039,11 @@ def commitctx(self, ctx, error=False): """Add a new revision to current repository. Revision information is passed via the context argument. + + ctx.files() should list all files involved in this commit, i.e. + modified/added/removed files. On merge, it may be wider than the + ctx.files() to be committed, since any file nodes derived directly + from p1 or p2 are excluded from the committed ctx.files(). """ tr = None @@ -2091,15 +2096,29 @@ raise # update manifest - self.ui.note(_("committing manifest\n")) removed = [f for f in sorted(removed) if f in m1 or f in m2] drop = [f for f in removed if f in m] for f in drop: del m[f] - mn = mctx.write(trp, linkrev, - p1.manifestnode(), p2.manifestnode(), - added, drop) files = changed + removed + md = None + if not files: + # if no "files" actually changed in terms of the changelog, + # try hard to detect unmodified manifest entry so that the + # exact same commit can be reproduced later on convert. + md = m1.diff(m, scmutil.matchfiles(self, ctx.files())) + if not files and md: + self.ui.debug('not reusing manifest (no file change in ' + 'changelog, but manifest differs)\n') + if files or md: + self.ui.note(_("committing manifest\n")) + mn = mctx.write(trp, linkrev, + p1.manifestnode(), p2.manifestnode(), + added, drop) + else: + self.ui.debug('reusing manifest form p1 (listed files ' + 'actually unchanged)\n') + mn = p1.manifestnode() else: self.ui.debug('reusing manifest from p1 (no file change)\n') mn = p1.manifestnode()