2005-06-07 12:00:56 +04:00
|
|
|
# Minimal support for git commands on an hg repository
|
|
|
|
#
|
2006-08-12 23:30:02 +04:00
|
|
|
# Copyright 2005, 2006 Chris Mason <mason@suse.com>
|
2005-06-07 12:00:56 +04:00
|
|
|
#
|
2009-04-26 03:08:54 +04:00
|
|
|
# This software may be used and distributed according to the terms of the
|
2010-01-20 07:20:08 +03:00
|
|
|
# GNU General Public License version 2 or any later version.
|
2009-04-26 03:25:53 +04:00
|
|
|
|
2009-06-22 17:48:08 +04:00
|
|
|
'''browse the repository in a graphical way
|
2008-06-12 13:33:47 +04:00
|
|
|
|
2009-07-26 03:47:25 +04:00
|
|
|
The hgk extension allows browsing the history of a repository in a
|
|
|
|
graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not
|
|
|
|
distributed with Mercurial.)
|
2008-06-12 13:33:47 +04:00
|
|
|
|
2009-07-26 03:47:25 +04:00
|
|
|
hgk consists of two parts: a Tcl script that does the displaying and
|
|
|
|
querying of information, and an extension to Mercurial named hgk.py,
|
|
|
|
which provides hooks for hgk to get information. hgk can be found in
|
|
|
|
the contrib directory, and the extension is shipped in the hgext
|
|
|
|
repository, and needs to be enabled.
|
2008-06-12 13:33:47 +04:00
|
|
|
|
2010-05-18 18:31:10 +04:00
|
|
|
The :hg:`view` command will launch the hgk Tcl script. For this command
|
2009-07-26 03:47:25 +04:00
|
|
|
to work, hgk must be in your search path. Alternately, you can specify
|
2010-08-28 06:36:35 +04:00
|
|
|
the path to hgk in your configuration file::
|
2008-06-12 13:33:47 +04:00
|
|
|
|
|
|
|
[hgk]
|
2015-06-26 01:37:14 +03:00
|
|
|
path = /location/of/hgk
|
2008-06-12 13:33:47 +04:00
|
|
|
|
2009-07-26 03:47:25 +04:00
|
|
|
hgk can make use of the extdiff extension to visualize revisions.
|
|
|
|
Assuming you had already configured extdiff vdiff command, just add::
|
2008-06-12 13:33:47 +04:00
|
|
|
|
|
|
|
[hgk]
|
|
|
|
vdiff=vdiff
|
|
|
|
|
2009-07-26 03:47:25 +04:00
|
|
|
Revisions context menu will now display additional entries to fire
|
|
|
|
vdiff on hovered and selected revisions.
|
2009-07-08 01:54:42 +04:00
|
|
|
'''
|
2005-06-07 12:00:56 +04:00
|
|
|
|
2016-05-06 19:20:40 +03:00
|
|
|
from __future__ import absolute_import
|
|
|
|
|
2008-01-18 19:48:25 +03:00
|
|
|
import os
|
2016-05-14 08:03:12 +03:00
|
|
|
|
|
|
|
from mercurial.i18n import _
|
|
|
|
from mercurial.node import (
|
|
|
|
nullid,
|
|
|
|
nullrev,
|
|
|
|
short,
|
|
|
|
)
|
2016-05-06 19:20:40 +03:00
|
|
|
from mercurial import (
|
|
|
|
commands,
|
|
|
|
obsolete,
|
|
|
|
patch,
|
2017-10-22 21:33:27 +03:00
|
|
|
pycompat,
|
2016-01-09 17:07:20 +03:00
|
|
|
registrar,
|
2016-05-06 19:20:40 +03:00
|
|
|
scmutil,
|
py3: introduce a wrapper for __builtins__.{raw_,}input()
In order to make this work, we have to wrap the io streams in a
TextIOWrapper so that __builtins__.input() can do unicode IO on Python
3. We can't just restore the original (unicode) sys.std* because we
might be running a cmdserver, and if we blindly restore sys.* to the
original values then we end up breaking the cmdserver. Sadly,
TextIOWrapper tries to close the underlying stream during its __del__,
so we have to make a sublcass to prevent that.
If you see errors like:
TypeError: a bytes-like object is required, not 'str'
On an input() or print() call on Python 3, the substitution of
sys.std* is probably the root cause.
A previous version of this change tried to put the bytesinput() method
in pycompat - it turns out we need to do some encoding handling, so we
have to be in a higher layer that's allowed to use
mercurial.encoding.encoding. As a result, this is in util for now,
with the TextIOWrapper subclass hiding in encoding.py. I'm not sure of
a better place for the time being.
Differential Revision: https://phab.mercurial-scm.org/D299
2017-07-24 21:38:40 +03:00
|
|
|
util,
|
2016-05-06 19:20:40 +03:00
|
|
|
)
|
2005-09-14 04:33:10 +04:00
|
|
|
|
2014-05-05 08:31:51 +04:00
|
|
|
cmdtable = {}
|
2016-01-09 17:07:20 +03:00
|
|
|
command = registrar.command(cmdtable)
|
2016-08-23 18:26:08 +03:00
|
|
|
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
|
2015-04-28 23:44:37 +03:00
|
|
|
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
|
|
|
|
# be specifying the version(s) of Mercurial they are tested with, or
|
|
|
|
# leave the attribute unspecified.
|
2016-08-23 18:26:08 +03:00
|
|
|
testedwith = 'ships-with-hg-core'
|
2012-05-15 23:37:49 +04:00
|
|
|
|
2017-06-30 04:42:35 +03:00
|
|
|
configtable = {}
|
|
|
|
configitem = registrar.configitem(configtable)
|
|
|
|
|
|
|
|
configitem('hgk', 'path',
|
|
|
|
default='hgk',
|
|
|
|
)
|
|
|
|
|
flake8: enable F821 check
Summary:
This check is useful and detects real errors (ex. fbconduit). Unfortunately
`arc lint` will run it with both py2 and py3 so a lot of py2 builtins will
still be warned.
I didn't find a clean way to disable py3 check. So this diff tries to fix them.
For `xrange`, the change was done by a script:
```
import sys
import redbaron
headertypes = {'comment', 'endl', 'from_import', 'import', 'string',
'assignment', 'atomtrailers'}
xrangefix = '''try:
xrange(0)
except NameError:
xrange = range
'''
def isxrange(x):
try:
return x[0].value == 'xrange'
except Exception:
return False
def main(argv):
for i, path in enumerate(argv):
print('(%d/%d) scanning %s' % (i + 1, len(argv), path))
content = open(path).read()
try:
red = redbaron.RedBaron(content)
except Exception:
print(' warning: failed to parse')
continue
hasxrange = red.find('atomtrailersnode', value=isxrange)
hasxrangefix = 'xrange = range' in content
if hasxrangefix or not hasxrange:
print(' no need to change')
continue
# find a place to insert the compatibility statement
changed = False
for node in red:
if node.type in headertypes:
continue
# node.insert_before is an easier API, but it has bugs changing
# other "finally" and "except" positions. So do the insert
# manually.
# # node.insert_before(xrangefix)
line = node.absolute_bounding_box.top_left.line - 1
lines = content.splitlines(1)
content = ''.join(lines[:line]) + xrangefix + ''.join(lines[line:])
changed = True
break
if changed:
# "content" is faster than "red.dumps()"
open(path, 'w').write(content)
print(' updated')
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
```
For other py2 builtins that do not have a py3 equivalent, some `# noqa`
were added as a workaround for now.
Reviewed By: DurhamG
Differential Revision: D6934535
fbshipit-source-id: 546b62830af144bc8b46788d2e0fd00496838939
2018-02-10 04:31:44 +03:00
|
|
|
try:
|
|
|
|
xrange(0)
|
|
|
|
except NameError:
|
|
|
|
xrange = range
|
|
|
|
|
2014-05-05 08:31:51 +04:00
|
|
|
@command('debug-diff-tree',
|
|
|
|
[('p', 'patch', None, _('generate patch')),
|
|
|
|
('r', 'recursive', None, _('recursive')),
|
|
|
|
('P', 'pretty', None, _('pretty')),
|
|
|
|
('s', 'stdin', None, _('stdin')),
|
|
|
|
('C', 'copy', None, _('detect copies')),
|
|
|
|
('S', 'search', "", _('search'))],
|
2015-03-28 21:34:03 +03:00
|
|
|
('[OPTION]... NODE1 NODE2 [FILE]...'),
|
2014-05-05 09:33:22 +04:00
|
|
|
inferrepo=True)
|
2006-09-06 04:13:08 +04:00
|
|
|
def difftree(ui, repo, node1=None, node2=None, *files, **opts):
|
2005-09-14 04:33:10 +04:00
|
|
|
"""diff trees from two commits"""
|
2017-10-22 21:33:27 +03:00
|
|
|
|
2017-03-15 09:48:25 +03:00
|
|
|
def __difftree(repo, node1, node2, files=None):
|
2006-12-26 05:26:23 +03:00
|
|
|
assert node2 is not None
|
2017-03-15 09:48:25 +03:00
|
|
|
if files is None:
|
|
|
|
files = []
|
2008-06-26 23:35:46 +04:00
|
|
|
mmap = repo[node1].manifest()
|
|
|
|
mmap2 = repo[node2].manifest()
|
2011-06-19 01:52:51 +04:00
|
|
|
m = scmutil.match(repo[node1], files)
|
2008-06-27 22:43:29 +04:00
|
|
|
modified, added, removed = repo.status(node1, node2, m)[:3]
|
2008-03-07 00:51:16 +03:00
|
|
|
empty = short(nullid)
|
2005-06-15 02:04:15 +04:00
|
|
|
|
2006-01-12 15:35:09 +03:00
|
|
|
for f in modified:
|
2005-06-15 02:04:15 +04:00
|
|
|
# TODO get file permissions
|
check-code: detect "missing _() in ui message" more exactly
Before this patch, "missing _() in ui message" rule overlooks
translatable message, which starts with other than alphabet.
To detect "missing _() in ui message" more exactly, this patch
improves the regexp with assumptions below.
- sequence consisting of below might precede "translatable message"
in same string token
- formatting string, which starts with '%'
- escaped character, which starts with 'b' (as replacement of '\\'), or
- characters other than '%', 'b' and 'x' (as replacement of alphabet)
- any string tokens might precede a string token, which contains
"translatable message"
This patch builds an input file, which is used to examine "missing _()
in ui message" detection, before '"$check_code" stringjoin.py' in
test-contrib-check-code.t, because this reduces amount of change churn
in subsequent patch.
This patch also applies "()" instead of "_()" on messages below to
hide false-positives:
- messages for ui.debug() or debug commands/tools
- contrib/debugshell.py
- hgext/win32mbcs.py (ui.write() is used, though)
- mercurial/commands.py
- _debugchangegroup
- debugindex
- debuglocks
- debugrevlog
- debugrevspec
- debugtemplate
- untranslatable messages
- doc/gendoc.py (ReST specific text)
- hgext/hgk.py (permission string)
- hgext/keyword.py (text written into configuration file)
- mercurial/cmdutil.py (formatting strings for JSON)
2016-06-20 18:50:39 +03:00
|
|
|
ui.write((":100664 100664 %s %s M\t%s\t%s\n") %
|
2008-03-07 00:51:16 +03:00
|
|
|
(short(mmap[f]), short(mmap2[f]), f, f))
|
2006-01-12 15:35:09 +03:00
|
|
|
for f in added:
|
check-code: detect "missing _() in ui message" more exactly
Before this patch, "missing _() in ui message" rule overlooks
translatable message, which starts with other than alphabet.
To detect "missing _() in ui message" more exactly, this patch
improves the regexp with assumptions below.
- sequence consisting of below might precede "translatable message"
in same string token
- formatting string, which starts with '%'
- escaped character, which starts with 'b' (as replacement of '\\'), or
- characters other than '%', 'b' and 'x' (as replacement of alphabet)
- any string tokens might precede a string token, which contains
"translatable message"
This patch builds an input file, which is used to examine "missing _()
in ui message" detection, before '"$check_code" stringjoin.py' in
test-contrib-check-code.t, because this reduces amount of change churn
in subsequent patch.
This patch also applies "()" instead of "_()" on messages below to
hide false-positives:
- messages for ui.debug() or debug commands/tools
- contrib/debugshell.py
- hgext/win32mbcs.py (ui.write() is used, though)
- mercurial/commands.py
- _debugchangegroup
- debugindex
- debuglocks
- debugrevlog
- debugrevspec
- debugtemplate
- untranslatable messages
- doc/gendoc.py (ReST specific text)
- hgext/hgk.py (permission string)
- hgext/keyword.py (text written into configuration file)
- mercurial/cmdutil.py (formatting strings for JSON)
2016-06-20 18:50:39 +03:00
|
|
|
ui.write((":000000 100664 %s %s N\t%s\t%s\n") %
|
2008-03-07 00:51:16 +03:00
|
|
|
(empty, short(mmap2[f]), f, f))
|
2006-01-12 15:35:09 +03:00
|
|
|
for f in removed:
|
check-code: detect "missing _() in ui message" more exactly
Before this patch, "missing _() in ui message" rule overlooks
translatable message, which starts with other than alphabet.
To detect "missing _() in ui message" more exactly, this patch
improves the regexp with assumptions below.
- sequence consisting of below might precede "translatable message"
in same string token
- formatting string, which starts with '%'
- escaped character, which starts with 'b' (as replacement of '\\'), or
- characters other than '%', 'b' and 'x' (as replacement of alphabet)
- any string tokens might precede a string token, which contains
"translatable message"
This patch builds an input file, which is used to examine "missing _()
in ui message" detection, before '"$check_code" stringjoin.py' in
test-contrib-check-code.t, because this reduces amount of change churn
in subsequent patch.
This patch also applies "()" instead of "_()" on messages below to
hide false-positives:
- messages for ui.debug() or debug commands/tools
- contrib/debugshell.py
- hgext/win32mbcs.py (ui.write() is used, though)
- mercurial/commands.py
- _debugchangegroup
- debugindex
- debuglocks
- debugrevlog
- debugrevspec
- debugtemplate
- untranslatable messages
- doc/gendoc.py (ReST specific text)
- hgext/hgk.py (permission string)
- hgext/keyword.py (text written into configuration file)
- mercurial/cmdutil.py (formatting strings for JSON)
2016-06-20 18:50:39 +03:00
|
|
|
ui.write((":100664 000000 %s %s D\t%s\t%s\n") %
|
2008-03-07 00:51:16 +03:00
|
|
|
(short(mmap[f]), empty, f, f))
|
2005-06-07 12:00:56 +04:00
|
|
|
##
|
|
|
|
|
2005-09-14 04:33:10 +04:00
|
|
|
while True:
|
2017-10-22 21:33:27 +03:00
|
|
|
if opts[r'stdin']:
|
2005-09-14 04:33:10 +04:00
|
|
|
try:
|
py3: introduce a wrapper for __builtins__.{raw_,}input()
In order to make this work, we have to wrap the io streams in a
TextIOWrapper so that __builtins__.input() can do unicode IO on Python
3. We can't just restore the original (unicode) sys.std* because we
might be running a cmdserver, and if we blindly restore sys.* to the
original values then we end up breaking the cmdserver. Sadly,
TextIOWrapper tries to close the underlying stream during its __del__,
so we have to make a sublcass to prevent that.
If you see errors like:
TypeError: a bytes-like object is required, not 'str'
On an input() or print() call on Python 3, the substitution of
sys.std* is probably the root cause.
A previous version of this change tried to put the bytesinput() method
in pycompat - it turns out we need to do some encoding handling, so we
have to be in a higher layer that's allowed to use
mercurial.encoding.encoding. As a result, this is in util for now,
with the TextIOWrapper subclass hiding in encoding.py. I'm not sure of
a better place for the time being.
Differential Revision: https://phab.mercurial-scm.org/D299
2017-07-24 21:38:40 +03:00
|
|
|
line = util.bytesinput(ui.fin, ui.fout).split(' ')
|
2005-09-14 04:33:10 +04:00
|
|
|
node1 = line[0]
|
|
|
|
if len(line) > 1:
|
|
|
|
node2 = line[1]
|
|
|
|
else:
|
|
|
|
node2 = None
|
|
|
|
except EOFError:
|
|
|
|
break
|
|
|
|
node1 = repo.lookup(node1)
|
|
|
|
if node2:
|
|
|
|
node2 = repo.lookup(node2)
|
|
|
|
else:
|
|
|
|
node2 = node1
|
|
|
|
node1 = repo.changelog.parents(node1)[0]
|
2017-10-22 21:33:27 +03:00
|
|
|
if opts[r'patch']:
|
|
|
|
if opts[r'pretty']:
|
2008-01-18 19:48:25 +03:00
|
|
|
catcommit(ui, repo, node2, "")
|
2011-06-19 01:52:51 +04:00
|
|
|
m = scmutil.match(repo[node1], files)
|
2014-11-19 08:38:19 +03:00
|
|
|
diffopts = patch.difffeatureopts(ui)
|
|
|
|
diffopts.git = True
|
2008-11-03 18:48:23 +03:00
|
|
|
chunks = patch.diff(repo, node1, node2, match=m,
|
2014-11-19 08:38:19 +03:00
|
|
|
opts=diffopts)
|
2008-11-03 18:48:23 +03:00
|
|
|
for chunk in chunks:
|
2009-05-25 00:37:20 +04:00
|
|
|
ui.write(chunk)
|
2005-09-14 04:33:10 +04:00
|
|
|
else:
|
2006-09-06 04:13:08 +04:00
|
|
|
__difftree(repo, node1, node2, files=files)
|
2017-10-22 21:33:27 +03:00
|
|
|
if not opts[r'stdin']:
|
2005-09-14 04:33:10 +04:00
|
|
|
break
|
2005-06-07 12:00:56 +04:00
|
|
|
|
2008-01-18 19:48:25 +03:00
|
|
|
def catcommit(ui, repo, n, prefix, ctx=None):
|
2010-02-08 17:36:34 +03:00
|
|
|
nlprefix = '\n' + prefix
|
2006-12-26 05:27:24 +03:00
|
|
|
if ctx is None:
|
2008-06-26 23:35:46 +04:00
|
|
|
ctx = repo[n]
|
2012-05-12 17:54:54 +04:00
|
|
|
# use ctx.node() instead ??
|
2012-11-25 23:53:47 +04:00
|
|
|
ui.write(("tree %s\n" % short(ctx.changeset()[0])))
|
2008-07-12 03:46:02 +04:00
|
|
|
for p in ctx.parents():
|
2012-11-25 23:53:47 +04:00
|
|
|
ui.write(("parent %s\n" % p))
|
2008-07-12 03:46:02 +04:00
|
|
|
|
2006-12-26 05:27:24 +03:00
|
|
|
date = ctx.date()
|
2007-01-24 02:41:53 +03:00
|
|
|
description = ctx.description().replace("\0", "")
|
2012-11-25 23:53:47 +04:00
|
|
|
ui.write(("author %s %s %s\n" % (ctx.user(), int(date[0]), date[1])))
|
2015-04-03 23:44:25 +03:00
|
|
|
|
|
|
|
if 'committer' in ctx.extra():
|
|
|
|
ui.write(("committer %s\n" % ctx.extra()['committer']))
|
|
|
|
|
2012-11-25 23:53:47 +04:00
|
|
|
ui.write(("revision %d\n" % ctx.rev()))
|
2013-03-22 20:19:41 +04:00
|
|
|
ui.write(("branch %s\n" % ctx.branch()))
|
2015-03-28 22:05:01 +03:00
|
|
|
if obsolete.isenabled(repo, obsolete.createmarkersopt):
|
|
|
|
if ctx.obsolete():
|
|
|
|
ui.write(("obsolete\n"))
|
2013-03-22 20:19:41 +04:00
|
|
|
ui.write(("phase %s\n\n" % ctx.phasestr()))
|
2008-01-18 19:48:25 +03:00
|
|
|
|
2005-06-07 12:00:56 +04:00
|
|
|
if prefix != "":
|
2012-05-12 17:54:54 +04:00
|
|
|
ui.write("%s%s\n" % (prefix,
|
|
|
|
description.replace('\n', nlprefix).strip()))
|
2005-06-07 12:00:56 +04:00
|
|
|
else:
|
2008-01-18 19:48:25 +03:00
|
|
|
ui.write(description + "\n")
|
2005-09-14 04:33:10 +04:00
|
|
|
if prefix:
|
2008-01-18 19:48:25 +03:00
|
|
|
ui.write('\0')
|
2005-06-07 12:00:56 +04:00
|
|
|
|
2015-03-28 21:34:03 +03:00
|
|
|
@command('debug-merge-base', [], _('REV REV'))
|
2005-09-14 04:33:10 +04:00
|
|
|
def base(ui, repo, node1, node2):
|
2009-01-03 19:15:15 +03:00
|
|
|
"""output common ancestor information"""
|
2005-09-14 04:33:10 +04:00
|
|
|
node1 = repo.lookup(node1)
|
|
|
|
node2 = repo.lookup(node2)
|
|
|
|
n = repo.changelog.ancestor(node1, node2)
|
2008-03-07 00:51:16 +03:00
|
|
|
ui.write(short(n) + "\n")
|
2005-06-07 12:00:56 +04:00
|
|
|
|
2014-05-05 08:31:51 +04:00
|
|
|
@command('debug-cat-file',
|
|
|
|
[('s', 'stdin', None, _('stdin'))],
|
2015-03-28 21:34:03 +03:00
|
|
|
_('[OPTION]... TYPE FILE'),
|
2014-05-05 09:33:22 +04:00
|
|
|
inferrepo=True)
|
2005-09-14 04:33:10 +04:00
|
|
|
def catfile(ui, repo, type=None, r=None, **opts):
|
|
|
|
"""cat a specific revision"""
|
2005-06-07 12:00:56 +04:00
|
|
|
# in stdin mode, every line except the commit is prefixed with two
|
|
|
|
# spaces. This way the our caller can find the commit without magic
|
|
|
|
# strings
|
|
|
|
#
|
|
|
|
prefix = ""
|
2017-10-22 21:33:27 +03:00
|
|
|
if opts[r'stdin']:
|
2005-06-15 02:04:15 +04:00
|
|
|
try:
|
py3: introduce a wrapper for __builtins__.{raw_,}input()
In order to make this work, we have to wrap the io streams in a
TextIOWrapper so that __builtins__.input() can do unicode IO on Python
3. We can't just restore the original (unicode) sys.std* because we
might be running a cmdserver, and if we blindly restore sys.* to the
original values then we end up breaking the cmdserver. Sadly,
TextIOWrapper tries to close the underlying stream during its __del__,
so we have to make a sublcass to prevent that.
If you see errors like:
TypeError: a bytes-like object is required, not 'str'
On an input() or print() call on Python 3, the substitution of
sys.std* is probably the root cause.
A previous version of this change tried to put the bytesinput() method
in pycompat - it turns out we need to do some encoding handling, so we
have to be in a higher layer that's allowed to use
mercurial.encoding.encoding. As a result, this is in util for now,
with the TextIOWrapper subclass hiding in encoding.py. I'm not sure of
a better place for the time being.
Differential Revision: https://phab.mercurial-scm.org/D299
2017-07-24 21:38:40 +03:00
|
|
|
(type, r) = util.bytesinput(ui.fin, ui.fout).split(' ')
|
2005-09-14 04:33:10 +04:00
|
|
|
prefix = " "
|
2005-06-15 02:04:15 +04:00
|
|
|
except EOFError:
|
|
|
|
return
|
2005-06-07 12:00:56 +04:00
|
|
|
|
|
|
|
else:
|
2005-09-14 04:33:10 +04:00
|
|
|
if not type or not r:
|
2008-08-31 18:12:02 +04:00
|
|
|
ui.warn(_("cat-file: type or revision not supplied\n"))
|
2005-09-14 04:33:10 +04:00
|
|
|
commands.help_(ui, 'cat-file')
|
2005-06-07 12:00:56 +04:00
|
|
|
|
|
|
|
while r:
|
2005-06-15 02:04:15 +04:00
|
|
|
if type != "commit":
|
2008-08-31 18:12:02 +04:00
|
|
|
ui.warn(_("aborting hg cat-file only understands commits\n"))
|
2010-02-08 17:36:34 +03:00
|
|
|
return 1
|
2005-07-19 21:41:08 +04:00
|
|
|
n = repo.lookup(r)
|
2008-01-18 19:48:25 +03:00
|
|
|
catcommit(ui, repo, n, prefix)
|
2017-10-22 21:33:27 +03:00
|
|
|
if opts[r'stdin']:
|
2005-06-15 02:04:15 +04:00
|
|
|
try:
|
py3: introduce a wrapper for __builtins__.{raw_,}input()
In order to make this work, we have to wrap the io streams in a
TextIOWrapper so that __builtins__.input() can do unicode IO on Python
3. We can't just restore the original (unicode) sys.std* because we
might be running a cmdserver, and if we blindly restore sys.* to the
original values then we end up breaking the cmdserver. Sadly,
TextIOWrapper tries to close the underlying stream during its __del__,
so we have to make a sublcass to prevent that.
If you see errors like:
TypeError: a bytes-like object is required, not 'str'
On an input() or print() call on Python 3, the substitution of
sys.std* is probably the root cause.
A previous version of this change tried to put the bytesinput() method
in pycompat - it turns out we need to do some encoding handling, so we
have to be in a higher layer that's allowed to use
mercurial.encoding.encoding. As a result, this is in util for now,
with the TextIOWrapper subclass hiding in encoding.py. I'm not sure of
a better place for the time being.
Differential Revision: https://phab.mercurial-scm.org/D299
2017-07-24 21:38:40 +03:00
|
|
|
(type, r) = util.bytesinput(ui.fin, ui.fout).split(' ')
|
2005-06-15 02:04:15 +04:00
|
|
|
except EOFError:
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
break
|
2005-06-07 12:00:56 +04:00
|
|
|
|
|
|
|
# git rev-tree is a confusing thing. You can supply a number of
|
|
|
|
# commit sha1s on the command line, and it walks the commit history
|
|
|
|
# telling you which commits are reachable from the supplied ones via
|
|
|
|
# a bitmask based on arg position.
|
|
|
|
# you can specify a commit to stop at by starting the sha1 with ^
|
2008-01-18 19:48:25 +03:00
|
|
|
def revtree(ui, args, repo, full="tree", maxnr=0, parents=False):
|
2005-09-14 04:33:10 +04:00
|
|
|
def chlogwalk():
|
2008-06-26 23:35:50 +04:00
|
|
|
count = len(repo)
|
2005-09-14 04:33:10 +04:00
|
|
|
i = count
|
|
|
|
l = [0] * 100
|
|
|
|
chunk = 100
|
|
|
|
while True:
|
|
|
|
if chunk > i:
|
|
|
|
chunk = i
|
|
|
|
i = 0
|
|
|
|
else:
|
|
|
|
i -= chunk
|
|
|
|
|
2009-05-26 01:06:11 +04:00
|
|
|
for x in xrange(chunk):
|
2005-09-14 04:33:10 +04:00
|
|
|
if i + x >= count:
|
|
|
|
l[chunk - x:] = [0] * (chunk - x)
|
|
|
|
break
|
2010-11-22 20:15:58 +03:00
|
|
|
if full is not None:
|
2014-09-28 17:21:29 +04:00
|
|
|
if (i + x) in repo:
|
|
|
|
l[x] = repo[i + x]
|
|
|
|
l[x].changeset() # force reading
|
2005-09-14 04:33:10 +04:00
|
|
|
else:
|
2014-09-28 17:21:29 +04:00
|
|
|
if (i + x) in repo:
|
|
|
|
l[x] = 1
|
2010-01-25 09:05:27 +03:00
|
|
|
for x in xrange(chunk - 1, -1, -1):
|
2005-09-14 04:33:10 +04:00
|
|
|
if l[x] != 0:
|
2010-11-22 20:15:58 +03:00
|
|
|
yield (i + x, full is not None and l[x] or None)
|
2005-09-14 04:33:10 +04:00
|
|
|
if i == 0:
|
|
|
|
break
|
2005-09-21 09:56:19 +04:00
|
|
|
|
2005-06-07 12:00:56 +04:00
|
|
|
# calculate and return the reachability bitmask for sha
|
|
|
|
def is_reachable(ar, reachable, sha):
|
2005-06-15 02:04:15 +04:00
|
|
|
if len(ar) == 0:
|
|
|
|
return 1
|
|
|
|
mask = 0
|
2006-10-19 16:16:51 +04:00
|
|
|
for i in xrange(len(ar)):
|
2005-06-15 02:04:15 +04:00
|
|
|
if sha in reachable[i]:
|
|
|
|
mask |= 1 << i
|
2005-06-07 12:00:56 +04:00
|
|
|
|
2005-06-15 02:04:15 +04:00
|
|
|
return mask
|
2005-06-07 12:00:56 +04:00
|
|
|
|
|
|
|
reachable = []
|
|
|
|
stop_sha1 = []
|
|
|
|
want_sha1 = []
|
2005-06-15 22:04:42 +04:00
|
|
|
count = 0
|
2005-06-07 12:00:56 +04:00
|
|
|
|
|
|
|
# figure out which commits they are asking for and which ones they
|
|
|
|
# want us to stop on
|
2009-05-27 00:59:52 +04:00
|
|
|
for i, arg in enumerate(args):
|
|
|
|
if arg.startswith('^'):
|
|
|
|
s = repo.lookup(arg[1:])
|
2005-07-19 21:41:08 +04:00
|
|
|
stop_sha1.append(s)
|
2005-06-15 02:04:15 +04:00
|
|
|
want_sha1.append(s)
|
2009-05-27 00:59:52 +04:00
|
|
|
elif arg != 'HEAD':
|
|
|
|
want_sha1.append(repo.lookup(arg))
|
2005-06-15 22:04:42 +04:00
|
|
|
|
2005-06-07 12:00:56 +04:00
|
|
|
# calculate the graph for the supplied commits
|
2009-05-27 00:59:52 +04:00
|
|
|
for i, n in enumerate(want_sha1):
|
2010-02-08 17:36:34 +03:00
|
|
|
reachable.append(set())
|
|
|
|
visit = [n]
|
2009-05-17 05:25:24 +04:00
|
|
|
reachable[i].add(n)
|
2005-06-15 02:04:15 +04:00
|
|
|
while visit:
|
|
|
|
n = visit.pop(0)
|
|
|
|
if n in stop_sha1:
|
2005-09-14 22:14:20 +04:00
|
|
|
continue
|
2005-06-15 02:04:15 +04:00
|
|
|
for p in repo.changelog.parents(n):
|
|
|
|
if p not in reachable[i]:
|
2009-05-17 05:25:24 +04:00
|
|
|
reachable[i].add(p)
|
2005-06-15 02:04:15 +04:00
|
|
|
visit.append(p)
|
|
|
|
if p in stop_sha1:
|
2005-09-14 22:14:20 +04:00
|
|
|
continue
|
2005-06-15 22:04:42 +04:00
|
|
|
|
2005-06-07 12:00:56 +04:00
|
|
|
# walk the repository looking for commits that are in our
|
|
|
|
# reachability graph
|
2006-12-26 05:27:24 +03:00
|
|
|
for i, ctx in chlogwalk():
|
2014-09-28 17:21:29 +04:00
|
|
|
if i not in repo:
|
|
|
|
continue
|
2005-06-15 02:04:15 +04:00
|
|
|
n = repo.changelog.node(i)
|
|
|
|
mask = is_reachable(want_sha1, reachable, n)
|
|
|
|
if mask:
|
2005-09-14 04:33:10 +04:00
|
|
|
parentstr = ""
|
|
|
|
if parents:
|
|
|
|
pp = repo.changelog.parents(n)
|
2008-03-07 00:51:16 +03:00
|
|
|
if pp[0] != nullid:
|
|
|
|
parentstr += " " + short(pp[0])
|
|
|
|
if pp[1] != nullid:
|
|
|
|
parentstr += " " + short(pp[1])
|
2005-06-15 22:04:42 +04:00
|
|
|
if not full:
|
2008-03-07 00:51:16 +03:00
|
|
|
ui.write("%s%s\n" % (short(n), parentstr))
|
2006-09-06 04:15:33 +04:00
|
|
|
elif full == "commit":
|
2008-03-07 00:51:16 +03:00
|
|
|
ui.write("%s%s\n" % (short(n), parentstr))
|
2008-01-18 19:48:25 +03:00
|
|
|
catcommit(ui, repo, n, ' ', ctx)
|
2005-06-15 22:04:42 +04:00
|
|
|
else:
|
|
|
|
(p1, p2) = repo.changelog.parents(n)
|
2008-03-07 00:51:16 +03:00
|
|
|
(h, h1, h2) = map(short, (n, p1, p2))
|
2005-06-15 22:04:42 +04:00
|
|
|
(i1, i2) = map(repo.changelog.rev, (p1, p2))
|
|
|
|
|
2006-12-26 05:27:24 +03:00
|
|
|
date = ctx.date()[0]
|
2008-01-18 19:48:25 +03:00
|
|
|
ui.write("%s %s:%s" % (date, h, mask))
|
2005-06-15 22:04:42 +04:00
|
|
|
mask = is_reachable(want_sha1, reachable, p1)
|
2008-03-07 00:51:16 +03:00
|
|
|
if i1 != nullrev and mask > 0:
|
2008-01-18 19:48:25 +03:00
|
|
|
ui.write("%s:%s " % (h1, mask)),
|
2005-06-15 22:04:42 +04:00
|
|
|
mask = is_reachable(want_sha1, reachable, p2)
|
2008-03-07 00:51:16 +03:00
|
|
|
if i2 != nullrev and mask > 0:
|
2008-01-18 19:48:25 +03:00
|
|
|
ui.write("%s:%s " % (h2, mask))
|
|
|
|
ui.write("\n")
|
2005-06-15 22:04:42 +04:00
|
|
|
if maxnr and count >= maxnr:
|
|
|
|
break
|
|
|
|
count += 1
|
2005-06-07 12:00:56 +04:00
|
|
|
|
|
|
|
# git rev-list tries to order things by date, and has the ability to stop
|
|
|
|
# at a given commit without walking the whole repo. TODO add the stop
|
|
|
|
# parameter
|
2014-05-05 08:31:51 +04:00
|
|
|
@command('debug-rev-list',
|
|
|
|
[('H', 'header', None, _('header')),
|
|
|
|
('t', 'topo-order', None, _('topo-order')),
|
|
|
|
('p', 'parents', None, _('parents')),
|
|
|
|
('n', 'max-count', 0, _('max-count'))],
|
2015-03-28 21:34:03 +03:00
|
|
|
('[OPTION]... REV...'))
|
2005-09-14 04:33:10 +04:00
|
|
|
def revlist(ui, repo, *revs, **opts):
|
|
|
|
"""print revisions"""
|
|
|
|
if opts['header']:
|
2005-06-15 22:04:42 +04:00
|
|
|
full = "commit"
|
|
|
|
else:
|
|
|
|
full = None
|
2005-09-14 04:33:10 +04:00
|
|
|
copy = [x for x in revs]
|
2017-10-22 21:33:27 +03:00
|
|
|
revtree(ui, copy, repo, full, opts[r'max_count'], opts[r'parents'])
|
2005-06-07 12:00:56 +04:00
|
|
|
|
2014-05-05 08:31:51 +04:00
|
|
|
@command('view',
|
|
|
|
[('l', 'limit', '',
|
|
|
|
_('limit number of changes displayed'), _('NUM'))],
|
2015-03-28 21:34:03 +03:00
|
|
|
_('[-l LIMIT] [REVRANGE]'))
|
2006-09-14 05:24:58 +04:00
|
|
|
def view(ui, repo, *etc, **opts):
|
2005-09-20 02:59:17 +04:00
|
|
|
"start interactive history viewer"
|
2017-10-22 21:33:27 +03:00
|
|
|
opts = pycompat.byteskwargs(opts)
|
2005-09-20 02:59:17 +04:00
|
|
|
os.chdir(repo.root)
|
2006-09-27 17:27:16 +04:00
|
|
|
optstr = ' '.join(['--%s %s' % (k, v) for k, v in opts.iteritems() if v])
|
2015-03-28 21:36:21 +03:00
|
|
|
if repo.filtername is None:
|
|
|
|
optstr += '--hidden'
|
|
|
|
|
2017-06-30 04:42:35 +03:00
|
|
|
cmd = ui.config("hgk", "path") + " %s %s" % (optstr, " ".join(etc))
|
2009-09-19 03:15:38 +04:00
|
|
|
ui.debug("running %s\n" % cmd)
|
2017-03-06 14:27:52 +03:00
|
|
|
ui.system(cmd, blockedtag='hgk_view')
|