##// END OF EJS Templates
mergetools: add new conflict marker format with diffs in...
mergetools: add new conflict marker format with diffs in I use 3-way conflict markers. Often when I resolve them, I manually compare one the base with one side and apply the differences to the other side. That can be hard when the conflict marker is large. This patch introduces a new type of conflict marker, which I'm hoping will make it easier to resolve conflicts. The new format uses `<<<<<<<` and `>>>>>>>` to open and close the markers, just like our existing 2-way and 3-way conflict markers. Instead of having 2 or 3 snapshots (left+right or left+base+right), it has a sequence of diffs. A diff looks like this: ``` ------- base +++++++ left a -b +c d ``` A diff that adds one side ("diff from nothing") has a `=======` header instead and does not have have `+` prefixed on its lines. A regular 3-way merge can be viewed as adding one side plus a diff between the base and the other side. It thus has two ways of being represented, depending on which side is being diffed: ``` <<<<<<< ======= left contents on left ------- base +++++++ right contents on -left +right >>>>>>> ``` or ``` <<<<<<< ------- base +++++++ left contents on -right +left ======= right contents on right >>>>>>> ``` I've made it so the new merge tool tries to pick a version that has the most common lines (no difference in the example above). I've called the new tool "mergediff" to stick to the convention of starting with "merge" if the tool tries a regular 3-way merge. The idea came from my pet VCS (placeholder name `jj`), which has support for octopus merges and other ways of ending up with merges of more than 3 versions. I wanted to be able to represent such conflicts in the working copy and therefore thought of this format (although I have not yet implemented it in my VCS). I then attended a meeting with Larry McVoy, who said BitKeeper has an option (`bk smerge -g`) for showing a similar format, which reminded me to actually attempt this in Mercurial. Differential Revision: https://phab.mercurial-scm.org/D9551

File last commit:

r46428:9ac96b9f default
r46724:bdc2bf68 default
Show More
scmposix.py
97 lines | 2.6 KiB | text/x-python | PythonLexer
Gregory Szorc
scmposix: use absolute_import
r27483 from __future__ import absolute_import
Yuya Nishihara
scmutil: narrow ImportError handling in termwidth()...
r30311 import array
Yuya Nishihara
scmutil: move util.termwidth()...
r30309 import errno
import fcntl
Gregory Szorc
scmposix: use absolute_import
r27483 import os
import sys
Gregory Szorc
py3: manually import getattr where it is needed...
r43359 from .pycompat import getattr
Gregory Szorc
scmposix: use absolute_import
r27483 from . import (
Pulkit Goyal
py3: make scmposix.userrcpath() return bytes...
r30276 encoding,
Pulkit Goyal
py3: use pycompat.sysargv in scmposix.systemrcpath()...
r30467 pycompat,
Yuya Nishihara
osutil: proxy through util (and platform) modules (API)...
r32203 util,
Gregory Szorc
scmposix: use absolute_import
r27483 )
Kevin Bullock
scmutil: split platform-specific bits into their own modules...
r18690
Yuya Nishihara
pager: use less as a fallback on Unix...
r32078 # BSD 'more' escapes ANSI color sequences by default. This can be disabled by
# $MORE variable, but there's no compatible option with Linux 'more'. Given
# OS X is widely used and most modern Unix systems would have 'less', setting
# 'less' as the default seems reasonable.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fallbackpager = b'less'
Yuya Nishihara
pager: use less as a fallback on Unix...
r32078
Augie Fackler
style: run a patched black on a subset of mercurial...
r43345
Kevin Bullock
scmutil: split platform-specific bits into their own modules...
r18690 def _rcfiles(path):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 rcs = [os.path.join(path, b'hgrc')]
rcdir = os.path.join(path, b'hgrc.d')
Kevin Bullock
scmutil: split platform-specific bits into their own modules...
r18690 try:
Augie Fackler
style: run a patched black on a subset of mercurial...
r43345 rcs.extend(
[
os.path.join(rcdir, f)
Martin von Zweigbergk
config: read system hgrc in lexicographical order...
r46428 for f, kind in sorted(util.listdir(rcdir))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if f.endswith(b".rc")
Augie Fackler
style: run a patched black on a subset of mercurial...
r43345 ]
)
Kevin Bullock
scmutil: split platform-specific bits into their own modules...
r18690 except OSError:
pass
return rcs
Augie Fackler
style: run a patched black on a subset of mercurial...
r43345
Kevin Bullock
scmutil: split platform-specific bits into their own modules...
r18690 def systemrcpath():
path = []
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if pycompat.sysplatform == b'plan9':
root = b'lib/mercurial'
Kevin Bullock
scmutil: split platform-specific bits into their own modules...
r18690 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 root = b'etc/mercurial'
Kevin Bullock
scmutil: split platform-specific bits into their own modules...
r18690 # old mod_python does not set sys.argv
if len(getattr(sys, 'argv', [])) > 0:
Pulkit Goyal
py3: use pycompat.sysargv in scmposix.systemrcpath()...
r30467 p = os.path.dirname(os.path.dirname(pycompat.sysargv[0]))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if p != b'/':
Mads Kiilerich
config: don't read the same config file twice...
r22583 path.extend(_rcfiles(os.path.join(p, root)))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 path.extend(_rcfiles(b'/' + root))
Kevin Bullock
scmutil: split platform-specific bits into their own modules...
r18690 return path
Augie Fackler
style: run a patched black on a subset of mercurial...
r43345
Kevin Bullock
scmutil: split platform-specific bits into their own modules...
r18690 def userrcpath():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if pycompat.sysplatform == b'plan9':
return [encoding.environ[b'home'] + b'/lib/hgrc']
Jun Wu
codemod: use pycompat.isdarwin...
r34648 elif pycompat.isdarwin:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return [os.path.expanduser(b'~/.hgrc')]
Kevin Bullock
scmutil: split platform-specific bits into their own modules...
r18690 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 confighome = encoding.environ.get(b'XDG_CONFIG_HOME')
David Demelier
hg: allow usage of XDG_CONFIG_HOME/hg/hgrc...
r30941 if confighome is None or not os.path.isabs(confighome):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 confighome = os.path.expanduser(b'~/.config')
David Demelier
hg: allow usage of XDG_CONFIG_HOME/hg/hgrc...
r30941
Augie Fackler
style: run a patched black on a subset of mercurial...
r43345 return [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 os.path.expanduser(b'~/.hgrc'),
os.path.join(confighome, b'hg', b'hgrc'),
Augie Fackler
style: run a patched black on a subset of mercurial...
r43345 ]
Yuya Nishihara
scmutil: move util.termwidth()...
r30309
Yuya Nishihara
scmutil: extend termwidth() to return terminal height, renamed to termsize()...
r30314 def termsize(ui):
Yuya Nishihara
scmutil: move util.termwidth()...
r30309 try:
import termios
Augie Fackler
style: run a patched black on a subset of mercurial...
r43345
Yuya Nishihara
scmutil: narrow ImportError handling in termwidth()...
r30311 TIOCGWINSZ = termios.TIOCGWINSZ # unavailable on IRIX (issue3449)
except (AttributeError, ImportError):
Yuya Nishihara
scmutil: extend termwidth() to return terminal height, renamed to termsize()...
r30314 return 80, 24
Yuya Nishihara
scmutil: remove superfluous indent from termwidth()
r30312
for dev in (ui.ferr, ui.fout, ui.fin):
try:
Yuya Nishihara
scmutil: move util.termwidth()...
r30309 try:
Yuya Nishihara
scmutil: remove superfluous indent from termwidth()
r30312 fd = dev.fileno()
except AttributeError:
continue
if not os.isatty(fd):
continue
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 arri = fcntl.ioctl(fd, TIOCGWINSZ, b'\0' * 8)
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 height, width = array.array('h', arri)[:2]
Yuya Nishihara
scmutil: extend termwidth() to return terminal height, renamed to termsize()...
r30314 if width > 0 and height > 0:
return width, height
Yuya Nishihara
scmutil: remove superfluous indent from termwidth()
r30312 except ValueError:
pass
except IOError as e:
Augie Fackler
scmposix: another suppression on IOError subscripting...
r43781 if e[0] == errno.EINVAL: # pytype: disable=unsupported-operands
Yuya Nishihara
scmutil: move util.termwidth()...
r30309 pass
Yuya Nishihara
scmutil: remove superfluous indent from termwidth()
r30312 else:
raise
Yuya Nishihara
scmutil: extend termwidth() to return terminal height, renamed to termsize()...
r30314 return 80, 24