Mercurial > hg
comparison mercurial/hg.py @ 2956:6dddcba7596a
merge.
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Fri, 18 Aug 2006 21:17:28 -0700 |
parents | 345bac2bc4ec |
children | 3acb76f0124d |
comparison
equal
deleted
inserted
replaced
2955:9d1c3529ebbc | 2956:6dddcba7596a |
---|---|
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, 2006 Matt Mackall <mpm@selenic.com> |
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> | |
4 # | 5 # |
5 # This software may be used and distributed according to the terms | 6 # This software may be used and distributed according to the terms |
6 # of the GNU General Public License, incorporated herein by reference. | 7 # of the GNU General Public License, incorporated herein by reference. |
7 | 8 |
8 from node import * | 9 from node import * |
9 from repo import * | 10 from repo import * |
10 from demandload import * | 11 from demandload import * |
11 from i18n import gettext as _ | 12 from i18n import gettext as _ |
12 demandload(globals(), "localrepo bundlerepo httprepo sshrepo statichttprepo") | 13 demandload(globals(), "localrepo bundlerepo httprepo sshrepo statichttprepo") |
13 demandload(globals(), "errno lock os shutil util") | 14 demandload(globals(), "errno lock os shutil util merge@_merge verify@_verify") |
14 | 15 |
15 def bundle(ui, path): | 16 def _local(path): |
16 if path.startswith('bundle://'): | 17 return (os.path.isfile(path and util.drop_scheme('file', path)) and |
17 path = path[9:] | 18 bundlerepo or localrepo) |
18 else: | |
19 path = path[7:] | |
20 s = path.split("+", 1) | |
21 if len(s) == 1: | |
22 repopath, bundlename = "", s[0] | |
23 else: | |
24 repopath, bundlename = s | |
25 return bundlerepo.bundlerepository(ui, repopath, bundlename) | |
26 | |
27 def hg(ui, path): | |
28 ui.warn(_("hg:// syntax is deprecated, please use http:// instead\n")) | |
29 return httprepo.httprepository(ui, path.replace("hg://", "http://")) | |
30 | |
31 def local_(ui, path, create=0): | |
32 if path.startswith('file:'): | |
33 path = path[5:] | |
34 return localrepo.localrepository(ui, path, create) | |
35 | |
36 def ssh_(ui, path, create=0): | |
37 return sshrepo.sshrepository(ui, path, create) | |
38 | |
39 def old_http(ui, path): | |
40 ui.warn(_("old-http:// syntax is deprecated, " | |
41 "please use static-http:// instead\n")) | |
42 return statichttprepo.statichttprepository( | |
43 ui, path.replace("old-http://", "http://")) | |
44 | |
45 def static_http(ui, path): | |
46 return statichttprepo.statichttprepository( | |
47 ui, path.replace("static-http://", "http://")) | |
48 | 19 |
49 schemes = { | 20 schemes = { |
50 'bundle': bundle, | 21 'bundle': bundlerepo, |
51 'file': local_, | 22 'file': _local, |
52 'hg': hg, | 23 'hg': httprepo, |
53 'http': lambda ui, path: httprepo.httprepository(ui, path), | 24 'http': httprepo, |
54 'https': lambda ui, path: httprepo.httpsrepository(ui, path), | 25 'https': httprepo, |
55 'old-http': old_http, | 26 'old-http': statichttprepo, |
56 'ssh': ssh_, | 27 'ssh': sshrepo, |
57 'static-http': static_http, | 28 'static-http': statichttprepo, |
58 } | 29 } |
59 | 30 |
60 def repository(ui, path=None, create=0): | 31 def _lookup(path): |
61 scheme = None | 32 scheme = 'file' |
62 if path: | 33 if path: |
63 c = path.find(':') | 34 c = path.find(':') |
64 if c > 0: | 35 if c > 0: |
65 scheme = schemes.get(path[:c]) | 36 scheme = path[:c] |
66 else: | 37 thing = schemes.get(scheme) or schemes['file'] |
67 path = '' | 38 try: |
68 ctor = scheme or schemes['file'] | 39 return thing(path) |
69 if create: | 40 except TypeError: |
41 return thing | |
42 | |
43 def islocal(repo): | |
44 '''return true if repo or path is local''' | |
45 if isinstance(repo, str): | |
70 try: | 46 try: |
71 return ctor(ui, path, create) | 47 return _lookup(repo).islocal(repo) |
72 except TypeError: | 48 except AttributeError: |
73 raise util.Abort(_('cannot create new repository over "%s" protocol') % | 49 return False |
74 scheme) | 50 return repo.local() |
75 return ctor(ui, path) | 51 |
52 repo_setup_hooks = [] | |
53 | |
54 def repository(ui, path=None, create=False): | |
55 """return a repository object for the specified path""" | |
56 repo = _lookup(path).instance(ui, path, create) | |
57 for hook in repo_setup_hooks: | |
58 hook(ui, repo) | |
59 return repo | |
60 | |
61 def defaultdest(source): | |
62 '''return default destination of clone if none is given''' | |
63 return os.path.basename(os.path.normpath(source)) | |
76 | 64 |
77 def clone(ui, source, dest=None, pull=False, rev=None, update=True, | 65 def clone(ui, source, dest=None, pull=False, rev=None, update=True, |
78 stream=False): | 66 stream=False): |
79 """Make a copy of an existing repository. | 67 """Make a copy of an existing repository. |
80 | 68 |
88 pushes. | 76 pushes. |
89 | 77 |
90 If an exception is raised, the partly cloned/updated destination | 78 If an exception is raised, the partly cloned/updated destination |
91 repository will be deleted. | 79 repository will be deleted. |
92 | 80 |
93 Keyword arguments: | 81 Arguments: |
82 | |
83 source: repository object or URL | |
94 | 84 |
95 dest: URL of destination repository to create (defaults to base | 85 dest: URL of destination repository to create (defaults to base |
96 name of source repository) | 86 name of source repository) |
97 | 87 |
98 pull: always pull from source repository, even in local case | 88 pull: always pull from source repository, even in local case |
103 rev: revision to clone up to (implies pull=True) | 93 rev: revision to clone up to (implies pull=True) |
104 | 94 |
105 update: update working directory after clone completes, if | 95 update: update working directory after clone completes, if |
106 destination is local repository | 96 destination is local repository |
107 """ | 97 """ |
98 if isinstance(source, str): | |
99 src_repo = repository(ui, source) | |
100 else: | |
101 src_repo = source | |
102 source = src_repo.url() | |
103 | |
108 if dest is None: | 104 if dest is None: |
109 dest = os.path.basename(os.path.normpath(source)) | 105 dest = defaultdest(source) |
106 | |
107 def localpath(path): | |
108 if path.startswith('file://'): | |
109 return path[7:] | |
110 if path.startswith('file:'): | |
111 return path[5:] | |
112 return path | |
113 | |
114 dest = localpath(dest) | |
115 source = localpath(source) | |
110 | 116 |
111 if os.path.exists(dest): | 117 if os.path.exists(dest): |
112 raise util.Abort(_("destination '%s' already exists"), dest) | 118 raise util.Abort(_("destination '%s' already exists"), dest) |
113 | 119 |
114 class DirCleanup(object): | 120 class DirCleanup(object): |
119 self.dir_ = None | 125 self.dir_ = None |
120 def __del__(self): | 126 def __del__(self): |
121 if self.dir_: | 127 if self.dir_: |
122 self.rmtree(self.dir_, True) | 128 self.rmtree(self.dir_, True) |
123 | 129 |
124 src_repo = repository(ui, source) | |
125 | |
126 dest_repo = None | 130 dest_repo = None |
127 try: | 131 try: |
128 dest_repo = repository(ui, dest) | 132 dest_repo = repository(ui, dest) |
129 raise util.Abort(_("destination '%s' already exists." % dest)) | 133 raise util.Abort(_("destination '%s' already exists." % dest)) |
130 except RepoError: | 134 except RepoError: |
131 dest_repo = repository(ui, dest, create=True) | 135 dest_repo = repository(ui, dest, create=True) |
132 | 136 |
133 dest_path = None | 137 dest_path = None |
134 dir_cleanup = None | 138 dir_cleanup = None |
135 if dest_repo.local(): | 139 if dest_repo.local(): |
136 dest_path = os.path.realpath(dest) | 140 dest_path = os.path.realpath(dest_repo.root) |
137 dir_cleanup = DirCleanup(dest_path) | 141 dir_cleanup = DirCleanup(dest_path) |
138 | 142 |
139 abspath = source | 143 abspath = source |
140 copy = False | 144 copy = False |
141 if src_repo.local() and dest_repo.local(): | 145 if src_repo.local() and dest_repo.local(): |
200 | 204 |
201 if dest_lock: | 205 if dest_lock: |
202 dest_lock.release() | 206 dest_lock.release() |
203 | 207 |
204 if update: | 208 if update: |
205 dest_repo.update(dest_repo.changelog.tip()) | 209 _merge.update(dest_repo, dest_repo.changelog.tip()) |
206 if dir_cleanup: | 210 if dir_cleanup: |
207 dir_cleanup.close() | 211 dir_cleanup.close() |
208 | 212 |
209 return src_repo, dest_repo | 213 return src_repo, dest_repo |
214 | |
215 def update(repo, node): | |
216 """update the working directory to node, merging linear changes""" | |
217 return _merge.update(repo, node) | |
218 | |
219 def clean(repo, node, wlock=None, show_stats=True): | |
220 """forcibly switch the working directory to node, clobbering changes""" | |
221 return _merge.update(repo, node, force=True, wlock=wlock, | |
222 show_stats=show_stats) | |
223 | |
224 def merge(repo, node, force=None, remind=True, wlock=None): | |
225 """branch merge with node, resolving changes""" | |
226 return _merge.update(repo, node, branchmerge=True, force=force, | |
227 remind=remind, wlock=wlock) | |
228 | |
229 def revert(repo, node, choose, wlock): | |
230 """revert changes to revision in node without updating dirstate""" | |
231 return _merge.update(repo, node, force=True, partial=choose, | |
232 show_stats=False, wlock=wlock) | |
233 | |
234 def verify(repo): | |
235 """verify the consistency of a repository""" | |
236 return _verify.verify(repo) |