Details
Details
- Reviewers
yuja - Group Reviewers
hg-reviewers - Commits
- rHG3723b42ff953: filemerge: move temp file unlinks to _maketempfiles
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Lint
Lint Skipped - Unit
Unit Tests Skipped
yuja |
hg-reviewers |
Lint Skipped |
Unit Tests Skipped |
Path | Packages | |||
---|---|---|---|---|
M | mercurial/filemerge.py (16 lines) |
# filemerge.py - file-level merge handling for Mercurial | # filemerge.py - file-level merge handling for Mercurial | ||||
# | # | ||||
# Copyright 2006, 2007, 2008 Matt Mackall <mpm@selenic.com> | # Copyright 2006, 2007, 2008 Matt Mackall <mpm@selenic.com> | ||||
# | # | ||||
# This software may be used and distributed according to the terms of the | # This software may be used and distributed according to the terms of the | ||||
# GNU General Public License version 2 or any later version. | # GNU General Public License version 2 or any later version. | ||||
from __future__ import absolute_import | from __future__ import absolute_import | ||||
import contextlib | |||||
import os | import os | ||||
import re | import re | ||||
import tempfile | import tempfile | ||||
from .i18n import _ | from .i18n import _ | ||||
from .node import nullid, short | from .node import nullid, short | ||||
from . import ( | from . import ( | ||||
def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None): | def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None): | ||||
tool, toolpath, binary, symlink = toolconf | tool, toolpath, binary, symlink = toolconf | ||||
if fcd.isabsent() or fco.isabsent(): | if fcd.isabsent() or fco.isabsent(): | ||||
repo.ui.warn(_('warning: %s cannot merge change/delete conflict ' | repo.ui.warn(_('warning: %s cannot merge change/delete conflict ' | ||||
'for %s\n') % (tool, fcd.path())) | 'for %s\n') % (tool, fcd.path())) | ||||
return False, 1, None | return False, 1, None | ||||
unused, unused, unused, back = files | unused, unused, unused, back = files | ||||
localpath = _workingpath(repo, fcd) | localpath = _workingpath(repo, fcd) | ||||
basepath, otherpath = _maketempfiles(repo, fco, fca) | with _maketempfiles(repo, fco, fca) as temppaths: | ||||
try: | basepath, otherpath = temppaths | ||||
outpath = "" | outpath = "" | ||||
mylabel, otherlabel = labels[:2] | mylabel, otherlabel = labels[:2] | ||||
if len(labels) >= 3: | if len(labels) >= 3: | ||||
baselabel = labels[2] | baselabel = labels[2] | ||||
else: | else: | ||||
baselabel = 'base' | baselabel = 'base' | ||||
env = {'HG_FILE': fcd.path(), | env = {'HG_FILE': fcd.path(), | ||||
'HG_MY_NODE': short(mynode), | 'HG_MY_NODE': short(mynode), | ||||
cmd = toolpath + ' ' + args | cmd = toolpath + ' ' + args | ||||
if _toolbool(ui, tool, "gui"): | if _toolbool(ui, tool, "gui"): | ||||
repo.ui.status(_('running merge tool %s for file %s\n') % | repo.ui.status(_('running merge tool %s for file %s\n') % | ||||
(tool, fcd.path())) | (tool, fcd.path())) | ||||
repo.ui.debug('launching merge tool: %s\n' % cmd) | repo.ui.debug('launching merge tool: %s\n' % cmd) | ||||
r = ui.system(cmd, cwd=repo.root, environ=env, blockedtag='mergetool') | r = ui.system(cmd, cwd=repo.root, environ=env, blockedtag='mergetool') | ||||
repo.ui.debug('merge tool returned: %d\n' % r) | repo.ui.debug('merge tool returned: %d\n' % r) | ||||
return True, r, False | return True, r, False | ||||
finally: | |||||
util.unlink(basepath) | |||||
util.unlink(otherpath) | |||||
def _formatconflictmarker(ctx, template, label, pad): | def _formatconflictmarker(ctx, template, label, pad): | ||||
"""Applies the given template to the ctx, prefixed by the label. | """Applies the given template to the ctx, prefixed by the label. | ||||
Pad is the minimum width of the label prefix, so that multiple markers | Pad is the minimum width of the label prefix, so that multiple markers | ||||
can have aligned templated parts. | can have aligned templated parts. | ||||
""" | """ | ||||
if ctx.node() is None: | if ctx.node() is None: | ||||
if isinstance(fcd, context.overlayworkingfilectx): | if isinstance(fcd, context.overlayworkingfilectx): | ||||
util.writefile(back, fcd.data()) | util.writefile(back, fcd.data()) | ||||
else: | else: | ||||
util.copyfile(a, back) | util.copyfile(a, back) | ||||
# A arbitraryfilectx is returned, so we can run the same functions on | # A arbitraryfilectx is returned, so we can run the same functions on | ||||
# the backup context regardless of where it lives. | # the backup context regardless of where it lives. | ||||
return context.arbitraryfilectx(back, repo=repo) | return context.arbitraryfilectx(back, repo=repo) | ||||
@contextlib.contextmanager | |||||
def _maketempfiles(repo, fco, fca): | def _maketempfiles(repo, fco, fca): | ||||
"""Writes out `fco` and `fca` as temporary files, so an external merge | """Writes out `fco` and `fca` as temporary files, so an external merge | ||||
tool may use them. | tool may use them. | ||||
""" | """ | ||||
def temp(prefix, ctx): | def temp(prefix, ctx): | ||||
fullbase, ext = os.path.splitext(ctx.path()) | fullbase, ext = os.path.splitext(ctx.path()) | ||||
pre = "%s~%s." % (os.path.basename(fullbase), prefix) | pre = "%s~%s." % (os.path.basename(fullbase), prefix) | ||||
(fd, name) = tempfile.mkstemp(prefix=pre, suffix=ext) | (fd, name) = tempfile.mkstemp(prefix=pre, suffix=ext) | ||||
data = repo.wwritedata(ctx.path(), ctx.data()) | data = repo.wwritedata(ctx.path(), ctx.data()) | ||||
f = os.fdopen(fd, r"wb") | f = os.fdopen(fd, r"wb") | ||||
f.write(data) | f.write(data) | ||||
f.close() | f.close() | ||||
return name | return name | ||||
b = temp("base", fca) | b = temp("base", fca) | ||||
c = temp("other", fco) | c = temp("other", fco) | ||||
try: | |||||
return b, c | yield b, c | ||||
finally: | |||||
util.unlink(b) | |||||
util.unlink(c) | |||||
def _filemerge(premerge, repo, wctx, 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 |