Mercurial > public > mercurial-scm > hg
comparison mercurial/hg.py @ 46663:a4c19a162615
sshpeer: enable+fix warning about sshpeers not being closed explicitly
I recommend looking at this with a diff that ignores indentation.
The test changes are because localrepo.close() updates some cache,
which appears happens earlier now on rollbacks or strips or something.
The http changes are because httppeer.close() prints stats with
--verbose.
Differential Revision: https://phab.mercurial-scm.org/D9999
author | Valentin Gatien-Baron <valentin.gatienbaron@gmail.com> |
---|---|
date | Mon, 15 Feb 2021 14:48:36 -0500 |
parents | 95a615dd77bf |
children | 66fb04552122 |
comparison
equal
deleted
inserted
replaced
46662:db8037e38085 | 46663:a4c19a162615 |
---|---|
676 srcpeer = peer(ui, peeropts, source) | 676 srcpeer = peer(ui, peeropts, source) |
677 else: | 677 else: |
678 srcpeer = source.peer() # in case we were called with a localrepo | 678 srcpeer = source.peer() # in case we were called with a localrepo |
679 branches = (None, branch or []) | 679 branches = (None, branch or []) |
680 origsource = source = srcpeer.url() | 680 origsource = source = srcpeer.url() |
681 revs, checkout = addbranchrevs(srcpeer, srcpeer, branches, revs) | 681 srclock = destlock = cleandir = None |
682 | 682 destpeer = None |
683 if dest is None: | 683 try: |
684 dest = defaultdest(source) | 684 revs, checkout = addbranchrevs(srcpeer, srcpeer, branches, revs) |
685 if dest: | 685 |
686 ui.status(_(b"destination directory: %s\n") % dest) | 686 if dest is None: |
687 else: | 687 dest = defaultdest(source) |
688 dest = ui.expandpath(dest) | 688 if dest: |
689 | 689 ui.status(_(b"destination directory: %s\n") % dest) |
690 dest = util.urllocalpath(dest) | 690 else: |
691 source = util.urllocalpath(source) | 691 dest = ui.expandpath(dest) |
692 | 692 |
693 if not dest: | 693 dest = util.urllocalpath(dest) |
694 raise error.InputError(_(b"empty destination path is not valid")) | 694 source = util.urllocalpath(source) |
695 | 695 |
696 destvfs = vfsmod.vfs(dest, expandpath=True) | 696 if not dest: |
697 if destvfs.lexists(): | 697 raise error.InputError(_(b"empty destination path is not valid")) |
698 if not destvfs.isdir(): | 698 |
699 raise error.InputError(_(b"destination '%s' already exists") % dest) | 699 destvfs = vfsmod.vfs(dest, expandpath=True) |
700 elif destvfs.listdir(): | 700 if destvfs.lexists(): |
701 raise error.InputError(_(b"destination '%s' is not empty") % dest) | 701 if not destvfs.isdir(): |
702 | 702 raise error.InputError( |
703 createopts = {} | 703 _(b"destination '%s' already exists") % dest |
704 narrow = False | |
705 | |
706 if storeincludepats is not None: | |
707 narrowspec.validatepatterns(storeincludepats) | |
708 narrow = True | |
709 | |
710 if storeexcludepats is not None: | |
711 narrowspec.validatepatterns(storeexcludepats) | |
712 narrow = True | |
713 | |
714 if narrow: | |
715 # Include everything by default if only exclusion patterns defined. | |
716 if storeexcludepats and not storeincludepats: | |
717 storeincludepats = {b'path:.'} | |
718 | |
719 createopts[b'narrowfiles'] = True | |
720 | |
721 if depth: | |
722 createopts[b'shallowfilestore'] = True | |
723 | |
724 if srcpeer.capable(b'lfs-serve'): | |
725 # Repository creation honors the config if it disabled the extension, so | |
726 # we can't just announce that lfs will be enabled. This check avoids | |
727 # saying that lfs will be enabled, and then saying it's an unknown | |
728 # feature. The lfs creation option is set in either case so that a | |
729 # requirement is added. If the extension is explicitly disabled but the | |
730 # requirement is set, the clone aborts early, before transferring any | |
731 # data. | |
732 createopts[b'lfs'] = True | |
733 | |
734 if extensions.disabled_help(b'lfs'): | |
735 ui.status( | |
736 _( | |
737 b'(remote is using large file support (lfs), but it is ' | |
738 b'explicitly disabled in the local configuration)\n' | |
739 ) | 704 ) |
740 ) | 705 elif destvfs.listdir(): |
741 else: | 706 raise error.InputError( |
742 ui.status( | 707 _(b"destination '%s' is not empty") % dest |
743 _( | |
744 b'(remote is using large file support (lfs); lfs will ' | |
745 b'be enabled for this repository)\n' | |
746 ) | 708 ) |
747 ) | 709 |
748 | 710 createopts = {} |
749 shareopts = shareopts or {} | 711 narrow = False |
750 sharepool = shareopts.get(b'pool') | 712 |
751 sharenamemode = shareopts.get(b'mode') | 713 if storeincludepats is not None: |
752 if sharepool and islocal(dest): | 714 narrowspec.validatepatterns(storeincludepats) |
753 sharepath = None | 715 narrow = True |
754 if sharenamemode == b'identity': | 716 |
755 # Resolve the name from the initial changeset in the remote | 717 if storeexcludepats is not None: |
756 # repository. This returns nullid when the remote is empty. It | 718 narrowspec.validatepatterns(storeexcludepats) |
757 # raises RepoLookupError if revision 0 is filtered or otherwise | 719 narrow = True |
758 # not available. If we fail to resolve, sharing is not enabled. | 720 |
759 try: | 721 if narrow: |
760 with srcpeer.commandexecutor() as e: | 722 # Include everything by default if only exclusion patterns defined. |
761 rootnode = e.callcommand( | 723 if storeexcludepats and not storeincludepats: |
762 b'lookup', | 724 storeincludepats = {b'path:.'} |
763 { | 725 |
764 b'key': b'0', | 726 createopts[b'narrowfiles'] = True |
765 }, | 727 |
766 ).result() | 728 if depth: |
767 | 729 createopts[b'shallowfilestore'] = True |
768 if rootnode != nullid: | 730 |
769 sharepath = os.path.join(sharepool, hex(rootnode)) | 731 if srcpeer.capable(b'lfs-serve'): |
770 else: | 732 # Repository creation honors the config if it disabled the extension, so |
733 # we can't just announce that lfs will be enabled. This check avoids | |
734 # saying that lfs will be enabled, and then saying it's an unknown | |
735 # feature. The lfs creation option is set in either case so that a | |
736 # requirement is added. If the extension is explicitly disabled but the | |
737 # requirement is set, the clone aborts early, before transferring any | |
738 # data. | |
739 createopts[b'lfs'] = True | |
740 | |
741 if extensions.disabled_help(b'lfs'): | |
742 ui.status( | |
743 _( | |
744 b'(remote is using large file support (lfs), but it is ' | |
745 b'explicitly disabled in the local configuration)\n' | |
746 ) | |
747 ) | |
748 else: | |
749 ui.status( | |
750 _( | |
751 b'(remote is using large file support (lfs); lfs will ' | |
752 b'be enabled for this repository)\n' | |
753 ) | |
754 ) | |
755 | |
756 shareopts = shareopts or {} | |
757 sharepool = shareopts.get(b'pool') | |
758 sharenamemode = shareopts.get(b'mode') | |
759 if sharepool and islocal(dest): | |
760 sharepath = None | |
761 if sharenamemode == b'identity': | |
762 # Resolve the name from the initial changeset in the remote | |
763 # repository. This returns nullid when the remote is empty. It | |
764 # raises RepoLookupError if revision 0 is filtered or otherwise | |
765 # not available. If we fail to resolve, sharing is not enabled. | |
766 try: | |
767 with srcpeer.commandexecutor() as e: | |
768 rootnode = e.callcommand( | |
769 b'lookup', | |
770 { | |
771 b'key': b'0', | |
772 }, | |
773 ).result() | |
774 | |
775 if rootnode != nullid: | |
776 sharepath = os.path.join(sharepool, hex(rootnode)) | |
777 else: | |
778 ui.status( | |
779 _( | |
780 b'(not using pooled storage: ' | |
781 b'remote appears to be empty)\n' | |
782 ) | |
783 ) | |
784 except error.RepoLookupError: | |
771 ui.status( | 785 ui.status( |
772 _( | 786 _( |
773 b'(not using pooled storage: ' | 787 b'(not using pooled storage: ' |
774 b'remote appears to be empty)\n' | 788 b'unable to resolve identity of remote)\n' |
775 ) | 789 ) |
776 ) | 790 ) |
777 except error.RepoLookupError: | 791 elif sharenamemode == b'remote': |
792 sharepath = os.path.join( | |
793 sharepool, hex(hashutil.sha1(source).digest()) | |
794 ) | |
795 else: | |
796 raise error.Abort( | |
797 _(b'unknown share naming mode: %s') % sharenamemode | |
798 ) | |
799 | |
800 # TODO this is a somewhat arbitrary restriction. | |
801 if narrow: | |
778 ui.status( | 802 ui.status( |
779 _( | 803 _(b'(pooled storage not supported for narrow clones)\n') |
780 b'(not using pooled storage: ' | |
781 b'unable to resolve identity of remote)\n' | |
782 ) | |
783 ) | 804 ) |
784 elif sharenamemode == b'remote': | 805 sharepath = None |
785 sharepath = os.path.join( | 806 |
786 sharepool, hex(hashutil.sha1(source).digest()) | 807 if sharepath: |
787 ) | 808 return clonewithshare( |
788 else: | 809 ui, |
789 raise error.Abort( | 810 peeropts, |
790 _(b'unknown share naming mode: %s') % sharenamemode | 811 sharepath, |
791 ) | 812 source, |
792 | 813 srcpeer, |
793 # TODO this is a somewhat arbitrary restriction. | 814 dest, |
794 if narrow: | 815 pull=pull, |
795 ui.status(_(b'(pooled storage not supported for narrow clones)\n')) | 816 rev=revs, |
796 sharepath = None | 817 update=update, |
797 | 818 stream=stream, |
798 if sharepath: | 819 ) |
799 return clonewithshare( | 820 |
800 ui, | 821 srcrepo = srcpeer.local() |
801 peeropts, | 822 |
802 sharepath, | |
803 source, | |
804 srcpeer, | |
805 dest, | |
806 pull=pull, | |
807 rev=revs, | |
808 update=update, | |
809 stream=stream, | |
810 ) | |
811 | |
812 srclock = destlock = cleandir = None | |
813 srcrepo = srcpeer.local() | |
814 try: | |
815 abspath = origsource | 823 abspath = origsource |
816 if islocal(origsource): | 824 if islocal(origsource): |
817 abspath = os.path.abspath(util.urllocalpath(origsource)) | 825 abspath = os.path.abspath(util.urllocalpath(origsource)) |
818 | 826 |
819 if islocal(dest): | 827 if islocal(dest): |
1050 release(srclock, destlock) | 1058 release(srclock, destlock) |
1051 if cleandir is not None: | 1059 if cleandir is not None: |
1052 shutil.rmtree(cleandir, True) | 1060 shutil.rmtree(cleandir, True) |
1053 if srcpeer is not None: | 1061 if srcpeer is not None: |
1054 srcpeer.close() | 1062 srcpeer.close() |
1063 if destpeer and destpeer.local() is None: | |
1064 destpeer.close() | |
1055 return srcpeer, destpeer | 1065 return srcpeer, destpeer |
1056 | 1066 |
1057 | 1067 |
1058 def _showstats(repo, stats, quietempty=False): | 1068 def _showstats(repo, stats, quietempty=False): |
1059 if quietempty and stats.isempty(): | 1069 if quietempty and stats.isempty(): |
1251 (remoterepo, incomingchangesetlist, displayer) parameters, | 1261 (remoterepo, incomingchangesetlist, displayer) parameters, |
1252 and is supposed to contain only code that can't be unified. | 1262 and is supposed to contain only code that can't be unified. |
1253 """ | 1263 """ |
1254 source, branches = parseurl(ui.expandpath(source), opts.get(b'branch')) | 1264 source, branches = parseurl(ui.expandpath(source), opts.get(b'branch')) |
1255 other = peer(repo, opts, source) | 1265 other = peer(repo, opts, source) |
1256 ui.status(_(b'comparing with %s\n') % util.hidepassword(source)) | 1266 cleanupfn = other.close |
1257 revs, checkout = addbranchrevs(repo, other, branches, opts.get(b'rev')) | |
1258 | |
1259 if revs: | |
1260 revs = [other.lookup(rev) for rev in revs] | |
1261 other, chlist, cleanupfn = bundlerepo.getremotechanges( | |
1262 ui, repo, other, revs, opts[b"bundle"], opts[b"force"] | |
1263 ) | |
1264 try: | 1267 try: |
1268 ui.status(_(b'comparing with %s\n') % util.hidepassword(source)) | |
1269 revs, checkout = addbranchrevs(repo, other, branches, opts.get(b'rev')) | |
1270 | |
1271 if revs: | |
1272 revs = [other.lookup(rev) for rev in revs] | |
1273 other, chlist, cleanupfn = bundlerepo.getremotechanges( | |
1274 ui, repo, other, revs, opts[b"bundle"], opts[b"force"] | |
1275 ) | |
1276 | |
1265 if not chlist: | 1277 if not chlist: |
1266 ui.status(_(b"no changes found\n")) | 1278 ui.status(_(b"no changes found\n")) |
1267 return subreporecurse() | 1279 return subreporecurse() |
1268 ui.pager(b'incoming') | 1280 ui.pager(b'incoming') |
1269 displayer = logcmdutil.changesetdisplayer( | 1281 displayer = logcmdutil.changesetdisplayer( |
1318 revs, checkout = addbranchrevs(repo, repo, branches, opts.get(b'rev')) | 1330 revs, checkout = addbranchrevs(repo, repo, branches, opts.get(b'rev')) |
1319 if revs: | 1331 if revs: |
1320 revs = [repo[rev].node() for rev in scmutil.revrange(repo, revs)] | 1332 revs = [repo[rev].node() for rev in scmutil.revrange(repo, revs)] |
1321 | 1333 |
1322 other = peer(repo, opts, dest) | 1334 other = peer(repo, opts, dest) |
1323 outgoing = discovery.findcommonoutgoing( | 1335 try: |
1324 repo, other, revs, force=opts.get(b'force') | 1336 outgoing = discovery.findcommonoutgoing( |
1325 ) | 1337 repo, other, revs, force=opts.get(b'force') |
1326 o = outgoing.missing | 1338 ) |
1327 if not o: | 1339 o = outgoing.missing |
1328 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded) | 1340 if not o: |
1329 return o, other | 1341 scmutil.nochangesfound(repo.ui, repo, outgoing.excluded) |
1342 return o, other | |
1343 except: # re-raises | |
1344 other.close() | |
1345 raise | |
1330 | 1346 |
1331 | 1347 |
1332 def outgoing(ui, repo, dest, opts): | 1348 def outgoing(ui, repo, dest, opts): |
1333 def recurse(): | 1349 def recurse(): |
1334 ret = 1 | 1350 ret = 1 |
1339 ret = min(ret, sub.outgoing(ui, dest, opts)) | 1355 ret = min(ret, sub.outgoing(ui, dest, opts)) |
1340 return ret | 1356 return ret |
1341 | 1357 |
1342 limit = logcmdutil.getlimit(opts) | 1358 limit = logcmdutil.getlimit(opts) |
1343 o, other = _outgoing(ui, repo, dest, opts) | 1359 o, other = _outgoing(ui, repo, dest, opts) |
1344 if not o: | 1360 try: |
1361 if not o: | |
1362 cmdutil.outgoinghooks(ui, repo, other, opts, o) | |
1363 return recurse() | |
1364 | |
1365 if opts.get(b'newest_first'): | |
1366 o.reverse() | |
1367 ui.pager(b'outgoing') | |
1368 displayer = logcmdutil.changesetdisplayer(ui, repo, opts) | |
1369 count = 0 | |
1370 for n in o: | |
1371 if limit is not None and count >= limit: | |
1372 break | |
1373 parents = [p for p in repo.changelog.parents(n) if p != nullid] | |
1374 if opts.get(b'no_merges') and len(parents) == 2: | |
1375 continue | |
1376 count += 1 | |
1377 displayer.show(repo[n]) | |
1378 displayer.close() | |
1345 cmdutil.outgoinghooks(ui, repo, other, opts, o) | 1379 cmdutil.outgoinghooks(ui, repo, other, opts, o) |
1346 return recurse() | 1380 recurse() |
1347 | 1381 return 0 # exit code is zero since we found outgoing changes |
1348 if opts.get(b'newest_first'): | 1382 finally: |
1349 o.reverse() | 1383 other.close() |
1350 ui.pager(b'outgoing') | |
1351 displayer = logcmdutil.changesetdisplayer(ui, repo, opts) | |
1352 count = 0 | |
1353 for n in o: | |
1354 if limit is not None and count >= limit: | |
1355 break | |
1356 parents = [p for p in repo.changelog.parents(n) if p != nullid] | |
1357 if opts.get(b'no_merges') and len(parents) == 2: | |
1358 continue | |
1359 count += 1 | |
1360 displayer.show(repo[n]) | |
1361 displayer.close() | |
1362 cmdutil.outgoinghooks(ui, repo, other, opts, o) | |
1363 recurse() | |
1364 return 0 # exit code is zero since we found outgoing changes | |
1365 | 1384 |
1366 | 1385 |
1367 def verify(repo, level=None): | 1386 def verify(repo, level=None): |
1368 """verify the consistency of a repository""" | 1387 """verify the consistency of a repository""" |
1369 ret = verifymod.verify(repo, level=level) | 1388 ret = verifymod.verify(repo, level=level) |