##// END OF EJS Templates
clone: move code into hg module. make doc better....
Vadim Gelfer -
r2597:5ba8be56 default
parent child Browse files
Show More
@@ -956,107 +956,15 b' def clone(ui, source, dest=None, **opts)'
956 .hg/hgrc will be created on the remote side. Look at the help text
956 .hg/hgrc will be created on the remote side. Look at the help text
957 for the pull command for important details about ssh:// URLs.
957 for the pull command for important details about ssh:// URLs.
958 """
958 """
959 if dest is None:
960 dest = os.path.basename(os.path.normpath(source))
961
962 if os.path.exists(dest):
963 raise util.Abort(_("destination '%s' already exists"), dest)
964
965 class Dircleanup(object):
966 def __init__(self, dir_):
967 self.rmtree = shutil.rmtree
968 self.dir_ = dir_
969 def close(self):
970 self.dir_ = None
971 def __del__(self):
972 if self.dir_:
973 self.rmtree(self.dir_, True)
974
975 if opts['ssh']:
959 if opts['ssh']:
976 ui.setconfig("ui", "ssh", opts['ssh'])
960 ui.setconfig("ui", "ssh", opts['ssh'])
977 if opts['remotecmd']:
961 if opts['remotecmd']:
978 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
962 ui.setconfig("ui", "remotecmd", opts['remotecmd'])
979
963
980 source = ui.expandpath(source)
964 hg.clone(ui, ui.expandpath(source), dest,
981 src_repo = hg.repository(ui, source)
965 pull=opts['pull'],
982
966 rev=opts['rev'],
983 dest_repo = None
967 update=not opts['noupdate'])
984 try:
985 dest_repo = hg.repository(ui, dest)
986 raise util.Abort(_("destination '%s' already exists." % dest))
987 except hg.RepoError:
988 dest_repo = hg.repository(ui, dest, create=1)
989
990 dest_path = None
991 d = None
992 if dest_repo.local():
993 dest_path = os.path.realpath(dest)
994 d = Dircleanup(dest_path)
995
996 abspath = source
997 copy = False
998 if src_repo.local() and dest_repo.local():
999 abspath = os.path.abspath(source)
1000 if not opts['pull'] and not opts['rev']:
1001 copy = True
1002
1003 if copy:
1004 try:
1005 # we use a lock here because if we race with commit, we
1006 # can end up with extra data in the cloned revlogs that's
1007 # not pointed to by changesets, thus causing verify to
1008 # fail
1009 l1 = src_repo.lock()
1010 except lock.LockException:
1011 copy = False
1012
1013 if copy:
1014 # we lock here to avoid premature writing to the target
1015 l2 = lock.lock(os.path.join(dest_path, ".hg", "lock"))
1016
1017 # we need to remove the (empty) data dir in dest so copyfiles can do it's work
1018 os.rmdir( os.path.join(dest_path, ".hg", "data") )
1019 files = "data 00manifest.d 00manifest.i 00changelog.d 00changelog.i"
1020 for f in files.split():
1021 src = os.path.join(source, ".hg", f)
1022 dst = os.path.join(dest_path, ".hg", f)
1023 try:
1024 util.copyfiles(src, dst)
1025 except OSError, inst:
1026 if inst.errno != errno.ENOENT:
1027 raise
1028
1029 # we need to re-init the repo after manually copying the data into it
1030 dest_repo = hg.repository(ui, dest)
1031
1032 else:
1033 revs = None
1034 if opts['rev']:
1035 if not src_repo.local():
1036 error = _("clone -r not supported yet for remote repositories.")
1037 raise util.Abort(error)
1038 else:
1039 revs = [src_repo.lookup(rev) for rev in opts['rev']]
1040
1041 if dest_repo.local():
1042 dest_repo.pull(src_repo, heads = revs)
1043 elif src_repo.local():
1044 src_repo.push(dest_repo, revs = revs)
1045 else:
1046 error = _("clone from remote to remote not supported.")
1047 raise util.Abort(error)
1048
1049 if dest_repo.local():
1050 f = dest_repo.opener("hgrc", "w", text=True)
1051 f.write("[paths]\n")
1052 f.write("default = %s\n" % abspath)
1053 f.close()
1054
1055 if not opts['noupdate']:
1056 doupdate(dest_repo.ui, dest_repo)
1057
1058 if d:
1059 d.close()
1060
968
1061 def commit(ui, repo, *pats, **opts):
969 def commit(ui, repo, *pats, **opts):
1062 """commit the specified files or all outstanding changes
970 """commit the specified files or all outstanding changes
@@ -10,7 +10,7 b' from repo import *'
10 from demandload import *
10 from demandload import *
11 from i18n import gettext as _
11 from i18n import gettext as _
12 demandload(globals(), "localrepo bundlerepo httprepo sshrepo statichttprepo")
12 demandload(globals(), "localrepo bundlerepo httprepo sshrepo statichttprepo")
13 demandload(globals(), "os util")
13 demandload(globals(), "errno lock os shutil util")
14
14
15 def bundle(ui, path):
15 def bundle(ui, path):
16 if path.startswith('bundle://'):
16 if path.startswith('bundle://'):
@@ -73,3 +73,133 b' def repository(ui, path=None, create=0):'
73 raise util.Abort(_('cannot create new repository over "%s" protocol') %
73 raise util.Abort(_('cannot create new repository over "%s" protocol') %
74 scheme)
74 scheme)
75 return ctor(ui, path)
75 return ctor(ui, path)
76
77 def clone(ui, source, dest=None, pull=False, rev=None, update=True):
78 """Make a copy of an existing repository.
79
80 Create a copy of an existing repository in a new directory. The
81 source and destination are URLs, as passed to the repository
82 function. Returns a pair of repository objects, the source and
83 newly created destination.
84
85 The location of the source is added to the new repository's
86 .hg/hgrc file, as the default to be used for future pulls and
87 pushes.
88
89 If an exception is raised, the partly cloned/updated destination
90 repository will be deleted.
91
92 Keyword arguments:
93
94 dest: URL of destination repository to create (defaults to base
95 name of source repository)
96
97 pull: always pull from source repository, even in local case
98
99 rev: revision to clone up to (implies pull=True)
100
101 update: update working directory after clone completes, if
102 destination is local repository
103 """
104 if dest is None:
105 dest = os.path.basename(os.path.normpath(source))
106
107 if os.path.exists(dest):
108 raise util.Abort(_("destination '%s' already exists"), dest)
109
110 class DirCleanup(object):
111 def __init__(self, dir_):
112 self.rmtree = shutil.rmtree
113 self.dir_ = dir_
114 def close(self):
115 self.dir_ = None
116 def __del__(self):
117 if self.dir_:
118 self.rmtree(self.dir_, True)
119
120 src_repo = repository(ui, source)
121
122 dest_repo = None
123 try:
124 dest_repo = repository(ui, dest)
125 raise util.Abort(_("destination '%s' already exists." % dest))
126 except RepoError:
127 dest_repo = repository(ui, dest, create=True)
128
129 dest_path = None
130 dir_cleanup = None
131 if dest_repo.local():
132 dest_path = os.path.realpath(dest)
133 dir_cleanup = DirCleanup(dest_path)
134
135 abspath = source
136 copy = False
137 if src_repo.local() and dest_repo.local():
138 abspath = os.path.abspath(source)
139 copy = not pull and not rev
140
141 src_lock, dest_lock = None, None
142 if copy:
143 try:
144 # we use a lock here because if we race with commit, we
145 # can end up with extra data in the cloned revlogs that's
146 # not pointed to by changesets, thus causing verify to
147 # fail
148 src_lock = src_repo.lock()
149 except lock.LockException:
150 copy = False
151
152 if copy:
153 # we lock here to avoid premature writing to the target
154 dest_lock = lock.lock(os.path.join(dest_path, ".hg", "lock"))
155
156 # we need to remove the (empty) data dir in dest so copyfiles
157 # can do its work
158 os.rmdir(os.path.join(dest_path, ".hg", "data"))
159 files = "data 00manifest.d 00manifest.i 00changelog.d 00changelog.i"
160 for f in files.split():
161 src = os.path.join(source, ".hg", f)
162 dst = os.path.join(dest_path, ".hg", f)
163 try:
164 util.copyfiles(src, dst)
165 except OSError, inst:
166 if inst.errno != errno.ENOENT:
167 raise
168
169 # we need to re-init the repo after manually copying the data
170 # into it
171 dest_repo = repository(ui, dest)
172
173 else:
174 revs = None
175 if rev:
176 if not src_repo.local():
177 raise util.Abort(_("clone by revision not supported yet "
178 "for remote repositories"))
179 revs = [src_repo.lookup(r) for r in rev]
180
181 if dest_repo.local():
182 dest_repo.pull(src_repo, heads=revs)
183 elif src_repo.local():
184 src_repo.push(dest_repo, revs=revs)
185 else:
186 raise util.Abort(_("clone from remote to remote not supported"))
187
188 if src_lock:
189 src_lock.release()
190
191 if dest_repo.local():
192 fp = dest_repo.opener("hgrc", "w", text=True)
193 fp.write("[paths]\n")
194 fp.write("default = %s\n" % abspath)
195 fp.close()
196
197 if dest_lock:
198 dest_lock.release()
199
200 if update:
201 dest_repo.update(dest_repo.changelog.tip())
202 if dir_cleanup:
203 dir_cleanup.close()
204
205 return src_repo, dest_repo
General Comments 0
You need to be logged in to leave comments. Login now