mergestate reading although cheap is not free. Let's read mergestate once on top
and pass it into _filecommit().
In upcoming patches, we will be reading mergestate more in _filecommit().
| marmoute |
| hg-reviewers |
mergestate reading although cheap is not free. Let's read mergestate once on top
and pass it into _filecommit().
In upcoming patches, we will be reading mergestate more in _filecommit().
| No Linters Available |
| No Unit Test Coverage |
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/commit.py (12 lines) | |||
| M | tests/test-annotate.t (2 lines) | |||
| M | tests/test-fastannotate-hg.t (2 lines) |
| Commit | Parents | Author | Summary | Date |
|---|---|---|---|---|
| e82b76915ffa | 092035fbd429 | Pulkit Goyal | Sep 3 2020, 4:44 AM |
| m1ctx = p1.manifestctx() | m1ctx = p1.manifestctx() | ||||
| m2ctx = p2.manifestctx() | m2ctx = p2.manifestctx() | ||||
| mctx = m1ctx.copy() | mctx = m1ctx.copy() | ||||
| m = mctx.read() | m = mctx.read() | ||||
| m1 = m1ctx.read() | m1 = m1ctx.read() | ||||
| m2 = m2ctx.read() | m2 = m2ctx.read() | ||||
| ms = mergestate.mergestate.read(repo) | |||||
| if not ms.active(): | |||||
| ms = None | |||||
| files = metadata.ChangingFiles() | files = metadata.ChangingFiles() | ||||
| # check in files | # check in files | ||||
| added = [] | added = [] | ||||
| removed = list(ctx.removed()) | removed = list(ctx.removed()) | ||||
| linkrev = len(repo) | linkrev = len(repo) | ||||
| repo.ui.note(_(b"committing files:\n")) | repo.ui.note(_(b"committing files:\n")) | ||||
| uipathfn = scmutil.getuipathfn(repo) | uipathfn = scmutil.getuipathfn(repo) | ||||
| for f in sorted(ctx.modified() + ctx.added()): | for f in sorted(ctx.modified() + ctx.added()): | ||||
| repo.ui.note(uipathfn(f) + b"\n") | repo.ui.note(uipathfn(f) + b"\n") | ||||
| try: | try: | ||||
| fctx = ctx[f] | fctx = ctx[f] | ||||
| if fctx is None: | if fctx is None: | ||||
| removed.append(f) | removed.append(f) | ||||
| else: | else: | ||||
| added.append(f) | added.append(f) | ||||
| m[f], is_touched = _filecommit( | m[f], is_touched = _filecommit( | ||||
| repo, fctx, m1, m2, linkrev, tr, writefilecopymeta, | repo, fctx, m1, m2, linkrev, tr, writefilecopymeta, ms | ||||
| ) | ) | ||||
| if is_touched: | if is_touched: | ||||
| if is_touched == 'added': | if is_touched == 'added': | ||||
| files.mark_added(f) | files.mark_added(f) | ||||
| else: | else: | ||||
| files.mark_touched(f) | files.mark_touched(f) | ||||
| m.setflag(f, fctx.flags()) | m.setflag(f, fctx.flags()) | ||||
| except OSError: | except OSError: | ||||
| files.mark_removed(f) | files.mark_removed(f) | ||||
| mn = _commit_manifest(tr, linkrev, ctx, mctx, m, files.touched, added, drop) | mn = _commit_manifest(tr, linkrev, ctx, mctx, m, files.touched, added, drop) | ||||
| return mn, files | return mn, files | ||||
| def _filecommit( | def _filecommit( | ||||
| repo, fctx, manifest1, manifest2, linkrev, tr, includecopymeta, | repo, fctx, manifest1, manifest2, linkrev, tr, includecopymeta, ms=None, | ||||
| ): | ): | ||||
| """ | """ | ||||
| commit an individual file as part of a larger transaction | commit an individual file as part of a larger transaction | ||||
| input: | input: | ||||
| fctx: a file context with the content we are trying to commit | fctx: a file context with the content we are trying to commit | ||||
| manifest1: manifest of changeset first parent | manifest1: manifest of changeset first parent | ||||
| manifest2: manifest of changeset second parent | manifest2: manifest of changeset second parent | ||||
| linkrev: revision number of the changeset being created | linkrev: revision number of the changeset being created | ||||
| tr: current transation | tr: current transation | ||||
| individual: boolean, set to False to skip storing the copy data | individual: boolean, set to False to skip storing the copy data | ||||
| (only used by the Google specific feature of using | (only used by the Google specific feature of using | ||||
| changeset extra as copy source of truth). | changeset extra as copy source of truth). | ||||
| ms: mergestate object (None if no mergestate exists | |||||
| while committing) | |||||
| output: (filenode, touched) | output: (filenode, touched) | ||||
| filenode: the filenode that should be used by this changeset | filenode: the filenode that should be used by this changeset | ||||
| touched: one of: None (mean untouched), 'added' or 'modified' | touched: one of: None (mean untouched), 'added' or 'modified' | ||||
| """ | """ | ||||
| fname = fctx.path() | fname = fctx.path() | ||||
| # is one parent an ancestor of the other? | # is one parent an ancestor of the other? | ||||
| fparentancestors = flog.commonancestorsheads(fparent1, fparent2) | fparentancestors = flog.commonancestorsheads(fparent1, fparent2) | ||||
| if fparent1 in fparentancestors: | if fparent1 in fparentancestors: | ||||
| fparent1, fparent2 = fparent2, nullid | fparent1, fparent2 = fparent2, nullid | ||||
| elif fparent2 in fparentancestors: | elif fparent2 in fparentancestors: | ||||
| fparent2 = nullid | fparent2 = nullid | ||||
| elif not fparentancestors: | elif not fparentancestors: | ||||
| # TODO: this whole if-else might be simplified much more | # TODO: this whole if-else might be simplified much more | ||||
| ms = mergestate.mergestate.read(repo) | if ms and ms.extras(fname).get(b'filenode-source') == b'other': | ||||
| if ms.extras(fname).get(b'filenode-source') == b'other': | |||||
| fparent1, fparent2 = fparent2, nullid | fparent1, fparent2 = fparent2, nullid | ||||
| # is the file changed? | # is the file changed? | ||||
| text = fctx.data() | text = fctx.data() | ||||
| if fparent2 != nullid or meta or flog.cmp(fparent1, text): | if fparent2 != nullid or meta or flog.cmp(fparent1, text): | ||||
| if touched is None: # do not overwrite added | if touched is None: # do not overwrite added | ||||
| touched = 'modified' | touched = 'modified' | ||||
| fnode = flog.add(text, meta, tr, linkrev, fparent1, fparent2) | fnode = flog.add(text, meta, tr, linkrev, fparent1, fparent2) | ||||
| "hg debugsetparents" to merge without ancestor check by "hg merge", | "hg debugsetparents" to merge without ancestor check by "hg merge", | ||||
| and (2) the extension to allow filelog merging between the revision | and (2) the extension to allow filelog merging between the revision | ||||
| and its ancestor by overriding "repo._filecommit". | and its ancestor by overriding "repo._filecommit". | ||||
| $ cat > ../legacyrepo.py <<EOF | $ cat > ../legacyrepo.py <<EOF | ||||
| > from __future__ import absolute_import | > from __future__ import absolute_import | ||||
| > from mercurial import commit, error, extensions, node | > from mercurial import commit, error, extensions, node | ||||
| > def _filecommit(orig, repo, fctx, manifest1, manifest2, | > def _filecommit(orig, repo, fctx, manifest1, manifest2, | ||||
| > linkrev, tr, includecopymeta): | > linkrev, tr, includecopymeta, ms=None): | ||||
| > fname = fctx.path() | > fname = fctx.path() | ||||
| > text = fctx.data() | > text = fctx.data() | ||||
| > flog = repo.file(fname) | > flog = repo.file(fname) | ||||
| > fparent1 = manifest1.get(fname, node.nullid) | > fparent1 = manifest1.get(fname, node.nullid) | ||||
| > fparent2 = manifest2.get(fname, node.nullid) | > fparent2 = manifest2.get(fname, node.nullid) | ||||
| > meta = {} | > meta = {} | ||||
| > copy = fctx.copysource() | > copy = fctx.copysource() | ||||
| > if copy and copy != fname: | > if copy and copy != fname: | ||||
| "hg debugsetparents" to merge without ancestor check by "hg merge", | "hg debugsetparents" to merge without ancestor check by "hg merge", | ||||
| and (2) the extension to allow filelog merging between the revision | and (2) the extension to allow filelog merging between the revision | ||||
| and its ancestor by overriding "repo._filecommit". | and its ancestor by overriding "repo._filecommit". | ||||
| $ cat > ../legacyrepo.py <<EOF | $ cat > ../legacyrepo.py <<EOF | ||||
| > from __future__ import absolute_import | > from __future__ import absolute_import | ||||
| > from mercurial import commit, error, extensions, node | > from mercurial import commit, error, extensions, node | ||||
| > def _filecommit(orig, repo, fctx, manifest1, manifest2, | > def _filecommit(orig, repo, fctx, manifest1, manifest2, | ||||
| > linkrev, tr, includecopymeta): | > linkrev, tr, includecopymeta, ms=None): | ||||
| > fname = fctx.path() | > fname = fctx.path() | ||||
| > text = fctx.data() | > text = fctx.data() | ||||
| > flog = repo.file(fname) | > flog = repo.file(fname) | ||||
| > fparent1 = manifest1.get(fname, node.nullid) | > fparent1 = manifest1.get(fname, node.nullid) | ||||
| > fparent2 = manifest2.get(fname, node.nullid) | > fparent2 = manifest2.get(fname, node.nullid) | ||||
| > meta = {} | > meta = {} | ||||
| > copy = fctx.copysource() | > copy = fctx.copysource() | ||||
| > if copy and copy != fname: | > if copy and copy != fname: | ||||