@@ -462,6 +462,7 @@
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files
+ (sent 8 HTTP requests and 3526 bytes; received 961 bytes in responses) (?)
$ grep 'lfs' .hg/requires $SERVER_REQUIRES
.hg/requires:lfs
$TESTTMP/server/.hg/requires:lfs
@@ -382,6 +382,7 @@
devel-peer-request: 16 bytes of commands arguments in headers
devel-peer-request: finished in *.???? seconds (200) (glob)
received listkey for "phases": 15 bytes
+ (sent 9 HTTP requests and 3898 bytes; received 920 bytes in responses)
$ hg rollback -q
$ sed 's/.*] "/"/' < ../access.log
@@ -361,6 +361,7 @@
bundle2-input-bundle: 5 parts total
transaction abort!
rollback completed
+ truncating cache/rbc-revs-v1 to 8
abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
no rollback information available
0:6675d58eff77
@@ -808,7 +809,6 @@
acl: acl.deny.bookmarks not enabled
acl: bookmark access granted: "ef1ea85a6374b77d6da9dcda9541f498f2d17df7" on bookmark "moving-bookmark"
bundle2-input-bundle: 7 parts total
- truncating cache/rbc-revs-v1 to 8
updating the branch cache
invalid branch cache (served.hidden): tip differs
added 1 changesets with 1 changes to 1 files
@@ -900,6 +900,7 @@
bundle2-input-bundle: 7 parts total
transaction abort!
rollback completed
+ truncating cache/rbc-revs-v1 to 8
abort: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
no rollback information available
0:6675d58eff77
@@ -985,7 +986,6 @@
bundle2-input-part: "phase-heads" supported
bundle2-input-part: total payload size 24
bundle2-input-bundle: 5 parts total
- truncating cache/rbc-revs-v1 to 8
updating the branch cache
added 3 changesets with 3 changes to 3 files
bundle2-output-bundle: "HG20", 1 parts total
@@ -1073,6 +1073,7 @@
bundle2-input-bundle: 5 parts total
transaction abort!
rollback completed
+ truncating cache/rbc-revs-v1 to 8
abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
no rollback information available
0:6675d58eff77
@@ -1322,7 +1323,6 @@
bundle2-input-part: "phase-heads" supported
bundle2-input-part: total payload size 24
bundle2-input-bundle: 5 parts total
- truncating cache/rbc-revs-v1 to 8
updating the branch cache
added 3 changesets with 3 changes to 3 files
bundle2-output-bundle: "HG20", 1 parts total
@@ -1499,6 +1499,7 @@
bundle2-input-bundle: 5 parts total
transaction abort!
rollback completed
+ truncating cache/rbc-revs-v1 to 8
abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
no rollback information available
0:6675d58eff77
@@ -1583,7 +1584,6 @@
bundle2-input-part: "phase-heads" supported
bundle2-input-part: total payload size 24
bundle2-input-bundle: 5 parts total
- truncating cache/rbc-revs-v1 to 8
updating the branch cache
added 3 changesets with 3 changes to 3 files
bundle2-output-bundle: "HG20", 1 parts total
@@ -1671,6 +1671,7 @@
bundle2-input-bundle: 5 parts total
transaction abort!
rollback completed
+ truncating cache/rbc-revs-v1 to 8
abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
no rollback information available
0:6675d58eff77
@@ -21,7 +21,10 @@
dest = repo.ui.expandpath(b'default')
peer = hg.peer(repo, {}, dest)
- flogheads = peer.x_rfl_getflogheads(path)
+ try:
+ flogheads = peer.x_rfl_getflogheads(path)
+ finally:
+ peer.close()
if flogheads:
for head in flogheads:
@@ -716,13 +716,17 @@
_(b'sharing subrepo %s from %s\n')
% (subrelpath(self), srcurl)
)
- shared = hg.share(
- self._repo._subparent.baseui,
- getpeer(),
- self._repo.root,
- update=False,
- bookmarks=False,
- )
+ peer = getpeer()
+ try:
+ shared = hg.share(
+ self._repo._subparent.baseui,
+ peer,
+ self._repo.root,
+ update=False,
+ bookmarks=False,
+ )
+ finally:
+ peer.close()
self._repo = shared.local()
else:
# TODO: find a common place for this and this code in the
@@ -743,14 +747,18 @@
_(b'cloning subrepo %s from %s\n')
% (subrelpath(self), util.hidepassword(srcurl))
)
- other, cloned = hg.clone(
- self._repo._subparent.baseui,
- {},
- getpeer(),
- self._repo.root,
- update=False,
- shareopts=shareopts,
- )
+ peer = getpeer()
+ try:
+ other, cloned = hg.clone(
+ self._repo._subparent.baseui,
+ {},
+ peer,
+ self._repo.root,
+ update=False,
+ shareopts=shareopts,
+ )
+ finally:
+ peer.close()
self._repo = cloned.local()
self._initrepo(parentrepo, source, create=True)
self._cachestorehash(srcurl)
@@ -760,7 +768,11 @@
% (subrelpath(self), util.hidepassword(srcurl))
)
cleansub = self.storeclean(srcurl)
- exchange.pull(self._repo, getpeer())
+ peer = getpeer()
+ try:
+ exchange.pull(self._repo, peer)
+ finally:
+ peer.close()
if cleansub:
# keep the repo clean after pull
self._cachestorehash(srcurl)
@@ -845,7 +857,10 @@
% (subrelpath(self), util.hidepassword(dsturl))
)
other = hg.peer(self._repo, {b'ssh': ssh}, dsturl)
- res = exchange.push(self._repo, other, force, newbranch=newbranch)
+ try:
+ res = exchange.push(self._repo, other, force, newbranch=newbranch)
+ finally:
+ other.close()
# the repo is now clean
self._cachestorehash(dsturl)
@@ -175,10 +175,7 @@
# to deadlocks due to a peer get gc'ed in a fork
# We add our own stack trace, because the stacktrace when called
# from __del__ is useless.
- if False: # enabled in next commit
- ui.develwarn(
- b'missing close on SSH connection created at:\n%s' % warn
- )
+ ui.develwarn(b'missing close on SSH connection created at:\n%s' % warn)
def _makeconnection(ui, sshcmd, args, remotecmd, path, sshenv=None):
@@ -1841,9 +1841,12 @@
if revs:
revs = [repo.lookup(rev) for rev in revs]
other = hg.peer(repo, {}, dest)
- repo.ui.pushbuffer()
- outgoing = discovery.findcommonoutgoing(repo, other, onlyheads=revs)
- repo.ui.popbuffer()
+ try:
+ repo.ui.pushbuffer()
+ outgoing = discovery.findcommonoutgoing(repo, other, onlyheads=revs)
+ repo.ui.popbuffer()
+ finally:
+ other.close()
cl = repo.changelog
o = {cl.rev(r) for r in outgoing.missing}
return subset & o
@@ -678,140 +678,148 @@
srcpeer = source.peer() # in case we were called with a localrepo
branches = (None, branch or [])
origsource = source = srcpeer.url()
- revs, checkout = addbranchrevs(srcpeer, srcpeer, branches, revs)
-
- if dest is None:
- dest = defaultdest(source)
- if dest:
- ui.status(_(b"destination directory: %s\n") % dest)
- else:
- dest = ui.expandpath(dest)
-
- dest = util.urllocalpath(dest)
- source = util.urllocalpath(source)
-
- if not dest:
- raise error.InputError(_(b"empty destination path is not valid"))
-
- destvfs = vfsmod.vfs(dest, expandpath=True)
- if destvfs.lexists():
- if not destvfs.isdir():
- raise error.InputError(_(b"destination '%s' already exists") % dest)
- elif destvfs.listdir():
- raise error.InputError(_(b"destination '%s' is not empty") % dest)
-
- createopts = {}
- narrow = False
-
- if storeincludepats is not None:
- narrowspec.validatepatterns(storeincludepats)
- narrow = True
-
- if storeexcludepats is not None:
- narrowspec.validatepatterns(storeexcludepats)
- narrow = True
-
- if narrow:
- # Include everything by default if only exclusion patterns defined.
- if storeexcludepats and not storeincludepats:
- storeincludepats = {b'path:.'}
-
- createopts[b'narrowfiles'] = True
-
- if depth:
- createopts[b'shallowfilestore'] = True
-
- if srcpeer.capable(b'lfs-serve'):
- # Repository creation honors the config if it disabled the extension, so
- # we can't just announce that lfs will be enabled. This check avoids
- # saying that lfs will be enabled, and then saying it's an unknown
- # feature. The lfs creation option is set in either case so that a
- # requirement is added. If the extension is explicitly disabled but the
- # requirement is set, the clone aborts early, before transferring any
- # data.
- createopts[b'lfs'] = True
-
- if extensions.disabled_help(b'lfs'):
- ui.status(
- _(
- b'(remote is using large file support (lfs), but it is '
- b'explicitly disabled in the local configuration)\n'
+ srclock = destlock = cleandir = None
+ destpeer = None
+ try:
+ revs, checkout = addbranchrevs(srcpeer, srcpeer, branches, revs)
+
+ if dest is None:
+ dest = defaultdest(source)
+ if dest:
+ ui.status(_(b"destination directory: %s\n") % dest)
+ else:
+ dest = ui.expandpath(dest)
+
+ dest = util.urllocalpath(dest)
+ source = util.urllocalpath(source)
+
+ if not dest:
+ raise error.InputError(_(b"empty destination path is not valid"))
+
+ destvfs = vfsmod.vfs(dest, expandpath=True)
+ if destvfs.lexists():
+ if not destvfs.isdir():
+ raise error.InputError(
+ _(b"destination '%s' already exists") % dest
)
- )
- else:
- ui.status(
- _(
- b'(remote is using large file support (lfs); lfs will '
- b'be enabled for this repository)\n'
+ elif destvfs.listdir():
+ raise error.InputError(
+ _(b"destination '%s' is not empty") % dest
)
- )
-
- shareopts = shareopts or {}
- sharepool = shareopts.get(b'pool')
- sharenamemode = shareopts.get(b'mode')
- if sharepool and islocal(dest):
- sharepath = None
- if sharenamemode == b'identity':
- # Resolve the name from the initial changeset in the remote
- # repository. This returns nullid when the remote is empty. It
- # raises RepoLookupError if revision 0 is filtered or otherwise
- # not available. If we fail to resolve, sharing is not enabled.
- try:
- with srcpeer.commandexecutor() as e:
- rootnode = e.callcommand(
- b'lookup',
- {
- b'key': b'0',
- },
- ).result()
-
- if rootnode != nullid:
- sharepath = os.path.join(sharepool, hex(rootnode))
- else:
+
+ createopts = {}
+ narrow = False
+
+ if storeincludepats is not None:
+ narrowspec.validatepatterns(storeincludepats)
+ narrow = True
+
+ if storeexcludepats is not None:
+ narrowspec.validatepatterns(storeexcludepats)
+ narrow = True
+
+ if narrow:
+ # Include everything by default if only exclusion patterns defined.
+ if storeexcludepats and not storeincludepats:
+ storeincludepats = {b'path:.'}
+
+ createopts[b'narrowfiles'] = True
+
+ if depth:
+ createopts[b'shallowfilestore'] = True
+
+ if srcpeer.capable(b'lfs-serve'):
+ # Repository creation honors the config if it disabled the extension, so
+ # we can't just announce that lfs will be enabled. This check avoids
+ # saying that lfs will be enabled, and then saying it's an unknown
+ # feature. The lfs creation option is set in either case so that a
+ # requirement is added. If the extension is explicitly disabled but the
+ # requirement is set, the clone aborts early, before transferring any
+ # data.
+ createopts[b'lfs'] = True
+
+ if extensions.disabled_help(b'lfs'):
+ ui.status(
+ _(
+ b'(remote is using large file support (lfs), but it is '
+ b'explicitly disabled in the local configuration)\n'
+ )
+ )
+ else:
+ ui.status(
+ _(
+ b'(remote is using large file support (lfs); lfs will '
+ b'be enabled for this repository)\n'
+ )
+ )
+
+ shareopts = shareopts or {}
+ sharepool = shareopts.get(b'pool')
+ sharenamemode = shareopts.get(b'mode')
+ if sharepool and islocal(dest):
+ sharepath = None
+ if sharenamemode == b'identity':
+ # Resolve the name from the initial changeset in the remote
+ # repository. This returns nullid when the remote is empty. It
+ # raises RepoLookupError if revision 0 is filtered or otherwise
+ # not available. If we fail to resolve, sharing is not enabled.
+ try:
+ with srcpeer.commandexecutor() as e:
+ rootnode = e.callcommand(
+ b'lookup',
+ {
+ b'key': b'0',
+ },
+ ).result()
+
+ if rootnode != nullid:
+ sharepath = os.path.join(sharepool, hex(rootnode))
+ else:
+ ui.status(
+ _(
+ b'(not using pooled storage: '
+ b'remote appears to be empty)\n'
+ )
+ )
+ except error.RepoLookupError:
ui.status(
_(
b'(not using pooled storage: '
- b'remote appears to be empty)\n'
+ b'unable to resolve identity of remote)\n'
)
)
- except error.RepoLookupError:
+ elif sharenamemode == b'remote':
+ sharepath = os.path.join(
+ sharepool, hex(hashutil.sha1(source).digest())
+ )
+ else:
+ raise error.Abort(
+ _(b'unknown share naming mode: %s') % sharenamemode
+ )
+
+ # TODO this is a somewhat arbitrary restriction.
+ if narrow:
ui.status(
- _(
- b'(not using pooled storage: '
- b'unable to resolve identity of remote)\n'
- )
+ _(b'(pooled storage not supported for narrow clones)\n')
)
- elif sharenamemode == b'remote':
- sharepath = os.path.join(
- sharepool, hex(hashutil.sha1(source).digest())
- )
- else:
- raise error.Abort(
- _(b'unknown share naming mode: %s') % sharenamemode
- )
-
- # TODO this is a somewhat arbitrary restriction.
- if narrow:
- ui.status(_(b'(pooled storage not supported for narrow clones)\n'))
- sharepath = None
-
- if sharepath:
- return clonewithshare(
- ui,
- peeropts,
- sharepath,
- source,
- srcpeer,
- dest,
- pull=pull,
- rev=revs,
- update=update,
- stream=stream,
- )
-
- srclock = destlock = cleandir = None
- srcrepo = srcpeer.local()
- try:
+ sharepath = None
+
+ if sharepath:
+ return clonewithshare(
+ ui,
+ peeropts,
+ sharepath,
+ source,
+ srcpeer,
+ dest,
+ pull=pull,
+ rev=revs,
+ update=update,
+ stream=stream,
+ )
+
+ srcrepo = srcpeer.local()
+
abspath = origsource
if islocal(origsource):
abspath = os.path.abspath(util.urllocalpath(origsource))
@@ -1052,6 +1060,8 @@
shutil.rmtree(cleandir, True)
if srcpeer is not None:
srcpeer.close()
+ if destpeer and destpeer.local() is None:
+ destpeer.close()
return srcpeer, destpeer
@@ -1253,15 +1263,17 @@
"""
source, branches = parseurl(ui.expandpath(source), opts.get(b'branch'))
other = peer(repo, opts, source)
- ui.status(_(b'comparing with %s\n') % util.hidepassword(source))
- revs, checkout = addbranchrevs(repo, other, branches, opts.get(b'rev'))
-
- if revs:
- revs = [other.lookup(rev) for rev in revs]
- other, chlist, cleanupfn = bundlerepo.getremotechanges(
- ui, repo, other, revs, opts[b"bundle"], opts[b"force"]
- )
+ cleanupfn = other.close
try:
+ ui.status(_(b'comparing with %s\n') % util.hidepassword(source))
+ revs, checkout = addbranchrevs(repo, other, branches, opts.get(b'rev'))
+
+ if revs:
+ revs = [other.lookup(rev) for rev in revs]
+ other, chlist, cleanupfn = bundlerepo.getremotechanges(
+ ui, repo, other, revs, opts[b"bundle"], opts[b"force"]
+ )
+
if not chlist:
ui.status(_(b"no changes found\n"))
return subreporecurse()
@@ -1320,13 +1332,17 @@
revs = [repo[rev].node() for rev in scmutil.revrange(repo, revs)]
other = peer(repo, opts, dest)
- outgoing = discovery.findcommonoutgoing(
- repo, other, revs, force=opts.get(b'force')
- )
- o = outgoing.missing
- if not o:
- scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
- return o, other
+ try:
+ outgoing = discovery.findcommonoutgoing(
+ repo, other, revs, force=opts.get(b'force')
+ )
+ o = outgoing.missing
+ if not o:
+ scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
+ return o, other
+ except: # re-raises
+ other.close()
+ raise
def outgoing(ui, repo, dest, opts):
@@ -1341,27 +1357,30 @@
limit = logcmdutil.getlimit(opts)
o, other = _outgoing(ui, repo, dest, opts)
- if not o:
+ try:
+ if not o:
+ cmdutil.outgoinghooks(ui, repo, other, opts, o)
+ return recurse()
+
+ if opts.get(b'newest_first'):
+ o.reverse()
+ ui.pager(b'outgoing')
+ displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
+ count = 0
+ for n in o:
+ if limit is not None and count >= limit:
+ break
+ parents = [p for p in repo.changelog.parents(n) if p != nullid]
+ if opts.get(b'no_merges') and len(parents) == 2:
+ continue
+ count += 1
+ displayer.show(repo[n])
+ displayer.close()
cmdutil.outgoinghooks(ui, repo, other, opts, o)
- return recurse()
-
- if opts.get(b'newest_first'):
- o.reverse()
- ui.pager(b'outgoing')
- displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
- count = 0
- for n in o:
- if limit is not None and count >= limit:
- break
- parents = [p for p in repo.changelog.parents(n) if p != nullid]
- if opts.get(b'no_merges') and len(parents) == 2:
- continue
- count += 1
- displayer.show(repo[n])
- displayer.close()
- cmdutil.outgoinghooks(ui, repo, other, opts, o)
- recurse()
- return 0 # exit code is zero since we found outgoing changes
+ recurse()
+ return 0 # exit code is zero since we found outgoing changes
+ finally:
+ other.close()
def verify(repo, level=None):
@@ -471,17 +471,20 @@
"""lists the capabilities of a remote peer"""
opts = pycompat.byteskwargs(opts)
peer = hg.peer(ui, opts, path)
- caps = peer.capabilities()
- ui.writenoi18n(b'Main capabilities:\n')
- for c in sorted(caps):
- ui.write(b' %s\n' % c)
- b2caps = bundle2.bundle2caps(peer)
- if b2caps:
- ui.writenoi18n(b'Bundle2 capabilities:\n')
- for key, values in sorted(pycompat.iteritems(b2caps)):
- ui.write(b' %s\n' % key)
- for v in values:
- ui.write(b' %s\n' % v)
+ try:
+ caps = peer.capabilities()
+ ui.writenoi18n(b'Main capabilities:\n')
+ for c in sorted(caps):
+ ui.write(b' %s\n' % c)
+ b2caps = bundle2.bundle2caps(peer)
+ if b2caps:
+ ui.writenoi18n(b'Bundle2 capabilities:\n')
+ for key, values in sorted(pycompat.iteritems(b2caps)):
+ ui.write(b' %s\n' % key)
+ for v in values:
+ ui.write(b' %s\n' % v)
+ finally:
+ peer.close()
@command(
@@ -2615,12 +2618,17 @@
with ui.configoverride(overrides):
peer = hg.peer(ui, {}, path)
- local = peer.local() is not None
- canpush = peer.canpush()
-
- ui.write(_(b'url: %s\n') % peer.url())
- ui.write(_(b'local: %s\n') % (_(b'yes') if local else _(b'no')))
- ui.write(_(b'pushable: %s\n') % (_(b'yes') if canpush else _(b'no')))
+ try:
+ local = peer.local() is not None
+ canpush = peer.canpush()
+
+ ui.write(_(b'url: %s\n') % peer.url())
+ ui.write(_(b'local: %s\n') % (_(b'yes') if local else _(b'no')))
+ ui.write(
+ _(b'pushable: %s\n') % (_(b'yes') if canpush else _(b'no'))
+ )
+ finally:
+ peer.close()
@command(
@@ -2723,26 +2731,30 @@
"""
target = hg.peer(ui, {}, repopath)
- if keyinfo:
- key, old, new = keyinfo
- with target.commandexecutor() as e:
- r = e.callcommand(
- b'pushkey',
- {
- b'namespace': namespace,
- b'key': key,
- b'old': old,
- b'new': new,
- },
- ).result()
-
- ui.status(pycompat.bytestr(r) + b'\n')
- return not r
- else:
- for k, v in sorted(pycompat.iteritems(target.listkeys(namespace))):
- ui.write(
- b"%s\t%s\n" % (stringutil.escapestr(k), stringutil.escapestr(v))
- )
+ try:
+ if keyinfo:
+ key, old, new = keyinfo
+ with target.commandexecutor() as e:
+ r = e.callcommand(
+ b'pushkey',
+ {
+ b'namespace': namespace,
+ b'key': key,
+ b'old': old,
+ b'new': new,
+ },
+ ).result()
+
+ ui.status(pycompat.bytestr(r) + b'\n')
+ return not r
+ else:
+ for k, v in sorted(pycompat.iteritems(target.listkeys(namespace))):
+ ui.write(
+ b"%s\t%s\n"
+ % (stringutil.escapestr(k), stringutil.escapestr(v))
+ )
+ finally:
+ target.close()
@command(b'debugpvec', [], _(b'A B'))
@@ -4092,19 +4104,22 @@
def debugwireargs(ui, repopath, *vals, **opts):
opts = pycompat.byteskwargs(opts)
repo = hg.peer(ui, opts, repopath)
- for opt in cmdutil.remoteopts:
- del opts[opt[1]]
- args = {}
- for k, v in pycompat.iteritems(opts):
- if v:
- args[k] = v
- args = pycompat.strkwargs(args)
- # run twice to check that we don't mess up the stream for the next command
- res1 = repo.debugwireargs(*vals, **args)
- res2 = repo.debugwireargs(*vals, **args)
- ui.write(b"%s\n" % res1)
- if res1 != res2:
- ui.warn(b"%s\n" % res2)
+ try:
+ for opt in cmdutil.remoteopts:
+ del opts[opt[1]]
+ args = {}
+ for k, v in pycompat.iteritems(opts):
+ if v:
+ args[k] = v
+ args = pycompat.strkwargs(args)
+ # run twice to check that we don't mess up the stream for the next command
+ res1 = repo.debugwireargs(*vals, **args)
+ res2 = repo.debugwireargs(*vals, **args)
+ ui.write(b"%s\n" % res1)
+ if res1 != res2:
+ ui.warn(b"%s\n" % res2)
+ finally:
+ repo.close()
def _parsewirelangblocks(fh):
@@ -3820,132 +3820,138 @@
output = []
revs = []
- if source:
- source, branches = hg.parseurl(ui.expandpath(source))
- peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
- repo = peer.local()
- revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
-
- fm = ui.formatter(b'identify', opts)
- fm.startitem()
-
- if not repo:
- if num or branch or tags:
- raise error.InputError(
- _(b"can't query remote revision number, branch, or tags")
- )
- if not rev and revs:
- rev = revs[0]
- if not rev:
- rev = b"tip"
-
- remoterev = peer.lookup(rev)
- hexrev = fm.hexfunc(remoterev)
- if default or id:
- output = [hexrev]
- fm.data(id=hexrev)
-
- @util.cachefunc
- def getbms():
- bms = []
-
- if b'bookmarks' in peer.listkeys(b'namespaces'):
- hexremoterev = hex(remoterev)
- bms = [
- bm
- for bm, bmr in pycompat.iteritems(
- peer.listkeys(b'bookmarks')
+ peer = None
+ try:
+ if source:
+ source, branches = hg.parseurl(ui.expandpath(source))
+ # only pass ui when no repo
+ peer = hg.peer(repo or ui, opts, source)
+ repo = peer.local()
+ revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
+
+ fm = ui.formatter(b'identify', opts)
+ fm.startitem()
+
+ if not repo:
+ if num or branch or tags:
+ raise error.InputError(
+ _(b"can't query remote revision number, branch, or tags")
+ )
+ if not rev and revs:
+ rev = revs[0]
+ if not rev:
+ rev = b"tip"
+
+ remoterev = peer.lookup(rev)
+ hexrev = fm.hexfunc(remoterev)
+ if default or id:
+ output = [hexrev]
+ fm.data(id=hexrev)
+
+ @util.cachefunc
+ def getbms():
+ bms = []
+
+ if b'bookmarks' in peer.listkeys(b'namespaces'):
+ hexremoterev = hex(remoterev)
+ bms = [
+ bm
+ for bm, bmr in pycompat.iteritems(
+ peer.listkeys(b'bookmarks')
+ )
+ if bmr == hexremoterev
+ ]
+
+ return sorted(bms)
+
+ if fm.isplain():
+ if bookmarks:
+ output.extend(getbms())
+ elif default and not ui.quiet:
+ # multiple bookmarks for a single parent separated by '/'
+ bm = b'/'.join(getbms())
+ if bm:
+ output.append(bm)
+ else:
+ fm.data(node=hex(remoterev))
+ if bookmarks or b'bookmarks' in fm.datahint():
+ fm.data(bookmarks=fm.formatlist(getbms(), name=b'bookmark'))
+ else:
+ if rev:
+ repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
+ ctx = scmutil.revsingle(repo, rev, None)
+
+ if ctx.rev() is None:
+ ctx = repo[None]
+ parents = ctx.parents()
+ taglist = []
+ for p in parents:
+ taglist.extend(p.tags())
+
+ dirty = b""
+ if ctx.dirty(missing=True, merge=False, branch=False):
+ dirty = b'+'
+ fm.data(dirty=dirty)
+
+ hexoutput = [fm.hexfunc(p.node()) for p in parents]
+ if default or id:
+ output = [b"%s%s" % (b'+'.join(hexoutput), dirty)]
+ fm.data(id=b"%s%s" % (b'+'.join(hexoutput), dirty))
+
+ if num:
+ numoutput = [b"%d" % p.rev() for p in parents]
+ output.append(b"%s%s" % (b'+'.join(numoutput), dirty))
+
+ fm.data(
+ parents=fm.formatlist(
+ [fm.hexfunc(p.node()) for p in parents], name=b'node'
)
- if bmr == hexremoterev
- ]
-
- return sorted(bms)
-
- if fm.isplain():
- if bookmarks:
- output.extend(getbms())
- elif default and not ui.quiet:
+ )
+ else:
+ hexoutput = fm.hexfunc(ctx.node())
+ if default or id:
+ output = [hexoutput]
+ fm.data(id=hexoutput)
+
+ if num:
+ output.append(pycompat.bytestr(ctx.rev()))
+ taglist = ctx.tags()
+
+ if default and not ui.quiet:
+ b = ctx.branch()
+ if b != b'default':
+ output.append(b"(%s)" % b)
+
+ # multiple tags for a single parent separated by '/'
+ t = b'/'.join(taglist)
+ if t:
+ output.append(t)
+
# multiple bookmarks for a single parent separated by '/'
- bm = b'/'.join(getbms())
+ bm = b'/'.join(ctx.bookmarks())
if bm:
output.append(bm)
- else:
- fm.data(node=hex(remoterev))
- if bookmarks or b'bookmarks' in fm.datahint():
- fm.data(bookmarks=fm.formatlist(getbms(), name=b'bookmark'))
- else:
- if rev:
- repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
- ctx = scmutil.revsingle(repo, rev, None)
-
- if ctx.rev() is None:
- ctx = repo[None]
- parents = ctx.parents()
- taglist = []
- for p in parents:
- taglist.extend(p.tags())
-
- dirty = b""
- if ctx.dirty(missing=True, merge=False, branch=False):
- dirty = b'+'
- fm.data(dirty=dirty)
-
- hexoutput = [fm.hexfunc(p.node()) for p in parents]
- if default or id:
- output = [b"%s%s" % (b'+'.join(hexoutput), dirty)]
- fm.data(id=b"%s%s" % (b'+'.join(hexoutput), dirty))
-
- if num:
- numoutput = [b"%d" % p.rev() for p in parents]
- output.append(b"%s%s" % (b'+'.join(numoutput), dirty))
-
- fm.data(
- parents=fm.formatlist(
- [fm.hexfunc(p.node()) for p in parents], name=b'node'
- )
- )
- else:
- hexoutput = fm.hexfunc(ctx.node())
- if default or id:
- output = [hexoutput]
- fm.data(id=hexoutput)
-
- if num:
- output.append(pycompat.bytestr(ctx.rev()))
- taglist = ctx.tags()
-
- if default and not ui.quiet:
- b = ctx.branch()
- if b != b'default':
- output.append(b"(%s)" % b)
-
- # multiple tags for a single parent separated by '/'
- t = b'/'.join(taglist)
- if t:
- output.append(t)
-
- # multiple bookmarks for a single parent separated by '/'
- bm = b'/'.join(ctx.bookmarks())
- if bm:
- output.append(bm)
- else:
- if branch:
- output.append(ctx.branch())
-
- if tags:
- output.extend(taglist)
-
- if bookmarks:
- output.extend(ctx.bookmarks())
-
- fm.data(node=ctx.hex())
- fm.data(branch=ctx.branch())
- fm.data(tags=fm.formatlist(taglist, name=b'tag', sep=b':'))
- fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name=b'bookmark'))
- fm.context(ctx=ctx)
-
- fm.plain(b"%s\n" % b' '.join(output))
- fm.end()
+ else:
+ if branch:
+ output.append(ctx.branch())
+
+ if tags:
+ output.extend(taglist)
+
+ if bookmarks:
+ output.extend(ctx.bookmarks())
+
+ fm.data(node=ctx.hex())
+ fm.data(branch=ctx.branch())
+ fm.data(tags=fm.formatlist(taglist, name=b'tag', sep=b':'))
+ fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name=b'bookmark'))
+ fm.context(ctx=ctx)
+
+ fm.plain(b"%s\n" % b' '.join(output))
+ fm.end()
+ finally:
+ if peer:
+ peer.close()
@command(
@@ -4291,12 +4297,15 @@
ui.expandpath(source), opts.get(b'branch')
)
other = hg.peer(repo, opts, source)
- if b'bookmarks' not in other.listkeys(b'namespaces'):
- ui.warn(_(b"remote doesn't support bookmarks\n"))
- return 0
- ui.pager(b'incoming')
- ui.status(_(b'comparing with %s\n') % util.hidepassword(source))
- return bookmarks.incoming(ui, repo, other)
+ try:
+ if b'bookmarks' not in other.listkeys(b'namespaces'):
+ ui.warn(_(b"remote doesn't support bookmarks\n"))
+ return 0
+ ui.pager(b'incoming')
+ ui.status(_(b'comparing with %s\n') % util.hidepassword(source))
+ return bookmarks.incoming(ui, repo, other)
+ finally:
+ other.close()
repo._subtoppath = ui.expandpath(source)
try:
@@ -4327,7 +4336,8 @@
Returns 0 on success.
"""
opts = pycompat.byteskwargs(opts)
- hg.peer(ui, opts, ui.expandpath(dest), create=True)
+ peer = hg.peer(ui, opts, ui.expandpath(dest), create=True)
+ peer.close()
@command(
@@ -4963,12 +4973,15 @@
if opts.get(b'bookmarks'):
dest = path.pushloc or path.loc
other = hg.peer(repo, opts, dest)
- if b'bookmarks' not in other.listkeys(b'namespaces'):
- ui.warn(_(b"remote doesn't support bookmarks\n"))
- return 0
- ui.status(_(b'comparing with %s\n') % util.hidepassword(dest))
- ui.pager(b'outgoing')
- return bookmarks.outgoing(ui, repo, other)
+ try:
+ if b'bookmarks' not in other.listkeys(b'namespaces'):
+ ui.warn(_(b"remote doesn't support bookmarks\n"))
+ return 0
+ ui.status(_(b'comparing with %s\n') % util.hidepassword(dest))
+ ui.pager(b'outgoing')
+ return bookmarks.outgoing(ui, repo, other)
+ finally:
+ other.close()
repo._subtoppath = path.pushloc or path.loc
try:
@@ -5679,63 +5692,67 @@
revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get(b'rev'))
other = hg.peer(repo, opts, dest)
- if revs:
- revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
- if not revs:
+ try:
+ if revs:
+ revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
+ if not revs:
+ raise error.InputError(
+ _(b"specified revisions evaluate to an empty set"),
+ hint=_(b"use different revision arguments"),
+ )
+ elif path.pushrev:
+ # It doesn't make any sense to specify ancestor revisions. So limit
+ # to DAG heads to make discovery simpler.
+ expr = revsetlang.formatspec(b'heads(%r)', path.pushrev)
+ revs = scmutil.revrange(repo, [expr])
+ revs = [repo[rev].node() for rev in revs]
+ if not revs:
+ raise error.InputError(
+ _(b'default push revset for path evaluates to an empty set')
+ )
+ elif ui.configbool(b'commands', b'push.require-revs'):
raise error.InputError(
- _(b"specified revisions evaluate to an empty set"),
- hint=_(b"use different revision arguments"),
+ _(b'no revisions specified to push'),
+ hint=_(b'did you mean "hg push -r ."?'),
)
- elif path.pushrev:
- # It doesn't make any sense to specify ancestor revisions. So limit
- # to DAG heads to make discovery simpler.
- expr = revsetlang.formatspec(b'heads(%r)', path.pushrev)
- revs = scmutil.revrange(repo, [expr])
- revs = [repo[rev].node() for rev in revs]
- if not revs:
- raise error.InputError(
- _(b'default push revset for path evaluates to an empty set')
- )
- elif ui.configbool(b'commands', b'push.require-revs'):
- raise error.InputError(
- _(b'no revisions specified to push'),
- hint=_(b'did you mean "hg push -r ."?'),
+
+ repo._subtoppath = dest
+ try:
+ # push subrepos depth-first for coherent ordering
+ c = repo[b'.']
+ subs = c.substate # only repos that are committed
+ for s in sorted(subs):
+ result = c.sub(s).push(opts)
+ if result == 0:
+ return not result
+ finally:
+ del repo._subtoppath
+
+ opargs = dict(
+ opts.get(b'opargs', {})
+ ) # copy opargs since we may mutate it
+ opargs.setdefault(b'pushvars', []).extend(opts.get(b'pushvars', []))
+
+ pushop = exchange.push(
+ repo,
+ other,
+ opts.get(b'force'),
+ revs=revs,
+ newbranch=opts.get(b'new_branch'),
+ bookmarks=opts.get(b'bookmark', ()),
+ publish=opts.get(b'publish'),
+ opargs=opargs,
)
- repo._subtoppath = dest
- try:
- # push subrepos depth-first for coherent ordering
- c = repo[b'.']
- subs = c.substate # only repos that are committed
- for s in sorted(subs):
- result = c.sub(s).push(opts)
- if result == 0:
- return not result
+ result = not pushop.cgresult
+
+ if pushop.bkresult is not None:
+ if pushop.bkresult == 2:
+ result = 2
+ elif not result and pushop.bkresult:
+ result = 2
finally:
- del repo._subtoppath
-
- opargs = dict(opts.get(b'opargs', {})) # copy opargs since we may mutate it
- opargs.setdefault(b'pushvars', []).extend(opts.get(b'pushvars', []))
-
- pushop = exchange.push(
- repo,
- other,
- opts.get(b'force'),
- revs=revs,
- newbranch=opts.get(b'new_branch'),
- bookmarks=opts.get(b'bookmark', ()),
- publish=opts.get(b'publish'),
- opargs=opargs,
- )
-
- result = not pushop.cgresult
-
- if pushop.bkresult is not None:
- if pushop.bkresult == 2:
- result = 2
- elif not result and pushop.bkresult:
- result = 2
-
+ other.close()
return result
@@ -595,77 +595,83 @@
ui.status(_(b'comparing with %s\n') % util.hidepassword(url))
remote = hg.peer(repo, opts, url)
- # check narrow support before doing anything if widening needs to be
- # performed. In future we should also abort if client is ellipses and
- # server does not support ellipses
- if widening and wireprototypes.NARROWCAP not in remote.capabilities():
- raise error.Abort(_(b"server does not support narrow clones"))
-
- commoninc = discovery.findcommonincoming(repo, remote)
-
- if autoremoveincludes:
- outgoing = discovery.findcommonoutgoing(
- repo, remote, commoninc=commoninc
- )
- ui.status(_(b'looking for unused includes to remove\n'))
- localfiles = set()
- for n in itertools.chain(outgoing.missing, outgoing.excluded):
- localfiles.update(repo[n].files())
- suggestedremovals = []
- for include in sorted(oldincludes):
- match = narrowspec.match(repo.root, [include], oldexcludes)
- if not any(match(f) for f in localfiles):
- suggestedremovals.append(include)
- if suggestedremovals:
- for s in suggestedremovals:
- ui.status(b'%s\n' % s)
- if (
- ui.promptchoice(
- _(
- b'remove these unused includes (yn)?'
- b'$$ &Yes $$ &No'
+ try:
+ # check narrow support before doing anything if widening needs to be
+ # performed. In future we should also abort if client is ellipses and
+ # server does not support ellipses
+ if (
+ widening
+ and wireprototypes.NARROWCAP not in remote.capabilities()
+ ):
+ raise error.Abort(_(b"server does not support narrow clones"))
+
+ commoninc = discovery.findcommonincoming(repo, remote)
+
+ if autoremoveincludes:
+ outgoing = discovery.findcommonoutgoing(
+ repo, remote, commoninc=commoninc
+ )
+ ui.status(_(b'looking for unused includes to remove\n'))
+ localfiles = set()
+ for n in itertools.chain(outgoing.missing, outgoing.excluded):
+ localfiles.update(repo[n].files())
+ suggestedremovals = []
+ for include in sorted(oldincludes):
+ match = narrowspec.match(repo.root, [include], oldexcludes)
+ if not any(match(f) for f in localfiles):
+ suggestedremovals.append(include)
+ if suggestedremovals:
+ for s in suggestedremovals:
+ ui.status(b'%s\n' % s)
+ if (
+ ui.promptchoice(
+ _(
+ b'remove these unused includes (yn)?'
+ b'$$ &Yes $$ &No'
+ )
)
- )
- == 0
- ):
- removedincludes.update(suggestedremovals)
- narrowing = True
- else:
- ui.status(_(b'found no unused includes\n'))
-
- if narrowing:
- newincludes = oldincludes - removedincludes
- newexcludes = oldexcludes | addedexcludes
- _narrow(
- ui,
- repo,
- remote,
- commoninc,
- oldincludes,
- oldexcludes,
- newincludes,
- newexcludes,
- opts[b'force_delete_local_changes'],
- opts[b'backup'],
- )
- # _narrow() updated the narrowspec and _widen() below needs to
- # use the updated values as its base (otherwise removed includes
- # and addedexcludes will be lost in the resulting narrowspec)
- oldincludes = newincludes
- oldexcludes = newexcludes
-
- if widening:
- newincludes = oldincludes | addedincludes
- newexcludes = oldexcludes - removedexcludes
- _widen(
- ui,
- repo,
- remote,
- commoninc,
- oldincludes,
- oldexcludes,
- newincludes,
- newexcludes,
- )
+ == 0
+ ):
+ removedincludes.update(suggestedremovals)
+ narrowing = True
+ else:
+ ui.status(_(b'found no unused includes\n'))
+
+ if narrowing:
+ newincludes = oldincludes - removedincludes
+ newexcludes = oldexcludes | addedexcludes
+ _narrow(
+ ui,
+ repo,
+ remote,
+ commoninc,
+ oldincludes,
+ oldexcludes,
+ newincludes,
+ newexcludes,
+ opts[b'force_delete_local_changes'],
+ opts[b'backup'],
+ )
+ # _narrow() updated the narrowspec and _widen() below needs to
+ # use the updated values as its base (otherwise removed includes
+ # and addedexcludes will be lost in the resulting narrowspec)
+ oldincludes = newincludes
+ oldexcludes = newexcludes
+
+ if widening:
+ newincludes = oldincludes | addedincludes
+ newexcludes = oldexcludes - removedexcludes
+ _widen(
+ ui,
+ repo,
+ remote,
+ commoninc,
+ oldincludes,
+ oldexcludes,
+ newincludes,
+ newexcludes,
+ )
+ finally:
+ remote.close()
return 0
@@ -704,16 +704,19 @@
if scratchbookmarks:
other = hg.peer(repo, opts, source)
- fetchedbookmarks = other.listkeyspatterns(
- b'bookmarks', patterns=scratchbookmarks
- )
- for bookmark in scratchbookmarks:
- if bookmark not in fetchedbookmarks:
- raise error.Abort(
- b'remote bookmark %s not found!' % bookmark
- )
- scratchbookmarks[bookmark] = fetchedbookmarks[bookmark]
- revs.append(fetchedbookmarks[bookmark])
+ try:
+ fetchedbookmarks = other.listkeyspatterns(
+ b'bookmarks', patterns=scratchbookmarks
+ )
+ for bookmark in scratchbookmarks:
+ if bookmark not in fetchedbookmarks:
+ raise error.Abort(
+ b'remote bookmark %s not found!' % bookmark
+ )
+ scratchbookmarks[bookmark] = fetchedbookmarks[bookmark]
+ revs.append(fetchedbookmarks[bookmark])
+ finally:
+ other.close()
opts[b'bookmark'] = bookmarks
opts[b'rev'] = revs
@@ -848,10 +851,13 @@
if common.isremotebooksenabled(ui):
if bookmark and scratchpush:
other = hg.peer(repo, opts, destpath)
- fetchedbookmarks = other.listkeyspatterns(
- b'bookmarks', patterns=[bookmark]
- )
- remotescratchbookmarks.update(fetchedbookmarks)
+ try:
+ fetchedbookmarks = other.listkeyspatterns(
+ b'bookmarks', patterns=[bookmark]
+ )
+ remotescratchbookmarks.update(fetchedbookmarks)
+ finally:
+ other.close()
_saveremotebookmarks(repo, remotescratchbookmarks, destpath)
if oldphasemove:
exchange._localphasemove = oldphasemove