Mercurial > public > mercurial-scm > hg
diff mercurial/localrepo.py @ 45204:ce9ee81df9ff
commitctx: extract _filecommit too
This function is exclusively used in `commitctx`. So we should extract it too
for consistency and to reduce the `localrepo` bloat.
This is part of a larger refactoring/cleanup of the commitctx code to clarify
and augment the logic gathering metadata useful for copy tracing. The current
code is a tad too long and entangled to make such update easy.
Differential Revision: https://phab.mercurial-scm.org/D8710
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 07 Jul 2020 00:18:15 +0200 |
parents | ae5c1a3bc339 |
children | dc457177dbc1 |
line wrap: on
line diff
--- a/mercurial/localrepo.py Mon Jul 06 23:14:52 2020 +0200 +++ b/mercurial/localrepo.py Tue Jul 07 00:18:15 2020 +0200 @@ -2771,145 +2771,6 @@ """Returns the wlock if it's held, or None if it's not.""" return self._currentlock(self._wlockref) - def _filecommit( - self, fctx, manifest1, manifest2, linkrev, tr, includecopymeta, - ): - """ - commit an individual file as part of a larger transaction - - input: - - fctx: a file context with the content we are trying to commit - manifest1: manifest of changeset first parent - manifest2: manifest of changeset second parent - linkrev: revision number of the changeset being created - tr: current transation - individual: boolean, set to False to skip storing the copy data - (only used by the Google specific feature of using - changeset extra as copy source of truth). - - output: (filenode, touched) - - filenode: the filenode that should be used by this changeset - touched: one of: None, 'added' or 'modified' - """ - - fname = fctx.path() - fparent1 = manifest1.get(fname, nullid) - fparent2 = manifest2.get(fname, nullid) - touched = None - if fparent1 == fparent2 == nullid: - touched = 'added' - - if isinstance(fctx, context.filectx): - # This block fast path most comparisons which are usually done. It - # assumes that bare filectx is used and no merge happened, hence no - # need to create a new file revision in this case. - node = fctx.filenode() - if node in [fparent1, fparent2]: - self.ui.debug(b'reusing %s filelog entry\n' % fname) - if ( - fparent1 != nullid - and manifest1.flags(fname) != fctx.flags() - ) or ( - fparent2 != nullid - and manifest2.flags(fname) != fctx.flags() - ): - touched = 'modified' - return node, touched - - flog = self.file(fname) - meta = {} - cfname = fctx.copysource() - fnode = None - - if cfname and cfname != fname: - # Mark the new revision of this file as a copy of another - # file. This copy data will effectively act as a parent - # of this new revision. If this is a merge, the first - # parent will be the nullid (meaning "look up the copy data") - # and the second one will be the other parent. For example: - # - # 0 --- 1 --- 3 rev1 changes file foo - # \ / rev2 renames foo to bar and changes it - # \- 2 -/ rev3 should have bar with all changes and - # should record that bar descends from - # bar in rev2 and foo in rev1 - # - # this allows this merge to succeed: - # - # 0 --- 1 --- 3 rev4 reverts the content change from rev2 - # \ / merging rev3 and rev4 should use bar@rev2 - # \- 2 --- 4 as the merge base - # - - cnode = manifest1.get(cfname) - newfparent = fparent2 - - if manifest2: # branch merge - if fparent2 == nullid or cnode is None: # copied on remote side - if cfname in manifest2: - cnode = manifest2[cfname] - newfparent = fparent1 - - # Here, we used to search backwards through history to try to find - # where the file copy came from if the source of a copy was not in - # the parent directory. However, this doesn't actually make sense to - # do (what does a copy from something not in your working copy even - # mean?) and it causes bugs (eg, issue4476). Instead, we will warn - # the user that copy information was dropped, so if they didn't - # expect this outcome it can be fixed, but this is the correct - # behavior in this circumstance. - - if cnode: - self.ui.debug( - b" %s: copy %s:%s\n" % (fname, cfname, hex(cnode)) - ) - if includecopymeta: - meta[b"copy"] = cfname - meta[b"copyrev"] = hex(cnode) - fparent1, fparent2 = nullid, newfparent - else: - self.ui.warn( - _( - b"warning: can't find ancestor for '%s' " - b"copied from '%s'!\n" - ) - % (fname, cfname) - ) - - elif fparent1 == nullid: - fparent1, fparent2 = fparent2, nullid - elif fparent2 != nullid: - # is one parent an ancestor of the other? - fparentancestors = flog.commonancestorsheads(fparent1, fparent2) - if fparent1 in fparentancestors: - fparent1, fparent2 = fparent2, nullid - elif fparent2 in fparentancestors: - fparent2 = nullid - elif not fparentancestors: - # TODO: this whole if-else might be simplified much more - ms = mergestatemod.mergestate.read(self) - if ( - fname in ms - and ms[fname] == mergestatemod.MERGE_RECORD_MERGED_OTHER - ): - fparent1, fparent2 = fparent2, nullid - - # is the file changed? - text = fctx.data() - if fparent2 != nullid or meta or flog.cmp(fparent1, text): - if touched is None: # do not overwrite added - touched = 'modified' - fnode = flog.add(text, meta, tr, linkrev, fparent1, fparent2) - # are just the flags changed during merge? - elif fname in manifest1 and manifest1.flags(fname) != fctx.flags(): - touched = 'modified' - fnode = fparent1 - else: - fnode = fparent1 - return fnode, touched - def checkcommitpatterns(self, wctx, match, status, fail): """check for commit arguments that aren't committable""" if match.isexact() or match.prefix():