Commits

Steve Borho  committed 01b9175

sync: remove URL splitting and -push and some password hiding

The intent is for the sync tool buttons to *always* use the URL shown in the
text entry.

The layout of the sync tool is now mostly static, items aren't shown and hidden
except for the options label which is usually not shown. Uses Mercurial's url
class effectively

TODO: add per-repo LRU history to the urllabel

  • Participants
  • Parent commits a3a4c88

Comments (0)

Files changed (1)

File tortoisehg/hgqt/sync.py

 # GNU General Public License version 2 or any later version.
 
 import os
-import re
 import tempfile
-import urlparse
 
 from PyQt4.QtCore import *
 from PyQt4.QtGui import *
 
-from mercurial import hg, ui, url, util, scmutil, httpconnection
+from mercurial import hg, ui, util, scmutil, httpconnection
 
-from tortoisehg.util import hglib, wconfig, paths
+from tortoisehg.util import hglib, wconfig
 from tortoisehg.hgqt.i18n import _
 from tortoisehg.hgqt import qtlib, cmdui, thgrepo, rebase, resolve, hgrcutil
 
-def parseurl(path):
-    if path.startswith('ssh://'):
-        scheme = 'ssh'
-        p = path[len('ssh://'):]
-        user, passwd = None, None
-        if p.find('@') != -1:
-            user, p = tuple(p.rsplit('@', 1))
-            if user.find(':') != -1:
-                user, passwd = tuple(user.rsplit(':', 1))
-        m = re.match(r'([^:/]+)(:(\d+))?(/(.*))?$', p)
-        if m:
-            host = m.group(1)
-            port = m.group(3)
-            folder = m.group(5) or '.'
-        else:
-            qtlib.WarningMsgBox(_('Malformed ssh URL'), hglib.tounicode(path))
-            host, port, folder = '', '', ''
-    elif path.startswith(('http://', 'https://', 'svn+https://', 'git://')):
-        # work around http://bugs.python.org/issue7904
-        if 'svn+https' not in urlparse.uses_netloc:
-            urlparse.uses_netloc.append('svn+https')
-        if 'git' not in urlparse.uses_netloc:
-            urlparse.uses_netloc.append('git')
-        snpaqf = urlparse.urlparse(path)
-        scheme, netloc, folder, params, query, fragment = snpaqf
-        host, port, user, passwd = hglib.netlocsplit(netloc)
-        if folder.startswith('/'):
-            folder = folder[1:]
+def parseurl(url):
+    assert type(url) == unicode
+    return util.url(hglib.fromunicode(url))
+
+def linkify(url):
+    assert type(url) == unicode
+    u = util.url(hglib.fromunicode(url))
+    if u.scheme in ('local', 'http', 'https'):
+        safe = util.hidepassword(hglib.fromunicode(url))
+        return u'<a href="%s">%s</a>' % (url, hglib.tounicode(safe))
     else:
-        user, host, port, passwd = [''] * 4
-        folder = path
-        scheme = 'local'
-    return user, host, port, folder, passwd, scheme
-
-def linkify(urlu):
-    scheme = parseurl(hglib.fromunicode(urlu))[5].lower()
-    if scheme in ('local', 'http', 'https'):
-        return u'<a href="%s">%s</a>' % (urlu, urlu)
-    else:
-        return urlu
+        return url
 
 class SyncWidget(QWidget, qtlib.TaskWidget):
     syncStarted = pyqtSignal()  # incoming/outgoing/pull/push started
         self.setLayout(layout)
         self.setAcceptDrops(True)
 
-        self._schemes = ['local', 'ssh', 'http', 'https']
-        if 'hgsubversion' in repo.extensions():
-            self._schemes.append('svn+https')
-        if 'hggit' in repo.extensions() or 'git' in repo.extensions():
-            self._schemes.append('git')
-
         self.repo = repo
         self.finishfunc = None
-        self.curuser = None
-        self.default_user = None
-        self.lastsshuser = None
-        self.curpw = None
-        self.updateInProgress = False
         self.opts = {}
         self.cmenu = None
         self.embedded = bool(parent)
         hbox = QHBoxLayout()
         hbox.setContentsMargins(0, 0, 0, 0)
         bottomlayout.addLayout(hbox)
-        hbox.addWidget(QLabel(_('<b>Remote Repository:</b>')))
-        self.urllabel = QLabel()
-        self.urllabel.setTextInteractionFlags(Qt.TextSelectableByMouse)
-        self.urllabel.setAcceptDrops(False)
-        hbox.addWidget(self.urllabel)
-        self.pushlabel = QLabel(_('<b>Remote Push Repository:</b>'))
-        hbox.addWidget(self.pushlabel)
-        self.pushlabel.hide()
-        self.pushurllabel = QLabel()
-        self.pushurllabel.setTextInteractionFlags(Qt.TextSelectableByMouse)
-        self.pushurllabel.setAcceptDrops(False)
-        hbox.addWidget(self.pushurllabel)
-        hbox.addStretch()
-
-        hbox = QHBoxLayout()
-        hbox.setContentsMargins(0, 0, 0, 0)
-        bottomlayout.addLayout(hbox)
 
         self.pathEditToolbar = tbar = QToolBar(_('Path Edit Toolbar'))
         tbar.setStyleSheet(qtlib.tbstylesheet)
         tbar.setIconSize(QSize(16, 16))
         hbox.addWidget(tbar)
 
+        a = tbar.addAction(qtlib.geticon('thg-password'), _('Security'))
+        a.setToolTip(_('Manage HTTPS connection security and user authentication'))
+        self.securebutton = a
+        tbar.addWidget(qtlib.Spacer(2, 2))
+
         style = QApplication.style()
         a = tbar.addAction(style.standardIcon(QStyle.SP_DialogSaveButton),
                           _('Save'))
         self.savebutton = a
         tbar.addWidget(qtlib.Spacer(2, 2))
 
-        self.schemecombo = QComboBox()
-        for s in self._schemes:
-            self.schemecombo.addItem(s)
-        self.schemecombo.currentIndexChanged.connect(self.schemeChange)
-        tbar.addWidget(self.schemecombo)
-        tbar.addWidget(qtlib.Spacer(2, 2))
-
-        a = tbar.addAction(qtlib.geticon('thg-password'), _('Security'))
-        a.setToolTip(_('Manage HTTPS connection security and user authentication'))
-        self.securebutton = a
-        tbar.addWidget(qtlib.Spacer(2, 2))
-
-        self.hostAndPortActions = []
-
-        fontm = QFontMetrics(self.font())
-        self.hostentry = QLineEdit()
-        self.hostentry.setToolTip(_('Hostname'))
-        self.hostentry.setAcceptDrops(False)
-        self.hostentry.setFixedWidth(30 * fontm.width('9'))
-        self.hostentry.textChanged.connect(self.refreshUrl)
-        self.hostAndPortActions.append(tbar.addWidget(self.hostentry))
-        self.hostAndPortActions.append(tbar.addWidget(qtlib.Spacer(2, 2)))
-
-        w = QLabel(':')
-        self.hostAndPortActions.append(tbar.addWidget(w))
-        self.hostAndPortActions.append(tbar.addWidget(qtlib.Spacer(2, 2)))
-        self.portentry = QLineEdit()
-        self.portentry.setAcceptDrops(False)
-        self.portentry.setToolTip(_('Port'))
-        self.portentry.setFixedWidth(8 * fontm.width('9'))
-        self.portentry.setValidator(QIntValidator(0, 65536, self.portentry))
-        self.portentry.textChanged.connect(self.refreshUrl)
-        self.hostAndPortActions.append(tbar.addWidget(self.portentry))
-        self.hostAndPortActions.append(tbar.addWidget(qtlib.Spacer(2, 2)))
-        w = QLabel('/')
-        self.hostAndPortActions.append(tbar.addWidget(w))
-        self.hostAndPortActions.append(tbar.addWidget(qtlib.Spacer(2, 2)))
-        self.pathentry = QLineEdit()
-        self.pathentry.setAcceptDrops(False)
-        self.pathentry.setToolTip(_('Path'))
-        self.pathentry.textChanged.connect(self.refreshUrl)
-        tbar.addWidget(self.pathentry)
+        self.urlentry = QLineEdit()
+        self.urlentry.textChanged.connect(self.urlChanged)
+        tbar.addWidget(self.urlentry)
 
         hbox = QHBoxLayout()
         hbox.setContentsMargins(0, 0, 0, 0)
             self.curalias = None
             self.setUrl('')
 
-        self.default_user = self.curuser
-        self.lastsshuser = self.curuser
-        QTimer.singleShot(0, lambda:self.pathentry.setFocus())
-
     def canswitch(self):
         return not self.targetcheckbox.isChecked()
 
-    def schemeChange(self):
-        if self.default_user:
-            scheme = self._schemes[self.schemecombo.currentIndex()]
-            if scheme == 'ssh':
-                self.default_user = self.curuser
-                self.curuser = self.lastsshuser
-            else:
-                self.curuser = self.default_user
-
-        self.refreshUrl()
-
     def refreshStatusTips(self):
-        url = self.currentUrl(True)
-        urlu = hglib.tounicode(url)
+        urlu = self.currentUrl()
         self.incomingAction.setStatusTip(_('Preview incoming changesets from %s') % urlu)
         self.pullAction.setStatusTip(_('Pull incoming changesets from %s') % urlu)
-        url = self.currentPushUrl()
-        urlu = hglib.tounicode(url)
         self.outgoingAction.setStatusTip(_('Filter outgoing changesets to %s') % urlu)
         self.pushAction.setStatusTip(_('Push outgoing changesets to %s') % urlu)
 
         tm = PathsModel(pairs, self)
         self.reltv.setModel(tm)
 
+    def currentUrl(self):
+        return unicode(self.urlentry.text())
+
+    def urlChanged(self):
+        self.securebutton.setEnabled('https://' in self.currentUrl())
+
     def refreshUrl(self):
-        'User has changed schema/host/port/path'
-        if self.updateInProgress:
-            return
-        self.urllabel.setText(hglib.tounicode(self.currentUrl(True)))
-        if self.curalias and self.curalias + '-push' in self.paths:
-            self.pushlabel.show()
-            self.pushurllabel.setText(hglib.tounicode(self.currentPushUrl()))
-        else:
-            self.pushlabel.hide()
-            self.pushurllabel.setText('')
-
-        schemeIndex = self.schemecombo.currentIndex()
-        scheme = self._schemes[schemeIndex]
-        for w in self.hostAndPortActions:
-            w.setVisible(schemeIndex != 0)
-        self.securebutton.setVisible(scheme.endswith('https'))
+        'User has selected a new URL'
+        self.urlChanged()
 
         opts = []
         for opt, value in self.opts.iteritems():
         self.optionslabel.setVisible(bool(opts))
         self.optionshdrlabel.setVisible(bool(opts))
 
-    def currentUrl(self, hidepw):
-        scheme = self._schemes[self.schemecombo.currentIndex()]
-        if scheme == 'local':
-            return hglib.fromunicode(self.pathentry.text())
-        else:
-            path = self.pathentry.text()
-            host = self.hostentry.text()
-            port = self.portentry.text()
-            parts = [scheme, '://']
-            if scheme == 'ssh' and '@' in host:
-                user, host = unicode(host).split('@', 1)
-                self.curuser = hglib.fromunicode(user)
-                self.lastsshuser = self.curuser
-            if self.curuser:
-                parts.append(self.curuser)
-                if self.curpw:
-                    parts.append(':')
-                    parts.append(hidepw and '***' or self.curpw)
-                parts.append('@')
-            parts.append(hglib.fromunicode(host))
-            if port:
-                parts.extend([':', hglib.fromunicode(port)])
-            parts.extend(['/', hglib.fromunicode(path)])
-            return ''.join(parts)
-
-    def currentPushUrl(self):
-        if self.curalias and self.curalias + '-push' in self.paths:
-            url = self.paths[self.curalias + '-push']
-            user, host, port, folder, passwd, scheme = parseurl(url)
-            parts = [scheme, '://']
-            if scheme == 'local':
-                return folder
-            if scheme == 'ssh' and '@' in host:
-                user, host = host.split('@', 1)
-            if user:
-                parts.append(user)
-                if passwd:
-                    parts.append(':***')
-                parts.append('@')
-            parts.append(host)
-            if port:
-                parts.extend([':', port])
-            parts.extend(['/', folder])
-            return ''.join(parts)
-        else:
-            return self.currentUrl(True)
-
     def pathSelected(self, index):
         aliasindex = index.sibling(index.row(), 0)
         alias = aliasindex.data(Qt.DisplayRole).toString()
 
     def setUrl(self, newurl):
         'User has selected a new URL: newurl is expected in local encoding'
-        try:
-            user, host, port, folder, passwd, scheme = parseurl(newurl)
-        except TypeError:
-            return
-        self.updateInProgress = True
-        for i, val in enumerate(self._schemes):
-            if scheme == val:
-                self.schemecombo.setCurrentIndex(i)
-                break
-        self.hostentry.setText(hglib.tounicode(host or ''))
-        self.portentry.setText(hglib.tounicode(port or ''))
-        self.pathentry.setText(hglib.tounicode(folder or ''))
-        self.curuser = user
-        self.curpw = passwd
-        self.updateInProgress = False
+        self.urlentry.setText(newurl)
         self.refreshUrl()
         self.refreshStatusTips()
 
 
     def exploreurl(self):
         url = hglib.fromunicode(self.menuurl)
-        u, h, p, folder, pw, scheme = parseurl(url)
-        if scheme == 'local':
+        if parseurl(url).scheme == 'local':
             qtlib.openlocalurl(folder)
         else:
             QDesktopServices.openUrl(QUrl(url))
 
     def terminalurl(self):
         url = hglib.fromunicode(self.menuurl)
-        u, h, p, folder, pw, scheme = parseurl(url)
-        if scheme != 'local':
+        if parseurl(url).scheme != 'local':
             qtlib.InfoMsgBox(_('Repository not local'),
                         _('A terminal shell cannot be opened for remote'))
             return
     def editurl(self):
         alias = hglib.fromunicode(self.menualias)
         url = hglib.fromunicode(self.menuurl)
-        dlg = SaveDialog(self.repo, alias, url, url, self, edit=True)
+        dlg = SaveDialog(self.repo, alias, url, self, edit=True)
         dlg.setWindowFlags(Qt.Sheet)
         dlg.setWindowModality(Qt.WindowModal)
         if dlg.exec_() == QDialog.Accepted:
             alias = 'default'
         else:
             alias = 'new'
-        url = self.currentUrl(False)
-        safeurl = self.currentUrl(True)
-        dlg = SaveDialog(self.repo, alias, url, safeurl, self)
+        dlg = SaveDialog(self.repo, alias, self.currentUrl(), self)
         dlg.setWindowFlags(Qt.Sheet)
         dlg.setWindowModality(Qt.WindowModal)
         if dlg.exec_() == QDialog.Accepted:
             self.reload()
 
     def secureclicked(self):
-        dlg = SecureDialog(self.repo, self.currentUrl(False), self)
+        dlg = SecureDialog(self.repo, self.currentUrl(), self)
         dlg.setWindowFlags(Qt.Sheet)
         dlg.setWindowModality(Qt.WindowModal)
         dlg.exec_()
         if self.opts.get('debug'):
             cmdline.append('--debug')
 
-        cururl = self.currentUrl(False)
-        implicitpushrepo = False
-        if ('push' in cmdline or 'outgoing' in cmdline) and \
-           self.curalias and self.curalias + '-push' in self.paths:
-            implicitpushrepo = True
-            cururl = self.paths[self.curalias + '-push']
+        cururl = self.currentUrl()
+        lurl = hglib.fromunicode(cururl)
+        u = parseurl(cururl)
 
-        if not cururl:
-            host = ''
-            folder = ''
-        else:
-            user, host, port, folder, passwd, scheme = parseurl(cururl)
-
-        if not host and not folder:
+        if not u.host and not u.path:
             self.switchToRequest.emit('sync')
             qtlib.WarningMsgBox(_('No remote repository URL or path set'),
                     _('No valid <i>default</i> remote repository URL or path '
                     parent=self)
             return
 
-        if scheme == 'https':
-            if self.repo.ui.configbool('insecurehosts', host):
+        if u.scheme == 'https':
+            if self.repo.ui.configbool('insecurehosts', u.host):
                 cmdline.append('--insecure')
-            if user:
-                cleanurl = util.removeauth(cururl)
+            if u.user:
+                cleanurl = util.removeauth(lurl)
                 res = httpconnection.readauthforuri(self.repo.ui, cleanurl,
-                                                    user)
+                                                    u.user)
                 if res:
                     group, auth = res
                     if auth.get('username'):
                             self.setUrl(cleanurl)
                             self.saveclicked()
 
-        safeurl = self.currentUrl(True)
-        if implicitpushrepo:
-            safeurl = self.currentPushUrl()
-
+        safeurl = util.hidepassword(lurl)
         display = ' '.join(cmdline + [safeurl]).replace('\n', '^M')
         if not self.opts.get('mq'):
-            cmdline.append(cururl)
+            cmdline.append(lurl)
         self.repo.incrementBusyCount()
-        self.cmd.run(cmdline, display=display, useproc='p4://' in cururl)
+        self.cmd.run(cmdline, display=display, useproc='p4://' in lurl)
 
     def outputHook(self, msg, label):
         if '\'hg push --new-branch\'' in msg:
         if self.cmd.core.running():
             self.output.emit(_('sync command already running'), 'control')
             return
-        save = self.currentUrl(False)
+        save = self.currentUrl()
         orev = self.opts.get('rev')
         self.setUrl(bundle)
         if rev is not None:
 
     def inclicked(self):
         self.syncStarted.emit()
-        url = self.currentUrl(True)
-        urlu = hglib.tounicode(url)
-        link = linkify(urlu)
+        url = self.currentUrl()
+        link = linkify(url)
         self.showMessage.emit(_('Getting incoming changesets from %s...') % link)
         if self.embedded and not url.startswith('p4://') and \
            not self.opts.get('subrepos'):
                     self.showMessage.emit(_('No incoming changesets from %s') % link)
                 else:
                     self.showMessage.emit(_('Incoming from %s aborted, ret %d') % (link, ret))
-            bfile = url
+            bfile = hglib.fromunicode(url)
             for badchar in (':', '*', '\\', '?', '#'):
                 bfile = bfile.replace(badchar, '')
             bfile = bfile.replace('/', '_')
             cmdline = ['--repository', self.repo.root, 'incoming']
             self.run(cmdline, ('force', 'branch', 'rev', 'subrepos'))
 
-    def pullclicked(self, urltoshow=None):
+    def pullclicked(self, url=None):
         self.syncStarted.emit()
-        url = self.currentUrl(True)
-        urlu = hglib.tounicode(url)
-        link = linkify(urlu)
-        if urltoshow is None:
-            urltoshow = urlu
-        linktoshow = linkify(urltoshow)
+        link = linkify(url or self.currentUrl())
+
         def finished(ret, output):
             if ret == 0:
-                self.showMessage.emit(_('Pull from %s completed') % linktoshow)
+                self.showMessage.emit(_('Pull from %s completed') % link)
             else:
                 self.showMessage.emit(_('Pull from %s aborted, ret %d')
-                                      % (linktoshow, ret))
+                                      % (link, ret))
             self.pullCompleted.emit()
             # handle file conflicts during rebase
             if self.opts.get('rebase'):
 
     def outclicked(self):
         self.syncStarted.emit()
-        url = self.currentPushUrl()
-        urlu = hglib.tounicode(url)
-        link = linkify(urlu)
+
+        link = linkify(self.currentUrl())
         self.showMessage.emit(_('Finding outgoing changesets to %s...') % link)
         if self.embedded and not self.opts.get('subrepos'):
             def verifyhash(hash):
                              'branch=%r' % (pushall, rev, branch))
         validopts = ('force', 'new-branch', 'branch', 'rev', 'bookmark', 'mq')
         self.syncStarted.emit()
-        url = self.currentPushUrl()
-        urlu = hglib.tounicode(url)
-        link = linkify(urlu)
-        if (not hg.islocal(self.currentPushUrl()) and confirm
-            and not self.targetcheckbox.isChecked()):
+
+        lurl = hglib.fromunicode(self.currentUrl())
+        link = linkify(self.currentUrl())
+        if (not hg.islocal(lurl) and confirm and not self.targetcheckbox.isChecked()):
             r = qtlib.QuestionMsgBox(_('Confirm Push to remote Repository'),
                                      _('Push to remote repository\n%s\n?')
-                                     % urlu, parent=self)
+                                     % link, parent=self)
             if not r:
                 self.showMessage.emit(_('Push to %s aborted') % link)
                 self.pushCompleted.emit()
             # Select the "Local" scheme
             self.schemecombo.setCurrentIndex(0)
             # Set the pull source to the selected bundle file
-            self.pathentry.setText(bundlefile)
+            self.urlentry.setText(bundlefile)
             # Execute the incomming command, which will show the revisions in
             # the bundle, and let the user accept or reject them
             self.inclicked()
         super(PostPullDialog, self).reject()
 
 class SaveDialog(QDialog):
-    def __init__(self, repo, alias, origurl, safeurl, parent, edit=False):
+    def __init__(self, repo, alias, urlu, parent, edit=False):
         super(SaveDialog, self).__init__(parent)
 
         self.setWindowTitle(_('Save Path'))
                             ~Qt.WindowContextHelpButtonHint)
 
         self.repo = repo
-        self.origurl = origurl
+        self.origurl = hglib.fromunicode(urlu)
         self.setLayout(QFormLayout(fieldGrowthPolicy=QFormLayout.ExpandingFieldsGrow))
 
         self.origalias = alias
         self.aliasentry.textChanged.connect(self.aliasChanged)
         self.layout().addRow(_('Alias'), self.aliasentry)
 
+        safeurl = util.hidepassword(self.origurl)
+
         self.edit = edit
         if edit:
-            self.urlentry = QLineEdit(hglib.tounicode(origurl))
+            self.urlentry = QLineEdit(urlu)
             self.urlentry.textChanged.connect(self.urlChanged)
             self.layout().addRow(_('URL'), self.urlentry)
         else:
             self.urllabel = QLabel(hglib.tounicode(safeurl))
             self.layout().addRow(_('URL'), self.urllabel)
 
-        user, host, port, folder, passwd, scheme = parseurl(origurl)
-        if not edit and (user or passwd) and scheme in ('http', 'https'):
-            cleanurl = util.removeauth(origurl)
+        u = parseurl(urlu)
+        if not edit and (u.user or u.passwd) and u.scheme in ('http', 'https'):
+            cleanurl = util.removeauth(self.origurl)
             def showurl(showclean):
                 newurl = showclean and cleanurl or safeurl
                 self.urllabel.setText(hglib.tounicode(newurl))
         self.bb.button(QDialogButtonBox.Save).setEnabled(enabled)
 
 class SecureDialog(QDialog):
-    def __init__(self, repo, origurl, parent):
+    def __init__(self, repo, urlu, parent):
         super(SecureDialog, self).__init__(parent)
 
         def genfingerprint():
             pretty = ":".join([hash[x:x + 2] for x in xrange(0, len(hash), 2)])
             le.setText(pretty)
 
-        user, host, port, folder, passwd, scheme = parseurl(origurl)
-        uhost = hglib.tounicode(host)
+        u = parseurl(urlu)
+        uhost = hglib.tounicode(u.host)
         self.setWindowTitle(_('Security: ') + uhost)
         self.setWindowFlags(self.windowFlags() & \
                             ~Qt.WindowContextHelpButtonHint)
 
         # if the already user has an [auth] configuration for this URL, use it
-        cleanurl = util.removeauth(origurl)
-        res = httpconnection.readauthforuri(repo.ui, cleanurl, user)
+        cleanurl = util.removeauth(hglib.fromunicode(urlu))
+        res = httpconnection.readauthforuri(repo.ui, cleanurl, u.user)
         if res:
             self.alias, auth = res
         else:
-            self.alias, auth = host, {}
+            self.alias, auth = u.host, {}
         self.repo = repo
-        self.host = host
+        self.host = u.host
         if cleanurl.startswith('svn+https://'):
             self.schemes = 'svn+https'
         else:
         self.insecureradio = QRadioButton(
             _('No host validation, but still encrypted (bad)'))
         hbox = QHBoxLayout()
-        fprint = repo.ui.config('hostfingerprints', host, '')
+        fprint = repo.ui.config('hostfingerprints', u.host, '')
         self.fprintentry = le = QLineEdit(fprint)
         self.fprintradio.toggled.connect(self.fprintentry.setEnabled)
         self.fprintentry.setEnabled(False)
         self.cacertradio.setChecked(True) # default
         if fprint:
             self.fprintradio.setChecked(True)
-        elif repo.ui.config('insecurehosts', host):
+        elif repo.ui.config('insecurehosts', u.host):
             self.insecureradio.setChecked(True)
 
         authbox = QGroupBox(_('User Authentication'))
         authbox.setLayout(form)
         self.layout().addWidget(authbox)
 
-        self.userentry = QLineEdit(user or auth.get('username', ''))
+        self.userentry = QLineEdit(u.user or auth.get('username', ''))
         self.userentry.setToolTip(
 _('''Optional. Username to authenticate with. If not given, and the remote
 site requires basic or digest authentication, the user will be prompted for
 foo.username = $USER.'''))
         form.addRow(_('Username'), self.userentry)
 
-        self.pwentry = QLineEdit(passwd or auth.get('password', ''))
+        self.pwentry = QLineEdit(u.passwd or auth.get('password', ''))
         self.pwentry.setEchoMode(QLineEdit.Password)
         self.pwentry.setToolTip(
 _('''Optional. Password to authenticate with. If not given, and the remote
 
 
 def run(ui, *pats, **opts):
+    from tortoisehg.util import paths
     repo = thgrepo.repository(ui, path=paths.find_root())
     return SyncWidget(repo, None, **opts)