comparison mercurial/commands.py @ 2549:e1831f06eef1

Added ability to clone from a local repository to a (new) remote one. Rearranged the clone command a good bit to make sure it validates that the source does exist and that the destination doesn't before doing anything. Before I moved the source repo check it would create the destination repository before it verified the source existed. Moved the responsibility for creating the destination repo root directory entirly into the localrepo class so that local to local cloning doesn't break. This also simplifies the code a bit since it's no longer being done in both clone and init. Changed the names of the 'repo' and 'other' variables to 'dest_repo' and 'src_repo' to maintain my sanity. Passes 82/83 tests. The only failure is the version number test, which I suspect is supposed to fail since it comes from a generated file.
author Sean Meiners <sean.meiners@linspire.com>
date Fri, 30 Jun 2006 19:24:02 -0700
parents 0ab63318bc36
children 5b426676f616
comparison
equal deleted inserted replaced
2546:8cb894370514 2549:e1831f06eef1
917 dest = os.path.basename(os.path.normpath(source)) 917 dest = os.path.basename(os.path.normpath(source))
918 918
919 if os.path.exists(dest): 919 if os.path.exists(dest):
920 raise util.Abort(_("destination '%s' already exists"), dest) 920 raise util.Abort(_("destination '%s' already exists"), dest)
921 921
922 dest = os.path.realpath(dest)
923
924 class Dircleanup(object): 922 class Dircleanup(object):
925 def __init__(self, dir_): 923 def __init__(self, dir_):
926 self.rmtree = shutil.rmtree 924 self.rmtree = shutil.rmtree
927 self.dir_ = dir_ 925 self.dir_ = dir_
928 os.mkdir(dir_)
929 def close(self): 926 def close(self):
930 self.dir_ = None 927 self.dir_ = None
931 def __del__(self): 928 def __del__(self):
932 if self.dir_: 929 if self.dir_:
933 self.rmtree(self.dir_, True) 930 self.rmtree(self.dir_, True)
936 ui.setconfig("ui", "ssh", opts['ssh']) 933 ui.setconfig("ui", "ssh", opts['ssh'])
937 if opts['remotecmd']: 934 if opts['remotecmd']:
938 ui.setconfig("ui", "remotecmd", opts['remotecmd']) 935 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
939 936
940 source = ui.expandpath(source) 937 source = ui.expandpath(source)
941 938 src_repo = hg.repository(ui, source)
942 d = Dircleanup(dest) 939
940 dest_repo = None
941 try:
942 dest_repo = hg.repository(ui, dest)
943 raise util.Abort(_("destination '%s' already exists." % dest))
944 except hg.RepoError:
945 dest_repo = hg.repository(ui, dest, create=1)
946
947 dest_path = None
948 d = None
949 if dest_repo.local():
950 dest_path = os.path.realpath(dest)
951 d = Dircleanup(dest_path)
952
943 abspath = source 953 abspath = source
944 other = hg.repository(ui, source)
945
946 copy = False 954 copy = False
947 if other.dev() != -1: 955 if src_repo.local() and dest_repo.local():
948 abspath = os.path.abspath(source) 956 abspath = os.path.abspath(source)
949 if not opts['pull'] and not opts['rev']: 957 if not opts['pull'] and not opts['rev']:
950 copy = True 958 copy = True
951 959
952 if copy: 960 if copy:
953 try: 961 try:
954 # we use a lock here because if we race with commit, we 962 # we use a lock here because if we race with commit, we
955 # can end up with extra data in the cloned revlogs that's 963 # can end up with extra data in the cloned revlogs that's
956 # not pointed to by changesets, thus causing verify to 964 # not pointed to by changesets, thus causing verify to
957 # fail 965 # fail
958 l1 = other.lock() 966 l1 = src_repo.lock()
959 except lock.LockException: 967 except lock.LockException:
960 copy = False 968 copy = False
961 969
962 if copy: 970 if copy:
963 # we lock here to avoid premature writing to the target 971 # we lock here to avoid premature writing to the target
964 os.mkdir(os.path.join(dest, ".hg")) 972 l2 = lock.lock(os.path.join(dest_path, ".hg", "lock"))
965 l2 = lock.lock(os.path.join(dest, ".hg", "lock")) 973
966 974 # we need to remove the (empty) data dir in dest so copyfiles can do it's work
975 os.rmdir( os.path.join(dest_path, ".hg", "data") )
967 files = "data 00manifest.d 00manifest.i 00changelog.d 00changelog.i" 976 files = "data 00manifest.d 00manifest.i 00changelog.d 00changelog.i"
968 for f in files.split(): 977 for f in files.split():
969 src = os.path.join(source, ".hg", f) 978 src = os.path.join(source, ".hg", f)
970 dst = os.path.join(dest, ".hg", f) 979 dst = os.path.join(dest_path, ".hg", f)
971 try: 980 try:
972 util.copyfiles(src, dst) 981 util.copyfiles(src, dst)
973 except OSError, inst: 982 except OSError, inst:
974 if inst.errno != errno.ENOENT: 983 if inst.errno != errno.ENOENT:
975 raise 984 raise
976 985
977 repo = hg.repository(ui, dest) 986 # we need to re-init the repo after manually copying the data into it
987 dest_repo = hg.repository(ui, dest)
978 988
979 else: 989 else:
980 revs = None 990 revs = None
981 if opts['rev']: 991 if opts['rev']:
982 if not other.local(): 992 if not src_repo.local():
983 error = _("clone -r not supported yet for remote repositories.") 993 error = _("clone -r not supported yet for remote repositories.")
984 raise util.Abort(error) 994 raise util.Abort(error)
985 else: 995 else:
986 revs = [other.lookup(rev) for rev in opts['rev']] 996 revs = [src_repo.lookup(rev) for rev in opts['rev']]
987 repo = hg.repository(ui, dest, create=1) 997
988 repo.pull(other, heads = revs) 998 if dest_repo.local():
989 999 dest_repo.pull(src_repo, heads = revs)
990 f = repo.opener("hgrc", "w", text=True) 1000 elif src_repo.local():
991 f.write("[paths]\n") 1001 src_repo.push(dest_repo, revs = revs)
992 f.write("default = %s\n" % abspath) 1002 else:
993 f.close() 1003 error = _("clone from remote to remote not supported.")
994 1004 raise util.Abort(error)
995 if not opts['noupdate']: 1005
996 doupdate(repo.ui, repo) 1006 if dest_repo.local():
997 1007 f = dest_repo.opener("hgrc", "w", text=True)
998 d.close() 1008 f.write("[paths]\n")
1009 f.write("default = %s\n" % abspath)
1010 f.close()
1011
1012 if not opts['noupdate']:
1013 doupdate(dest_repo.ui, dest_repo)
1014
1015 if d:
1016 d.close()
999 1017
1000 def commit(ui, repo, *pats, **opts): 1018 def commit(ui, repo, *pats, **opts):
1001 """commit the specified files or all outstanding changes 1019 """commit the specified files or all outstanding changes
1002 1020
1003 Commit changes to the given files into the repository. 1021 Commit changes to the given files into the repository.
1903 Initialize a new repository in the given directory. If the given 1921 Initialize a new repository in the given directory. If the given
1904 directory does not exist, it is created. 1922 directory does not exist, it is created.
1905 1923
1906 If no directory is given, the current directory is used. 1924 If no directory is given, the current directory is used.
1907 """ 1925 """
1908 if not os.path.exists(dest):
1909 os.mkdir(dest)
1910 hg.repository(ui, dest, create=1) 1926 hg.repository(ui, dest, create=1)
1911 1927
1912 def locate(ui, repo, *pats, **opts): 1928 def locate(ui, repo, *pats, **opts):
1913 """locate files matching specific patterns 1929 """locate files matching specific patterns
1914 1930