##// END OF EJS Templates
pull: with -u and -r, update to the first revision given...
Sune Foldager -
r10358:d42821cd default
parent child Browse files
Show More
@@ -1,372 +1,372 b''
1 # hg.py - repository classes for mercurial
1 # hg.py - repository classes for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 from i18n import _
9 from i18n import _
10 from lock import release
10 from lock import release
11 import localrepo, bundlerepo, httprepo, sshrepo, statichttprepo
11 import localrepo, bundlerepo, httprepo, sshrepo, statichttprepo
12 import lock, util, extensions, error, encoding
12 import lock, util, extensions, error, encoding
13 import merge as _merge
13 import merge as _merge
14 import verify as _verify
14 import verify as _verify
15 import errno, os, shutil
15 import errno, os, shutil
16
16
17 def _local(path):
17 def _local(path):
18 return (os.path.isfile(util.drop_scheme('file', path)) and
18 return (os.path.isfile(util.drop_scheme('file', path)) and
19 bundlerepo or localrepo)
19 bundlerepo or localrepo)
20
20
21 def parseurl(url, revs=[]):
21 def parseurl(url, revs=[]):
22 '''parse url#branch, returning url, branch + revs'''
22 '''parse url#branch, returning url, branch + revs'''
23
23
24 if '#' not in url:
24 if '#' not in url:
25 return url, (revs or None), revs and revs[-1] or None
25 return url, (revs or None), revs and revs[0] or None
26
26
27 url, branch = url.split('#', 1)
27 url, branch = url.split('#', 1)
28 checkout = revs and revs[-1] or branch
28 checkout = revs and revs[0] or branch
29 return url, (revs or []) + [branch], checkout
29 return url, (revs or []) + [branch], checkout
30
30
31 schemes = {
31 schemes = {
32 'bundle': bundlerepo,
32 'bundle': bundlerepo,
33 'file': _local,
33 'file': _local,
34 'http': httprepo,
34 'http': httprepo,
35 'https': httprepo,
35 'https': httprepo,
36 'ssh': sshrepo,
36 'ssh': sshrepo,
37 'static-http': statichttprepo,
37 'static-http': statichttprepo,
38 }
38 }
39
39
40 def _lookup(path):
40 def _lookup(path):
41 scheme = 'file'
41 scheme = 'file'
42 if path:
42 if path:
43 c = path.find(':')
43 c = path.find(':')
44 if c > 0:
44 if c > 0:
45 scheme = path[:c]
45 scheme = path[:c]
46 thing = schemes.get(scheme) or schemes['file']
46 thing = schemes.get(scheme) or schemes['file']
47 try:
47 try:
48 return thing(path)
48 return thing(path)
49 except TypeError:
49 except TypeError:
50 return thing
50 return thing
51
51
52 def islocal(repo):
52 def islocal(repo):
53 '''return true if repo or path is local'''
53 '''return true if repo or path is local'''
54 if isinstance(repo, str):
54 if isinstance(repo, str):
55 try:
55 try:
56 return _lookup(repo).islocal(repo)
56 return _lookup(repo).islocal(repo)
57 except AttributeError:
57 except AttributeError:
58 return False
58 return False
59 return repo.local()
59 return repo.local()
60
60
61 def repository(ui, path='', create=False):
61 def repository(ui, path='', create=False):
62 """return a repository object for the specified path"""
62 """return a repository object for the specified path"""
63 repo = _lookup(path).instance(ui, path, create)
63 repo = _lookup(path).instance(ui, path, create)
64 ui = getattr(repo, "ui", ui)
64 ui = getattr(repo, "ui", ui)
65 for name, module in extensions.extensions():
65 for name, module in extensions.extensions():
66 hook = getattr(module, 'reposetup', None)
66 hook = getattr(module, 'reposetup', None)
67 if hook:
67 if hook:
68 hook(ui, repo)
68 hook(ui, repo)
69 return repo
69 return repo
70
70
71 def defaultdest(source):
71 def defaultdest(source):
72 '''return default destination of clone if none is given'''
72 '''return default destination of clone if none is given'''
73 return os.path.basename(os.path.normpath(source))
73 return os.path.basename(os.path.normpath(source))
74
74
75 def localpath(path):
75 def localpath(path):
76 if path.startswith('file://localhost/'):
76 if path.startswith('file://localhost/'):
77 return path[16:]
77 return path[16:]
78 if path.startswith('file://'):
78 if path.startswith('file://'):
79 return path[7:]
79 return path[7:]
80 if path.startswith('file:'):
80 if path.startswith('file:'):
81 return path[5:]
81 return path[5:]
82 return path
82 return path
83
83
84 def share(ui, source, dest=None, update=True):
84 def share(ui, source, dest=None, update=True):
85 '''create a shared repository'''
85 '''create a shared repository'''
86
86
87 if not islocal(source):
87 if not islocal(source):
88 raise util.Abort(_('can only share local repositories'))
88 raise util.Abort(_('can only share local repositories'))
89
89
90 if not dest:
90 if not dest:
91 dest = defaultdest(source)
91 dest = defaultdest(source)
92 else:
92 else:
93 dest = ui.expandpath(dest)
93 dest = ui.expandpath(dest)
94
94
95 if isinstance(source, str):
95 if isinstance(source, str):
96 origsource = ui.expandpath(source)
96 origsource = ui.expandpath(source)
97 source, rev, checkout = parseurl(origsource, '')
97 source, rev, checkout = parseurl(origsource, '')
98 srcrepo = repository(ui, source)
98 srcrepo = repository(ui, source)
99 else:
99 else:
100 srcrepo = source
100 srcrepo = source
101 origsource = source = srcrepo.url()
101 origsource = source = srcrepo.url()
102 checkout = None
102 checkout = None
103
103
104 sharedpath = srcrepo.sharedpath # if our source is already sharing
104 sharedpath = srcrepo.sharedpath # if our source is already sharing
105
105
106 root = os.path.realpath(dest)
106 root = os.path.realpath(dest)
107 roothg = os.path.join(root, '.hg')
107 roothg = os.path.join(root, '.hg')
108
108
109 if os.path.exists(roothg):
109 if os.path.exists(roothg):
110 raise util.Abort(_('destination already exists'))
110 raise util.Abort(_('destination already exists'))
111
111
112 if not os.path.isdir(root):
112 if not os.path.isdir(root):
113 os.mkdir(root)
113 os.mkdir(root)
114 os.mkdir(roothg)
114 os.mkdir(roothg)
115
115
116 requirements = ''
116 requirements = ''
117 try:
117 try:
118 requirements = srcrepo.opener('requires').read()
118 requirements = srcrepo.opener('requires').read()
119 except IOError, inst:
119 except IOError, inst:
120 if inst.errno != errno.ENOENT:
120 if inst.errno != errno.ENOENT:
121 raise
121 raise
122
122
123 requirements += 'shared\n'
123 requirements += 'shared\n'
124 file(os.path.join(roothg, 'requires'), 'w').write(requirements)
124 file(os.path.join(roothg, 'requires'), 'w').write(requirements)
125 file(os.path.join(roothg, 'sharedpath'), 'w').write(sharedpath)
125 file(os.path.join(roothg, 'sharedpath'), 'w').write(sharedpath)
126
126
127 default = srcrepo.ui.config('paths', 'default')
127 default = srcrepo.ui.config('paths', 'default')
128 if default:
128 if default:
129 f = file(os.path.join(roothg, 'hgrc'), 'w')
129 f = file(os.path.join(roothg, 'hgrc'), 'w')
130 f.write('[paths]\ndefault = %s\n' % default)
130 f.write('[paths]\ndefault = %s\n' % default)
131 f.close()
131 f.close()
132
132
133 r = repository(ui, root)
133 r = repository(ui, root)
134
134
135 if update:
135 if update:
136 r.ui.status(_("updating working directory\n"))
136 r.ui.status(_("updating working directory\n"))
137 if update is not True:
137 if update is not True:
138 checkout = update
138 checkout = update
139 for test in (checkout, 'default', 'tip'):
139 for test in (checkout, 'default', 'tip'):
140 if test is None:
140 if test is None:
141 continue
141 continue
142 try:
142 try:
143 uprev = r.lookup(test)
143 uprev = r.lookup(test)
144 break
144 break
145 except error.RepoLookupError:
145 except error.RepoLookupError:
146 continue
146 continue
147 _update(r, uprev)
147 _update(r, uprev)
148
148
149 def clone(ui, source, dest=None, pull=False, rev=None, update=True,
149 def clone(ui, source, dest=None, pull=False, rev=None, update=True,
150 stream=False):
150 stream=False):
151 """Make a copy of an existing repository.
151 """Make a copy of an existing repository.
152
152
153 Create a copy of an existing repository in a new directory. The
153 Create a copy of an existing repository in a new directory. The
154 source and destination are URLs, as passed to the repository
154 source and destination are URLs, as passed to the repository
155 function. Returns a pair of repository objects, the source and
155 function. Returns a pair of repository objects, the source and
156 newly created destination.
156 newly created destination.
157
157
158 The location of the source is added to the new repository's
158 The location of the source is added to the new repository's
159 .hg/hgrc file, as the default to be used for future pulls and
159 .hg/hgrc file, as the default to be used for future pulls and
160 pushes.
160 pushes.
161
161
162 If an exception is raised, the partly cloned/updated destination
162 If an exception is raised, the partly cloned/updated destination
163 repository will be deleted.
163 repository will be deleted.
164
164
165 Arguments:
165 Arguments:
166
166
167 source: repository object or URL
167 source: repository object or URL
168
168
169 dest: URL of destination repository to create (defaults to base
169 dest: URL of destination repository to create (defaults to base
170 name of source repository)
170 name of source repository)
171
171
172 pull: always pull from source repository, even in local case
172 pull: always pull from source repository, even in local case
173
173
174 stream: stream raw data uncompressed from repository (fast over
174 stream: stream raw data uncompressed from repository (fast over
175 LAN, slow over WAN)
175 LAN, slow over WAN)
176
176
177 rev: revision to clone up to (implies pull=True)
177 rev: revision to clone up to (implies pull=True)
178
178
179 update: update working directory after clone completes, if
179 update: update working directory after clone completes, if
180 destination is local repository (True means update to default rev,
180 destination is local repository (True means update to default rev,
181 anything else is treated as a revision)
181 anything else is treated as a revision)
182 """
182 """
183
183
184 if isinstance(source, str):
184 if isinstance(source, str):
185 origsource = ui.expandpath(source)
185 origsource = ui.expandpath(source)
186 source, rev, checkout = parseurl(origsource, rev)
186 source, rev, checkout = parseurl(origsource, rev)
187 src_repo = repository(ui, source)
187 src_repo = repository(ui, source)
188 else:
188 else:
189 src_repo = source
189 src_repo = source
190 origsource = source = src_repo.url()
190 origsource = source = src_repo.url()
191 checkout = rev and rev[-1] or None
191 checkout = rev and rev[0] or None
192
192
193 if dest is None:
193 if dest is None:
194 dest = defaultdest(source)
194 dest = defaultdest(source)
195 ui.status(_("destination directory: %s\n") % dest)
195 ui.status(_("destination directory: %s\n") % dest)
196 else:
196 else:
197 dest = ui.expandpath(dest)
197 dest = ui.expandpath(dest)
198
198
199 dest = localpath(dest)
199 dest = localpath(dest)
200 source = localpath(source)
200 source = localpath(source)
201
201
202 if os.path.exists(dest):
202 if os.path.exists(dest):
203 if not os.path.isdir(dest):
203 if not os.path.isdir(dest):
204 raise util.Abort(_("destination '%s' already exists") % dest)
204 raise util.Abort(_("destination '%s' already exists") % dest)
205 elif os.listdir(dest):
205 elif os.listdir(dest):
206 raise util.Abort(_("destination '%s' is not empty") % dest)
206 raise util.Abort(_("destination '%s' is not empty") % dest)
207
207
208 class DirCleanup(object):
208 class DirCleanup(object):
209 def __init__(self, dir_):
209 def __init__(self, dir_):
210 self.rmtree = shutil.rmtree
210 self.rmtree = shutil.rmtree
211 self.dir_ = dir_
211 self.dir_ = dir_
212 def close(self):
212 def close(self):
213 self.dir_ = None
213 self.dir_ = None
214 def cleanup(self):
214 def cleanup(self):
215 if self.dir_:
215 if self.dir_:
216 self.rmtree(self.dir_, True)
216 self.rmtree(self.dir_, True)
217
217
218 src_lock = dest_lock = dir_cleanup = None
218 src_lock = dest_lock = dir_cleanup = None
219 try:
219 try:
220 if islocal(dest):
220 if islocal(dest):
221 dir_cleanup = DirCleanup(dest)
221 dir_cleanup = DirCleanup(dest)
222
222
223 abspath = origsource
223 abspath = origsource
224 copy = False
224 copy = False
225 if src_repo.cancopy() and islocal(dest):
225 if src_repo.cancopy() and islocal(dest):
226 abspath = os.path.abspath(util.drop_scheme('file', origsource))
226 abspath = os.path.abspath(util.drop_scheme('file', origsource))
227 copy = not pull and not rev
227 copy = not pull and not rev
228
228
229 if copy:
229 if copy:
230 try:
230 try:
231 # we use a lock here because if we race with commit, we
231 # we use a lock here because if we race with commit, we
232 # can end up with extra data in the cloned revlogs that's
232 # can end up with extra data in the cloned revlogs that's
233 # not pointed to by changesets, thus causing verify to
233 # not pointed to by changesets, thus causing verify to
234 # fail
234 # fail
235 src_lock = src_repo.lock(wait=False)
235 src_lock = src_repo.lock(wait=False)
236 except error.LockError:
236 except error.LockError:
237 copy = False
237 copy = False
238
238
239 if copy:
239 if copy:
240 src_repo.hook('preoutgoing', throw=True, source='clone')
240 src_repo.hook('preoutgoing', throw=True, source='clone')
241 hgdir = os.path.realpath(os.path.join(dest, ".hg"))
241 hgdir = os.path.realpath(os.path.join(dest, ".hg"))
242 if not os.path.exists(dest):
242 if not os.path.exists(dest):
243 os.mkdir(dest)
243 os.mkdir(dest)
244 else:
244 else:
245 # only clean up directories we create ourselves
245 # only clean up directories we create ourselves
246 dir_cleanup.dir_ = hgdir
246 dir_cleanup.dir_ = hgdir
247 try:
247 try:
248 dest_path = hgdir
248 dest_path = hgdir
249 os.mkdir(dest_path)
249 os.mkdir(dest_path)
250 except OSError, inst:
250 except OSError, inst:
251 if inst.errno == errno.EEXIST:
251 if inst.errno == errno.EEXIST:
252 dir_cleanup.close()
252 dir_cleanup.close()
253 raise util.Abort(_("destination '%s' already exists")
253 raise util.Abort(_("destination '%s' already exists")
254 % dest)
254 % dest)
255 raise
255 raise
256
256
257 for f in src_repo.store.copylist():
257 for f in src_repo.store.copylist():
258 src = os.path.join(src_repo.sharedpath, f)
258 src = os.path.join(src_repo.sharedpath, f)
259 dst = os.path.join(dest_path, f)
259 dst = os.path.join(dest_path, f)
260 dstbase = os.path.dirname(dst)
260 dstbase = os.path.dirname(dst)
261 if dstbase and not os.path.exists(dstbase):
261 if dstbase and not os.path.exists(dstbase):
262 os.mkdir(dstbase)
262 os.mkdir(dstbase)
263 if os.path.exists(src):
263 if os.path.exists(src):
264 if dst.endswith('data'):
264 if dst.endswith('data'):
265 # lock to avoid premature writing to the target
265 # lock to avoid premature writing to the target
266 dest_lock = lock.lock(os.path.join(dstbase, "lock"))
266 dest_lock = lock.lock(os.path.join(dstbase, "lock"))
267 util.copyfiles(src, dst)
267 util.copyfiles(src, dst)
268
268
269 # we need to re-init the repo after manually copying the data
269 # we need to re-init the repo after manually copying the data
270 # into it
270 # into it
271 dest_repo = repository(ui, dest)
271 dest_repo = repository(ui, dest)
272 src_repo.hook('outgoing', source='clone', node='0'*40)
272 src_repo.hook('outgoing', source='clone', node='0'*40)
273 else:
273 else:
274 try:
274 try:
275 dest_repo = repository(ui, dest, create=True)
275 dest_repo = repository(ui, dest, create=True)
276 except OSError, inst:
276 except OSError, inst:
277 if inst.errno == errno.EEXIST:
277 if inst.errno == errno.EEXIST:
278 dir_cleanup.close()
278 dir_cleanup.close()
279 raise util.Abort(_("destination '%s' already exists")
279 raise util.Abort(_("destination '%s' already exists")
280 % dest)
280 % dest)
281 raise
281 raise
282
282
283 revs = None
283 revs = None
284 if rev:
284 if rev:
285 if 'lookup' not in src_repo.capabilities:
285 if 'lookup' not in src_repo.capabilities:
286 raise util.Abort(_("src repository does not support "
286 raise util.Abort(_("src repository does not support "
287 "revision lookup and so doesn't "
287 "revision lookup and so doesn't "
288 "support clone by revision"))
288 "support clone by revision"))
289 revs = [src_repo.lookup(r) for r in rev]
289 revs = [src_repo.lookup(r) for r in rev]
290 checkout = revs[0]
290 checkout = revs[0]
291 if dest_repo.local():
291 if dest_repo.local():
292 dest_repo.clone(src_repo, heads=revs, stream=stream)
292 dest_repo.clone(src_repo, heads=revs, stream=stream)
293 elif src_repo.local():
293 elif src_repo.local():
294 src_repo.push(dest_repo, revs=revs)
294 src_repo.push(dest_repo, revs=revs)
295 else:
295 else:
296 raise util.Abort(_("clone from remote to remote not supported"))
296 raise util.Abort(_("clone from remote to remote not supported"))
297
297
298 if dir_cleanup:
298 if dir_cleanup:
299 dir_cleanup.close()
299 dir_cleanup.close()
300
300
301 if dest_repo.local():
301 if dest_repo.local():
302 fp = dest_repo.opener("hgrc", "w", text=True)
302 fp = dest_repo.opener("hgrc", "w", text=True)
303 fp.write("[paths]\n")
303 fp.write("[paths]\n")
304 fp.write("default = %s\n" % abspath)
304 fp.write("default = %s\n" % abspath)
305 fp.close()
305 fp.close()
306
306
307 dest_repo.ui.setconfig('paths', 'default', abspath)
307 dest_repo.ui.setconfig('paths', 'default', abspath)
308
308
309 if update:
309 if update:
310 if update is not True:
310 if update is not True:
311 checkout = update
311 checkout = update
312 if src_repo.local():
312 if src_repo.local():
313 checkout = src_repo.lookup(update)
313 checkout = src_repo.lookup(update)
314 for test in (checkout, 'default', 'tip'):
314 for test in (checkout, 'default', 'tip'):
315 if test is None:
315 if test is None:
316 continue
316 continue
317 try:
317 try:
318 uprev = dest_repo.lookup(test)
318 uprev = dest_repo.lookup(test)
319 break
319 break
320 except error.RepoLookupError:
320 except error.RepoLookupError:
321 continue
321 continue
322 bn = dest_repo[uprev].branch()
322 bn = dest_repo[uprev].branch()
323 dest_repo.ui.status(_("updating to branch %s\n")
323 dest_repo.ui.status(_("updating to branch %s\n")
324 % encoding.tolocal(bn))
324 % encoding.tolocal(bn))
325 _update(dest_repo, uprev)
325 _update(dest_repo, uprev)
326
326
327 return src_repo, dest_repo
327 return src_repo, dest_repo
328 finally:
328 finally:
329 release(src_lock, dest_lock)
329 release(src_lock, dest_lock)
330 if dir_cleanup is not None:
330 if dir_cleanup is not None:
331 dir_cleanup.cleanup()
331 dir_cleanup.cleanup()
332
332
333 def _showstats(repo, stats):
333 def _showstats(repo, stats):
334 repo.ui.status(_("%d files updated, %d files merged, "
334 repo.ui.status(_("%d files updated, %d files merged, "
335 "%d files removed, %d files unresolved\n") % stats)
335 "%d files removed, %d files unresolved\n") % stats)
336
336
337 def update(repo, node):
337 def update(repo, node):
338 """update the working directory to node, merging linear changes"""
338 """update the working directory to node, merging linear changes"""
339 stats = _merge.update(repo, node, False, False, None)
339 stats = _merge.update(repo, node, False, False, None)
340 _showstats(repo, stats)
340 _showstats(repo, stats)
341 if stats[3]:
341 if stats[3]:
342 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
342 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
343 return stats[3] > 0
343 return stats[3] > 0
344
344
345 # naming conflict in clone()
345 # naming conflict in clone()
346 _update = update
346 _update = update
347
347
348 def clean(repo, node, show_stats=True):
348 def clean(repo, node, show_stats=True):
349 """forcibly switch the working directory to node, clobbering changes"""
349 """forcibly switch the working directory to node, clobbering changes"""
350 stats = _merge.update(repo, node, False, True, None)
350 stats = _merge.update(repo, node, False, True, None)
351 if show_stats:
351 if show_stats:
352 _showstats(repo, stats)
352 _showstats(repo, stats)
353 return stats[3] > 0
353 return stats[3] > 0
354
354
355 def merge(repo, node, force=None, remind=True):
355 def merge(repo, node, force=None, remind=True):
356 """branch merge with node, resolving changes"""
356 """branch merge with node, resolving changes"""
357 stats = _merge.update(repo, node, True, force, False)
357 stats = _merge.update(repo, node, True, force, False)
358 _showstats(repo, stats)
358 _showstats(repo, stats)
359 if stats[3]:
359 if stats[3]:
360 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
360 repo.ui.status(_("use 'hg resolve' to retry unresolved file merges "
361 "or 'hg update -C' to abandon\n"))
361 "or 'hg update -C' to abandon\n"))
362 elif remind:
362 elif remind:
363 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
363 repo.ui.status(_("(branch merge, don't forget to commit)\n"))
364 return stats[3] > 0
364 return stats[3] > 0
365
365
366 def revert(repo, node, choose):
366 def revert(repo, node, choose):
367 """revert changes to revision in node without updating dirstate"""
367 """revert changes to revision in node without updating dirstate"""
368 return _merge.update(repo, node, False, True, choose)[3] > 0
368 return _merge.update(repo, node, False, True, choose)[3] > 0
369
369
370 def verify(repo):
370 def verify(repo):
371 """verify the consistency of a repository"""
371 """verify the consistency of a repository"""
372 return _verify.verify(repo)
372 return _verify.verify(repo)
@@ -1,30 +1,35 b''
1 #!/bin/sh
1 #!/bin/sh
2
2
3 hg init repo
3 hg init repo
4 cd repo
4 cd repo
5 echo foo > foo
5 echo foo > foo
6 hg ci -qAm 'add foo'
6 hg ci -qAm 'add foo'
7 echo >> foo
7 echo >> foo
8 hg ci -m 'change foo'
8 hg ci -m 'change foo'
9 hg up -qC 0
9 hg up -qC 0
10 echo bar > bar
10 echo bar > bar
11 hg ci -qAm 'add bar'
11 hg ci -qAm 'add bar'
12 hg log
12 hg log
13 cd ..
13 cd ..
14 hg init copy
14 hg init copy
15 cd copy
15 cd copy
16
16
17 echo '% pull a missing revision'
17 echo '% pull a missing revision'
18 hg pull -qr missing ../repo
18 hg pull -qr missing ../repo
19
19
20 echo '% pull multiple revisions with update'
21 hg pull -qu -r 0 -r 1 ../repo
22 hg -q parents
23 hg rollback
24
20 echo '% pull -r 0'
25 echo '% pull -r 0'
21 hg pull -qr 0 ../repo
26 hg pull -qr 0 ../repo
22 hg log
27 hg log
23
28
24 echo '% pull -r 1'
29 echo '% pull -r 1'
25 hg pull -qr 1 ../repo
30 hg pull -qr 1 ../repo
26 hg log
31 hg log
27
32
28 # this used to abort: received changelog group is empty
33 # this used to abort: received changelog group is empty
29 echo '% pull -r 1 again'
34 echo '% pull -r 1 again'
30 hg pull -qr 1 ../repo
35 hg pull -qr 1 ../repo
@@ -1,39 +1,42 b''
1 changeset: 2:effea6de0384
1 changeset: 2:effea6de0384
2 tag: tip
2 tag: tip
3 parent: 0:bbd179dfa0a7
3 parent: 0:bbd179dfa0a7
4 user: test
4 user: test
5 date: Thu Jan 01 00:00:00 1970 +0000
5 date: Thu Jan 01 00:00:00 1970 +0000
6 summary: add bar
6 summary: add bar
7
7
8 changeset: 1:ed1b79f46b9a
8 changeset: 1:ed1b79f46b9a
9 user: test
9 user: test
10 date: Thu Jan 01 00:00:00 1970 +0000
10 date: Thu Jan 01 00:00:00 1970 +0000
11 summary: change foo
11 summary: change foo
12
12
13 changeset: 0:bbd179dfa0a7
13 changeset: 0:bbd179dfa0a7
14 user: test
14 user: test
15 date: Thu Jan 01 00:00:00 1970 +0000
15 date: Thu Jan 01 00:00:00 1970 +0000
16 summary: add foo
16 summary: add foo
17
17
18 % pull a missing revision
18 % pull a missing revision
19 abort: unknown revision 'missing'!
19 abort: unknown revision 'missing'!
20 % pull multiple revisions with update
21 0:bbd179dfa0a7
22 rolling back last transaction
20 % pull -r 0
23 % pull -r 0
21 changeset: 0:bbd179dfa0a7
24 changeset: 0:bbd179dfa0a7
22 tag: tip
25 tag: tip
23 user: test
26 user: test
24 date: Thu Jan 01 00:00:00 1970 +0000
27 date: Thu Jan 01 00:00:00 1970 +0000
25 summary: add foo
28 summary: add foo
26
29
27 % pull -r 1
30 % pull -r 1
28 changeset: 1:ed1b79f46b9a
31 changeset: 1:ed1b79f46b9a
29 tag: tip
32 tag: tip
30 user: test
33 user: test
31 date: Thu Jan 01 00:00:00 1970 +0000
34 date: Thu Jan 01 00:00:00 1970 +0000
32 summary: change foo
35 summary: change foo
33
36
34 changeset: 0:bbd179dfa0a7
37 changeset: 0:bbd179dfa0a7
35 user: test
38 user: test
36 date: Thu Jan 01 00:00:00 1970 +0000
39 date: Thu Jan 01 00:00:00 1970 +0000
37 summary: add foo
40 summary: add foo
38
41
39 % pull -r 1 again
42 % pull -r 1 again
General Comments 0
You need to be logged in to leave comments. Login now