In the in-memory merge branch. we'll need to call a function (`flushall`) on
the wctx inside of _xmerge.
This prepares the way so it can be done without hacks like `fcd.ctx()`.
| quark |
| hg-reviewers |
In the in-memory merge branch. we'll need to call a function (`flushall`) on
the wctx inside of _xmerge.
This prepares the way so it can be done without hacks like `fcd.ctx()`.
| Automatic diff as part of commit; lint not applicable. |
| Automatic diff as part of commit; unit tests not applicable. |
It's now back in the stack.
| Path | Packages | |||
|---|---|---|---|---|
| M | hgext/largefiles/overrides.py (4 lines) | |||
| M | mercurial/filemerge.py (12 lines) | |||
| M | mercurial/merge.py (10 lines) | |||
| M | tests/failfilemerge.py (3 lines) |
| # make sure lfile doesn't get synclfdirstate'd as normal | # make sure lfile doesn't get synclfdirstate'd as normal | ||||
| lfdirstate.add(lfile) | lfdirstate.add(lfile) | ||||
| lfdirstate.write() | lfdirstate.write() | ||||
| return orig(repo, actions, branchmerge) | return orig(repo, actions, branchmerge) | ||||
| # Override filemerge to prompt the user about how they wish to merge | # Override filemerge to prompt the user about how they wish to merge | ||||
| # largefiles. This will handle identical edits without prompting the user. | # largefiles. This will handle identical edits without prompting the user. | ||||
| def overridefilemerge(origfn, premerge, repo, mynode, orig, fcd, fco, fca, | def overridefilemerge(origfn, premerge, repo, wctx, mynode, orig, fcd, fco, fca, | ||||
| labels=None): | labels=None): | ||||
| if not lfutil.isstandin(orig) or fcd.isabsent() or fco.isabsent(): | if not lfutil.isstandin(orig) or fcd.isabsent() or fco.isabsent(): | ||||
| return origfn(premerge, repo, mynode, orig, fcd, fco, fca, | return origfn(premerge, repo, wctx, mynode, orig, fcd, fco, fca, | ||||
| labels=labels) | labels=labels) | ||||
| ahash = lfutil.readasstandin(fca).lower() | ahash = lfutil.readasstandin(fca).lower() | ||||
| dhash = lfutil.readasstandin(fcd).lower() | dhash = lfutil.readasstandin(fcd).lower() | ||||
| ohash = lfutil.readasstandin(fco).lower() | ohash = lfutil.readasstandin(fco).lower() | ||||
| if (ohash != ahash and | if (ohash != ahash and | ||||
| ohash != dhash and | ohash != dhash and | ||||
| (dhash == ahash or | (dhash == ahash or | ||||
| f.close() | f.close() | ||||
| return name | return name | ||||
| b = temp("base", fca) | b = temp("base", fca) | ||||
| c = temp("other", fco) | c = temp("other", fco) | ||||
| return b, c | return b, c | ||||
| def _filemerge(premerge, repo, mynode, orig, fcd, fco, fca, labels=None): | def _filemerge(premerge, repo, wctx, mynode, orig, fcd, fco, fca, labels=None): | ||||
| """perform a 3-way merge in the working directory | """perform a 3-way merge in the working directory | ||||
| premerge = whether this is a premerge | premerge = whether this is a premerge | ||||
| mynode = parent node before merge | mynode = parent node before merge | ||||
| orig = original local filename before merge | orig = original local filename before merge | ||||
| fco = other file context | fco = other file context | ||||
| fca = ancestor file context | fca = ancestor file context | ||||
| fcd = local file context for current/destination file | fcd = local file context for current/destination file | ||||
| if back is not None and _toolbool(ui, tool, "fixeol"): | if back is not None and _toolbool(ui, tool, "fixeol"): | ||||
| _matcheol(_workingpath(repo, fcd), back) | _matcheol(_workingpath(repo, fcd), back) | ||||
| return r | return r | ||||
| def _workingpath(repo, ctx): | def _workingpath(repo, ctx): | ||||
| return repo.wjoin(ctx.path()) | return repo.wjoin(ctx.path()) | ||||
| def premerge(repo, mynode, orig, fcd, fco, fca, labels=None): | def premerge(repo, wctx, mynode, orig, fcd, fco, fca, labels=None): | ||||
| return _filemerge(True, repo, mynode, orig, fcd, fco, fca, labels=labels) | return _filemerge(True, repo, wctx, mynode, orig, fcd, fco, fca, | ||||
| labels=labels) | |||||
| def filemerge(repo, mynode, orig, fcd, fco, fca, labels=None): | def filemerge(repo, wctx, mynode, orig, fcd, fco, fca, labels=None): | ||||
| return _filemerge(False, repo, mynode, orig, fcd, fco, fca, labels=labels) | return _filemerge(False, repo, wctx, mynode, orig, fcd, fco, fca, | ||||
| labels=labels) | |||||
| def loadinternalmerge(ui, extname, registrarobj): | def loadinternalmerge(ui, extname, registrarobj): | ||||
| """Load internal merge tool from specified registrarobj | """Load internal merge tool from specified registrarobj | ||||
| """ | """ | ||||
| for name, func in registrarobj._table.iteritems(): | for name, func in registrarobj._table.iteritems(): | ||||
| fullname = ':' + name | fullname = ':' + name | ||||
| internals[fullname] = func | internals[fullname] = func | ||||
| internals['internal:' + name] = func | internals['internal:' + name] = func | ||||
| internalsdoc[fullname] = func | internalsdoc[fullname] = func | ||||
| # load built-in merge tools explicitly to setup internalsdoc | # load built-in merge tools explicitly to setup internalsdoc | ||||
| loadinternalmerge(None, None, internaltool) | loadinternalmerge(None, None, internaltool) | ||||
| # tell hggettext to extract docstrings from these functions: | # tell hggettext to extract docstrings from these functions: | ||||
| i18nfunctions = internals.values() | i18nfunctions = internals.values() | ||||
| if preresolve: | if preresolve: | ||||
| # restore local | # restore local | ||||
| if hash != nullhex: | if hash != nullhex: | ||||
| f = self._repo.vfs('merge/' + hash) | f = self._repo.vfs('merge/' + hash) | ||||
| wctx[dfile].write(f.read(), flags) | wctx[dfile].write(f.read(), flags) | ||||
| f.close() | f.close() | ||||
| else: | else: | ||||
| wctx[dfile].remove(ignoremissing=True) | wctx[dfile].remove(ignoremissing=True) | ||||
| complete, r, deleted = filemerge.premerge(self._repo, self._local, | complete, r, deleted = filemerge.premerge(self._repo, wctx, | ||||
| lfile, fcd, fco, fca, | self._local, lfile, fcd, | ||||
| fco, fca, | |||||
| labels=self._labels) | labels=self._labels) | ||||
| else: | else: | ||||
| complete, r, deleted = filemerge.filemerge(self._repo, self._local, | complete, r, deleted = filemerge.filemerge(self._repo, wctx, | ||||
| lfile, fcd, fco, fca, | self._local, lfile, fcd, | ||||
| fco, fca, | |||||
| labels=self._labels) | labels=self._labels) | ||||
| if r is None: | if r is None: | ||||
| # no real conflict | # no real conflict | ||||
| del self._state[dfile] | del self._state[dfile] | ||||
| self._stateextras.pop(dfile, None) | self._stateextras.pop(dfile, None) | ||||
| self._dirty = True | self._dirty = True | ||||
| elif not r: | elif not r: | ||||
| self.mark(dfile, 'r') | self.mark(dfile, 'r') | ||||
| # extension to emulate interrupting filemerge._filemerge | # extension to emulate interrupting filemerge._filemerge | ||||
| from __future__ import absolute_import | from __future__ import absolute_import | ||||
| from mercurial import ( | from mercurial import ( | ||||
| error, | error, | ||||
| extensions, | extensions, | ||||
| filemerge, | filemerge, | ||||
| ) | ) | ||||
| def failfilemerge(filemergefn, | def failfilemerge(filemergefn, | ||||
| premerge, repo, mynode, orig, fcd, fco, fca, labels=None): | premerge, repo, wctx, mynode, orig, fcd, fco, fca, | ||||
| labels=None): | |||||
| raise error.Abort("^C") | raise error.Abort("^C") | ||||
| return filemergefn(premerge, repo, mynode, orig, fcd, fco, fca, labels) | return filemergefn(premerge, repo, mynode, orig, fcd, fco, fca, labels) | ||||
| def extsetup(ui): | def extsetup(ui): | ||||
| extensions.wrapfunction(filemerge, '_filemerge', | extensions.wrapfunction(filemerge, '_filemerge', | ||||
| failfilemerge) | failfilemerge) | ||||