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): |
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( |
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) |