summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Cowgill <jcowgill@debian.org>2018-12-22 10:47:29 +0000
committerJames Cowgill <jcowgill@debian.org>2018-12-22 10:47:29 +0000
commit41c422dff219468b00c2ed7e42c831863e2b06a1 (patch)
treeba55ecc48268a60ca3523bad2d3207dca13eeaf0
parent82d8a5ac948a5d558bf51e418fd845c30ac80995 (diff)
New upstream version 4.8.1
-rw-r--r--PKG-INFO2
-rw-r--r--doc/source-cs/preface.txt6
-rw-r--r--doc/source-ja/preface.txt6
-rw-r--r--doc/source/conf.py4
-rw-r--r--doc/source/preface.txt6
-rw-r--r--hgext3rd/thg.py7
-rwxr-xr-xthg7
-rw-r--r--tortoisehg/hgqt/about.py4
-rw-r--r--tortoisehg/hgqt/bisect.py3
-rw-r--r--tortoisehg/hgqt/clone.py3
-rw-r--r--tortoisehg/hgqt/commit.py4
-rw-r--r--tortoisehg/hgqt/docklog.py1
-rw-r--r--tortoisehg/hgqt/filedata.py12
-rw-r--r--tortoisehg/hgqt/filedialogs.py7
-rw-r--r--tortoisehg/hgqt/fileview.py8
-rw-r--r--tortoisehg/hgqt/graft.py16
-rw-r--r--tortoisehg/hgqt/grep.py6
-rw-r--r--tortoisehg/hgqt/hgemail_ui.py4
-rw-r--r--tortoisehg/hgqt/matching.py7
-rw-r--r--tortoisehg/hgqt/merge.py11
-rw-r--r--tortoisehg/hgqt/mq.py10
-rw-r--r--tortoisehg/hgqt/postreview_ui.py4
-rw-r--r--tortoisehg/hgqt/qfold.py10
-rw-r--r--tortoisehg/hgqt/qscilib.py8
-rw-r--r--tortoisehg/hgqt/qtlib.py3
-rw-r--r--tortoisehg/hgqt/repofilter.py7
-rw-r--r--tortoisehg/hgqt/repoview.py31
-rw-r--r--tortoisehg/hgqt/repowidget.py30
-rw-r--r--tortoisehg/hgqt/revpanel.py7
-rw-r--r--tortoisehg/hgqt/run.py9
-rw-r--r--tortoisehg/hgqt/rupdate.py11
-rw-r--r--tortoisehg/hgqt/serve_ui.py4
-rw-r--r--tortoisehg/hgqt/settings.py11
-rw-r--r--tortoisehg/hgqt/thgstrip.py7
-rw-r--r--tortoisehg/hgqt/update.py5
-rw-r--r--tortoisehg/hgqt/visdiff.py6
-rw-r--r--tortoisehg/hgqt/webconf_ui.py4
-rw-r--r--tortoisehg/util/__version__.py2
-rw-r--r--tortoisehg/util/hglib.py33
-rw-r--r--tortoisehg/util/hgversion.py2
-rw-r--r--tortoisehg/util/patchctx.py1
-rw-r--r--tortoisehg/util/version.py80
42 files changed, 266 insertions, 143 deletions
diff --git a/PKG-INFO b/PKG-INFO
index eab1878..3dccb77 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.0
Name: tortoisehg
-Version: 4.7
+Version: 4.8.1
Summary: TortoiseHg dialogs for Mercurial VCS
Home-page: https://tortoisehg.bitbucket.io
Author: Steve Borho
diff --git a/doc/source-cs/preface.txt b/doc/source-cs/preface.txt
index 0b532f3..d783afd 100644
--- a/doc/source-cs/preface.txt
+++ b/doc/source-cs/preface.txt
@@ -45,12 +45,6 @@ na neomezené množství počítačů a šířit ve shodě s licencí GPLv2.
Komunita
========
-Adresy:
-
-* `Uživatelé <https://lists.sourceforge.net/lists/listinfo/tortoisehg-discuss>`_ - Oznámení, otázky-odpovědi a diskuze o vlastnostech
-* `Vývojáři <https://lists.sourceforge.net/lists/listinfo/tortoisehg-develop>`_ - Oprávky, zprávy o chybách a diskuze o vývoji programu.
-* `Problémy <https://lists.sourceforge.net/lists/listinfo/tortoisehg-issues>`_ - Přehled zaznamenávaných problémů.
-
Naše Wiki na stránkách Bitbucket je `zde <https://bitbucket.org/tortoisehg/thg/wiki/Home>`_ .
Poděkování
diff --git a/doc/source-ja/preface.txt b/doc/source-ja/preface.txt
index f94cc05..6873433 100644
--- a/doc/source-ja/preface.txt
+++ b/doc/source-ja/preface.txt
@@ -57,12 +57,6 @@ GPLv2 ライセンスに従う限り再配布も可能です。
コミュニティ
============
-メーリングリスト:
-
-* `利用者 ML <https://lists.sourceforge.net/lists/listinfo/tortoisehg-discuss>`_ - アナウンス、使い方などの質問、機能の議論など。
-* `開発者 ML <https://lists.sourceforge.net/lists/listinfo/tortoisehg-develop>`_ - パッチ投稿、バグ報告、開発関連の議論など。
-* `バグ通知 ML <https://lists.sourceforge.net/lists/listinfo/tortoisehg-issues>`_ - バグ管理システムからの自動通知メール。
-
Bitbucket には `公式 Wiki <https://bitbucket.org/tortoisehg/thg/wiki/Home>`_ もあります。
日本語 Wiki は `こちら <https://bitbucket.org/kuy/thg-ja/wiki/Home>`_ になります。
diff --git a/doc/source/conf.py b/doc/source/conf.py
index c47ba5c..601d765 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -49,9 +49,9 @@ copyright = u'2010-2018, Steve Borho and others'
# built documents.
#
# The short X.Y version.
-version = '3.8'
+version = '4.7'
# The full version, including alpha/beta/rc tags.
-release = '3.8.0'
+release = '4.7.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/doc/source/preface.txt b/doc/source/preface.txt
index 546856c..d0a11b4 100644
--- a/doc/source/preface.txt
+++ b/doc/source/preface.txt
@@ -52,11 +52,9 @@ according to the GPLv2 license.
Community
=========
-Mailing Lists:
+Mailing List::
-* `Users <https://lists.sourceforge.net/lists/listinfo/tortoisehg-discuss>`_ - Announcements, user Q&A, and feature discussions.
-* `Developers <thg-dev@googlegroups.com>`_ - Patches, bug reports, development discussions.
-* `Issues <https://lists.sourceforge.net/lists/listinfo/tortoisehg-issues>`_ - Notifications from the issue tracker.
+ `Developers <thg-dev@googlegroups.com>`_ - Patches, bug reports, development discussions.
And our `wiki <https://bitbucket.org/tortoisehg/thg/wiki/Home>`_ on Bitbucket.
diff --git a/hgext3rd/thg.py b/hgext3rd/thg.py
index a5f8bf6..c3be94c 100644
--- a/hgext3rd/thg.py
+++ b/hgext3rd/thg.py
@@ -54,12 +54,7 @@ else:
import threading
from mercurial import demandimport
-try:
- _updateignores = demandimport.IGNORES.update
-except AttributeError:
- # hg<4.7 (670eb4fa1b86)
- _updateignores = demandimport.ignore.extend
-_updateignores([
+demandimport.IGNORES.update([
'win32com.shell',
'numpy', # comtypes.npsupport does try-import
'tortoisehg.util.config',
diff --git a/thg b/thg
index 087e9c7..6e95d3b 100755
--- a/thg
+++ b/thg
@@ -59,12 +59,7 @@ else:
import threading
from mercurial import demandimport
-try:
- _updateignores = demandimport.IGNORES.update
-except AttributeError:
- # hg<4.7 (670eb4fa1b86)
- _updateignores = demandimport.ignore.extend
-_updateignores([
+demandimport.IGNORES.update([
'win32com.shell',
'numpy', # comtypes.npsupport does try-import
'tortoisehg.util.config',
diff --git a/tortoisehg/hgqt/about.py b/tortoisehg/hgqt/about.py
index 032c0bf..ef374c6 100644
--- a/tortoisehg/hgqt/about.py
+++ b/tortoisehg/hgqt/about.py
@@ -169,9 +169,7 @@ class AboutDialog(QDialog):
except (IndexError, ImportError, ValueError):
pass
try:
- thgv = version.version()
- if '+' in thgv:
- thgv = thgv[:thgv.index('+')]
+ thgv = version.package_version()
curver = tuple([int(p) for p in thgv.split('.')])
except ValueError:
curver = (0,0,0)
diff --git a/tortoisehg/hgqt/bisect.py b/tortoisehg/hgqt/bisect.py
index ae4f67e..bd41641 100644
--- a/tortoisehg/hgqt/bisect.py
+++ b/tortoisehg/hgqt/bisect.py
@@ -26,6 +26,7 @@ from .qtgui import (
from mercurial import (
error,
+ scmutil,
)
from ..util import hglib
@@ -157,7 +158,7 @@ class BisectDialog(QDialog):
def _lookupRevision(self, changeid):
try:
- ctx = self.repo[hglib.fromunicode(changeid)]
+ ctx = scmutil.revsymbol(self.repo, hglib.fromunicode(changeid))
return ctx.rev()
except (error.LookupError, error.RepoLookupError), e:
self._stbar.showMessage(hglib.tounicode(str(e)))
diff --git a/tortoisehg/hgqt/clone.py b/tortoisehg/hgqt/clone.py
index 5663a32..b286317 100644
--- a/tortoisehg/hgqt/clone.py
+++ b/tortoisehg/hgqt/clone.py
@@ -76,7 +76,8 @@ class CloneWidget(cmdui.AbstractCmdWidget):
self._cmdagent = cmdagent
self.ui = ui
- dest = src = os.getcwd()
+ dest = src = (self.ui.config('tortoisehg', 'defaultclonedest')
+ or os.getcwd())
if args:
if len(args) > 1:
src = args[0]
diff --git a/tortoisehg/hgqt/commit.py b/tortoisehg/hgqt/commit.py
index 0fe9deb..4228e82 100644
--- a/tortoisehg/hgqt/commit.py
+++ b/tortoisehg/hgqt/commit.py
@@ -56,6 +56,7 @@ from mercurial import (
error,
obsolete, # delete if obsolete becomes enabled by default
phases,
+ scmutil,
)
from mercurial.utils import (
dateutil,
@@ -569,7 +570,8 @@ class CommitWidget(QWidget, qtlib.TaskWidget):
if branch in [p.branch() for p in repo[None].parents()]:
resp = 0
else:
- rev = repo[branch].rev()
+ # TODO: should look up only in branch namespace
+ rev = scmutil.revsymbol(repo, branch).rev()
resp = qtlib.CustomPrompt(_('Confirm Branch Change'),
_('Named branch "%s" already exists, '
'last used in revision %d\n'
diff --git a/tortoisehg/hgqt/docklog.py b/tortoisehg/hgqt/docklog.py
index 6106ad3..fdf6b66 100644
--- a/tortoisehg/hgqt/docklog.py
+++ b/tortoisehg/hgqt/docklog.py
@@ -336,6 +336,7 @@ class ConsoleWidget(QWidget, qtlib.TaskWidget):
matchinfo = {}
for cmdspec in cmdtable:
for cmdname in cmdspec.split('|'):
+ # TODO: switch to hg>=4.8 (fa88170c10bb) syntax
if cmdname[0] == '^':
cmdname = cmdname[1:]
if cmdname.startswith(cmdstart):
diff --git a/tortoisehg/hgqt/filedata.py b/tortoisehg/hgqt/filedata.py
index 89163cf..08ae24a 100644
--- a/tortoisehg/hgqt/filedata.py
+++ b/tortoisehg/hgqt/filedata.py
@@ -226,13 +226,7 @@ class FileData(_AbstractFileData):
def _checkMaxDiff(self, ctx, wfile, maxdiff, force):
self.error = None
fctx = ctx.filectx(wfile)
- if ctx.rev() is None:
- size = fctx.size()
- else:
- # fctx.size() can read all data into memory in rename cases so
- # we read the size directly from the filelog, this is deeper
- # under the API than I prefer to go, but seems necessary
- size = fctx._filelog.rawsize(fctx.filerev())
+ size = hglib.getestimatedsize(fctx)
if not force and size > maxdiff:
raise _BadContent(_('File is larger than the specified max size.\n'
'maxdiff = %s KB') % (maxdiff // 1024))
@@ -312,7 +306,7 @@ class FileData(_AbstractFileData):
if status in ('R', '!'):
if wfile in ctx.p1():
fctx = ctx.p1()[wfile]
- if fctx._filelog.rawsize(fctx.filerev()) > maxdiff:
+ if hglib.getestimatedsize(fctx) > maxdiff:
self.error = mde
else:
olddata = fctx.data()
@@ -380,7 +374,7 @@ class FileData(_AbstractFileData):
self.olddata = olddata
if changeselect:
- diffopts = patch.diffopts(repo.ui, {})
+ diffopts = patch.difffeatureopts(repo.ui)
diffopts.git = True
m = match.exact(repo.root, repo.root, [wfile])
fp = cStringIO.StringIO()
diff --git a/tortoisehg/hgqt/filedialogs.py b/tortoisehg/hgqt/filedialogs.py
index 2f64cd3..81475b7 100644
--- a/tortoisehg/hgqt/filedialogs.py
+++ b/tortoisehg/hgqt/filedialogs.py
@@ -52,6 +52,10 @@ from .qtgui import (
QWidget,
)
+from mercurial import (
+ scmutil,
+)
+
from ..util import hglib
from ..util.i18n import _
from . import (
@@ -366,7 +370,8 @@ class FileLogDialog(_AbstractFileDialog):
if ':' in link:
scheme, param = link.split(':', 1)
if scheme == 'cset':
- rev = self.repo[hglib.fromunicode(param)].rev()
+ rev = scmutil.revsymbol(self.repo,
+ hglib.fromunicode(param)).rev()
return self.goto(rev)
QDesktopServices.openUrl(QUrl(link))
diff --git a/tortoisehg/hgqt/fileview.py b/tortoisehg/hgqt/fileview.py
index 524e94b..cf8e6ef 100644
--- a/tortoisehg/hgqt/fileview.py
+++ b/tortoisehg/hgqt/fileview.py
@@ -1118,12 +1118,16 @@ class _AnnotateViewControl(_AbstractViewControl):
links = []
fctxcache = {} # (path, rev): fctx
for l in data[0]['lines']:
- path, rev = l['file'], l['rev']
+ try:
+ path, rev, lineno = l['path'], l['rev'], l['lineno']
+ except KeyError:
+ # hg<4.8 (34ba47117164, 47cb6750dea3)
+ path, rev, lineno = l['file'], l['rev'], l['line_number']
try:
fctx = fctxcache[path, rev]
except KeyError:
fctx = fctxcache[path, rev] = repo[rev][path]
- links.append((fctx, l['line_number']))
+ links.append((fctx, lineno))
self._links = links
self._updateView()
diff --git a/tortoisehg/hgqt/graft.py b/tortoisehg/hgqt/graft.py
index 6ccfee0..323f4e5 100644
--- a/tortoisehg/hgqt/graft.py
+++ b/tortoisehg/hgqt/graft.py
@@ -24,6 +24,8 @@ from .qtgui import (
QVBoxLayout,
)
+from mercurial import scmutil
+
from ..util import hglib
from ..util.i18n import _
from . import (
@@ -53,7 +55,7 @@ class GraftDialog(QDialog):
self.valid = True
def cleanrevlist(revlist):
- return [self.repo[rev].rev() for rev in revlist]
+ return [scmutil.revsymbol(self.repo, rev).rev() for rev in revlist]
self.sourcelist = cleanrevlist(opts.get('source', ['.']))
currgraftrevs = self.graftstate()
if currgraftrevs:
@@ -220,17 +222,7 @@ class GraftDialog(QDialog):
sess.commandFinished.connect(self._abortFinished)
def graftstate(self):
- graftstatefile = self.repo.vfs.join('graftstate')
- if os.path.exists(graftstatefile):
- f = open(graftstatefile, 'r')
- info = f.readlines()
- f.close()
- if len(info):
- revlist = [rev.strip() for rev in info]
- revlist = [rev for rev in revlist if rev != '']
- if revlist:
- return revlist
- return None
+ return hglib.readgraftstate(self.repo)
def _runCommand(self, cmdline):
assert self._cmdsession.isFinished()
diff --git a/tortoisehg/hgqt/grep.py b/tortoisehg/hgqt/grep.py
index f33e62c..a689786 100644
--- a/tortoisehg/hgqt/grep.py
+++ b/tortoisehg/hgqt/grep.py
@@ -51,6 +51,7 @@ from mercurial import (
match,
subrepo,
ui,
+ scmutil,
)
from mercurial.utils import (
stringutil,
@@ -357,7 +358,7 @@ class SearchWidget(QWidget, qtlib.TaskWidget):
if inc: inc = map(str.strip, inc.split(','))
exc = hglib.fromunicode(self.excle.text())
if exc: exc = map(str.strip, exc.split(','))
- rev = hglib.fromunicode(self.revle.text()).strip()
+ revstr = hglib.fromunicode(self.revle.text()).strip()
self.addHistory(pattern, inc or [], exc or [])
if self.wctxradio.isChecked():
@@ -371,7 +372,8 @@ class SearchWidget(QWidget, qtlib.TaskWidget):
self.tv.setColumnHidden(COL_REVISION, True)
self.tv.setColumnHidden(COL_USER, True)
try:
- ctx = self.repo[rev or '.']
+ rev = scmutil.revsymbol(self.repo, revstr or '.').rev()
+ ctx = self.repo[rev]
except error.RepoError, e:
msg = _('grep: %s\n') % hglib.tounicode(str(e))
self.showMessage.emit(msg)
diff --git a/tortoisehg/hgqt/hgemail_ui.py b/tortoisehg/hgqt/hgemail_ui.py
index 1fb8bd4..b572d6e 100644
--- a/tortoisehg/hgqt/hgemail_ui.py
+++ b/tortoisehg/hgqt/hgemail_ui.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
-# Form implementation generated from reading ui file '/Users/sborho/repos/thg/tortoisehg/hgqt/hgemail.ui'
+# Form implementation generated from reading ui file '/home/sborho/repos/thg/tortoisehg/hgqt/hgemail.ui'
#
-# Created by: PyQt5 UI code generator 5.10.1
+# Created by: PyQt5 UI code generator 5.11.2
#
# WARNING! All changes made in this file will be lost!
diff --git a/tortoisehg/hgqt/matching.py b/tortoisehg/hgqt/matching.py
index d47ba36..e36c04f 100644
--- a/tortoisehg/hgqt/matching.py
+++ b/tortoisehg/hgqt/matching.py
@@ -26,7 +26,10 @@ from .qtgui import (
QVBoxLayout,
)
-from mercurial import error
+from mercurial import (
+ error,
+ scmutil,
+)
from ..util import hglib
from ..util.i18n import _
@@ -230,7 +233,7 @@ class MatchDialog(QDialog):
self.match_btn.setEnabled(True)
return
try:
- csinfo_update(self.repo[new_rev])
+ csinfo_update(scmutil.revsymbol(self.repo, new_rev))
return
except (error.LookupError, error.RepoLookupError, error.RepoError):
pass
diff --git a/tortoisehg/hgqt/merge.py b/tortoisehg/hgqt/merge.py
index 907e44e..5fe0a4f 100644
--- a/tortoisehg/hgqt/merge.py
+++ b/tortoisehg/hgqt/merge.py
@@ -599,10 +599,13 @@ class CommitPage(BasePage):
self.wizard().close()
return True
- user = hglib.tounicode(qtlib.getCurrentUsername(self, self.repo,
- self.opts))
- if not user:
- return False
+ # username will be prompted as necessary by hg if ui.askusername
+ user = self.opts.get('user')
+ if not self.repo.ui.configbool('ui', 'askusername'):
+ user = hglib.tounicode(qtlib.getCurrentUsername(self, self.repo,
+ self.opts))
+ if not user:
+ return False
self.setTitle(_('Committing...'))
self.setSubTitle(_('Please wait while committing merged files.'))
diff --git a/tortoisehg/hgqt/mq.py b/tortoisehg/hgqt/mq.py
index 373c8e3..5f056c6 100644
--- a/tortoisehg/hgqt/mq.py
+++ b/tortoisehg/hgqt/mq.py
@@ -45,7 +45,10 @@ from .qtgui import (
QWidget,
)
-from mercurial import error
+from mercurial import (
+ error,
+ scmutil,
+)
from ..util import hglib
from ..util.i18n import _
@@ -522,7 +525,10 @@ class PatchQueueModel(QAbstractListModel):
repo = self._repoagent.rawRepo()
patch = self._series[index.row()]
try:
- ctx = repo[patch]
+ if patch in repo.thgmqunappliedpatches:
+ ctx = repo[patch]
+ else:
+ ctx = scmutil.revsymbol(repo, patch)
except error.RepoLookupError:
# cache not updated after qdelete or qfinish
return
diff --git a/tortoisehg/hgqt/postreview_ui.py b/tortoisehg/hgqt/postreview_ui.py
index 70c7e67..16b770c 100644
--- a/tortoisehg/hgqt/postreview_ui.py
+++ b/tortoisehg/hgqt/postreview_ui.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
-# Form implementation generated from reading ui file '/Users/sborho/repos/thg/tortoisehg/hgqt/postreview.ui'
+# Form implementation generated from reading ui file '/home/sborho/repos/thg/tortoisehg/hgqt/postreview.ui'
#
-# Created by: PyQt5 UI code generator 5.10.1
+# Created by: PyQt5 UI code generator 5.11.2
#
# WARNING! All changes made in this file will be lost!
diff --git a/tortoisehg/hgqt/qfold.py b/tortoisehg/hgqt/qfold.py
index 962a079..41cf894 100644
--- a/tortoisehg/hgqt/qfold.py
+++ b/tortoisehg/hgqt/qfold.py
@@ -28,6 +28,9 @@ from .qtgui import (
)
from hgext import mq
+from mercurial import (
+ scmutil,
+)
from ..util import hglib
from ..util.i18n import _
@@ -135,9 +138,10 @@ class QFoldDialog(QDialog):
self.summ.setText(hglib.tounicode(txt))
def composeMsg(self, patches):
- return u'\n* * *\n'.join(
- [hglib.tounicode(self.repo[p].description())
- for p in ['qtip'] + patches])
+ descs = [scmutil.revsymbol(self.repo, 'qtip').description()]
+ # lookup of unapplied patches is handled by thgrepo hack
+ descs.extend(self.repo[p].description() for p in patches)
+ return u'\n* * *\n'.join(map(hglib.tounicode, descs))
@pyqtSlot()
def configChanged(self):
diff --git a/tortoisehg/hgqt/qscilib.py b/tortoisehg/hgqt/qscilib.py
index 579f21e..d0f94dc 100644
--- a/tortoisehg/hgqt/qscilib.py
+++ b/tortoisehg/hgqt/qscilib.py
@@ -34,6 +34,7 @@ from .qtgui import (
QCheckBox,
QDialog,
QDialogButtonBox,
+ QFont,
QInputMethodEvent,
QKeyEvent,
QKeySequence,
@@ -820,7 +821,12 @@ def fileEditor(filename, **opts):
editor.installEventFilter(KeyPressInterceptor(dialog))
editor.setMarginLineNumbers(1, True)
editor.setMarginWidth(1, '000')
- editor.setLexer(QsciLexerProperties())
+
+ lexer = QsciLexerProperties()
+ lexer.setFont(QFont('Monospace', 10), -1)
+
+ editor.setLexer(lexer)
+
if opts.get('foldable'):
editor.setFolding(QsciScintilla.BoxedTreeFoldStyle)
dialog.layout().addWidget(editor)
diff --git a/tortoisehg/hgqt/qtlib.py b/tortoisehg/hgqt/qtlib.py
index 9cf73db..c2bf940 100644
--- a/tortoisehg/hgqt/qtlib.py
+++ b/tortoisehg/hgqt/qtlib.py
@@ -22,6 +22,7 @@ import tempfile
import weakref
from .qtcore import (
+ PYQT_VERSION,
QByteArray,
QDir,
QEvent,
@@ -1470,5 +1471,5 @@ class PaletteSwitcher(object):
def setContextMenuShortcut(action, shortcut):
"""Set shortcut for a context menu action, making sure it's visible"""
action.setShortcut(shortcut)
- if QT_VERSION >= 0x50a00:
+ if QT_VERSION >= 0x50a00 and PYQT_VERSION >= 0x50a00:
action.setShortcutVisibleInContextMenu(True)
diff --git a/tortoisehg/hgqt/repofilter.py b/tortoisehg/hgqt/repofilter.py
index 35266ea..4f35255 100644
--- a/tortoisehg/hgqt/repofilter.py
+++ b/tortoisehg/hgqt/repofilter.py
@@ -35,6 +35,7 @@ from .qtgui import (
from mercurial import (
error,
repoview,
+ scmutil,
util,
)
@@ -60,6 +61,9 @@ def _firstword(query):
def _querytype(repo, query):
r"""
+ >>> # TODO: maybe replace with real repo
+ >>> origisrevsymbol = scmutil.isrevsymbol
+ >>> scmutil.isrevsymbol = lambda repo, changeid: changeid in repo
>>> repo = set('0 1 2 3 . stable'.split())
>>> _querytype(repo, u'') is None
True
@@ -79,6 +83,7 @@ def _querytype(repo, query):
'revset'
>>> _querytype(repo, u'\u3000') # UnicodeEncodeError
'revset'
+ >>> scmutil.isrevsymbol = origisrevsymbol
"""
if not query:
return
@@ -91,7 +96,7 @@ def _querytype(repo, query):
if not changeid:
return 'keyword'
try:
- if changeid in repo:
+ if scmutil.isrevsymbol(repo, changeid):
return 'revset'
except error.LookupError: # ambiguous changeid
pass
diff --git a/tortoisehg/hgqt/repoview.py b/tortoisehg/hgqt/repoview.py
index 702e33c..b97c250 100644
--- a/tortoisehg/hgqt/repoview.py
+++ b/tortoisehg/hgqt/repoview.py
@@ -366,20 +366,23 @@ class HgRepoView(QTableView):
"""
if isinstance(rev, unicode):
rev = hglib.fromunicode(rev)
- try:
- rev = scmutil.revsymbol(self.repo, rev).rev()
- except error.RepoError:
- self.showMessage.emit(_("Can't find revision '%s'")
- % hglib.tounicode(str(rev)))
- except LookupError as e:
- self.showMessage.emit(hglib.tounicode(str(e)))
- else:
- idx = self.model().indexFromRev(rev)
- if idx.isValid():
- flags = (QItemSelectionModel.ClearAndSelect
- | QItemSelectionModel.Rows)
- self.selectionModel().setCurrentIndex(idx, flags)
- self.scrollTo(idx)
+ if not isinstance(rev, int):
+ try:
+ rev = scmutil.revsymbol(self.repo, rev).rev()
+ except error.RepoError:
+ self.showMessage.emit(_("Can't find revision '%s'")
+ % hglib.tounicode(str(rev)))
+ return
+ except LookupError as e:
+ self.showMessage.emit(hglib.tounicode(str(e)))
+ return
+
+ idx = self.model().indexFromRev(rev)
+ if idx.isValid():
+ flags = (QItemSelectionModel.ClearAndSelect
+ | QItemSelectionModel.Rows)
+ self.selectionModel().setCurrentIndex(idx, flags)
+ self.scrollTo(idx)
def saveSettings(self, s = None):
if not s:
diff --git a/tortoisehg/hgqt/repowidget.py b/tortoisehg/hgqt/repowidget.py
index 857f7d4..b4e04f6 100644
--- a/tortoisehg/hgqt/repowidget.py
+++ b/tortoisehg/hgqt/repowidget.py
@@ -45,6 +45,7 @@ from .qtgui import (
from mercurial import (
error,
phases,
+ scmutil,
)
from mercurial.utils import (
procutil,
@@ -637,7 +638,7 @@ class RepoWidget(QWidget):
"""Select and scroll to the specified revision"""
try:
# try instant look up
- if hglib.fromunicode(revspec) in self.repo:
+ if scmutil.isrevsymbol(self.repo, hglib.fromunicode(revspec)):
self.repoview.goto(revspec)
return
except error.LookupError:
@@ -1287,7 +1288,8 @@ class RepoWidget(QWidget):
submenu = menu.addMenu(_('Change &Phase to'))
submenu.triggered.connect(self._changePhaseByMenu)
- for pnum, pname in enumerate(phases.phasenames):
+ # TODO: filter out hidden names better
+ for pnum, pname in enumerate(phases.phasenames[:3]):
a = entry(items, submenu, None, enablefuncs['isrev'], pname)
a.setData(pnum)
entry(items, menu)
@@ -1411,9 +1413,9 @@ class RepoWidget(QWidget):
dlg.restart(str(revB), str(revA))
def compressDlg():
ctxa, ctxb = map(self.repo.hgchangectx, self.menuselection)
- if ctxa.ancestor(ctxb) == ctxb:
+ if ctxa.ancestor(ctxb).rev() == ctxb.rev():
revs = self.menuselection[:]
- elif ctxa.ancestor(ctxb) == ctxa:
+ elif ctxa.ancestor(ctxb).rev() == ctxa.rev():
revs = [self.menuselection[1], self.menuselection[0]]
else:
InfoMsgBox(_('Unable to compress history'),
@@ -1803,13 +1805,27 @@ class RepoWidget(QWidget):
@pyqtSlot()
def mergeWithRevision(self):
+ # Don't use self.rev (i.e. the current revision.) This is a context
+ # menu handler, and the menu is open for the selected rows, not for
+ # the current row.
+ revisions = self.repoview.selectedRevisions()
+ if len(revisions) != 1:
+ QMessageBox.warning(self, _('Unable to merge'),
+ _('Please select a revision to merge.'))
+ return
+ rev = revisions[0]
+ if not isinstance(rev, int):
+ QMessageBox.warning(self, _('Unable to merge'),
+ _('Cannot merge with a pseudo revision %r.')
+ % rev)
+ return
pctx = self.repo['.']
- octx = self.repo[self.rev]
+ octx = self.repo[rev]
if pctx == octx:
QMessageBox.warning(self, _('Unable to merge'),
_('You cannot merge a revision with itself'))
return
- self._dialogs.open(RepoWidget._createMergeDialog, self.rev)
+ self._dialogs.open(RepoWidget._createMergeDialog, rev)
def _createMergeDialog(self, rev):
return merge.MergeDialog(self._repoagent, rev, self)
@@ -2035,7 +2051,7 @@ class RepoWidget(QWidget):
QMessageBox.warning(self, _('Cannot import selected revision'),
_('The selected revision (rev #%d) cannot be imported '
'because it is not a descendant of ''qparent'' (rev #%d)') \
- % (self.rev, self.repo['qparent'].rev()))
+ % (self.rev, scmutil.revsymbol(self.repo, 'qparent').rev()))
return
patchdir = self.repo.vfs.join('patches')
diff --git a/tortoisehg/hgqt/revpanel.py b/tortoisehg/hgqt/revpanel.py
index 2450283..a9cc3d6 100644
--- a/tortoisehg/hgqt/revpanel.py
+++ b/tortoisehg/hgqt/revpanel.py
@@ -8,7 +8,10 @@
from __future__ import absolute_import
-from mercurial import error
+from mercurial import (
+ error,
+ scmutil,
+)
from ..util import hglib, obsoleteutil
from ..util.i18n import _
@@ -81,7 +84,7 @@ def data_func(widget, item, ctx):
if not ts:
return None
try:
- tctx = ctx._repo[ts]
+ tctx = scmutil.revsymbol(ctx.repo(), ts)
return revline_data(tctx)
except (error.LookupError, error.RepoLookupError, error.RepoError):
return ts
diff --git a/tortoisehg/hgqt/run.py b/tortoisehg/hgqt/run.py
index d8c70a2..0da6c48 100644
--- a/tortoisehg/hgqt/run.py
+++ b/tortoisehg/hgqt/run.py
@@ -227,7 +227,9 @@ def _parse(ui, args):
sys.exit()
else:
alias, args = 'workbench', []
- aliases, i = cmdutil.findcmd(alias, table, ui.config("ui", "strict"))
+ # copies hg<4.8 (fa88170c10bb) behavior
+ stable = {k.lstrip('^'): e for k, e in table.items()}
+ aliases, i = cmdutil.findcmd(alias, stable, ui.config("ui", "strict"))
for a in aliases:
if a.startswith(alias):
alias = a
@@ -732,8 +734,10 @@ def help_(ui, name=None, with_version=False, **opts):
version(ui)
ui.write('\n')
+ # copies hg<4.8 (fa88170c10bb) behavior
+ stable = {k.lstrip('^'): e for k, e in table.items()}
try:
- aliases, i = cmdutil.findcmd(name, table, False)
+ aliases, i = cmdutil.findcmd(name, stable, False)
except error.AmbiguousCommand, inst:
select = lambda c: c.lstrip('^').startswith(inst.args[0])
helplist(_('list of commands:\n\n'), select)
@@ -771,6 +775,7 @@ def help_(ui, name=None, with_version=False, **opts):
if (not select and name != 'shortlist' and
e[0].__module__ != __name__):
continue
+ # TODO: switch to hg>=4.8 (fa88170c10bb) syntax
if name == "shortlist" and not f.startswith("^"):
continue
f = f.lstrip("^")
diff --git a/tortoisehg/hgqt/rupdate.py b/tortoisehg/hgqt/rupdate.py
index 6ed0166..e949f62 100644
--- a/tortoisehg/hgqt/rupdate.py
+++ b/tortoisehg/hgqt/rupdate.py
@@ -34,7 +34,10 @@ from .qtgui import (
QVBoxLayout,
)
-from mercurial import error
+from mercurial import (
+ error,
+ scmutil,
+)
from ..util import hglib
from ..util.i18n import _
@@ -145,7 +148,7 @@ class RemoteUpdateWidget(cmdui.AbstractCmdWidget):
self.commandChanged.emit()
return
try:
- self.target_info.update(self.repo[new_rev])
+ self.target_info.update(scmutil.revsymbol(self.repo, new_rev))
except (error.LookupError, error.RepoLookupError, error.RepoError):
self.target_info.setText(_('unknown revision!'))
self.commandChanged.emit()
@@ -153,8 +156,8 @@ class RemoteUpdateWidget(cmdui.AbstractCmdWidget):
def canRunCommand(self):
rev = hglib.fromunicode(self.rev_combo.currentText())
try:
- return rev in self.repo
- except error.LookupError:
+ return scmutil.isrevsymbol(self.repo, rev)
+ except error.AmbiguousPrefixLookupError:
# ambiguous changeid
return False
diff --git a/tortoisehg/hgqt/serve_ui.py b/tortoisehg/hgqt/serve_ui.py
index 672445f..1676cc8 100644
--- a/tortoisehg/hgqt/serve_ui.py
+++ b/tortoisehg/hgqt/serve_ui.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
-# Form implementation generated from reading ui file '/Users/sborho/repos/thg/tortoisehg/hgqt/serve.ui'
+# Form implementation generated from reading ui file '/home/sborho/repos/thg/tortoisehg/hgqt/serve.ui'
#
-# Created by: PyQt5 UI code generator 5.10.1
+# Created by: PyQt5 UI code generator 5.11.2
#
# WARNING! All changes made in this file will be lost!
diff --git a/tortoisehg/hgqt/settings.py b/tortoisehg/hgqt/settings.py
index 7ab201b..4e26b9b 100644
--- a/tortoisehg/hgqt/settings.py
+++ b/tortoisehg/hgqt/settings.py
@@ -694,6 +694,12 @@ INFO = (
_('If specified, files in the directory, e.g. .hgignore, are copied '
'to the newly-created repository.'),
globalonly=True),
+ _fi(_('Default Clone Destination'), 'tortoisehg.defaultclonedest',
+ genPathBrowser,
+ _('If specified, the destination field in the clone widget will be '
+ 'pre-filled with this path. Otherwise, it will be pre-filled with '
+ 'the current working directory.'),
+ globalonly=True),
)),
({'name': 'log', 'label': _('Workbench'), 'icon': 'hg-log'}, (
@@ -826,7 +832,7 @@ INFO = (
'This setting is used by the Merge, Tag and Backout dialogs. '
'Default: False')),
_fi(_('New Commit Phase'), 'phases.new-commit',
- (genDefaultCombo, phases.phasenames),
+ (genDefaultCombo, phases.phasenames[:3]),
_('The phase of new commits. Default: draft')),
_fi(_('Secret MQ Patches'), 'mq.secret', genBoolRBGroup,
_('Make MQ patches secret (instead of draft). '
@@ -1155,7 +1161,8 @@ INFO = (
)),
)),
-({'name': 'reviewboard', 'label': _('Review Board'), 'icon': 'reviewboard'}, (
+({'name': 'reviewboard', 'label': _('Review Board'), 'icon': 'reviewboard',
+ 'extension': 'reviewboard'}, (
_fi(_('Server'), 'reviewboard.server', genEditCombo,
_('Path to review board '
'example "http://demo.reviewboard.org"')),
diff --git a/tortoisehg/hgqt/thgstrip.py b/tortoisehg/hgqt/thgstrip.py
index f1b9341..62d0dbd 100644
--- a/tortoisehg/hgqt/thgstrip.py
+++ b/tortoisehg/hgqt/thgstrip.py
@@ -21,7 +21,10 @@ from .qtgui import (
QVBoxLayout,
)
-from mercurial import error
+from mercurial import (
+ error,
+ scmutil,
+)
from ..util import hglib
from ..util.i18n import _, ngettext
@@ -114,7 +117,7 @@ class StripWidget(cmdui.AbstractCmdWidget):
if not revstr:
return None
try:
- rev = self.repo[revstr].rev()
+ rev = scmutil.revsymbol(self.repo, revstr).rev()
except (error.RepoError, error.LookupError):
return None
return rev
diff --git a/tortoisehg/hgqt/update.py b/tortoisehg/hgqt/update.py
index aa74614..0ecc801 100644
--- a/tortoisehg/hgqt/update.py
+++ b/tortoisehg/hgqt/update.py
@@ -180,7 +180,7 @@ class UpdateWidget(cmdui.AbstractCmdWidget):
self.p1_info.update(self.ctxs[0].node())
merge = len(self.ctxs) == 2
if merge:
- self.p2_info.update(self.ctxs[1])
+ self.p2_info.update(self.ctxs[1].node())
new_rev = hglib.fromunicode(self.rev_combo.currentText())
if new_rev == 'null':
self.target_info.setText(_('remove working directory'))
@@ -324,7 +324,8 @@ class UpdateWidget(cmdui.AbstractCmdWidget):
if clean is None:
clean = isclean()
pa = p1.ancestor(p2)
- return not clean and (p1 == pa or p2 == pa)
+ return not clean \
+ and (p1.rev() == pa.rev() or p2.rev() == pa.rev())
def confirmupdate(clean=None):
if clean is None:
clean = isclean()
diff --git a/tortoisehg/hgqt/visdiff.py b/tortoisehg/hgqt/visdiff.py
index cd07e42..494143a 100644
--- a/tortoisehg/hgqt/visdiff.py
+++ b/tortoisehg/hgqt/visdiff.py
@@ -213,7 +213,11 @@ def visualdiff(ui, repo, pats, opts):
try:
ctx1b = None
if change:
- ctx2 = repo[change]
+ # TODO: figure out what's the expect type
+ if isinstance(change, str):
+ ctx2 = scmutil.revsymbol(repo, change)
+ else:
+ ctx2 = repo[change]
p = ctx2.parents()
if len(p) > 1:
ctx1a, ctx1b = p
diff --git a/tortoisehg/hgqt/webconf_ui.py b/tortoisehg/hgqt/webconf_ui.py
index ef47812..876a854 100644
--- a/tortoisehg/hgqt/webconf_ui.py
+++ b/tortoisehg/hgqt/webconf_ui.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
-# Form implementation generated from reading ui file '/Users/sborho/repos/thg/tortoisehg/hgqt/webconf.ui'
+# Form implementation generated from reading ui file '/home/sborho/repos/thg/tortoisehg/hgqt/webconf.ui'
#
-# Created by: PyQt5 UI code generator 5.10.1
+# Created by: PyQt5 UI code generator 5.11.2
#
# WARNING! All changes made in this file will be lost!
diff --git a/tortoisehg/util/__version__.py b/tortoisehg/util/__version__.py
index 93d182a..7b797e2 100644
--- a/tortoisehg/util/__version__.py
+++ b/tortoisehg/util/__version__.py
@@ -1,2 +1,2 @@
# this file is autogenerated by setup.py
-version = "4.7"
+version = "4.8.1"
diff --git a/tortoisehg/util/hglib.py b/tortoisehg/util/hglib.py
index c3f89bf..97e3d09 100644
--- a/tortoisehg/util/hglib.py
+++ b/tortoisehg/util/hglib.py
@@ -32,6 +32,7 @@ from mercurial import (
revset as revsetmod,
revsetlang,
scmutil,
+ state as statemod,
subrepoutil,
ui as uimod,
util,
@@ -250,6 +251,22 @@ def getqqueues(repo):
qqueues = []
return qqueues
+def readgraftstate(repo):
+ """Read a list of nodes from graftstate; or None if nothing in progress"""
+ graftstatefile = repo.vfs.join('graftstate')
+ if not os.path.exists(graftstatefile):
+ return
+ with open(graftstatefile, 'r') as f:
+ info = f.readlines()
+ if info and info[0] == '1\n':
+ # doesn't look like a list of nodes
+ return statemod.cmdstate(repo, 'graftstate').read()['nodes']
+ if len(info):
+ revlist = [rev.strip() for rev in info]
+ revlist = [rev for rev in revlist if rev != '']
+ if revlist:
+ return revlist
+
readmergestate = mergemod.mergestate.read
def readundodesc(repo):
@@ -290,11 +307,13 @@ def allextensions():
disabledexts = disabledextensions()
exts = (disabledexts or {}).copy()
exts.update(enabledexts)
+ exts.pop('configitems') # tortoisehg.util.configitems
if hasattr(sys, "frozen"):
if 'hgsubversion' not in exts:
exts['hgsubversion'] = _('hgsubversion packaged with thg')
if 'hggit' not in exts:
exts['hggit'] = _('hggit packaged with thg')
+ exts.pop('mercurial_extension_utils', None) # Part of keyring extension
return exts
def validateextensions(enabledexts):
@@ -316,7 +335,7 @@ def validateextensions(enabledexts):
exts['perfarce'] = _('perfarce is incompatible with hgsubversion')
return exts
-def _loadextensionwithblacklist(orig, ui, name, path):
+def _loadextensionwithblacklist(orig, ui, name, path, *args, **kwargs):
if name.startswith('hgext.') or name.startswith('hgext/'):
shortname = name[6:]
else:
@@ -324,7 +343,7 @@ def _loadextensionwithblacklist(orig, ui, name, path):
if shortname in _extensions_blacklist and not path: # only bundled ext
return
- return orig(ui, name, path)
+ return orig(ui, name, path, *args, **kwargs)
def _wrapextensionsloader():
"""Wrap extensions.load(ui, name) for blacklist to take effect"""
@@ -719,6 +738,16 @@ def user(ctx):
user = ''
return user
+def getestimatedsize(fctx):
+ """Return the size of the given fctx without loading the revision text"""
+ if fctx.rev() is None:
+ return fctx.size()
+ else:
+ # fctx.size() can read all data into memory in rename cases so
+ # we read the size directly from the filelog, this is deeper
+ # under the API than I prefer to go, but seems necessary
+ return fctx._filelog._revlog.rawsize(fctx.filerev())
+
def get_revision_desc(fctx, curpath=None):
"""return the revision description as a string"""
author = tounicode(username(fctx.user()))
diff --git a/tortoisehg/util/hgversion.py b/tortoisehg/util/hgversion.py
index 93d57a1..ea5063e 100644
--- a/tortoisehg/util/hgversion.py
+++ b/tortoisehg/util/hgversion.py
@@ -16,7 +16,7 @@ except AttributeError:
from mercurial import version
hgversion = version.get_version()
-testedwith = '4.6 4.7'
+testedwith = '4.7 4.8'
def checkhgversion(v):
"""range check the Mercurial version"""
diff --git a/tortoisehg/util/patchctx.py b/tortoisehg/util/patchctx.py
index 751497a..37cff32 100644
--- a/tortoisehg/util/patchctx.py
+++ b/tortoisehg/util/patchctx.py
@@ -110,6 +110,7 @@ class patchctx(object):
def description(self): return self._desc
def branch(self): return self._branch
def parents(self): return ()
+ def repo(self): return self._repo
def tags(self): return ()
def bookmarks(self): return ()
def children(self): return ()
diff --git a/tortoisehg/util/version.py b/tortoisehg/util/version.py
index 3c0a127..395fc1d 100644
--- a/tortoisehg/util/version.py
+++ b/tortoisehg/util/version.py
@@ -56,25 +56,69 @@ def version():
def package_version():
try:
branch, version = liveversion()
+ return _build_package_version(branch, version)
+ except:
+ pass
+ try:
+ import __version__
+ return _build_package_version('stable', __version__.version)
+ except ImportError:
+ return _('unknown')
- extra = None
- if '+' in version:
- version, extra = version.split('+', 1)
+def _build_package_version(branch, version):
+ """
+ >>> _build_package_version('default', '4.8+10')
+ '4.8.5010'
+ >>> _build_package_version('stable', '4.8.2+5')
+ '4.8.21005'
+ >>> _build_package_version('stable', '4.8')
+ '4.8.0'
+ >>> _build_package_version('stable', '4.8.3')
+ '4.8.3'
+ >>> _build_package_version('stable', '4.8rc1')
+ '4.7.91000'
+ >>> _build_package_version('stable', '4.8rc1+2')
+ '4.7.91002'
+ >>> _build_package_version('stable', '1.0rc0')
+ '0.9.90000'
+ >>> _build_package_version('stable', '0.1rc0')
+ '0.0.90000'
+ """
+ extra = rc = None
+ if '+' in version:
+ version, extra = version.split('+', 1)
+ if 'rc' in version:
+ version, rc = version.split('rc', 1)
+ if extra is None:
+ extra = '0' # rc should be a development release
- v = [int(x) for x in version.split('.')]
- while len(v) < 3:
- v.append(0)
- major, minor, periodic = v
+ v = [int(x) for x in version.split('.')]
+ if rc:
+ v = _decrement_version(v)
+ while len(v) < 3:
+ v.append(0)
+ major, minor, periodic = v
- if extra != None:
- tagdistance = int(extra.split('-', 1)[0])
- periodic *= 10000
- if branch == 'default':
- periodic += tagdistance + 5000
- else:
- periodic += tagdistance + 1000
+ if extra != None:
+ tagdistance = int(extra.split('-', 1)[0])
+ periodic *= 10000
+ if rc:
+ periodic += tagdistance + int(rc) * 1000 + 90000
+ elif branch == 'default':
+ periodic += tagdistance + 5000
+ else:
+ periodic += tagdistance + 1000
- return '.'.join([str(x) for x in (major, minor, periodic)])
- except:
- pass
- return _('unknown')
+ return '.'.join([str(x) for x in (major, minor, periodic)])
+
+def _decrement_version(v):
+ if not v:
+ return v
+ v = v[:]
+ p = len(v) - 1
+ v[p] -= 1
+ while p > 0 and v[p] < 0:
+ v[p] = 9
+ v[p - 1] -= 1
+ p -= 1
+ return v