##// END OF EJS Templates
codingstyle: use spaces instead of tabs
Benoit Boissinot -
r2631:8f564a87 default
parent child Browse files
Show More
@@ -1,209 +1,209
1 # hg.py - repository classes for mercurial
1 # hg.py - repository classes for mercurial
2 #
2 #
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 from node import *
8 from node import *
9 from repo import *
9 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(), "errno lock os shutil 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://'):
17 path = path[9:]
17 path = path[9:]
18 else:
18 else:
19 path = path[7:]
19 path = path[7:]
20 s = path.split("+", 1)
20 s = path.split("+", 1)
21 if len(s) == 1:
21 if len(s) == 1:
22 repopath, bundlename = "", s[0]
22 repopath, bundlename = "", s[0]
23 else:
23 else:
24 repopath, bundlename = s
24 repopath, bundlename = s
25 return bundlerepo.bundlerepository(ui, repopath, bundlename)
25 return bundlerepo.bundlerepository(ui, repopath, bundlename)
26
26
27 def hg(ui, path):
27 def hg(ui, path):
28 ui.warn(_("hg:// syntax is deprecated, please use http:// instead\n"))
28 ui.warn(_("hg:// syntax is deprecated, please use http:// instead\n"))
29 return httprepo.httprepository(ui, path.replace("hg://", "http://"))
29 return httprepo.httprepository(ui, path.replace("hg://", "http://"))
30
30
31 def local_(ui, path, create=0):
31 def local_(ui, path, create=0):
32 if path.startswith('file:'):
32 if path.startswith('file:'):
33 path = path[5:]
33 path = path[5:]
34 return localrepo.localrepository(ui, path, create)
34 return localrepo.localrepository(ui, path, create)
35
35
36 def ssh_(ui, path, create=0):
36 def ssh_(ui, path, create=0):
37 return sshrepo.sshrepository(ui, path, create)
37 return sshrepo.sshrepository(ui, path, create)
38
38
39 def old_http(ui, path):
39 def old_http(ui, path):
40 ui.warn(_("old-http:// syntax is deprecated, "
40 ui.warn(_("old-http:// syntax is deprecated, "
41 "please use static-http:// instead\n"))
41 "please use static-http:// instead\n"))
42 return statichttprepo.statichttprepository(
42 return statichttprepo.statichttprepository(
43 ui, path.replace("old-http://", "http://"))
43 ui, path.replace("old-http://", "http://"))
44
44
45 def static_http(ui, path):
45 def static_http(ui, path):
46 return statichttprepo.statichttprepository(
46 return statichttprepo.statichttprepository(
47 ui, path.replace("static-http://", "http://"))
47 ui, path.replace("static-http://", "http://"))
48
48
49 schemes = {
49 schemes = {
50 'bundle': bundle,
50 'bundle': bundle,
51 'file': local_,
51 'file': local_,
52 'hg': hg,
52 'hg': hg,
53 'http': lambda ui, path: httprepo.httprepository(ui, path),
53 'http': lambda ui, path: httprepo.httprepository(ui, path),
54 'https': lambda ui, path: httprepo.httpsrepository(ui, path),
54 'https': lambda ui, path: httprepo.httpsrepository(ui, path),
55 'old-http': old_http,
55 'old-http': old_http,
56 'ssh': ssh_,
56 'ssh': ssh_,
57 'static-http': static_http,
57 'static-http': static_http,
58 }
58 }
59
59
60 def repository(ui, path=None, create=0):
60 def repository(ui, path=None, create=0):
61 scheme = None
61 scheme = None
62 if path:
62 if path:
63 c = path.find(':')
63 c = path.find(':')
64 if c > 0:
64 if c > 0:
65 scheme = schemes.get(path[:c])
65 scheme = schemes.get(path[:c])
66 else:
66 else:
67 path = ''
67 path = ''
68 ctor = scheme or schemes['file']
68 ctor = scheme or schemes['file']
69 if create:
69 if create:
70 try:
70 try:
71 return ctor(ui, path, create)
71 return ctor(ui, path, create)
72 except TypeError:
72 except TypeError:
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
76
77 def clone(ui, source, dest=None, pull=False, rev=None, update=True,
77 def clone(ui, source, dest=None, pull=False, rev=None, update=True,
78 stream=False):
78 stream=False):
79 """Make a copy of an existing repository.
79 """Make a copy of an existing repository.
80
80
81 Create a copy of an existing repository in a new directory. The
81 Create a copy of an existing repository in a new directory. The
82 source and destination are URLs, as passed to the repository
82 source and destination are URLs, as passed to the repository
83 function. Returns a pair of repository objects, the source and
83 function. Returns a pair of repository objects, the source and
84 newly created destination.
84 newly created destination.
85
85
86 The location of the source is added to the new repository's
86 The location of the source is added to the new repository's
87 .hg/hgrc file, as the default to be used for future pulls and
87 .hg/hgrc file, as the default to be used for future pulls and
88 pushes.
88 pushes.
89
89
90 If an exception is raised, the partly cloned/updated destination
90 If an exception is raised, the partly cloned/updated destination
91 repository will be deleted.
91 repository will be deleted.
92
92
93 Keyword arguments:
93 Keyword arguments:
94
94
95 dest: URL of destination repository to create (defaults to base
95 dest: URL of destination repository to create (defaults to base
96 name of source repository)
96 name of source repository)
97
97
98 pull: always pull from source repository, even in local case
98 pull: always pull from source repository, even in local case
99
99
100 stream: stream raw data uncompressed from repository (fast over
100 stream: stream raw data uncompressed from repository (fast over
101 LAN, slow over WAN)
101 LAN, slow over WAN)
102
102
103 rev: revision to clone up to (implies pull=True)
103 rev: revision to clone up to (implies pull=True)
104
104
105 update: update working directory after clone completes, if
105 update: update working directory after clone completes, if
106 destination is local repository
106 destination is local repository
107 """
107 """
108 if dest is None:
108 if dest is None:
109 dest = os.path.basename(os.path.normpath(source))
109 dest = os.path.basename(os.path.normpath(source))
110
110
111 if os.path.exists(dest):
111 if os.path.exists(dest):
112 raise util.Abort(_("destination '%s' already exists"), dest)
112 raise util.Abort(_("destination '%s' already exists"), dest)
113
113
114 class DirCleanup(object):
114 class DirCleanup(object):
115 def __init__(self, dir_):
115 def __init__(self, dir_):
116 self.rmtree = shutil.rmtree
116 self.rmtree = shutil.rmtree
117 self.dir_ = dir_
117 self.dir_ = dir_
118 def close(self):
118 def close(self):
119 self.dir_ = None
119 self.dir_ = None
120 def __del__(self):
120 def __del__(self):
121 if self.dir_:
121 if self.dir_:
122 self.rmtree(self.dir_, True)
122 self.rmtree(self.dir_, True)
123
123
124 src_repo = repository(ui, source)
124 src_repo = repository(ui, source)
125
125
126 dest_repo = None
126 dest_repo = None
127 try:
127 try:
128 dest_repo = repository(ui, dest)
128 dest_repo = repository(ui, dest)
129 raise util.Abort(_("destination '%s' already exists." % dest))
129 raise util.Abort(_("destination '%s' already exists." % dest))
130 except RepoError:
130 except RepoError:
131 dest_repo = repository(ui, dest, create=True)
131 dest_repo = repository(ui, dest, create=True)
132
132
133 dest_path = None
133 dest_path = None
134 dir_cleanup = None
134 dir_cleanup = None
135 if dest_repo.local():
135 if dest_repo.local():
136 dest_path = os.path.realpath(dest)
136 dest_path = os.path.realpath(dest)
137 dir_cleanup = DirCleanup(dest_path)
137 dir_cleanup = DirCleanup(dest_path)
138
138
139 abspath = source
139 abspath = source
140 copy = False
140 copy = False
141 if src_repo.local() and dest_repo.local():
141 if src_repo.local() and dest_repo.local():
142 abspath = os.path.abspath(source)
142 abspath = os.path.abspath(source)
143 copy = not pull and not rev
143 copy = not pull and not rev
144
144
145 src_lock, dest_lock = None, None
145 src_lock, dest_lock = None, None
146 if copy:
146 if copy:
147 try:
147 try:
148 # we use a lock here because if we race with commit, we
148 # we use a lock here because if we race with commit, we
149 # can end up with extra data in the cloned revlogs that's
149 # can end up with extra data in the cloned revlogs that's
150 # not pointed to by changesets, thus causing verify to
150 # not pointed to by changesets, thus causing verify to
151 # fail
151 # fail
152 src_lock = src_repo.lock()
152 src_lock = src_repo.lock()
153 except lock.LockException:
153 except lock.LockException:
154 copy = False
154 copy = False
155
155
156 if copy:
156 if copy:
157 # we lock here to avoid premature writing to the target
157 # we lock here to avoid premature writing to the target
158 dest_lock = lock.lock(os.path.join(dest_path, ".hg", "lock"))
158 dest_lock = lock.lock(os.path.join(dest_path, ".hg", "lock"))
159
159
160 # we need to remove the (empty) data dir in dest so copyfiles
160 # we need to remove the (empty) data dir in dest so copyfiles
161 # can do its work
161 # can do its work
162 os.rmdir(os.path.join(dest_path, ".hg", "data"))
162 os.rmdir(os.path.join(dest_path, ".hg", "data"))
163 files = "data 00manifest.d 00manifest.i 00changelog.d 00changelog.i"
163 files = "data 00manifest.d 00manifest.i 00changelog.d 00changelog.i"
164 for f in files.split():
164 for f in files.split():
165 src = os.path.join(source, ".hg", f)
165 src = os.path.join(source, ".hg", f)
166 dst = os.path.join(dest_path, ".hg", f)
166 dst = os.path.join(dest_path, ".hg", f)
167 try:
167 try:
168 util.copyfiles(src, dst)
168 util.copyfiles(src, dst)
169 except OSError, inst:
169 except OSError, inst:
170 if inst.errno != errno.ENOENT:
170 if inst.errno != errno.ENOENT:
171 raise
171 raise
172
172
173 # we need to re-init the repo after manually copying the data
173 # we need to re-init the repo after manually copying the data
174 # into it
174 # into it
175 dest_repo = repository(ui, dest)
175 dest_repo = repository(ui, dest)
176
176
177 else:
177 else:
178 revs = None
178 revs = None
179 if rev:
179 if rev:
180 if not src_repo.local():
180 if not src_repo.local():
181 raise util.Abort(_("clone by revision not supported yet "
181 raise util.Abort(_("clone by revision not supported yet "
182 "for remote repositories"))
182 "for remote repositories"))
183 revs = [src_repo.lookup(r) for r in rev]
183 revs = [src_repo.lookup(r) for r in rev]
184
184
185 if dest_repo.local():
185 if dest_repo.local():
186 dest_repo.clone(src_repo, heads=revs, stream=stream)
186 dest_repo.clone(src_repo, heads=revs, stream=stream)
187 elif src_repo.local():
187 elif src_repo.local():
188 src_repo.push(dest_repo, revs=revs)
188 src_repo.push(dest_repo, revs=revs)
189 else:
189 else:
190 raise util.Abort(_("clone from remote to remote not supported"))
190 raise util.Abort(_("clone from remote to remote not supported"))
191
191
192 if src_lock:
192 if src_lock:
193 src_lock.release()
193 src_lock.release()
194
194
195 if dest_repo.local():
195 if dest_repo.local():
196 fp = dest_repo.opener("hgrc", "w", text=True)
196 fp = dest_repo.opener("hgrc", "w", text=True)
197 fp.write("[paths]\n")
197 fp.write("[paths]\n")
198 fp.write("default = %s\n" % abspath)
198 fp.write("default = %s\n" % abspath)
199 fp.close()
199 fp.close()
200
200
201 if dest_lock:
201 if dest_lock:
202 dest_lock.release()
202 dest_lock.release()
203
203
204 if update:
204 if update:
205 dest_repo.update(dest_repo.changelog.tip())
205 dest_repo.update(dest_repo.changelog.tip())
206 if dir_cleanup:
206 if dir_cleanup:
207 dir_cleanup.close()
207 dir_cleanup.close()
208
208
209 return src_repo, dest_repo
209 return src_repo, dest_repo
General Comments 0
You need to be logged in to leave comments. Login now