##// END OF EJS Templates
Fix income/pull with bundle and -R (issue 820)....
Peter Arrenbrecht -
r5664:da72b4d2 default
parent child Browse files
Show More
@@ -0,0 +1,84 b''
1 #!/bin/sh
2
3 echo "[extensions]" >> $HGRCPATH
4 echo "mq=" >> $HGRCPATH
5 echo "[defaults]" >> $HGRCPATH
6 echo "log = --template \"{rev}: {desc}\\n\"" >> $HGRCPATH
7 echo "heads = --template \"{rev}: {desc}\\n\"" >> $HGRCPATH
8 echo "incoming = --template \"{rev}: {desc}\\n\"" >> $HGRCPATH
9
10 echo "====== .hgrc"
11 cat $HGRCPATH
12
13 echo "====== Setup main"
14 hg init base
15 cd base
16 echo "One" > one
17 hg add
18 hg ci -m "main: one added."
19 echo "++" >> one
20 hg ci -m "main: one updated."
21
22 echo "====== Bundle main"
23 hg bundle --base=null ../main.hg
24 cd ..
25
26 echo "====== Incoming to fresh repo"
27 hg init fresh
28 echo ">> hg -R fresh incoming main.hg"
29 hg -R fresh incoming main.hg
30 echo ">> hg -R fresh incoming bundle:fresh+main.hg"
31 hg -R fresh incoming bundle:fresh+main.hg
32
33
34 echo "====== Setup queue"
35 cd base
36 hg qinit -c
37 hg qnew -m "patch: two added." two.patch
38 echo two > two
39 hg add
40 hg qrefresh
41 hg qcommit -m "queue: two.patch added."
42 hg qpop -a
43
44 echo "====== Bundle queue"
45 hg -R .hg/patches bundle --base=null ../queue.hgq
46 cd ..
47
48
49 echo "====== Clone base"
50 hg clone base copy
51 cd copy
52 hg qinit -c
53
54 echo "====== Incoming queue bundle"
55 echo ">> hg -R .hg/patches incoming ../queue.hgq"
56 hg -R .hg/patches incoming ../queue.hgq
57
58 echo "====== Pull queue bundle"
59 echo ">> hg -R .hg/patches pull --update ../queue.hgq"
60 hg -R .hg/patches pull --update ../queue.hgq
61 echo ">> hg -R .hg/patches heads"
62 hg -R .hg/patches heads
63 echo ">> hg -R .hg/patches log"
64 hg -R .hg/patches log
65 echo ">> hg qseries"
66 hg qseries
67 cd ..
68
69
70 echo "====== Clone base again"
71 hg clone base copy2
72 cd copy2
73 hg qinit -c
74
75 echo "====== Unbundle queue bundle"
76 echo ">> hg -R .hg/patches unbundle --update ../queue.hgq"
77 hg -R .hg/patches unbundle --update ../queue.hgq
78 echo ">> hg -R .hg/patches heads"
79 hg -R .hg/patches heads
80 echo ">> hg -R .hg/patches log"
81 hg -R .hg/patches log
82 echo ">> hg qseries"
83 hg qseries
84 cd ..
@@ -0,0 +1,68 b''
1 ====== .hgrc
2 [ui]
3 slash = True
4 [defaults]
5 backout = -d "0 0"
6 commit = -d "0 0"
7 debugrawcommit = -d "0 0"
8 tag = -d "0 0"
9 [extensions]
10 mq=
11 [defaults]
12 log = --template "{rev}: {desc}\n"
13 heads = --template "{rev}: {desc}\n"
14 incoming = --template "{rev}: {desc}\n"
15 ====== Setup main
16 adding one
17 ====== Bundle main
18 ====== Incoming to fresh repo
19 >> hg -R fresh incoming main.hg
20 comparing with main.hg
21 0: main: one added.
22 1: main: one updated.
23 >> hg -R fresh incoming bundle:fresh+main.hg
24 comparing with bundle:fresh+main.hg
25 0: main: one added.
26 1: main: one updated.
27 ====== Setup queue
28 adding two
29 Patch queue now empty
30 ====== Bundle queue
31 ====== Clone base
32 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
33 ====== Incoming queue bundle
34 >> hg -R .hg/patches incoming ../queue.hgq
35 comparing with ../queue.hgq
36 0: queue: two.patch added.
37 ====== Pull queue bundle
38 >> hg -R .hg/patches pull --update ../queue.hgq
39 pulling from ../queue.hgq
40 requesting all changes
41 adding changesets
42 adding manifests
43 adding file changes
44 added 1 changesets with 3 changes to 3 files
45 merging series
46 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
47 >> hg -R .hg/patches heads
48 0: queue: two.patch added.
49 >> hg -R .hg/patches log
50 0: queue: two.patch added.
51 >> hg qseries
52 two.patch
53 ====== Clone base again
54 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 ====== Unbundle queue bundle
56 >> hg -R .hg/patches unbundle --update ../queue.hgq
57 adding changesets
58 adding manifests
59 adding file changes
60 added 1 changesets with 3 changes to 3 files
61 merging series
62 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
63 >> hg -R .hg/patches heads
64 0: queue: two.patch added.
65 >> hg -R .hg/patches log
66 0: queue: two.patch added.
67 >> hg qseries
68 two.patch
@@ -1,269 +1,280 b''
1 """
1 """
2 bundlerepo.py - repository class for viewing uncompressed bundles
2 bundlerepo.py - repository class for viewing uncompressed bundles
3
3
4 This provides a read-only repository interface to bundles as if
4 This provides a read-only repository interface to bundles as if
5 they were part of the actual repository.
5 they were part of the actual repository.
6
6
7 Copyright 2006, 2007 Benoit Boissinot <bboissin@gmail.com>
7 Copyright 2006, 2007 Benoit Boissinot <bboissin@gmail.com>
8
8
9 This software may be used and distributed according to the terms
9 This software may be used and distributed according to the terms
10 of the GNU General Public License, incorporated herein by reference.
10 of the GNU General Public License, incorporated herein by reference.
11 """
11 """
12
12
13 from node import *
13 from node import *
14 from i18n import _
14 from i18n import _
15 import changegroup, util, os, struct, bz2, tempfile, mdiff
15 import changegroup, util, os, struct, bz2, tempfile, mdiff
16 import localrepo, changelog, manifest, filelog, revlog
16 import localrepo, changelog, manifest, filelog, revlog
17
17
18 class bundlerevlog(revlog.revlog):
18 class bundlerevlog(revlog.revlog):
19 def __init__(self, opener, indexfile, bundlefile,
19 def __init__(self, opener, indexfile, bundlefile,
20 linkmapper=None):
20 linkmapper=None):
21 # How it works:
21 # How it works:
22 # to retrieve a revision, we need to know the offset of
22 # to retrieve a revision, we need to know the offset of
23 # the revision in the bundlefile (an opened file).
23 # the revision in the bundlefile (an opened file).
24 #
24 #
25 # We store this offset in the index (start), to differentiate a
25 # We store this offset in the index (start), to differentiate a
26 # rev in the bundle and from a rev in the revlog, we check
26 # rev in the bundle and from a rev in the revlog, we check
27 # len(index[r]). If the tuple is bigger than 7, it is a bundle
27 # len(index[r]). If the tuple is bigger than 7, it is a bundle
28 # (it is bigger since we store the node to which the delta is)
28 # (it is bigger since we store the node to which the delta is)
29 #
29 #
30 revlog.revlog.__init__(self, opener, indexfile)
30 revlog.revlog.__init__(self, opener, indexfile)
31 self.bundlefile = bundlefile
31 self.bundlefile = bundlefile
32 self.basemap = {}
32 self.basemap = {}
33 def chunkpositer():
33 def chunkpositer():
34 for chunk in changegroup.chunkiter(bundlefile):
34 for chunk in changegroup.chunkiter(bundlefile):
35 pos = bundlefile.tell()
35 pos = bundlefile.tell()
36 yield chunk, pos - len(chunk)
36 yield chunk, pos - len(chunk)
37 n = self.count()
37 n = self.count()
38 prev = None
38 prev = None
39 for chunk, start in chunkpositer():
39 for chunk, start in chunkpositer():
40 size = len(chunk)
40 size = len(chunk)
41 if size < 80:
41 if size < 80:
42 raise util.Abort("invalid changegroup")
42 raise util.Abort("invalid changegroup")
43 start += 80
43 start += 80
44 size -= 80
44 size -= 80
45 node, p1, p2, cs = struct.unpack("20s20s20s20s", chunk[:80])
45 node, p1, p2, cs = struct.unpack("20s20s20s20s", chunk[:80])
46 if node in self.nodemap:
46 if node in self.nodemap:
47 prev = node
47 prev = node
48 continue
48 continue
49 for p in (p1, p2):
49 for p in (p1, p2):
50 if not p in self.nodemap:
50 if not p in self.nodemap:
51 raise revlog.LookupError(hex(p1), _("unknown parent %s") % short(p1))
51 raise revlog.LookupError(hex(p1), _("unknown parent %s") % short(p1))
52 if linkmapper is None:
52 if linkmapper is None:
53 link = n
53 link = n
54 else:
54 else:
55 link = linkmapper(cs)
55 link = linkmapper(cs)
56
56
57 if not prev:
57 if not prev:
58 prev = p1
58 prev = p1
59 # start, size, full unc. size, base (unused), link, p1, p2, node
59 # start, size, full unc. size, base (unused), link, p1, p2, node
60 e = (revlog.offset_type(start, 0), size, -1, -1, link,
60 e = (revlog.offset_type(start, 0), size, -1, -1, link,
61 self.rev(p1), self.rev(p2), node)
61 self.rev(p1), self.rev(p2), node)
62 self.basemap[n] = prev
62 self.basemap[n] = prev
63 self.index.insert(-1, e)
63 self.index.insert(-1, e)
64 self.nodemap[node] = n
64 self.nodemap[node] = n
65 prev = node
65 prev = node
66 n += 1
66 n += 1
67
67
68 def bundle(self, rev):
68 def bundle(self, rev):
69 """is rev from the bundle"""
69 """is rev from the bundle"""
70 if rev < 0:
70 if rev < 0:
71 return False
71 return False
72 return rev in self.basemap
72 return rev in self.basemap
73 def bundlebase(self, rev): return self.basemap[rev]
73 def bundlebase(self, rev): return self.basemap[rev]
74 def chunk(self, rev, df=None, cachelen=4096):
74 def chunk(self, rev, df=None, cachelen=4096):
75 # Warning: in case of bundle, the diff is against bundlebase,
75 # Warning: in case of bundle, the diff is against bundlebase,
76 # not against rev - 1
76 # not against rev - 1
77 # XXX: could use some caching
77 # XXX: could use some caching
78 if not self.bundle(rev):
78 if not self.bundle(rev):
79 return revlog.revlog.chunk(self, rev, df)
79 return revlog.revlog.chunk(self, rev, df)
80 self.bundlefile.seek(self.start(rev))
80 self.bundlefile.seek(self.start(rev))
81 return self.bundlefile.read(self.length(rev))
81 return self.bundlefile.read(self.length(rev))
82
82
83 def revdiff(self, rev1, rev2):
83 def revdiff(self, rev1, rev2):
84 """return or calculate a delta between two revisions"""
84 """return or calculate a delta between two revisions"""
85 if self.bundle(rev1) and self.bundle(rev2):
85 if self.bundle(rev1) and self.bundle(rev2):
86 # hot path for bundle
86 # hot path for bundle
87 revb = self.rev(self.bundlebase(rev2))
87 revb = self.rev(self.bundlebase(rev2))
88 if revb == rev1:
88 if revb == rev1:
89 return self.chunk(rev2)
89 return self.chunk(rev2)
90 elif not self.bundle(rev1) and not self.bundle(rev2):
90 elif not self.bundle(rev1) and not self.bundle(rev2):
91 return revlog.revlog.revdiff(self, rev1, rev2)
91 return revlog.revlog.revdiff(self, rev1, rev2)
92
92
93 return mdiff.textdiff(self.revision(self.node(rev1)),
93 return mdiff.textdiff(self.revision(self.node(rev1)),
94 self.revision(self.node(rev2)))
94 self.revision(self.node(rev2)))
95
95
96 def revision(self, node):
96 def revision(self, node):
97 """return an uncompressed revision of a given"""
97 """return an uncompressed revision of a given"""
98 if node == nullid: return ""
98 if node == nullid: return ""
99
99
100 text = None
100 text = None
101 chain = []
101 chain = []
102 iter_node = node
102 iter_node = node
103 rev = self.rev(iter_node)
103 rev = self.rev(iter_node)
104 # reconstruct the revision if it is from a changegroup
104 # reconstruct the revision if it is from a changegroup
105 while self.bundle(rev):
105 while self.bundle(rev):
106 if self._cache and self._cache[0] == iter_node:
106 if self._cache and self._cache[0] == iter_node:
107 text = self._cache[2]
107 text = self._cache[2]
108 break
108 break
109 chain.append(rev)
109 chain.append(rev)
110 iter_node = self.bundlebase(rev)
110 iter_node = self.bundlebase(rev)
111 rev = self.rev(iter_node)
111 rev = self.rev(iter_node)
112 if text is None:
112 if text is None:
113 text = revlog.revlog.revision(self, iter_node)
113 text = revlog.revlog.revision(self, iter_node)
114
114
115 while chain:
115 while chain:
116 delta = self.chunk(chain.pop())
116 delta = self.chunk(chain.pop())
117 text = mdiff.patches(text, [delta])
117 text = mdiff.patches(text, [delta])
118
118
119 p1, p2 = self.parents(node)
119 p1, p2 = self.parents(node)
120 if node != revlog.hash(text, p1, p2):
120 if node != revlog.hash(text, p1, p2):
121 raise revlog.RevlogError(_("integrity check failed on %s:%d")
121 raise revlog.RevlogError(_("integrity check failed on %s:%d")
122 % (self.datafile, self.rev(node)))
122 % (self.datafile, self.rev(node)))
123
123
124 self._cache = (node, self.rev(node), text)
124 self._cache = (node, self.rev(node), text)
125 return text
125 return text
126
126
127 def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
127 def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
128 raise NotImplementedError
128 raise NotImplementedError
129 def addgroup(self, revs, linkmapper, transaction, unique=0):
129 def addgroup(self, revs, linkmapper, transaction, unique=0):
130 raise NotImplementedError
130 raise NotImplementedError
131 def strip(self, rev, minlink):
131 def strip(self, rev, minlink):
132 raise NotImplementedError
132 raise NotImplementedError
133 def checksize(self):
133 def checksize(self):
134 raise NotImplementedError
134 raise NotImplementedError
135
135
136 class bundlechangelog(bundlerevlog, changelog.changelog):
136 class bundlechangelog(bundlerevlog, changelog.changelog):
137 def __init__(self, opener, bundlefile):
137 def __init__(self, opener, bundlefile):
138 changelog.changelog.__init__(self, opener)
138 changelog.changelog.__init__(self, opener)
139 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile)
139 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile)
140
140
141 class bundlemanifest(bundlerevlog, manifest.manifest):
141 class bundlemanifest(bundlerevlog, manifest.manifest):
142 def __init__(self, opener, bundlefile, linkmapper):
142 def __init__(self, opener, bundlefile, linkmapper):
143 manifest.manifest.__init__(self, opener)
143 manifest.manifest.__init__(self, opener)
144 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile,
144 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile,
145 linkmapper)
145 linkmapper)
146
146
147 class bundlefilelog(bundlerevlog, filelog.filelog):
147 class bundlefilelog(bundlerevlog, filelog.filelog):
148 def __init__(self, opener, path, bundlefile, linkmapper):
148 def __init__(self, opener, path, bundlefile, linkmapper):
149 filelog.filelog.__init__(self, opener, path)
149 filelog.filelog.__init__(self, opener, path)
150 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile,
150 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile,
151 linkmapper)
151 linkmapper)
152
152
153 class bundlerepository(localrepo.localrepository):
153 class bundlerepository(localrepo.localrepository):
154 def __init__(self, ui, path, bundlename):
154 def __init__(self, ui, path, bundlename):
155 localrepo.localrepository.__init__(self, ui, path)
155 localrepo.localrepository.__init__(self, ui, path)
156
156
157 self._url = 'bundle:' + bundlename
157 self._url = 'bundle:' + bundlename
158 if path: self._url += '+' + path
158 if path: self._url += '+' + path
159
159
160 self.tempfile = None
160 self.tempfile = None
161 self.bundlefile = open(bundlename, "rb")
161 self.bundlefile = open(bundlename, "rb")
162 header = self.bundlefile.read(6)
162 header = self.bundlefile.read(6)
163 if not header.startswith("HG"):
163 if not header.startswith("HG"):
164 raise util.Abort(_("%s: not a Mercurial bundle file") % bundlename)
164 raise util.Abort(_("%s: not a Mercurial bundle file") % bundlename)
165 elif not header.startswith("HG10"):
165 elif not header.startswith("HG10"):
166 raise util.Abort(_("%s: unknown bundle version") % bundlename)
166 raise util.Abort(_("%s: unknown bundle version") % bundlename)
167 elif header == "HG10BZ":
167 elif header == "HG10BZ":
168 fdtemp, temp = tempfile.mkstemp(prefix="hg-bundle-",
168 fdtemp, temp = tempfile.mkstemp(prefix="hg-bundle-",
169 suffix=".hg10un", dir=self.path)
169 suffix=".hg10un", dir=self.path)
170 self.tempfile = temp
170 self.tempfile = temp
171 fptemp = os.fdopen(fdtemp, 'wb')
171 fptemp = os.fdopen(fdtemp, 'wb')
172 def generator(f):
172 def generator(f):
173 zd = bz2.BZ2Decompressor()
173 zd = bz2.BZ2Decompressor()
174 zd.decompress("BZ")
174 zd.decompress("BZ")
175 for chunk in f:
175 for chunk in f:
176 yield zd.decompress(chunk)
176 yield zd.decompress(chunk)
177 gen = generator(util.filechunkiter(self.bundlefile, 4096))
177 gen = generator(util.filechunkiter(self.bundlefile, 4096))
178
178
179 try:
179 try:
180 fptemp.write("HG10UN")
180 fptemp.write("HG10UN")
181 for chunk in gen:
181 for chunk in gen:
182 fptemp.write(chunk)
182 fptemp.write(chunk)
183 finally:
183 finally:
184 fptemp.close()
184 fptemp.close()
185 self.bundlefile.close()
185 self.bundlefile.close()
186
186
187 self.bundlefile = open(self.tempfile, "rb")
187 self.bundlefile = open(self.tempfile, "rb")
188 # seek right after the header
188 # seek right after the header
189 self.bundlefile.seek(6)
189 self.bundlefile.seek(6)
190 elif header == "HG10UN":
190 elif header == "HG10UN":
191 # nothing to do
191 # nothing to do
192 pass
192 pass
193 else:
193 else:
194 raise util.Abort(_("%s: unknown bundle compression type")
194 raise util.Abort(_("%s: unknown bundle compression type")
195 % bundlename)
195 % bundlename)
196 # dict with the mapping 'filename' -> position in the bundle
196 # dict with the mapping 'filename' -> position in the bundle
197 self.bundlefilespos = {}
197 self.bundlefilespos = {}
198
198
199 def __getattr__(self, name):
199 def __getattr__(self, name):
200 if name == 'changelog':
200 if name == 'changelog':
201 self.changelog = bundlechangelog(self.sopener, self.bundlefile)
201 self.changelog = bundlechangelog(self.sopener, self.bundlefile)
202 self.manstart = self.bundlefile.tell()
202 self.manstart = self.bundlefile.tell()
203 return self.changelog
203 return self.changelog
204 if name == 'manifest':
204 if name == 'manifest':
205 self.bundlefile.seek(self.manstart)
205 self.bundlefile.seek(self.manstart)
206 self.manifest = bundlemanifest(self.sopener, self.bundlefile,
206 self.manifest = bundlemanifest(self.sopener, self.bundlefile,
207 self.changelog.rev)
207 self.changelog.rev)
208 self.filestart = self.bundlefile.tell()
208 self.filestart = self.bundlefile.tell()
209 return self.manifest
209 return self.manifest
210 if name == 'manstart':
210 if name == 'manstart':
211 self.changelog
211 self.changelog
212 return self.manstart
212 return self.manstart
213 if name == 'filestart':
213 if name == 'filestart':
214 self.manifest
214 self.manifest
215 return self.filestart
215 return self.filestart
216 return localrepo.localrepository.__getattr__(self, name)
216 return localrepo.localrepository.__getattr__(self, name)
217
217
218 def url(self):
218 def url(self):
219 return self._url
219 return self._url
220
220
221 def dev(self):
221 def dev(self):
222 return -1
222 return -1
223
223
224 def file(self, f):
224 def file(self, f):
225 if not self.bundlefilespos:
225 if not self.bundlefilespos:
226 self.bundlefile.seek(self.filestart)
226 self.bundlefile.seek(self.filestart)
227 while 1:
227 while 1:
228 chunk = changegroup.getchunk(self.bundlefile)
228 chunk = changegroup.getchunk(self.bundlefile)
229 if not chunk:
229 if not chunk:
230 break
230 break
231 self.bundlefilespos[chunk] = self.bundlefile.tell()
231 self.bundlefilespos[chunk] = self.bundlefile.tell()
232 for c in changegroup.chunkiter(self.bundlefile):
232 for c in changegroup.chunkiter(self.bundlefile):
233 pass
233 pass
234
234
235 if f[0] == '/':
235 if f[0] == '/':
236 f = f[1:]
236 f = f[1:]
237 if f in self.bundlefilespos:
237 if f in self.bundlefilespos:
238 self.bundlefile.seek(self.bundlefilespos[f])
238 self.bundlefile.seek(self.bundlefilespos[f])
239 return bundlefilelog(self.sopener, f, self.bundlefile,
239 return bundlefilelog(self.sopener, f, self.bundlefile,
240 self.changelog.rev)
240 self.changelog.rev)
241 else:
241 else:
242 return filelog.filelog(self.sopener, f)
242 return filelog.filelog(self.sopener, f)
243
243
244 def close(self):
244 def close(self):
245 """Close assigned bundle file immediately."""
245 """Close assigned bundle file immediately."""
246 self.bundlefile.close()
246 self.bundlefile.close()
247
247
248 def __del__(self):
248 def __del__(self):
249 bundlefile = getattr(self, 'bundlefile', None)
249 bundlefile = getattr(self, 'bundlefile', None)
250 if bundlefile and not bundlefile.closed:
250 if bundlefile and not bundlefile.closed:
251 bundlefile.close()
251 bundlefile.close()
252 tempfile = getattr(self, 'tempfile', None)
252 tempfile = getattr(self, 'tempfile', None)
253 if tempfile is not None:
253 if tempfile is not None:
254 os.unlink(tempfile)
254 os.unlink(tempfile)
255
255
256 def instance(ui, path, create):
256 def instance(ui, path, create):
257 if create:
257 if create:
258 raise util.Abort(_('cannot create new bundle repository'))
258 raise util.Abort(_('cannot create new bundle repository'))
259 parentpath = ui.config("bundle", "mainreporoot", "")
260 if parentpath:
261 # Try to make the full path relative so we get a nice, short URL.
262 # In particular, we don't want temp dir names in test outputs.
263 cwd = os.getcwd()
264 if parentpath == cwd:
265 parentpath = ''
266 else:
267 cwd = os.path.join(cwd,'')
268 if parentpath.startswith(cwd):
269 parentpath = parentpath[len(cwd):]
259 path = util.drop_scheme('file', path)
270 path = util.drop_scheme('file', path)
260 if path.startswith('bundle:'):
271 if path.startswith('bundle:'):
261 path = util.drop_scheme('bundle', path)
272 path = util.drop_scheme('bundle', path)
262 s = path.split("+", 1)
273 s = path.split("+", 1)
263 if len(s) == 1:
274 if len(s) == 1:
264 repopath, bundlename = "", s[0]
275 repopath, bundlename = parentpath, s[0]
265 else:
276 else:
266 repopath, bundlename = s
277 repopath, bundlename = s
267 else:
278 else:
268 repopath, bundlename = '', path
279 repopath, bundlename = parentpath, path
269 return bundlerepository(ui, repopath, bundlename)
280 return bundlerepository(ui, repopath, bundlename)
@@ -1,403 +1,404 b''
1 # dispatch.py - command dispatching for mercurial
1 # dispatch.py - command dispatching for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 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 i18n import _
9 from i18n import _
10 import os, sys, atexit, signal, pdb, traceback, socket, errno, shlex, time
10 import os, sys, atexit, signal, pdb, traceback, socket, errno, shlex, time
11 import util, commands, hg, lock, fancyopts, revlog, version, extensions, hook
11 import util, commands, hg, lock, fancyopts, revlog, version, extensions, hook
12 import cmdutil
12 import cmdutil
13 import ui as _ui
13 import ui as _ui
14
14
15 class ParseError(Exception):
15 class ParseError(Exception):
16 """Exception raised on errors in parsing the command line."""
16 """Exception raised on errors in parsing the command line."""
17
17
18 def run():
18 def run():
19 "run the command in sys.argv"
19 "run the command in sys.argv"
20 sys.exit(dispatch(sys.argv[1:]))
20 sys.exit(dispatch(sys.argv[1:]))
21
21
22 def dispatch(args):
22 def dispatch(args):
23 "run the command specified in args"
23 "run the command specified in args"
24 try:
24 try:
25 u = _ui.ui(traceback='--traceback' in args)
25 u = _ui.ui(traceback='--traceback' in args)
26 except util.Abort, inst:
26 except util.Abort, inst:
27 sys.stderr.write(_("abort: %s\n") % inst)
27 sys.stderr.write(_("abort: %s\n") % inst)
28 return -1
28 return -1
29 return _runcatch(u, args)
29 return _runcatch(u, args)
30
30
31 def _runcatch(ui, args):
31 def _runcatch(ui, args):
32 def catchterm(*args):
32 def catchterm(*args):
33 raise util.SignalInterrupt
33 raise util.SignalInterrupt
34
34
35 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
35 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
36 num = getattr(signal, name, None)
36 num = getattr(signal, name, None)
37 if num: signal.signal(num, catchterm)
37 if num: signal.signal(num, catchterm)
38
38
39 try:
39 try:
40 try:
40 try:
41 # enter the debugger before command execution
41 # enter the debugger before command execution
42 if '--debugger' in args:
42 if '--debugger' in args:
43 pdb.set_trace()
43 pdb.set_trace()
44 try:
44 try:
45 return _dispatch(ui, args)
45 return _dispatch(ui, args)
46 finally:
46 finally:
47 ui.flush()
47 ui.flush()
48 except:
48 except:
49 # enter the debugger when we hit an exception
49 # enter the debugger when we hit an exception
50 if '--debugger' in args:
50 if '--debugger' in args:
51 pdb.post_mortem(sys.exc_info()[2])
51 pdb.post_mortem(sys.exc_info()[2])
52 ui.print_exc()
52 ui.print_exc()
53 raise
53 raise
54
54
55 except ParseError, inst:
55 except ParseError, inst:
56 if inst.args[0]:
56 if inst.args[0]:
57 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
57 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
58 commands.help_(ui, inst.args[0])
58 commands.help_(ui, inst.args[0])
59 else:
59 else:
60 ui.warn(_("hg: %s\n") % inst.args[1])
60 ui.warn(_("hg: %s\n") % inst.args[1])
61 commands.help_(ui, 'shortlist')
61 commands.help_(ui, 'shortlist')
62 except cmdutil.AmbiguousCommand, inst:
62 except cmdutil.AmbiguousCommand, inst:
63 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
63 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
64 (inst.args[0], " ".join(inst.args[1])))
64 (inst.args[0], " ".join(inst.args[1])))
65 except cmdutil.UnknownCommand, inst:
65 except cmdutil.UnknownCommand, inst:
66 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
66 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
67 commands.help_(ui, 'shortlist')
67 commands.help_(ui, 'shortlist')
68 except hg.RepoError, inst:
68 except hg.RepoError, inst:
69 ui.warn(_("abort: %s!\n") % inst)
69 ui.warn(_("abort: %s!\n") % inst)
70 except lock.LockHeld, inst:
70 except lock.LockHeld, inst:
71 if inst.errno == errno.ETIMEDOUT:
71 if inst.errno == errno.ETIMEDOUT:
72 reason = _('timed out waiting for lock held by %s') % inst.locker
72 reason = _('timed out waiting for lock held by %s') % inst.locker
73 else:
73 else:
74 reason = _('lock held by %s') % inst.locker
74 reason = _('lock held by %s') % inst.locker
75 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
75 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
76 except lock.LockUnavailable, inst:
76 except lock.LockUnavailable, inst:
77 ui.warn(_("abort: could not lock %s: %s\n") %
77 ui.warn(_("abort: could not lock %s: %s\n") %
78 (inst.desc or inst.filename, inst.strerror))
78 (inst.desc or inst.filename, inst.strerror))
79 except revlog.RevlogError, inst:
79 except revlog.RevlogError, inst:
80 ui.warn(_("abort: %s!\n") % inst)
80 ui.warn(_("abort: %s!\n") % inst)
81 except util.SignalInterrupt:
81 except util.SignalInterrupt:
82 ui.warn(_("killed!\n"))
82 ui.warn(_("killed!\n"))
83 except KeyboardInterrupt:
83 except KeyboardInterrupt:
84 try:
84 try:
85 ui.warn(_("interrupted!\n"))
85 ui.warn(_("interrupted!\n"))
86 except IOError, inst:
86 except IOError, inst:
87 if inst.errno == errno.EPIPE:
87 if inst.errno == errno.EPIPE:
88 if ui.debugflag:
88 if ui.debugflag:
89 ui.warn(_("\nbroken pipe\n"))
89 ui.warn(_("\nbroken pipe\n"))
90 else:
90 else:
91 raise
91 raise
92 except socket.error, inst:
92 except socket.error, inst:
93 ui.warn(_("abort: %s\n") % inst[1])
93 ui.warn(_("abort: %s\n") % inst[1])
94 except IOError, inst:
94 except IOError, inst:
95 if hasattr(inst, "code"):
95 if hasattr(inst, "code"):
96 ui.warn(_("abort: %s\n") % inst)
96 ui.warn(_("abort: %s\n") % inst)
97 elif hasattr(inst, "reason"):
97 elif hasattr(inst, "reason"):
98 try: # usually it is in the form (errno, strerror)
98 try: # usually it is in the form (errno, strerror)
99 reason = inst.reason.args[1]
99 reason = inst.reason.args[1]
100 except: # it might be anything, for example a string
100 except: # it might be anything, for example a string
101 reason = inst.reason
101 reason = inst.reason
102 ui.warn(_("abort: error: %s\n") % reason)
102 ui.warn(_("abort: error: %s\n") % reason)
103 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
103 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
104 if ui.debugflag:
104 if ui.debugflag:
105 ui.warn(_("broken pipe\n"))
105 ui.warn(_("broken pipe\n"))
106 elif getattr(inst, "strerror", None):
106 elif getattr(inst, "strerror", None):
107 if getattr(inst, "filename", None):
107 if getattr(inst, "filename", None):
108 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
108 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
109 else:
109 else:
110 ui.warn(_("abort: %s\n") % inst.strerror)
110 ui.warn(_("abort: %s\n") % inst.strerror)
111 else:
111 else:
112 raise
112 raise
113 except OSError, inst:
113 except OSError, inst:
114 if getattr(inst, "filename", None):
114 if getattr(inst, "filename", None):
115 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
115 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
116 else:
116 else:
117 ui.warn(_("abort: %s\n") % inst.strerror)
117 ui.warn(_("abort: %s\n") % inst.strerror)
118 except util.UnexpectedOutput, inst:
118 except util.UnexpectedOutput, inst:
119 ui.warn(_("abort: %s") % inst[0])
119 ui.warn(_("abort: %s") % inst[0])
120 if not isinstance(inst[1], basestring):
120 if not isinstance(inst[1], basestring):
121 ui.warn(" %r\n" % (inst[1],))
121 ui.warn(" %r\n" % (inst[1],))
122 elif not inst[1]:
122 elif not inst[1]:
123 ui.warn(_(" empty string\n"))
123 ui.warn(_(" empty string\n"))
124 else:
124 else:
125 ui.warn("\n%r\n" % util.ellipsis(inst[1]))
125 ui.warn("\n%r\n" % util.ellipsis(inst[1]))
126 except ImportError, inst:
126 except ImportError, inst:
127 m = str(inst).split()[-1]
127 m = str(inst).split()[-1]
128 ui.warn(_("abort: could not import module %s!\n") % m)
128 ui.warn(_("abort: could not import module %s!\n") % m)
129 if m in "mpatch bdiff".split():
129 if m in "mpatch bdiff".split():
130 ui.warn(_("(did you forget to compile extensions?)\n"))
130 ui.warn(_("(did you forget to compile extensions?)\n"))
131 elif m in "zlib".split():
131 elif m in "zlib".split():
132 ui.warn(_("(is your Python install correct?)\n"))
132 ui.warn(_("(is your Python install correct?)\n"))
133
133
134 except util.Abort, inst:
134 except util.Abort, inst:
135 ui.warn(_("abort: %s\n") % inst)
135 ui.warn(_("abort: %s\n") % inst)
136 except MemoryError:
136 except MemoryError:
137 ui.warn(_("abort: out of memory\n"))
137 ui.warn(_("abort: out of memory\n"))
138 except SystemExit, inst:
138 except SystemExit, inst:
139 # Commands shouldn't sys.exit directly, but give a return code.
139 # Commands shouldn't sys.exit directly, but give a return code.
140 # Just in case catch this and and pass exit code to caller.
140 # Just in case catch this and and pass exit code to caller.
141 return inst.code
141 return inst.code
142 except:
142 except:
143 ui.warn(_("** unknown exception encountered, details follow\n"))
143 ui.warn(_("** unknown exception encountered, details follow\n"))
144 ui.warn(_("** report bug details to "
144 ui.warn(_("** report bug details to "
145 "http://www.selenic.com/mercurial/bts\n"))
145 "http://www.selenic.com/mercurial/bts\n"))
146 ui.warn(_("** or mercurial@selenic.com\n"))
146 ui.warn(_("** or mercurial@selenic.com\n"))
147 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
147 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
148 % version.get_version())
148 % version.get_version())
149 raise
149 raise
150
150
151 return -1
151 return -1
152
152
153 def _findrepo():
153 def _findrepo():
154 p = os.getcwd()
154 p = os.getcwd()
155 while not os.path.isdir(os.path.join(p, ".hg")):
155 while not os.path.isdir(os.path.join(p, ".hg")):
156 oldp, p = p, os.path.dirname(p)
156 oldp, p = p, os.path.dirname(p)
157 if p == oldp:
157 if p == oldp:
158 return None
158 return None
159
159
160 return p
160 return p
161
161
162 def _parse(ui, args):
162 def _parse(ui, args):
163 options = {}
163 options = {}
164 cmdoptions = {}
164 cmdoptions = {}
165
165
166 try:
166 try:
167 args = fancyopts.fancyopts(args, commands.globalopts, options)
167 args = fancyopts.fancyopts(args, commands.globalopts, options)
168 except fancyopts.getopt.GetoptError, inst:
168 except fancyopts.getopt.GetoptError, inst:
169 raise ParseError(None, inst)
169 raise ParseError(None, inst)
170
170
171 if args:
171 if args:
172 cmd, args = args[0], args[1:]
172 cmd, args = args[0], args[1:]
173 aliases, i = cmdutil.findcmd(ui, cmd, commands.table)
173 aliases, i = cmdutil.findcmd(ui, cmd, commands.table)
174 cmd = aliases[0]
174 cmd = aliases[0]
175 defaults = ui.config("defaults", cmd)
175 defaults = ui.config("defaults", cmd)
176 if defaults:
176 if defaults:
177 args = shlex.split(defaults) + args
177 args = shlex.split(defaults) + args
178 c = list(i[1])
178 c = list(i[1])
179 else:
179 else:
180 cmd = None
180 cmd = None
181 c = []
181 c = []
182
182
183 # combine global options into local
183 # combine global options into local
184 for o in commands.globalopts:
184 for o in commands.globalopts:
185 c.append((o[0], o[1], options[o[1]], o[3]))
185 c.append((o[0], o[1], options[o[1]], o[3]))
186
186
187 try:
187 try:
188 args = fancyopts.fancyopts(args, c, cmdoptions)
188 args = fancyopts.fancyopts(args, c, cmdoptions)
189 except fancyopts.getopt.GetoptError, inst:
189 except fancyopts.getopt.GetoptError, inst:
190 raise ParseError(cmd, inst)
190 raise ParseError(cmd, inst)
191
191
192 # separate global options back out
192 # separate global options back out
193 for o in commands.globalopts:
193 for o in commands.globalopts:
194 n = o[1]
194 n = o[1]
195 options[n] = cmdoptions[n]
195 options[n] = cmdoptions[n]
196 del cmdoptions[n]
196 del cmdoptions[n]
197
197
198 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
198 return (cmd, cmd and i[0] or None, args, options, cmdoptions)
199
199
200 def _parseconfig(config):
200 def _parseconfig(config):
201 """parse the --config options from the command line"""
201 """parse the --config options from the command line"""
202 parsed = []
202 parsed = []
203 for cfg in config:
203 for cfg in config:
204 try:
204 try:
205 name, value = cfg.split('=', 1)
205 name, value = cfg.split('=', 1)
206 section, name = name.split('.', 1)
206 section, name = name.split('.', 1)
207 if not section or not name:
207 if not section or not name:
208 raise IndexError
208 raise IndexError
209 parsed.append((section, name, value))
209 parsed.append((section, name, value))
210 except (IndexError, ValueError):
210 except (IndexError, ValueError):
211 raise util.Abort(_('malformed --config option: %s') % cfg)
211 raise util.Abort(_('malformed --config option: %s') % cfg)
212 return parsed
212 return parsed
213
213
214 def _earlygetopt(aliases, args):
214 def _earlygetopt(aliases, args):
215 """Return list of values for an option (or aliases).
215 """Return list of values for an option (or aliases).
216
216
217 The values are listed in the order they appear in args.
217 The values are listed in the order they appear in args.
218 The options and values are removed from args.
218 The options and values are removed from args.
219 """
219 """
220 try:
220 try:
221 argcount = args.index("--")
221 argcount = args.index("--")
222 except ValueError:
222 except ValueError:
223 argcount = len(args)
223 argcount = len(args)
224 shortopts = [opt for opt in aliases if len(opt) == 2]
224 shortopts = [opt for opt in aliases if len(opt) == 2]
225 values = []
225 values = []
226 pos = 0
226 pos = 0
227 while pos < argcount:
227 while pos < argcount:
228 if args[pos] in aliases:
228 if args[pos] in aliases:
229 if pos + 1 >= argcount:
229 if pos + 1 >= argcount:
230 # ignore and let getopt report an error if there is no value
230 # ignore and let getopt report an error if there is no value
231 break
231 break
232 del args[pos]
232 del args[pos]
233 values.append(args.pop(pos))
233 values.append(args.pop(pos))
234 argcount -= 2
234 argcount -= 2
235 elif args[pos][:2] in shortopts:
235 elif args[pos][:2] in shortopts:
236 # short option can have no following space, e.g. hg log -Rfoo
236 # short option can have no following space, e.g. hg log -Rfoo
237 values.append(args.pop(pos)[2:])
237 values.append(args.pop(pos)[2:])
238 argcount -= 1
238 argcount -= 1
239 else:
239 else:
240 pos += 1
240 pos += 1
241 return values
241 return values
242
242
243 _loaded = {}
243 _loaded = {}
244 def _dispatch(ui, args):
244 def _dispatch(ui, args):
245 # read --config before doing anything else
245 # read --config before doing anything else
246 # (e.g. to change trust settings for reading .hg/hgrc)
246 # (e.g. to change trust settings for reading .hg/hgrc)
247 config = _earlygetopt(['--config'], args)
247 config = _earlygetopt(['--config'], args)
248 if config:
248 if config:
249 ui.updateopts(config=_parseconfig(config))
249 ui.updateopts(config=_parseconfig(config))
250
250
251 # check for cwd
251 # check for cwd
252 cwd = _earlygetopt(['--cwd'], args)
252 cwd = _earlygetopt(['--cwd'], args)
253 if cwd:
253 if cwd:
254 os.chdir(cwd[-1])
254 os.chdir(cwd[-1])
255
255
256 # read the local repository .hgrc into a local ui object
256 # read the local repository .hgrc into a local ui object
257 path = _findrepo() or ""
257 path = _findrepo() or ""
258 if not path:
258 if not path:
259 lui = ui
259 lui = ui
260 if path:
260 if path:
261 try:
261 try:
262 lui = _ui.ui(parentui=ui)
262 lui = _ui.ui(parentui=ui)
263 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
263 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
264 except IOError:
264 except IOError:
265 pass
265 pass
266
266
267 # now we can expand paths, even ones in .hg/hgrc
267 # now we can expand paths, even ones in .hg/hgrc
268 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
268 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
269 if rpath:
269 if rpath:
270 path = lui.expandpath(rpath[-1])
270 path = lui.expandpath(rpath[-1])
271 lui = _ui.ui(parentui=ui)
271 lui = _ui.ui(parentui=ui)
272 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
272 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
273
273
274 extensions.loadall(lui)
274 extensions.loadall(lui)
275 for name, module in extensions.extensions():
275 for name, module in extensions.extensions():
276 if name in _loaded:
276 if name in _loaded:
277 continue
277 continue
278 cmdtable = getattr(module, 'cmdtable', {})
278 cmdtable = getattr(module, 'cmdtable', {})
279 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
279 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
280 if overrides:
280 if overrides:
281 ui.warn(_("extension '%s' overrides commands: %s\n")
281 ui.warn(_("extension '%s' overrides commands: %s\n")
282 % (name, " ".join(overrides)))
282 % (name, " ".join(overrides)))
283 commands.table.update(cmdtable)
283 commands.table.update(cmdtable)
284 _loaded[name] = 1
284 _loaded[name] = 1
285 # check for fallback encoding
285 # check for fallback encoding
286 fallback = lui.config('ui', 'fallbackencoding')
286 fallback = lui.config('ui', 'fallbackencoding')
287 if fallback:
287 if fallback:
288 util._fallbackencoding = fallback
288 util._fallbackencoding = fallback
289
289
290 fullargs = args
290 fullargs = args
291 cmd, func, args, options, cmdoptions = _parse(lui, args)
291 cmd, func, args, options, cmdoptions = _parse(lui, args)
292
292
293 if options["config"]:
293 if options["config"]:
294 raise util.Abort(_("Option --config may not be abbreviated!"))
294 raise util.Abort(_("Option --config may not be abbreviated!"))
295 if options["cwd"]:
295 if options["cwd"]:
296 raise util.Abort(_("Option --cwd may not be abbreviated!"))
296 raise util.Abort(_("Option --cwd may not be abbreviated!"))
297 if options["repository"]:
297 if options["repository"]:
298 raise util.Abort(_(
298 raise util.Abort(_(
299 "Option -R has to be separated from other options (i.e. not -qR) "
299 "Option -R has to be separated from other options (i.e. not -qR) "
300 "and --repository may only be abbreviated as --repo!"))
300 "and --repository may only be abbreviated as --repo!"))
301
301
302 if options["encoding"]:
302 if options["encoding"]:
303 util._encoding = options["encoding"]
303 util._encoding = options["encoding"]
304 if options["encodingmode"]:
304 if options["encodingmode"]:
305 util._encodingmode = options["encodingmode"]
305 util._encodingmode = options["encodingmode"]
306 if options["time"]:
306 if options["time"]:
307 def get_times():
307 def get_times():
308 t = os.times()
308 t = os.times()
309 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
309 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
310 t = (t[0], t[1], t[2], t[3], time.clock())
310 t = (t[0], t[1], t[2], t[3], time.clock())
311 return t
311 return t
312 s = get_times()
312 s = get_times()
313 def print_time():
313 def print_time():
314 t = get_times()
314 t = get_times()
315 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
315 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
316 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
316 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
317 atexit.register(print_time)
317 atexit.register(print_time)
318
318
319 ui.updateopts(options["verbose"], options["debug"], options["quiet"],
319 ui.updateopts(options["verbose"], options["debug"], options["quiet"],
320 not options["noninteractive"], options["traceback"])
320 not options["noninteractive"], options["traceback"])
321
321
322 if options['help']:
322 if options['help']:
323 return commands.help_(ui, cmd, options['version'])
323 return commands.help_(ui, cmd, options['version'])
324 elif options['version']:
324 elif options['version']:
325 return commands.version_(ui)
325 return commands.version_(ui)
326 elif not cmd:
326 elif not cmd:
327 return commands.help_(ui, 'shortlist')
327 return commands.help_(ui, 'shortlist')
328
328
329 repo = None
329 repo = None
330 if cmd not in commands.norepo.split():
330 if cmd not in commands.norepo.split():
331 try:
331 try:
332 repo = hg.repository(ui, path=path)
332 repo = hg.repository(ui, path=path)
333 ui = repo.ui
333 ui = repo.ui
334 ui.setconfig("bundle", "mainreporoot", repo.root)
334 if not repo.local():
335 if not repo.local():
335 raise util.Abort(_("repository '%s' is not local") % path)
336 raise util.Abort(_("repository '%s' is not local") % path)
336 except hg.RepoError:
337 except hg.RepoError:
337 if cmd not in commands.optionalrepo.split():
338 if cmd not in commands.optionalrepo.split():
338 if not path:
339 if not path:
339 raise hg.RepoError(_("There is no Mercurial repository here"
340 raise hg.RepoError(_("There is no Mercurial repository here"
340 " (.hg not found)"))
341 " (.hg not found)"))
341 raise
342 raise
342 d = lambda: func(ui, repo, *args, **cmdoptions)
343 d = lambda: func(ui, repo, *args, **cmdoptions)
343 else:
344 else:
344 d = lambda: func(ui, *args, **cmdoptions)
345 d = lambda: func(ui, *args, **cmdoptions)
345
346
346 # run pre-hook, and abort if it fails
347 # run pre-hook, and abort if it fails
347 ret = hook.hook(ui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs))
348 ret = hook.hook(ui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs))
348 if ret:
349 if ret:
349 return ret
350 return ret
350 ret = _runcommand(ui, options, cmd, d)
351 ret = _runcommand(ui, options, cmd, d)
351 # run post-hook, passing command result
352 # run post-hook, passing command result
352 hook.hook(ui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
353 hook.hook(ui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
353 result = ret)
354 result = ret)
354 return ret
355 return ret
355
356
356 def _runcommand(ui, options, cmd, cmdfunc):
357 def _runcommand(ui, options, cmd, cmdfunc):
357 def checkargs():
358 def checkargs():
358 try:
359 try:
359 return cmdfunc()
360 return cmdfunc()
360 except TypeError, inst:
361 except TypeError, inst:
361 # was this an argument error?
362 # was this an argument error?
362 tb = traceback.extract_tb(sys.exc_info()[2])
363 tb = traceback.extract_tb(sys.exc_info()[2])
363 if len(tb) != 2: # no
364 if len(tb) != 2: # no
364 raise
365 raise
365 raise ParseError(cmd, _("invalid arguments"))
366 raise ParseError(cmd, _("invalid arguments"))
366
367
367 if options['profile']:
368 if options['profile']:
368 import hotshot, hotshot.stats
369 import hotshot, hotshot.stats
369 prof = hotshot.Profile("hg.prof")
370 prof = hotshot.Profile("hg.prof")
370 try:
371 try:
371 try:
372 try:
372 return prof.runcall(checkargs)
373 return prof.runcall(checkargs)
373 except:
374 except:
374 try:
375 try:
375 ui.warn(_('exception raised - generating '
376 ui.warn(_('exception raised - generating '
376 'profile anyway\n'))
377 'profile anyway\n'))
377 except:
378 except:
378 pass
379 pass
379 raise
380 raise
380 finally:
381 finally:
381 prof.close()
382 prof.close()
382 stats = hotshot.stats.load("hg.prof")
383 stats = hotshot.stats.load("hg.prof")
383 stats.strip_dirs()
384 stats.strip_dirs()
384 stats.sort_stats('time', 'calls')
385 stats.sort_stats('time', 'calls')
385 stats.print_stats(40)
386 stats.print_stats(40)
386 elif options['lsprof']:
387 elif options['lsprof']:
387 try:
388 try:
388 from mercurial import lsprof
389 from mercurial import lsprof
389 except ImportError:
390 except ImportError:
390 raise util.Abort(_(
391 raise util.Abort(_(
391 'lsprof not available - install from '
392 'lsprof not available - install from '
392 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
393 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
393 p = lsprof.Profiler()
394 p = lsprof.Profiler()
394 p.enable(subcalls=True)
395 p.enable(subcalls=True)
395 try:
396 try:
396 return checkargs()
397 return checkargs()
397 finally:
398 finally:
398 p.disable()
399 p.disable()
399 stats = lsprof.Stats(p.getstats())
400 stats = lsprof.Stats(p.getstats())
400 stats.sort()
401 stats.sort()
401 stats.pprint(top=10, file=sys.stderr, climit=5)
402 stats.pprint(top=10, file=sys.stderr, climit=5)
402 else:
403 else:
403 return checkargs()
404 return checkargs()
@@ -1,108 +1,117 b''
1 #!/bin/sh
1 #!/bin/sh
2
2
3 cp "$TESTDIR"/printenv.py .
3 cp "$TESTDIR"/printenv.py .
4
4
5 echo "====== Setting up test"
5 echo "====== Setting up test"
6 hg init test
6 hg init test
7 cd test
7 cd test
8 echo 0 > afile
8 echo 0 > afile
9 hg add afile
9 hg add afile
10 hg commit -m "0.0" -d "1000000 0"
10 hg commit -m "0.0" -d "1000000 0"
11 echo 1 >> afile
11 echo 1 >> afile
12 hg commit -m "0.1" -d "1000000 0"
12 hg commit -m "0.1" -d "1000000 0"
13 echo 2 >> afile
13 echo 2 >> afile
14 hg commit -m "0.2" -d "1000000 0"
14 hg commit -m "0.2" -d "1000000 0"
15 echo 3 >> afile
15 echo 3 >> afile
16 hg commit -m "0.3" -d "1000000 0"
16 hg commit -m "0.3" -d "1000000 0"
17 hg update -C 0
17 hg update -C 0
18 echo 1 >> afile
18 echo 1 >> afile
19 hg commit -m "1.1" -d "1000000 0"
19 hg commit -m "1.1" -d "1000000 0"
20 echo 2 >> afile
20 echo 2 >> afile
21 hg commit -m "1.2" -d "1000000 0"
21 hg commit -m "1.2" -d "1000000 0"
22 echo "a line" > fred
22 echo "a line" > fred
23 echo 3 >> afile
23 echo 3 >> afile
24 hg add fred
24 hg add fred
25 hg commit -m "1.3" -d "1000000 0"
25 hg commit -m "1.3" -d "1000000 0"
26 hg mv afile adifferentfile
26 hg mv afile adifferentfile
27 hg commit -m "1.3m" -d "1000000 0"
27 hg commit -m "1.3m" -d "1000000 0"
28 hg update -C 3
28 hg update -C 3
29 hg mv afile anotherfile
29 hg mv afile anotherfile
30 hg commit -m "0.3m" -d "1000000 0"
30 hg commit -m "0.3m" -d "1000000 0"
31 hg verify
31 hg verify
32 cd ..
32 cd ..
33 hg init empty
33 hg init empty
34
34
35 echo "====== Bundle test to full.hg"
35 echo "====== Bundle test to full.hg"
36 hg -R test bundle full.hg empty
36 hg -R test bundle full.hg empty
37 echo "====== Unbundle full.hg in test"
37 echo "====== Unbundle full.hg in test"
38 hg -R test unbundle full.hg
38 hg -R test unbundle full.hg
39 echo "====== Verify empty"
39 echo "====== Verify empty"
40 hg -R empty heads
40 hg -R empty heads
41 hg -R empty verify
41 hg -R empty verify
42
42
43 echo "====== Pull full.hg into test (using --cwd)"
43 echo "====== Pull full.hg into test (using --cwd)"
44 hg --cwd test pull ../full.hg
44 hg --cwd test pull ../full.hg
45 echo "====== Pull full.hg into empty (using --cwd)"
45 echo "====== Pull full.hg into empty (using --cwd)"
46 hg --cwd empty pull ../full.hg
46 hg --cwd empty pull ../full.hg
47 echo "====== Rollback empty"
47 echo "====== Rollback empty"
48 hg -R empty rollback
48 hg -R empty rollback
49 echo "====== Pull full.hg into empty again (using --cwd)"
49 echo "====== Pull full.hg into empty again (using --cwd)"
50 hg --cwd empty pull ../full.hg
50 hg --cwd empty pull ../full.hg
51
51
52 echo "====== Pull full.hg into test (using -R)"
53 hg -R test pull full.hg
54 echo "====== Pull full.hg into empty (using -R)"
55 hg -R empty pull full.hg
56 echo "====== Rollback empty"
57 hg -R empty rollback
58 echo "====== Pull full.hg into empty again (using -R)"
59 hg -R empty pull full.hg
60
52 echo "====== Log -R full.hg in fresh empty"
61 echo "====== Log -R full.hg in fresh empty"
53 rm -r empty
62 rm -r empty
54 hg init empty
63 hg init empty
55 cd empty
64 cd empty
56 hg -R bundle://../full.hg log
65 hg -R bundle://../full.hg log
57
66
58 echo "====== Pull ../full.hg into empty (with hook)"
67 echo "====== Pull ../full.hg into empty (with hook)"
59 echo '[hooks]' >> .hg/hgrc
68 echo '[hooks]' >> .hg/hgrc
60 echo 'changegroup = python ../printenv.py changegroup' >> .hg/hgrc
69 echo 'changegroup = python ../printenv.py changegroup' >> .hg/hgrc
61 #doesn't work (yet ?)
70 #doesn't work (yet ?)
62 #hg -R bundle://../full.hg verify
71 #hg -R bundle://../full.hg verify
63 hg pull bundle://../full.hg
72 hg pull bundle://../full.hg
64 cd ..
73 cd ..
65
74
66 echo "====== Create partial clones"
75 echo "====== Create partial clones"
67 rm -r empty
76 rm -r empty
68 hg init empty
77 hg init empty
69 hg clone -r 3 test partial
78 hg clone -r 3 test partial
70 hg clone partial partial2
79 hg clone partial partial2
71 cd partial
80 cd partial
72 echo "====== Log -R full.hg in partial"
81 echo "====== Log -R full.hg in partial"
73 hg -R bundle://../full.hg log
82 hg -R bundle://../full.hg log
74 echo "====== Incoming full.hg in partial"
83 echo "====== Incoming full.hg in partial"
75 hg incoming bundle://../full.hg
84 hg incoming bundle://../full.hg
76 echo "====== Outgoing -R full.hg vs partial2 in partial"
85 echo "====== Outgoing -R full.hg vs partial2 in partial"
77 hg -R bundle://../full.hg outgoing ../partial2
86 hg -R bundle://../full.hg outgoing ../partial2
78 echo "====== Outgoing -R does-not-exist.hg vs partial2 in partial"
87 echo "====== Outgoing -R does-not-exist.hg vs partial2 in partial"
79 hg -R bundle://../does-not-exist.hg outgoing ../partial2
88 hg -R bundle://../does-not-exist.hg outgoing ../partial2
80 cd ..
89 cd ..
81
90
82 # test for http://www.selenic.com/mercurial/bts/issue216
91 # test for http://www.selenic.com/mercurial/bts/issue216
83 echo "====== Unbundle incremental bundles into fresh empty in one go"
92 echo "====== Unbundle incremental bundles into fresh empty in one go"
84 rm -r empty
93 rm -r empty
85 hg init empty
94 hg init empty
86 hg -R test bundle --base null -r 0 ../0.hg
95 hg -R test bundle --base null -r 0 ../0.hg
87 hg -R test bundle --base 0 -r 1 ../1.hg
96 hg -R test bundle --base 0 -r 1 ../1.hg
88 hg -R empty unbundle -u ../0.hg ../1.hg
97 hg -R empty unbundle -u ../0.hg ../1.hg
89
98
90 # test for 540d1059c802
99 # test for 540d1059c802
91 echo "====== test for 540d1059c802"
100 echo "====== test for 540d1059c802"
92 hg init orig
101 hg init orig
93 cd orig
102 cd orig
94 echo foo > foo
103 echo foo > foo
95 hg add foo
104 hg add foo
96 hg ci -m 'add foo' -d '0 0'
105 hg ci -m 'add foo' -d '0 0'
97
106
98 hg clone . ../copy
107 hg clone . ../copy
99 hg tag -d '0 0' foo
108 hg tag -d '0 0' foo
100
109
101 cd ../copy
110 cd ../copy
102 echo >> foo
111 echo >> foo
103 hg ci -m 'change foo' -d '0 0'
112 hg ci -m 'change foo' -d '0 0'
104 hg bundle ../bundle.hg ../orig
113 hg bundle ../bundle.hg ../orig
105
114
106 cd ../orig
115 cd ../orig
107 hg incoming ../bundle.hg
116 hg incoming ../bundle.hg
108 cd ..
117 cd ..
@@ -1,250 +1,268 b''
1 ====== Setting up test
1 ====== Setting up test
2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
3 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
4 checking changesets
4 checking changesets
5 checking manifests
5 checking manifests
6 crosschecking files in changesets and manifests
6 crosschecking files in changesets and manifests
7 checking files
7 checking files
8 4 files, 9 changesets, 7 total revisions
8 4 files, 9 changesets, 7 total revisions
9 ====== Bundle test to full.hg
9 ====== Bundle test to full.hg
10 searching for changes
10 searching for changes
11 ====== Unbundle full.hg in test
11 ====== Unbundle full.hg in test
12 adding changesets
12 adding changesets
13 adding manifests
13 adding manifests
14 adding file changes
14 adding file changes
15 added 0 changesets with 0 changes to 4 files
15 added 0 changesets with 0 changes to 4 files
16 (run 'hg update' to get a working copy)
16 (run 'hg update' to get a working copy)
17 ====== Verify empty
17 ====== Verify empty
18 changeset: -1:000000000000
18 changeset: -1:000000000000
19 tag: tip
19 tag: tip
20 user:
20 user:
21 date: Thu Jan 01 00:00:00 1970 +0000
21 date: Thu Jan 01 00:00:00 1970 +0000
22
22
23 checking changesets
23 checking changesets
24 checking manifests
24 checking manifests
25 crosschecking files in changesets and manifests
25 crosschecking files in changesets and manifests
26 checking files
26 checking files
27 0 files, 0 changesets, 0 total revisions
27 0 files, 0 changesets, 0 total revisions
28 ====== Pull full.hg into test (using --cwd)
28 ====== Pull full.hg into test (using --cwd)
29 pulling from ../full.hg
29 pulling from ../full.hg
30 searching for changes
30 searching for changes
31 no changes found
31 no changes found
32 ====== Pull full.hg into empty (using --cwd)
32 ====== Pull full.hg into empty (using --cwd)
33 pulling from ../full.hg
33 pulling from ../full.hg
34 requesting all changes
34 requesting all changes
35 adding changesets
35 adding changesets
36 adding manifests
36 adding manifests
37 adding file changes
37 adding file changes
38 added 9 changesets with 7 changes to 4 files (+1 heads)
38 added 9 changesets with 7 changes to 4 files (+1 heads)
39 (run 'hg heads' to see heads, 'hg merge' to merge)
39 (run 'hg heads' to see heads, 'hg merge' to merge)
40 ====== Rollback empty
40 ====== Rollback empty
41 rolling back last transaction
41 rolling back last transaction
42 ====== Pull full.hg into empty again (using --cwd)
42 ====== Pull full.hg into empty again (using --cwd)
43 pulling from ../full.hg
43 pulling from ../full.hg
44 requesting all changes
44 requesting all changes
45 adding changesets
45 adding changesets
46 adding manifests
46 adding manifests
47 adding file changes
47 adding file changes
48 added 9 changesets with 7 changes to 4 files (+1 heads)
48 added 9 changesets with 7 changes to 4 files (+1 heads)
49 (run 'hg heads' to see heads, 'hg merge' to merge)
49 (run 'hg heads' to see heads, 'hg merge' to merge)
50 ====== Pull full.hg into test (using -R)
51 pulling from full.hg
52 searching for changes
53 no changes found
54 ====== Pull full.hg into empty (using -R)
55 pulling from full.hg
56 searching for changes
57 no changes found
58 ====== Rollback empty
59 rolling back last transaction
60 ====== Pull full.hg into empty again (using -R)
61 pulling from full.hg
62 requesting all changes
63 adding changesets
64 adding manifests
65 adding file changes
66 added 9 changesets with 7 changes to 4 files (+1 heads)
67 (run 'hg heads' to see heads, 'hg merge' to merge)
50 ====== Log -R full.hg in fresh empty
68 ====== Log -R full.hg in fresh empty
51 changeset: 8:836ac62537ab
69 changeset: 8:836ac62537ab
52 tag: tip
70 tag: tip
53 parent: 3:ac69c658229d
71 parent: 3:ac69c658229d
54 user: test
72 user: test
55 date: Mon Jan 12 13:46:40 1970 +0000
73 date: Mon Jan 12 13:46:40 1970 +0000
56 summary: 0.3m
74 summary: 0.3m
57
75
58 changeset: 7:80fe151401c2
76 changeset: 7:80fe151401c2
59 user: test
77 user: test
60 date: Mon Jan 12 13:46:40 1970 +0000
78 date: Mon Jan 12 13:46:40 1970 +0000
61 summary: 1.3m
79 summary: 1.3m
62
80
63 changeset: 6:1e3f6b843bd6
81 changeset: 6:1e3f6b843bd6
64 user: test
82 user: test
65 date: Mon Jan 12 13:46:40 1970 +0000
83 date: Mon Jan 12 13:46:40 1970 +0000
66 summary: 1.3
84 summary: 1.3
67
85
68 changeset: 5:024e4e7df376
86 changeset: 5:024e4e7df376
69 user: test
87 user: test
70 date: Mon Jan 12 13:46:40 1970 +0000
88 date: Mon Jan 12 13:46:40 1970 +0000
71 summary: 1.2
89 summary: 1.2
72
90
73 changeset: 4:5f4f3ceb285e
91 changeset: 4:5f4f3ceb285e
74 parent: 0:5649c9d34dd8
92 parent: 0:5649c9d34dd8
75 user: test
93 user: test
76 date: Mon Jan 12 13:46:40 1970 +0000
94 date: Mon Jan 12 13:46:40 1970 +0000
77 summary: 1.1
95 summary: 1.1
78
96
79 changeset: 3:ac69c658229d
97 changeset: 3:ac69c658229d
80 user: test
98 user: test
81 date: Mon Jan 12 13:46:40 1970 +0000
99 date: Mon Jan 12 13:46:40 1970 +0000
82 summary: 0.3
100 summary: 0.3
83
101
84 changeset: 2:d62976ca1e50
102 changeset: 2:d62976ca1e50
85 user: test
103 user: test
86 date: Mon Jan 12 13:46:40 1970 +0000
104 date: Mon Jan 12 13:46:40 1970 +0000
87 summary: 0.2
105 summary: 0.2
88
106
89 changeset: 1:10b2180f755b
107 changeset: 1:10b2180f755b
90 user: test
108 user: test
91 date: Mon Jan 12 13:46:40 1970 +0000
109 date: Mon Jan 12 13:46:40 1970 +0000
92 summary: 0.1
110 summary: 0.1
93
111
94 changeset: 0:5649c9d34dd8
112 changeset: 0:5649c9d34dd8
95 user: test
113 user: test
96 date: Mon Jan 12 13:46:40 1970 +0000
114 date: Mon Jan 12 13:46:40 1970 +0000
97 summary: 0.0
115 summary: 0.0
98
116
99 ====== Pull ../full.hg into empty (with hook)
117 ====== Pull ../full.hg into empty (with hook)
100 changegroup hook: HG_NODE=5649c9d34dd87d0ecb5fd39672128376e83b22e1 HG_SOURCE=pull HG_URL=bundle:../full.hg
118 changegroup hook: HG_NODE=5649c9d34dd87d0ecb5fd39672128376e83b22e1 HG_SOURCE=pull HG_URL=bundle:../full.hg
101 pulling from bundle://../full.hg
119 pulling from bundle://../full.hg
102 requesting all changes
120 requesting all changes
103 adding changesets
121 adding changesets
104 adding manifests
122 adding manifests
105 adding file changes
123 adding file changes
106 added 9 changesets with 7 changes to 4 files (+1 heads)
124 added 9 changesets with 7 changes to 4 files (+1 heads)
107 (run 'hg heads' to see heads, 'hg merge' to merge)
125 (run 'hg heads' to see heads, 'hg merge' to merge)
108 ====== Create partial clones
126 ====== Create partial clones
109 requesting all changes
127 requesting all changes
110 adding changesets
128 adding changesets
111 adding manifests
129 adding manifests
112 adding file changes
130 adding file changes
113 added 4 changesets with 4 changes to 1 files
131 added 4 changesets with 4 changes to 1 files
114 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
132 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
115 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
133 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
116 ====== Log -R full.hg in partial
134 ====== Log -R full.hg in partial
117 changeset: 8:836ac62537ab
135 changeset: 8:836ac62537ab
118 tag: tip
136 tag: tip
119 parent: 3:ac69c658229d
137 parent: 3:ac69c658229d
120 user: test
138 user: test
121 date: Mon Jan 12 13:46:40 1970 +0000
139 date: Mon Jan 12 13:46:40 1970 +0000
122 summary: 0.3m
140 summary: 0.3m
123
141
124 changeset: 7:80fe151401c2
142 changeset: 7:80fe151401c2
125 user: test
143 user: test
126 date: Mon Jan 12 13:46:40 1970 +0000
144 date: Mon Jan 12 13:46:40 1970 +0000
127 summary: 1.3m
145 summary: 1.3m
128
146
129 changeset: 6:1e3f6b843bd6
147 changeset: 6:1e3f6b843bd6
130 user: test
148 user: test
131 date: Mon Jan 12 13:46:40 1970 +0000
149 date: Mon Jan 12 13:46:40 1970 +0000
132 summary: 1.3
150 summary: 1.3
133
151
134 changeset: 5:024e4e7df376
152 changeset: 5:024e4e7df376
135 user: test
153 user: test
136 date: Mon Jan 12 13:46:40 1970 +0000
154 date: Mon Jan 12 13:46:40 1970 +0000
137 summary: 1.2
155 summary: 1.2
138
156
139 changeset: 4:5f4f3ceb285e
157 changeset: 4:5f4f3ceb285e
140 parent: 0:5649c9d34dd8
158 parent: 0:5649c9d34dd8
141 user: test
159 user: test
142 date: Mon Jan 12 13:46:40 1970 +0000
160 date: Mon Jan 12 13:46:40 1970 +0000
143 summary: 1.1
161 summary: 1.1
144
162
145 changeset: 3:ac69c658229d
163 changeset: 3:ac69c658229d
146 user: test
164 user: test
147 date: Mon Jan 12 13:46:40 1970 +0000
165 date: Mon Jan 12 13:46:40 1970 +0000
148 summary: 0.3
166 summary: 0.3
149
167
150 changeset: 2:d62976ca1e50
168 changeset: 2:d62976ca1e50
151 user: test
169 user: test
152 date: Mon Jan 12 13:46:40 1970 +0000
170 date: Mon Jan 12 13:46:40 1970 +0000
153 summary: 0.2
171 summary: 0.2
154
172
155 changeset: 1:10b2180f755b
173 changeset: 1:10b2180f755b
156 user: test
174 user: test
157 date: Mon Jan 12 13:46:40 1970 +0000
175 date: Mon Jan 12 13:46:40 1970 +0000
158 summary: 0.1
176 summary: 0.1
159
177
160 changeset: 0:5649c9d34dd8
178 changeset: 0:5649c9d34dd8
161 user: test
179 user: test
162 date: Mon Jan 12 13:46:40 1970 +0000
180 date: Mon Jan 12 13:46:40 1970 +0000
163 summary: 0.0
181 summary: 0.0
164
182
165 ====== Incoming full.hg in partial
183 ====== Incoming full.hg in partial
166 comparing with bundle://../full.hg
184 comparing with bundle://../full.hg
167 searching for changes
185 searching for changes
168 changeset: 4:5f4f3ceb285e
186 changeset: 4:5f4f3ceb285e
169 parent: 0:5649c9d34dd8
187 parent: 0:5649c9d34dd8
170 user: test
188 user: test
171 date: Mon Jan 12 13:46:40 1970 +0000
189 date: Mon Jan 12 13:46:40 1970 +0000
172 summary: 1.1
190 summary: 1.1
173
191
174 changeset: 5:024e4e7df376
192 changeset: 5:024e4e7df376
175 user: test
193 user: test
176 date: Mon Jan 12 13:46:40 1970 +0000
194 date: Mon Jan 12 13:46:40 1970 +0000
177 summary: 1.2
195 summary: 1.2
178
196
179 changeset: 6:1e3f6b843bd6
197 changeset: 6:1e3f6b843bd6
180 user: test
198 user: test
181 date: Mon Jan 12 13:46:40 1970 +0000
199 date: Mon Jan 12 13:46:40 1970 +0000
182 summary: 1.3
200 summary: 1.3
183
201
184 changeset: 7:80fe151401c2
202 changeset: 7:80fe151401c2
185 user: test
203 user: test
186 date: Mon Jan 12 13:46:40 1970 +0000
204 date: Mon Jan 12 13:46:40 1970 +0000
187 summary: 1.3m
205 summary: 1.3m
188
206
189 changeset: 8:836ac62537ab
207 changeset: 8:836ac62537ab
190 tag: tip
208 tag: tip
191 parent: 3:ac69c658229d
209 parent: 3:ac69c658229d
192 user: test
210 user: test
193 date: Mon Jan 12 13:46:40 1970 +0000
211 date: Mon Jan 12 13:46:40 1970 +0000
194 summary: 0.3m
212 summary: 0.3m
195
213
196 ====== Outgoing -R full.hg vs partial2 in partial
214 ====== Outgoing -R full.hg vs partial2 in partial
197 comparing with ../partial2
215 comparing with ../partial2
198 searching for changes
216 searching for changes
199 changeset: 4:5f4f3ceb285e
217 changeset: 4:5f4f3ceb285e
200 parent: 0:5649c9d34dd8
218 parent: 0:5649c9d34dd8
201 user: test
219 user: test
202 date: Mon Jan 12 13:46:40 1970 +0000
220 date: Mon Jan 12 13:46:40 1970 +0000
203 summary: 1.1
221 summary: 1.1
204
222
205 changeset: 5:024e4e7df376
223 changeset: 5:024e4e7df376
206 user: test
224 user: test
207 date: Mon Jan 12 13:46:40 1970 +0000
225 date: Mon Jan 12 13:46:40 1970 +0000
208 summary: 1.2
226 summary: 1.2
209
227
210 changeset: 6:1e3f6b843bd6
228 changeset: 6:1e3f6b843bd6
211 user: test
229 user: test
212 date: Mon Jan 12 13:46:40 1970 +0000
230 date: Mon Jan 12 13:46:40 1970 +0000
213 summary: 1.3
231 summary: 1.3
214
232
215 changeset: 7:80fe151401c2
233 changeset: 7:80fe151401c2
216 user: test
234 user: test
217 date: Mon Jan 12 13:46:40 1970 +0000
235 date: Mon Jan 12 13:46:40 1970 +0000
218 summary: 1.3m
236 summary: 1.3m
219
237
220 changeset: 8:836ac62537ab
238 changeset: 8:836ac62537ab
221 tag: tip
239 tag: tip
222 parent: 3:ac69c658229d
240 parent: 3:ac69c658229d
223 user: test
241 user: test
224 date: Mon Jan 12 13:46:40 1970 +0000
242 date: Mon Jan 12 13:46:40 1970 +0000
225 summary: 0.3m
243 summary: 0.3m
226
244
227 ====== Outgoing -R does-not-exist.hg vs partial2 in partial
245 ====== Outgoing -R does-not-exist.hg vs partial2 in partial
228 abort: No such file or directory: ../does-not-exist.hg
246 abort: No such file or directory: ../does-not-exist.hg
229 ====== Unbundle incremental bundles into fresh empty in one go
247 ====== Unbundle incremental bundles into fresh empty in one go
230 adding changesets
248 adding changesets
231 adding manifests
249 adding manifests
232 adding file changes
250 adding file changes
233 added 1 changesets with 1 changes to 1 files
251 added 1 changesets with 1 changes to 1 files
234 adding changesets
252 adding changesets
235 adding manifests
253 adding manifests
236 adding file changes
254 adding file changes
237 added 1 changesets with 1 changes to 1 files
255 added 1 changesets with 1 changes to 1 files
238 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
256 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
239 ====== test for 540d1059c802
257 ====== test for 540d1059c802
240 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
258 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
241 searching for changes
259 searching for changes
242 comparing with ../bundle.hg
260 comparing with ../bundle.hg
243 searching for changes
261 searching for changes
244 changeset: 2:ed1b79f46b9a
262 changeset: 2:ed1b79f46b9a
245 tag: tip
263 tag: tip
246 parent: 0:bbd179dfa0a7
264 parent: 0:bbd179dfa0a7
247 user: test
265 user: test
248 date: Thu Jan 01 00:00:00 1970 +0000
266 date: Thu Jan 01 00:00:00 1970 +0000
249 summary: change foo
267 summary: change foo
250
268
General Comments 0
You need to be logged in to leave comments. Login now