##// END OF EJS Templates
convert/mtn: Fix conversion of large files from mtn (broken in ed97955e0c04)...
Daniel Atallah -
r13792:a916e8de default
parent child Browse files
Show More
@@ -1,358 +1,358 b''
1 # monotone.py - monotone support for the convert extension
1 # monotone.py - monotone support for the convert extension
2 #
2 #
3 # Copyright 2008, 2009 Mikkel Fahnoe Jorgensen <mikkel@dvide.com> and
3 # Copyright 2008, 2009 Mikkel Fahnoe Jorgensen <mikkel@dvide.com> and
4 # others
4 # others
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 import os, re
9 import os, re
10 from mercurial import util
10 from mercurial import util
11 from common import NoRepo, commit, converter_source, checktool
11 from common import NoRepo, commit, converter_source, checktool
12 from common import commandline
12 from common import commandline
13 from mercurial.i18n import _
13 from mercurial.i18n import _
14
14
15 class monotone_source(converter_source, commandline):
15 class monotone_source(converter_source, commandline):
16 def __init__(self, ui, path=None, rev=None):
16 def __init__(self, ui, path=None, rev=None):
17 converter_source.__init__(self, ui, path, rev)
17 converter_source.__init__(self, ui, path, rev)
18 commandline.__init__(self, ui, 'mtn')
18 commandline.__init__(self, ui, 'mtn')
19
19
20 self.ui = ui
20 self.ui = ui
21 self.path = path
21 self.path = path
22 self.automatestdio = False
22 self.automatestdio = False
23 self.rev = rev
23 self.rev = rev
24
24
25 norepo = NoRepo(_("%s does not look like a monotone repository")
25 norepo = NoRepo(_("%s does not look like a monotone repository")
26 % path)
26 % path)
27 if not os.path.exists(os.path.join(path, '_MTN')):
27 if not os.path.exists(os.path.join(path, '_MTN')):
28 # Could be a monotone repository (SQLite db file)
28 # Could be a monotone repository (SQLite db file)
29 try:
29 try:
30 header = file(path, 'rb').read(16)
30 header = file(path, 'rb').read(16)
31 except:
31 except:
32 header = ''
32 header = ''
33 if header != 'SQLite format 3\x00':
33 if header != 'SQLite format 3\x00':
34 raise norepo
34 raise norepo
35
35
36 # regular expressions for parsing monotone output
36 # regular expressions for parsing monotone output
37 space = r'\s*'
37 space = r'\s*'
38 name = r'\s+"((?:\\"|[^"])*)"\s*'
38 name = r'\s+"((?:\\"|[^"])*)"\s*'
39 value = name
39 value = name
40 revision = r'\s+\[(\w+)\]\s*'
40 revision = r'\s+\[(\w+)\]\s*'
41 lines = r'(?:.|\n)+'
41 lines = r'(?:.|\n)+'
42
42
43 self.dir_re = re.compile(space + "dir" + name)
43 self.dir_re = re.compile(space + "dir" + name)
44 self.file_re = re.compile(space + "file" + name +
44 self.file_re = re.compile(space + "file" + name +
45 "content" + revision)
45 "content" + revision)
46 self.add_file_re = re.compile(space + "add_file" + name +
46 self.add_file_re = re.compile(space + "add_file" + name +
47 "content" + revision)
47 "content" + revision)
48 self.patch_re = re.compile(space + "patch" + name +
48 self.patch_re = re.compile(space + "patch" + name +
49 "from" + revision + "to" + revision)
49 "from" + revision + "to" + revision)
50 self.rename_re = re.compile(space + "rename" + name + "to" + name)
50 self.rename_re = re.compile(space + "rename" + name + "to" + name)
51 self.delete_re = re.compile(space + "delete" + name)
51 self.delete_re = re.compile(space + "delete" + name)
52 self.tag_re = re.compile(space + "tag" + name + "revision" +
52 self.tag_re = re.compile(space + "tag" + name + "revision" +
53 revision)
53 revision)
54 self.cert_re = re.compile(lines + space + "name" + name +
54 self.cert_re = re.compile(lines + space + "name" + name +
55 "value" + value)
55 "value" + value)
56
56
57 attr = space + "file" + lines + space + "attr" + space
57 attr = space + "file" + lines + space + "attr" + space
58 self.attr_execute_re = re.compile(attr + '"mtn:execute"' +
58 self.attr_execute_re = re.compile(attr + '"mtn:execute"' +
59 space + '"true"')
59 space + '"true"')
60
60
61 # cached data
61 # cached data
62 self.manifest_rev = None
62 self.manifest_rev = None
63 self.manifest = None
63 self.manifest = None
64 self.files = None
64 self.files = None
65 self.dirs = None
65 self.dirs = None
66
66
67 checktool('mtn', abort=False)
67 checktool('mtn', abort=False)
68
68
69 def mtnrun(self, *args, **kwargs):
69 def mtnrun(self, *args, **kwargs):
70 if self.automatestdio:
70 if self.automatestdio:
71 return self.mtnrunstdio(*args, **kwargs)
71 return self.mtnrunstdio(*args, **kwargs)
72 else:
72 else:
73 return self.mtnrunsingle(*args, **kwargs)
73 return self.mtnrunsingle(*args, **kwargs)
74
74
75 def mtnrunsingle(self, *args, **kwargs):
75 def mtnrunsingle(self, *args, **kwargs):
76 kwargs['d'] = self.path
76 kwargs['d'] = self.path
77 return self.run0('automate', *args, **kwargs)
77 return self.run0('automate', *args, **kwargs)
78
78
79 def mtnrunstdio(self, *args, **kwargs):
79 def mtnrunstdio(self, *args, **kwargs):
80 # Prepare the command in automate stdio format
80 # Prepare the command in automate stdio format
81 command = []
81 command = []
82 for k, v in kwargs.iteritems():
82 for k, v in kwargs.iteritems():
83 command.append("%s:%s" % (len(k), k))
83 command.append("%s:%s" % (len(k), k))
84 if v:
84 if v:
85 command.append("%s:%s" % (len(v), v))
85 command.append("%s:%s" % (len(v), v))
86 if command:
86 if command:
87 command.insert(0, 'o')
87 command.insert(0, 'o')
88 command.append('e')
88 command.append('e')
89
89
90 command.append('l')
90 command.append('l')
91 for arg in args:
91 for arg in args:
92 command += "%s:%s" % (len(arg), arg)
92 command += "%s:%s" % (len(arg), arg)
93 command.append('e')
93 command.append('e')
94 command = ''.join(command)
94 command = ''.join(command)
95
95
96 self.ui.debug("mtn: sending '%s'\n" % command)
96 self.ui.debug("mtn: sending '%s'\n" % command)
97 self.mtnwritefp.write(command)
97 self.mtnwritefp.write(command)
98 self.mtnwritefp.flush()
98 self.mtnwritefp.flush()
99
99
100 return self.mtnstdioreadcommandoutput(command)
100 return self.mtnstdioreadcommandoutput(command)
101
101
102 def mtnstdioreadpacket(self):
102 def mtnstdioreadpacket(self):
103 read = None
103 read = None
104 commandnbr = ''
104 commandnbr = ''
105 while read != ':':
105 while read != ':':
106 read = self.mtnreadfp.read(1)
106 read = self.mtnreadfp.read(1)
107 if not read:
107 if not read:
108 raise util.Abort(_('bad mtn packet - no end of commandnbr'))
108 raise util.Abort(_('bad mtn packet - no end of commandnbr'))
109 commandnbr += read
109 commandnbr += read
110 commandnbr = commandnbr[:-1]
110 commandnbr = commandnbr[:-1]
111
111
112 stream = self.mtnreadfp.read(1)
112 stream = self.mtnreadfp.read(1)
113 if stream not in 'mewptl':
113 if stream not in 'mewptl':
114 raise util.Abort(_('bad mtn packet - bad stream type %s' % stream))
114 raise util.Abort(_('bad mtn packet - bad stream type %s' % stream))
115
115
116 read = self.mtnreadfp.read(1)
116 read = self.mtnreadfp.read(1)
117 if read != ':':
117 if read != ':':
118 raise util.Abort(_('bad mtn packet - no divider before size'))
118 raise util.Abort(_('bad mtn packet - no divider before size'))
119
119
120 read = None
120 read = None
121 lengthstr = ''
121 lengthstr = ''
122 while read != ':':
122 while read != ':':
123 read = self.mtnreadfp.read(1)
123 read = self.mtnreadfp.read(1)
124 if not read:
124 if not read:
125 raise util.Abort(_('bad mtn packet - no end of packet size'))
125 raise util.Abort(_('bad mtn packet - no end of packet size'))
126 lengthstr += read
126 lengthstr += read
127 try:
127 try:
128 length = long(lengthstr[:-1])
128 length = long(lengthstr[:-1])
129 except TypeError:
129 except TypeError:
130 raise util.Abort(_('bad mtn packet - bad packet size %s')
130 raise util.Abort(_('bad mtn packet - bad packet size %s')
131 % lengthstr)
131 % lengthstr)
132
132
133 read = self.mtnreadfp.read(length)
133 read = self.mtnreadfp.read(length)
134 if len(read) != length:
134 if len(read) != length:
135 raise util.Abort(_("bad mtn packet - unable to read full packet "
135 raise util.Abort(_("bad mtn packet - unable to read full packet "
136 "read %s of %s") % (len(read), length))
136 "read %s of %s") % (len(read), length))
137
137
138 return (commandnbr, stream, length, read)
138 return (commandnbr, stream, length, read)
139
139
140 def mtnstdioreadcommandoutput(self, command):
140 def mtnstdioreadcommandoutput(self, command):
141 retval = ''
141 retval = []
142 while True:
142 while True:
143 commandnbr, stream, length, output = self.mtnstdioreadpacket()
143 commandnbr, stream, length, output = self.mtnstdioreadpacket()
144 self.ui.debug('mtn: read packet %s:%s:%s\n' %
144 self.ui.debug('mtn: read packet %s:%s:%s\n' %
145 (commandnbr, stream, length))
145 (commandnbr, stream, length))
146
146
147 if stream == 'l':
147 if stream == 'l':
148 # End of command
148 # End of command
149 if output != '0':
149 if output != '0':
150 raise util.Abort(_("mtn command '%s' returned %s") %
150 raise util.Abort(_("mtn command '%s' returned %s") %
151 (command, output))
151 (command, output))
152 break
152 break
153 elif stream in 'ew':
153 elif stream in 'ew':
154 # Error, warning output
154 # Error, warning output
155 self.ui.warn(_('%s error:\n') % self.command)
155 self.ui.warn(_('%s error:\n') % self.command)
156 self.ui.warn(output)
156 self.ui.warn(output)
157 elif stream == 'p':
157 elif stream == 'p':
158 # Progress messages
158 # Progress messages
159 self.ui.debug('mtn: ' + output)
159 self.ui.debug('mtn: ' + output)
160 elif stream == 'm':
160 elif stream == 'm':
161 # Main stream - command output
161 # Main stream - command output
162 retval = output
162 retval.append(output)
163
163
164 return retval
164 return ''.join(retval)
165
165
166 def mtnloadmanifest(self, rev):
166 def mtnloadmanifest(self, rev):
167 if self.manifest_rev == rev:
167 if self.manifest_rev == rev:
168 return
168 return
169 self.manifest = self.mtnrun("get_manifest_of", rev).split("\n\n")
169 self.manifest = self.mtnrun("get_manifest_of", rev).split("\n\n")
170 self.manifest_rev = rev
170 self.manifest_rev = rev
171 self.files = {}
171 self.files = {}
172 self.dirs = {}
172 self.dirs = {}
173
173
174 for e in self.manifest:
174 for e in self.manifest:
175 m = self.file_re.match(e)
175 m = self.file_re.match(e)
176 if m:
176 if m:
177 attr = ""
177 attr = ""
178 name = m.group(1)
178 name = m.group(1)
179 node = m.group(2)
179 node = m.group(2)
180 if self.attr_execute_re.match(e):
180 if self.attr_execute_re.match(e):
181 attr += "x"
181 attr += "x"
182 self.files[name] = (node, attr)
182 self.files[name] = (node, attr)
183 m = self.dir_re.match(e)
183 m = self.dir_re.match(e)
184 if m:
184 if m:
185 self.dirs[m.group(1)] = True
185 self.dirs[m.group(1)] = True
186
186
187 def mtnisfile(self, name, rev):
187 def mtnisfile(self, name, rev):
188 # a non-file could be a directory or a deleted or renamed file
188 # a non-file could be a directory or a deleted or renamed file
189 self.mtnloadmanifest(rev)
189 self.mtnloadmanifest(rev)
190 return name in self.files
190 return name in self.files
191
191
192 def mtnisdir(self, name, rev):
192 def mtnisdir(self, name, rev):
193 self.mtnloadmanifest(rev)
193 self.mtnloadmanifest(rev)
194 return name in self.dirs
194 return name in self.dirs
195
195
196 def mtngetcerts(self, rev):
196 def mtngetcerts(self, rev):
197 certs = {"author":"<missing>", "date":"<missing>",
197 certs = {"author":"<missing>", "date":"<missing>",
198 "changelog":"<missing>", "branch":"<missing>"}
198 "changelog":"<missing>", "branch":"<missing>"}
199 certlist = self.mtnrun("certs", rev)
199 certlist = self.mtnrun("certs", rev)
200 # mtn < 0.45:
200 # mtn < 0.45:
201 # key "test@selenic.com"
201 # key "test@selenic.com"
202 # mtn >= 0.45:
202 # mtn >= 0.45:
203 # key [ff58a7ffb771907c4ff68995eada1c4da068d328]
203 # key [ff58a7ffb771907c4ff68995eada1c4da068d328]
204 certlist = re.split('\n\n key ["\[]', certlist)
204 certlist = re.split('\n\n key ["\[]', certlist)
205 for e in certlist:
205 for e in certlist:
206 m = self.cert_re.match(e)
206 m = self.cert_re.match(e)
207 if m:
207 if m:
208 name, value = m.groups()
208 name, value = m.groups()
209 value = value.replace(r'\"', '"')
209 value = value.replace(r'\"', '"')
210 value = value.replace(r'\\', '\\')
210 value = value.replace(r'\\', '\\')
211 certs[name] = value
211 certs[name] = value
212 # Monotone may have subsecond dates: 2005-02-05T09:39:12.364306
212 # Monotone may have subsecond dates: 2005-02-05T09:39:12.364306
213 # and all times are stored in UTC
213 # and all times are stored in UTC
214 certs["date"] = certs["date"].split('.')[0] + " UTC"
214 certs["date"] = certs["date"].split('.')[0] + " UTC"
215 return certs
215 return certs
216
216
217 # implement the converter_source interface:
217 # implement the converter_source interface:
218
218
219 def getheads(self):
219 def getheads(self):
220 if not self.rev:
220 if not self.rev:
221 return self.mtnrun("leaves").splitlines()
221 return self.mtnrun("leaves").splitlines()
222 else:
222 else:
223 return [self.rev]
223 return [self.rev]
224
224
225 def getchanges(self, rev):
225 def getchanges(self, rev):
226 #revision = self.mtncmd("get_revision %s" % rev).split("\n\n")
226 #revision = self.mtncmd("get_revision %s" % rev).split("\n\n")
227 revision = self.mtnrun("get_revision", rev).split("\n\n")
227 revision = self.mtnrun("get_revision", rev).split("\n\n")
228 files = {}
228 files = {}
229 ignoremove = {}
229 ignoremove = {}
230 renameddirs = []
230 renameddirs = []
231 copies = {}
231 copies = {}
232 for e in revision:
232 for e in revision:
233 m = self.add_file_re.match(e)
233 m = self.add_file_re.match(e)
234 if m:
234 if m:
235 files[m.group(1)] = rev
235 files[m.group(1)] = rev
236 ignoremove[m.group(1)] = rev
236 ignoremove[m.group(1)] = rev
237 m = self.patch_re.match(e)
237 m = self.patch_re.match(e)
238 if m:
238 if m:
239 files[m.group(1)] = rev
239 files[m.group(1)] = rev
240 # Delete/rename is handled later when the convert engine
240 # Delete/rename is handled later when the convert engine
241 # discovers an IOError exception from getfile,
241 # discovers an IOError exception from getfile,
242 # but only if we add the "from" file to the list of changes.
242 # but only if we add the "from" file to the list of changes.
243 m = self.delete_re.match(e)
243 m = self.delete_re.match(e)
244 if m:
244 if m:
245 files[m.group(1)] = rev
245 files[m.group(1)] = rev
246 m = self.rename_re.match(e)
246 m = self.rename_re.match(e)
247 if m:
247 if m:
248 toname = m.group(2)
248 toname = m.group(2)
249 fromname = m.group(1)
249 fromname = m.group(1)
250 if self.mtnisfile(toname, rev):
250 if self.mtnisfile(toname, rev):
251 ignoremove[toname] = 1
251 ignoremove[toname] = 1
252 copies[toname] = fromname
252 copies[toname] = fromname
253 files[toname] = rev
253 files[toname] = rev
254 files[fromname] = rev
254 files[fromname] = rev
255 elif self.mtnisdir(toname, rev):
255 elif self.mtnisdir(toname, rev):
256 renameddirs.append((fromname, toname))
256 renameddirs.append((fromname, toname))
257
257
258 # Directory renames can be handled only once we have recorded
258 # Directory renames can be handled only once we have recorded
259 # all new files
259 # all new files
260 for fromdir, todir in renameddirs:
260 for fromdir, todir in renameddirs:
261 renamed = {}
261 renamed = {}
262 for tofile in self.files:
262 for tofile in self.files:
263 if tofile in ignoremove:
263 if tofile in ignoremove:
264 continue
264 continue
265 if tofile.startswith(todir + '/'):
265 if tofile.startswith(todir + '/'):
266 renamed[tofile] = fromdir + tofile[len(todir):]
266 renamed[tofile] = fromdir + tofile[len(todir):]
267 # Avoid chained moves like:
267 # Avoid chained moves like:
268 # d1(/a) => d3/d1(/a)
268 # d1(/a) => d3/d1(/a)
269 # d2 => d3
269 # d2 => d3
270 ignoremove[tofile] = 1
270 ignoremove[tofile] = 1
271 for tofile, fromfile in renamed.items():
271 for tofile, fromfile in renamed.items():
272 self.ui.debug (_("copying file in renamed directory "
272 self.ui.debug (_("copying file in renamed directory "
273 "from '%s' to '%s'")
273 "from '%s' to '%s'")
274 % (fromfile, tofile), '\n')
274 % (fromfile, tofile), '\n')
275 files[tofile] = rev
275 files[tofile] = rev
276 copies[tofile] = fromfile
276 copies[tofile] = fromfile
277 for fromfile in renamed.values():
277 for fromfile in renamed.values():
278 files[fromfile] = rev
278 files[fromfile] = rev
279
279
280 return (files.items(), copies)
280 return (files.items(), copies)
281
281
282 def getfile(self, name, rev):
282 def getfile(self, name, rev):
283 if not self.mtnisfile(name, rev):
283 if not self.mtnisfile(name, rev):
284 raise IOError() # file was deleted or renamed
284 raise IOError() # file was deleted or renamed
285 try:
285 try:
286 data = self.mtnrun("get_file_of", name, r=rev)
286 data = self.mtnrun("get_file_of", name, r=rev)
287 except:
287 except:
288 raise IOError() # file was deleted or renamed
288 raise IOError() # file was deleted or renamed
289 self.mtnloadmanifest(rev)
289 self.mtnloadmanifest(rev)
290 node, attr = self.files.get(name, (None, ""))
290 node, attr = self.files.get(name, (None, ""))
291 return data, attr
291 return data, attr
292
292
293 def getcommit(self, rev):
293 def getcommit(self, rev):
294 extra = {}
294 extra = {}
295 certs = self.mtngetcerts(rev)
295 certs = self.mtngetcerts(rev)
296 if certs.get('suspend') == certs["branch"]:
296 if certs.get('suspend') == certs["branch"]:
297 extra['close'] = '1'
297 extra['close'] = '1'
298 return commit(
298 return commit(
299 author=certs["author"],
299 author=certs["author"],
300 date=util.datestr(util.strdate(certs["date"], "%Y-%m-%dT%H:%M:%S")),
300 date=util.datestr(util.strdate(certs["date"], "%Y-%m-%dT%H:%M:%S")),
301 desc=certs["changelog"],
301 desc=certs["changelog"],
302 rev=rev,
302 rev=rev,
303 parents=self.mtnrun("parents", rev).splitlines(),
303 parents=self.mtnrun("parents", rev).splitlines(),
304 branch=certs["branch"],
304 branch=certs["branch"],
305 extra=extra)
305 extra=extra)
306
306
307 def gettags(self):
307 def gettags(self):
308 tags = {}
308 tags = {}
309 for e in self.mtnrun("tags").split("\n\n"):
309 for e in self.mtnrun("tags").split("\n\n"):
310 m = self.tag_re.match(e)
310 m = self.tag_re.match(e)
311 if m:
311 if m:
312 tags[m.group(1)] = m.group(2)
312 tags[m.group(1)] = m.group(2)
313 return tags
313 return tags
314
314
315 def getchangedfiles(self, rev, i):
315 def getchangedfiles(self, rev, i):
316 # This function is only needed to support --filemap
316 # This function is only needed to support --filemap
317 # ... and we don't support that
317 # ... and we don't support that
318 raise NotImplementedError()
318 raise NotImplementedError()
319
319
320 def before(self):
320 def before(self):
321 # Check if we have a new enough version to use automate stdio
321 # Check if we have a new enough version to use automate stdio
322 version = 0.0
322 version = 0.0
323 try:
323 try:
324 versionstr = self.mtnrunsingle("interface_version")
324 versionstr = self.mtnrunsingle("interface_version")
325 version = float(versionstr)
325 version = float(versionstr)
326 except Exception:
326 except Exception:
327 raise util.Abort(_("unable to determine mtn automate interface "
327 raise util.Abort(_("unable to determine mtn automate interface "
328 "version"))
328 "version"))
329
329
330 if version >= 12.0:
330 if version >= 12.0:
331 self.automatestdio = True
331 self.automatestdio = True
332 self.ui.debug("mtn automate version %s - using automate stdio\n" %
332 self.ui.debug("mtn automate version %s - using automate stdio\n" %
333 version)
333 version)
334
334
335 # launch the long-running automate stdio process
335 # launch the long-running automate stdio process
336 self.mtnwritefp, self.mtnreadfp = self._run2('automate', 'stdio',
336 self.mtnwritefp, self.mtnreadfp = self._run2('automate', 'stdio',
337 '-d', self.path)
337 '-d', self.path)
338 # read the headers
338 # read the headers
339 read = self.mtnreadfp.readline()
339 read = self.mtnreadfp.readline()
340 if read != 'format-version: 2\n':
340 if read != 'format-version: 2\n':
341 raise util.Abort(_('mtn automate stdio header unexpected: %s')
341 raise util.Abort(_('mtn automate stdio header unexpected: %s')
342 % read)
342 % read)
343 while read != '\n':
343 while read != '\n':
344 read = self.mtnreadfp.readline()
344 read = self.mtnreadfp.readline()
345 if not read:
345 if not read:
346 raise util.Abort(_("failed to reach end of mtn automate "
346 raise util.Abort(_("failed to reach end of mtn automate "
347 "stdio headers"))
347 "stdio headers"))
348 else:
348 else:
349 self.ui.debug("mtn automate version %s - not using automate stdio "
349 self.ui.debug("mtn automate version %s - not using automate stdio "
350 "(automate >= 12.0 - mtn >= 0.46 is needed)\n" % version)
350 "(automate >= 12.0 - mtn >= 0.46 is needed)\n" % version)
351
351
352 def after(self):
352 def after(self):
353 if self.automatestdio:
353 if self.automatestdio:
354 self.mtnwritefp.close()
354 self.mtnwritefp.close()
355 self.mtnwritefp = None
355 self.mtnwritefp = None
356 self.mtnreadfp.close()
356 self.mtnreadfp.close()
357 self.mtnreadfp = None
357 self.mtnreadfp = None
358
358
@@ -1,368 +1,388 b''
1
1
2 $ "$TESTDIR/hghave" mtn || exit 80
2 $ "$TESTDIR/hghave" mtn || exit 80
3
3
4 Monotone directory is called .monotone on *nix and monotone
4 Monotone directory is called .monotone on *nix and monotone
5 on Windows. Having a variable here ease test patching.
5 on Windows. Having a variable here ease test patching.
6
6
7 $ mtndir=.monotone
7 $ mtndir=.monotone
8 $ echo "[extensions]" >> $HGRCPATH
8 $ echo "[extensions]" >> $HGRCPATH
9 $ echo "convert=" >> $HGRCPATH
9 $ echo "convert=" >> $HGRCPATH
10 $ echo 'graphlog =' >> $HGRCPATH
10 $ echo 'graphlog =' >> $HGRCPATH
11
11
12 Windows version of monotone home
12 Windows version of monotone home
13
13
14 $ APPDATA=$HOME; export APPDATA
14 $ APPDATA=$HOME; export APPDATA
15
15
16 tedious monotone keys configuration
16 tedious monotone keys configuration
17 The /dev/null redirection is necessary under Windows, or
17 The /dev/null redirection is necessary under Windows, or
18 it complains about home directory permissions
18 it complains about home directory permissions
19
19
20 $ mtn --quiet genkey test@selenic.com 1>/dev/null 2>&1 <<EOF
20 $ mtn --quiet genkey test@selenic.com 1>/dev/null 2>&1 <<EOF
21 > passphrase
21 > passphrase
22 > passphrase
22 > passphrase
23 > EOF
23 > EOF
24 $ cat >> $HOME/$mtndir/monotonerc <<EOF
24 $ cat >> $HOME/$mtndir/monotonerc <<EOF
25 > function get_passphrase(keypair_id)
25 > function get_passphrase(keypair_id)
26 > return "passphrase"
26 > return "passphrase"
27 > end
27 > end
28 > EOF
28 > EOF
29
29
30 create monotone repository
30 create monotone repository
31
31
32 $ mtn db init --db=repo.mtn
32 $ mtn db init --db=repo.mtn
33 $ mtn --db=repo.mtn --branch=com.selenic.test setup workingdir
33 $ mtn --db=repo.mtn --branch=com.selenic.test setup workingdir
34 $ cd workingdir
34 $ cd workingdir
35 $ echo a > a
35 $ echo a > a
36 $ mkdir dir
36 $ mkdir dir
37 $ echo b > dir/b
37 $ echo b > dir/b
38 $ echo d > dir/d
38 $ echo d > dir/d
39 $ python -c 'file("bin", "wb").write("a\\x00b")'
39 $ python -c 'file("bin", "wb").write("a\\x00b")'
40 $ echo c > c
40 $ echo c > c
41 $ mtn add a dir/b dir/d c bin
41 $ mtn add a dir/b dir/d c bin
42 mtn: adding a to workspace manifest
42 mtn: adding a to workspace manifest
43 mtn: adding bin to workspace manifest
43 mtn: adding bin to workspace manifest
44 mtn: adding c to workspace manifest
44 mtn: adding c to workspace manifest
45 mtn: adding dir to workspace manifest
45 mtn: adding dir to workspace manifest
46 mtn: adding dir/b to workspace manifest
46 mtn: adding dir/b to workspace manifest
47 mtn: adding dir/d to workspace manifest
47 mtn: adding dir/d to workspace manifest
48 $ mtn ci -m initialize
48 $ mtn ci -m initialize
49 mtn: beginning commit on branch 'com.selenic.test'
49 mtn: beginning commit on branch 'com.selenic.test'
50 mtn: committed revision 0f6e5e4f2e7d2a8ef312408f57618abf026afd90
50 mtn: committed revision 0f6e5e4f2e7d2a8ef312408f57618abf026afd90
51
51
52 update monotone working directory
52 update monotone working directory
53
53
54 $ mtn mv a dir/a
54 $ mtn mv a dir/a
55 mtn: skipping dir, already accounted for in workspace
55 mtn: skipping dir, already accounted for in workspace
56 mtn: renaming a to dir/a in workspace manifest
56 mtn: renaming a to dir/a in workspace manifest
57 $ echo a >> dir/a
57 $ echo a >> dir/a
58 $ echo b >> dir/b
58 $ echo b >> dir/b
59 $ mtn drop c
59 $ mtn drop c
60 mtn: dropping c from workspace manifest
60 mtn: dropping c from workspace manifest
61 $ python -c 'file("bin", "wb").write("b\\x00c")'
61 $ python -c 'file("bin", "wb").write("b\\x00c")'
62 $ mtn ci -m update1
62 $ mtn ci -m update1
63 mtn: beginning commit on branch 'com.selenic.test'
63 mtn: beginning commit on branch 'com.selenic.test'
64 mtn: committed revision 51d0a982464573a2a2cf5ee2c9219c652aaebeff
64 mtn: committed revision 51d0a982464573a2a2cf5ee2c9219c652aaebeff
65 $ cd ..
65 $ cd ..
66
66
67 convert once
67 convert once
68
68
69 $ hg convert -s mtn repo.mtn
69 $ hg convert -s mtn repo.mtn
70 assuming destination repo.mtn-hg
70 assuming destination repo.mtn-hg
71 initializing destination repo.mtn-hg repository
71 initializing destination repo.mtn-hg repository
72 scanning source...
72 scanning source...
73 sorting...
73 sorting...
74 converting...
74 converting...
75 1 initialize
75 1 initialize
76 0 update1
76 0 update1
77 $ cd workingdir
77 $ cd workingdir
78 $ echo e > e
78 $ echo e > e
79 $ mtn add e
79 $ mtn add e
80 mtn: adding e to workspace manifest
80 mtn: adding e to workspace manifest
81 $ mtn drop dir/b
81 $ mtn drop dir/b
82 mtn: dropping dir/b from workspace manifest
82 mtn: dropping dir/b from workspace manifest
83 $ mtn mv bin bin2
83 $ mtn mv bin bin2
84 mtn: renaming bin to bin2 in workspace manifest
84 mtn: renaming bin to bin2 in workspace manifest
85 $ mtn ci -m 'update2 "with" quotes'
85 $ mtn ci -m 'update2 "with" quotes'
86 mtn: beginning commit on branch 'com.selenic.test'
86 mtn: beginning commit on branch 'com.selenic.test'
87 mtn: committed revision ebe58335d85d8cb176b6d0a12be04f5314b998da
87 mtn: committed revision ebe58335d85d8cb176b6d0a12be04f5314b998da
88
88
89 test directory move
89 test directory move
90
90
91 $ mkdir -p dir1/subdir1
91 $ mkdir -p dir1/subdir1
92 $ mkdir -p dir1/subdir2_other
92 $ mkdir -p dir1/subdir2_other
93 $ echo file1 > dir1/subdir1/file1
93 $ echo file1 > dir1/subdir1/file1
94 $ echo file2 > dir1/subdir2_other/file1
94 $ echo file2 > dir1/subdir2_other/file1
95 $ mtn add dir1/subdir1/file1 dir1/subdir2_other/file1
95 $ mtn add dir1/subdir1/file1 dir1/subdir2_other/file1
96 mtn: adding dir1 to workspace manifest
96 mtn: adding dir1 to workspace manifest
97 mtn: adding dir1/subdir1 to workspace manifest
97 mtn: adding dir1/subdir1 to workspace manifest
98 mtn: adding dir1/subdir1/file1 to workspace manifest
98 mtn: adding dir1/subdir1/file1 to workspace manifest
99 mtn: adding dir1/subdir2_other to workspace manifest
99 mtn: adding dir1/subdir2_other to workspace manifest
100 mtn: adding dir1/subdir2_other/file1 to workspace manifest
100 mtn: adding dir1/subdir2_other/file1 to workspace manifest
101 $ mtn ci -m createdir1
101 $ mtn ci -m createdir1
102 mtn: beginning commit on branch 'com.selenic.test'
102 mtn: beginning commit on branch 'com.selenic.test'
103 mtn: committed revision a8d62bc04fee4d2936d28e98bbcc81686dd74306
103 mtn: committed revision a8d62bc04fee4d2936d28e98bbcc81686dd74306
104 $ mtn rename dir1/subdir1 dir1/subdir2
104 $ mtn rename dir1/subdir1 dir1/subdir2
105 mtn: skipping dir1, already accounted for in workspace
105 mtn: skipping dir1, already accounted for in workspace
106 mtn: renaming dir1/subdir1 to dir1/subdir2 in workspace manifest
106 mtn: renaming dir1/subdir1 to dir1/subdir2 in workspace manifest
107 $ mtn ci -m movedir1
107 $ mtn ci -m movedir1
108 mtn: beginning commit on branch 'com.selenic.test'
108 mtn: beginning commit on branch 'com.selenic.test'
109 mtn: committed revision 2c3d241bbbfe538b1b51d910f5676407e3f4d3a6
109 mtn: committed revision 2c3d241bbbfe538b1b51d910f5676407e3f4d3a6
110
110
111 test subdirectory move
111 test subdirectory move
112
112
113 $ mtn mv dir dir2
113 $ mtn mv dir dir2
114 mtn: renaming dir to dir2 in workspace manifest
114 mtn: renaming dir to dir2 in workspace manifest
115 $ echo newfile > dir2/newfile
115 $ echo newfile > dir2/newfile
116 $ mtn drop dir2/d
116 $ mtn drop dir2/d
117 mtn: dropping dir2/d from workspace manifest
117 mtn: dropping dir2/d from workspace manifest
118 $ mtn add dir2/newfile
118 $ mtn add dir2/newfile
119 mtn: adding dir2/newfile to workspace manifest
119 mtn: adding dir2/newfile to workspace manifest
120 $ mtn ci -m movedir
120 $ mtn ci -m movedir
121 mtn: beginning commit on branch 'com.selenic.test'
121 mtn: beginning commit on branch 'com.selenic.test'
122 mtn: committed revision fdb5a02dae8bfce3a79b3393680af471016e1b4c
122 mtn: committed revision fdb5a02dae8bfce3a79b3393680af471016e1b4c
123
123
124 Test directory removal with empty directory
124 Test directory removal with empty directory
125
125
126 $ mkdir dir2/dir
126 $ mkdir dir2/dir
127 $ mkdir dir2/dir/subdir
127 $ mkdir dir2/dir/subdir
128 $ echo f > dir2/dir/subdir/f
128 $ echo f > dir2/dir/subdir/f
129 $ mkdir dir2/dir/emptydir
129 $ mkdir dir2/dir/emptydir
130 $ mtn add --quiet -R dir2/dir
130 $ mtn add --quiet -R dir2/dir
131 $ mtn ci -m emptydir
131 $ mtn ci -m emptydir
132 mtn: beginning commit on branch 'com.selenic.test'
132 mtn: beginning commit on branch 'com.selenic.test'
133 mtn: committed revision 8bbf76d717001d24964e4604739fdcd0f539fc88
133 mtn: committed revision 8bbf76d717001d24964e4604739fdcd0f539fc88
134 $ mtn drop -R dir2/dir
134 $ mtn drop -R dir2/dir
135 mtn: dropping dir2/dir/subdir/f from workspace manifest
135 mtn: dropping dir2/dir/subdir/f from workspace manifest
136 mtn: dropping dir2/dir/subdir from workspace manifest
136 mtn: dropping dir2/dir/subdir from workspace manifest
137 mtn: dropping dir2/dir/emptydir from workspace manifest
137 mtn: dropping dir2/dir/emptydir from workspace manifest
138 mtn: dropping dir2/dir from workspace manifest
138 mtn: dropping dir2/dir from workspace manifest
139 $ mtn ci -m dropdirectory
139 $ mtn ci -m dropdirectory
140 mtn: beginning commit on branch 'com.selenic.test'
140 mtn: beginning commit on branch 'com.selenic.test'
141 mtn: committed revision 2323d4bc324e6c82628dc04d47a9fd32ad24e322
141 mtn: committed revision 2323d4bc324e6c82628dc04d47a9fd32ad24e322
142
142
143 test directory and file move
143 test directory and file move
144
144
145 $ mkdir -p dir3/d1
145 $ mkdir -p dir3/d1
146 $ echo a > dir3/a
146 $ echo a > dir3/a
147 $ mtn add dir3/a dir3/d1
147 $ mtn add dir3/a dir3/d1
148 mtn: adding dir3 to workspace manifest
148 mtn: adding dir3 to workspace manifest
149 mtn: adding dir3/a to workspace manifest
149 mtn: adding dir3/a to workspace manifest
150 mtn: adding dir3/d1 to workspace manifest
150 mtn: adding dir3/d1 to workspace manifest
151 $ mtn ci -m dirfilemove
151 $ mtn ci -m dirfilemove
152 mtn: beginning commit on branch 'com.selenic.test'
152 mtn: beginning commit on branch 'com.selenic.test'
153 mtn: committed revision 47b192f720faa622f48c68d1eb075b26d405aa8b
153 mtn: committed revision 47b192f720faa622f48c68d1eb075b26d405aa8b
154 $ mtn mv dir3/a dir3/d1/a
154 $ mtn mv dir3/a dir3/d1/a
155 mtn: skipping dir3/d1, already accounted for in workspace
155 mtn: skipping dir3/d1, already accounted for in workspace
156 mtn: renaming dir3/a to dir3/d1/a in workspace manifest
156 mtn: renaming dir3/a to dir3/d1/a in workspace manifest
157 $ mtn mv dir3/d1 dir3/d2
157 $ mtn mv dir3/d1 dir3/d2
158 mtn: skipping dir3, already accounted for in workspace
158 mtn: skipping dir3, already accounted for in workspace
159 mtn: renaming dir3/d1 to dir3/d2 in workspace manifest
159 mtn: renaming dir3/d1 to dir3/d2 in workspace manifest
160 $ mtn ci -m dirfilemove2
160 $ mtn ci -m dirfilemove2
161 mtn: beginning commit on branch 'com.selenic.test'
161 mtn: beginning commit on branch 'com.selenic.test'
162 mtn: committed revision 8b543a400d3ee7f6d4bb1835b9b9e3747c8cb632
162 mtn: committed revision 8b543a400d3ee7f6d4bb1835b9b9e3747c8cb632
163
163
164 test directory move into another directory move
164 test directory move into another directory move
165
165
166 $ mkdir dir4
166 $ mkdir dir4
167 $ mkdir dir5
167 $ mkdir dir5
168 $ echo a > dir4/a
168 $ echo a > dir4/a
169 $ mtn add dir4/a dir5
169 $ mtn add dir4/a dir5
170 mtn: adding dir4 to workspace manifest
170 mtn: adding dir4 to workspace manifest
171 mtn: adding dir4/a to workspace manifest
171 mtn: adding dir4/a to workspace manifest
172 mtn: adding dir5 to workspace manifest
172 mtn: adding dir5 to workspace manifest
173 $ mtn ci -m dirdirmove
173 $ mtn ci -m dirdirmove
174 mtn: beginning commit on branch 'com.selenic.test'
174 mtn: beginning commit on branch 'com.selenic.test'
175 mtn: committed revision 466e0b2afc7a55aa2b4ab2f57cb240bb6cd66fc7
175 mtn: committed revision 466e0b2afc7a55aa2b4ab2f57cb240bb6cd66fc7
176 $ mtn mv dir5 dir6
176 $ mtn mv dir5 dir6
177 mtn: renaming dir5 to dir6 in workspace manifest
177 mtn: renaming dir5 to dir6 in workspace manifest
178 $ mtn mv dir4 dir6/dir4
178 $ mtn mv dir4 dir6/dir4
179 mtn: skipping dir6, already accounted for in workspace
179 mtn: skipping dir6, already accounted for in workspace
180 mtn: renaming dir4 to dir6/dir4 in workspace manifest
180 mtn: renaming dir4 to dir6/dir4 in workspace manifest
181 $ mtn ci -m dirdirmove2
181 $ mtn ci -m dirdirmove2
182 mtn: beginning commit on branch 'com.selenic.test'
182 mtn: beginning commit on branch 'com.selenic.test'
183 mtn: committed revision 3d1f77ebad0c23a5d14911be3b670f990991b749
183 mtn: committed revision 3d1f77ebad0c23a5d14911be3b670f990991b749
184
184
185 test diverging directory moves
185 test diverging directory moves
186
186
187 $ mkdir -p dir7/dir9/dir8
187 $ mkdir -p dir7/dir9/dir8
188 $ echo a > dir7/dir9/dir8/a
188 $ echo a > dir7/dir9/dir8/a
189 $ echo b > dir7/dir9/b
189 $ echo b > dir7/dir9/b
190 $ echo c > dir7/c
190 $ echo c > dir7/c
191 $ mtn add -R dir7
191 $ mtn add -R dir7
192 mtn: adding dir7 to workspace manifest
192 mtn: adding dir7 to workspace manifest
193 mtn: adding dir7/c to workspace manifest
193 mtn: adding dir7/c to workspace manifest
194 mtn: adding dir7/dir9 to workspace manifest
194 mtn: adding dir7/dir9 to workspace manifest
195 mtn: adding dir7/dir9/b to workspace manifest
195 mtn: adding dir7/dir9/b to workspace manifest
196 mtn: adding dir7/dir9/dir8 to workspace manifest
196 mtn: adding dir7/dir9/dir8 to workspace manifest
197 mtn: adding dir7/dir9/dir8/a to workspace manifest
197 mtn: adding dir7/dir9/dir8/a to workspace manifest
198 $ mtn ci -m divergentdirmove
198 $ mtn ci -m divergentdirmove
199 mtn: beginning commit on branch 'com.selenic.test'
199 mtn: beginning commit on branch 'com.selenic.test'
200 mtn: committed revision 08a08511f18b428d840199b062de90d0396bc2ed
200 mtn: committed revision 08a08511f18b428d840199b062de90d0396bc2ed
201 $ mtn mv dir7 dir7-2
201 $ mtn mv dir7 dir7-2
202 mtn: renaming dir7 to dir7-2 in workspace manifest
202 mtn: renaming dir7 to dir7-2 in workspace manifest
203 $ mtn mv dir7-2/dir9 dir9-2
203 $ mtn mv dir7-2/dir9 dir9-2
204 mtn: renaming dir7-2/dir9 to dir9-2 in workspace manifest
204 mtn: renaming dir7-2/dir9 to dir9-2 in workspace manifest
205 $ mtn mv dir9-2/dir8 dir8-2
205 $ mtn mv dir9-2/dir8 dir8-2
206 mtn: renaming dir9-2/dir8 to dir8-2 in workspace manifest
206 mtn: renaming dir9-2/dir8 to dir8-2 in workspace manifest
207 $ mtn ci -m divergentdirmove2
207 $ mtn ci -m divergentdirmove2
208 mtn: beginning commit on branch 'com.selenic.test'
208 mtn: beginning commit on branch 'com.selenic.test'
209 mtn: committed revision 4a736634505795f17786fffdf2c9cbf5b11df6f6
209 mtn: committed revision 4a736634505795f17786fffdf2c9cbf5b11df6f6
210
210
211 test large file support (> 32kB)
212
213 $ python -c 'for x in range(10000): print x' > large-file
214 $ $TESTDIR/md5sum.py large-file
215 5d6de8a95c3b6bf9e0ffb808ba5299c1 large-file
216 $ mtn add large-file
217 mtn: adding large-file to workspace manifest
218 $ mtn ci -m largefile
219 mtn: beginning commit on branch 'com.selenic.test'
220 mtn: committed revision f0a20fecd10dc4392d18fe69a03f1f4919d3387b
221
211 test suspending (closing a branch)
222 test suspending (closing a branch)
212
223
213 $ mtn suspend 4a736634505795f17786fffdf2c9cbf5b11df6f6 2> /dev/null
224 $ mtn suspend f0a20fecd10dc4392d18fe69a03f1f4919d3387b 2> /dev/null
214 $ cd ..
225 $ cd ..
215
226
216 convert incrementally
227 convert incrementally
217
228
218 $ hg convert -s mtn repo.mtn
229 $ hg convert -s mtn repo.mtn
219 assuming destination repo.mtn-hg
230 assuming destination repo.mtn-hg
220 scanning source...
231 scanning source...
221 sorting...
232 sorting...
222 converting...
233 converting...
223 11 update2 "with" quotes
234 12 update2 "with" quotes
224 10 createdir1
235 11 createdir1
225 9 movedir1
236 10 movedir1
226 8 movedir
237 9 movedir
227 7 emptydir
238 8 emptydir
228 6 dropdirectory
239 7 dropdirectory
229 5 dirfilemove
240 6 dirfilemove
230 4 dirfilemove2
241 5 dirfilemove2
231 3 dirdirmove
242 4 dirdirmove
232 2 dirdirmove2
243 3 dirdirmove2
233 1 divergentdirmove
244 2 divergentdirmove
234 0 divergentdirmove2
245 1 divergentdirmove2
246 0 largefile
235 $ glog()
247 $ glog()
236 > {
248 > {
237 > hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@"
249 > hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@"
238 > }
250 > }
239 $ cd repo.mtn-hg
251 $ cd repo.mtn-hg
240 $ hg up -C
252 $ hg up -C
241 11 files updated, 0 files merged, 0 files removed, 0 files unresolved
253 12 files updated, 0 files merged, 0 files removed, 0 files unresolved
242 $ glog
254 $ glog
243 @ 13 "divergentdirmove2" files: dir7-2/c dir7/c dir7/dir9/b dir7/dir9/dir8/a dir8-2/a dir9-2/b
255 @ 14 "largefile" files: large-file
256 |
257 o 13 "divergentdirmove2" files: dir7-2/c dir7/c dir7/dir9/b dir7/dir9/dir8/a dir8-2/a dir9-2/b
244 |
258 |
245 o 12 "divergentdirmove" files: dir7/c dir7/dir9/b dir7/dir9/dir8/a
259 o 12 "divergentdirmove" files: dir7/c dir7/dir9/b dir7/dir9/dir8/a
246 |
260 |
247 o 11 "dirdirmove2" files: dir4/a dir6/dir4/a
261 o 11 "dirdirmove2" files: dir4/a dir6/dir4/a
248 |
262 |
249 o 10 "dirdirmove" files: dir4/a
263 o 10 "dirdirmove" files: dir4/a
250 |
264 |
251 o 9 "dirfilemove2" files: dir3/a dir3/d2/a
265 o 9 "dirfilemove2" files: dir3/a dir3/d2/a
252 |
266 |
253 o 8 "dirfilemove" files: dir3/a
267 o 8 "dirfilemove" files: dir3/a
254 |
268 |
255 o 7 "dropdirectory" files: dir2/dir/subdir/f
269 o 7 "dropdirectory" files: dir2/dir/subdir/f
256 |
270 |
257 o 6 "emptydir" files: dir2/dir/subdir/f
271 o 6 "emptydir" files: dir2/dir/subdir/f
258 |
272 |
259 o 5 "movedir" files: dir/a dir/d dir2/a dir2/newfile
273 o 5 "movedir" files: dir/a dir/d dir2/a dir2/newfile
260 |
274 |
261 o 4 "movedir1" files: dir1/subdir1/file1 dir1/subdir2/file1
275 o 4 "movedir1" files: dir1/subdir1/file1 dir1/subdir2/file1
262 |
276 |
263 o 3 "createdir1" files: dir1/subdir1/file1 dir1/subdir2_other/file1
277 o 3 "createdir1" files: dir1/subdir1/file1 dir1/subdir2_other/file1
264 |
278 |
265 o 2 "update2 "with" quotes" files: bin bin2 dir/b e
279 o 2 "update2 "with" quotes" files: bin bin2 dir/b e
266 |
280 |
267 o 1 "update1" files: a bin c dir/a dir/b
281 o 1 "update1" files: a bin c dir/a dir/b
268 |
282 |
269 o 0 "initialize" files: a bin c dir/b dir/d
283 o 0 "initialize" files: a bin c dir/b dir/d
270
284
271
285
272 manifest
286 manifest
273
287
274 $ hg manifest
288 $ hg manifest
275 bin2
289 bin2
276 dir1/subdir2/file1
290 dir1/subdir2/file1
277 dir1/subdir2_other/file1
291 dir1/subdir2_other/file1
278 dir2/a
292 dir2/a
279 dir2/newfile
293 dir2/newfile
280 dir3/d2/a
294 dir3/d2/a
281 dir6/dir4/a
295 dir6/dir4/a
282 dir7-2/c
296 dir7-2/c
283 dir8-2/a
297 dir8-2/a
284 dir9-2/b
298 dir9-2/b
285 e
299 e
300 large-file
286
301
287 contents
302 contents
288
303
289 $ cat dir2/a
304 $ cat dir2/a
290 a
305 a
291 a
306 a
292 $ test -d dir2/dir && echo 'removed dir2/dir is still there!'
307 $ test -d dir2/dir && echo 'removed dir2/dir is still there!'
293 [1]
308 [1]
294
309
295 file move
310 file move
296
311
297 $ hg log -v -C -r 1 | grep copies
312 $ hg log -v -C -r 1 | grep copies
298 copies: dir/a (a)
313 copies: dir/a (a)
299
314
300 check directory move
315 check directory move
301
316
302 $ hg manifest -r 4
317 $ hg manifest -r 4
303 bin2
318 bin2
304 dir/a
319 dir/a
305 dir/d
320 dir/d
306 dir1/subdir2/file1
321 dir1/subdir2/file1
307 dir1/subdir2_other/file1
322 dir1/subdir2_other/file1
308 e
323 e
309 $ test -d dir1/subdir2 || echo 'new dir1/subdir2 does not exist!'
324 $ test -d dir1/subdir2 || echo 'new dir1/subdir2 does not exist!'
310 $ test -d dir1/subdir1 && echo 'renamed dir1/subdir1 is still there!'
325 $ test -d dir1/subdir1 && echo 'renamed dir1/subdir1 is still there!'
311 [1]
326 [1]
312 $ hg log -v -C -r 4 | grep copies
327 $ hg log -v -C -r 4 | grep copies
313 copies: dir1/subdir2/file1 (dir1/subdir1/file1)
328 copies: dir1/subdir2/file1 (dir1/subdir1/file1)
314
329
315 check file remove with directory move
330 check file remove with directory move
316
331
317 $ hg manifest -r 5
332 $ hg manifest -r 5
318 bin2
333 bin2
319 dir1/subdir2/file1
334 dir1/subdir2/file1
320 dir1/subdir2_other/file1
335 dir1/subdir2_other/file1
321 dir2/a
336 dir2/a
322 dir2/newfile
337 dir2/newfile
323 e
338 e
324
339
325 check file move with directory move
340 check file move with directory move
326
341
327 $ hg manifest -r 9
342 $ hg manifest -r 9
328 bin2
343 bin2
329 dir1/subdir2/file1
344 dir1/subdir2/file1
330 dir1/subdir2_other/file1
345 dir1/subdir2_other/file1
331 dir2/a
346 dir2/a
332 dir2/newfile
347 dir2/newfile
333 dir3/d2/a
348 dir3/d2/a
334 e
349 e
335
350
336 check file directory directory move
351 check file directory directory move
337
352
338 $ hg manifest -r 11
353 $ hg manifest -r 11
339 bin2
354 bin2
340 dir1/subdir2/file1
355 dir1/subdir2/file1
341 dir1/subdir2_other/file1
356 dir1/subdir2_other/file1
342 dir2/a
357 dir2/a
343 dir2/newfile
358 dir2/newfile
344 dir3/d2/a
359 dir3/d2/a
345 dir6/dir4/a
360 dir6/dir4/a
346 e
361 e
347
362
348 check divergent directory moves
363 check divergent directory moves
349
364
350 $ hg manifest -r 13
365 $ hg manifest -r 13
351 bin2
366 bin2
352 dir1/subdir2/file1
367 dir1/subdir2/file1
353 dir1/subdir2_other/file1
368 dir1/subdir2_other/file1
354 dir2/a
369 dir2/a
355 dir2/newfile
370 dir2/newfile
356 dir3/d2/a
371 dir3/d2/a
357 dir6/dir4/a
372 dir6/dir4/a
358 dir7-2/c
373 dir7-2/c
359 dir8-2/a
374 dir8-2/a
360 dir9-2/b
375 dir9-2/b
361 e
376 e
362
377
378 test large file support (> 32kB)
379
380 $ $TESTDIR/md5sum.py large-file
381 5d6de8a95c3b6bf9e0ffb808ba5299c1 large-file
382
363 check branch closing
383 check branch closing
364
384
365 $ hg branches -a
385 $ hg branches -a
366 $ hg branches -c
386 $ hg branches -c
367 com.selenic.test 13:* (closed) (glob)
387 com.selenic.test 14:* (closed) (glob)
368
388
General Comments 0
You need to be logged in to leave comments. Login now