##// END OF EJS Templates
convert/mtn: convert suspended branches as closed branches...
Daniel Atallah -
r13779:c13bfa45 default
parent child Browse files
Show More
@@ -1,354 +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 = output
163
163
164 return retval
164 return 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 certs = self.mtngetcerts(rev)
294 extra = {}
295 certs = self.mtngetcerts(rev)
296 if certs.get('suspend') == certs["branch"]:
297 extra['close'] = '1'
295 return commit(
298 return commit(
296 author=certs["author"],
299 author=certs["author"],
297 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")),
298 desc=certs["changelog"],
301 desc=certs["changelog"],
299 rev=rev,
302 rev=rev,
300 parents=self.mtnrun("parents", rev).splitlines(),
303 parents=self.mtnrun("parents", rev).splitlines(),
301 branch=certs["branch"])
304 branch=certs["branch"],
305 extra=extra)
302
306
303 def gettags(self):
307 def gettags(self):
304 tags = {}
308 tags = {}
305 for e in self.mtnrun("tags").split("\n\n"):
309 for e in self.mtnrun("tags").split("\n\n"):
306 m = self.tag_re.match(e)
310 m = self.tag_re.match(e)
307 if m:
311 if m:
308 tags[m.group(1)] = m.group(2)
312 tags[m.group(1)] = m.group(2)
309 return tags
313 return tags
310
314
311 def getchangedfiles(self, rev, i):
315 def getchangedfiles(self, rev, i):
312 # This function is only needed to support --filemap
316 # This function is only needed to support --filemap
313 # ... and we don't support that
317 # ... and we don't support that
314 raise NotImplementedError()
318 raise NotImplementedError()
315
319
316 def before(self):
320 def before(self):
317 # 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
318 version = 0.0
322 version = 0.0
319 try:
323 try:
320 versionstr = self.mtnrunsingle("interface_version")
324 versionstr = self.mtnrunsingle("interface_version")
321 version = float(versionstr)
325 version = float(versionstr)
322 except Exception:
326 except Exception:
323 raise util.Abort(_("unable to determine mtn automate interface "
327 raise util.Abort(_("unable to determine mtn automate interface "
324 "version"))
328 "version"))
325
329
326 if version >= 12.0:
330 if version >= 12.0:
327 self.automatestdio = True
331 self.automatestdio = True
328 self.ui.debug("mtn automate version %s - using automate stdio\n" %
332 self.ui.debug("mtn automate version %s - using automate stdio\n" %
329 version)
333 version)
330
334
331 # launch the long-running automate stdio process
335 # launch the long-running automate stdio process
332 self.mtnwritefp, self.mtnreadfp = self._run2('automate', 'stdio',
336 self.mtnwritefp, self.mtnreadfp = self._run2('automate', 'stdio',
333 '-d', self.path)
337 '-d', self.path)
334 # read the headers
338 # read the headers
335 read = self.mtnreadfp.readline()
339 read = self.mtnreadfp.readline()
336 if read != 'format-version: 2\n':
340 if read != 'format-version: 2\n':
337 raise util.Abort(_('mtn automate stdio header unexpected: %s')
341 raise util.Abort(_('mtn automate stdio header unexpected: %s')
338 % read)
342 % read)
339 while read != '\n':
343 while read != '\n':
340 read = self.mtnreadfp.readline()
344 read = self.mtnreadfp.readline()
341 if not read:
345 if not read:
342 raise util.Abort(_("failed to reach end of mtn automate "
346 raise util.Abort(_("failed to reach end of mtn automate "
343 "stdio headers"))
347 "stdio headers"))
344 else:
348 else:
345 self.ui.debug("mtn automate version %s - not using automate stdio "
349 self.ui.debug("mtn automate version %s - not using automate stdio "
346 "(automate >= 12.0 - mtn >= 0.46 is needed)\n" % version)
350 "(automate >= 12.0 - mtn >= 0.46 is needed)\n" % version)
347
351
348 def after(self):
352 def after(self):
349 if self.automatestdio:
353 if self.automatestdio:
350 self.mtnwritefp.close()
354 self.mtnwritefp.close()
351 self.mtnwritefp = None
355 self.mtnwritefp = None
352 self.mtnreadfp.close()
356 self.mtnreadfp.close()
353 self.mtnreadfp = None
357 self.mtnreadfp = None
354
358
@@ -1,357 +1,368 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
211 test suspending (closing a branch)
212
213 $ mtn suspend 4a736634505795f17786fffdf2c9cbf5b11df6f6 2> /dev/null
210 $ cd ..
214 $ cd ..
211
215
212 convert incrementally
216 convert incrementally
213
217
214 $ hg convert -s mtn repo.mtn
218 $ hg convert -s mtn repo.mtn
215 assuming destination repo.mtn-hg
219 assuming destination repo.mtn-hg
216 scanning source...
220 scanning source...
217 sorting...
221 sorting...
218 converting...
222 converting...
219 11 update2 "with" quotes
223 11 update2 "with" quotes
220 10 createdir1
224 10 createdir1
221 9 movedir1
225 9 movedir1
222 8 movedir
226 8 movedir
223 7 emptydir
227 7 emptydir
224 6 dropdirectory
228 6 dropdirectory
225 5 dirfilemove
229 5 dirfilemove
226 4 dirfilemove2
230 4 dirfilemove2
227 3 dirdirmove
231 3 dirdirmove
228 2 dirdirmove2
232 2 dirdirmove2
229 1 divergentdirmove
233 1 divergentdirmove
230 0 divergentdirmove2
234 0 divergentdirmove2
231 $ glog()
235 $ glog()
232 > {
236 > {
233 > hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@"
237 > hg glog --template '{rev} "{desc|firstline}" files: {files}\n' "$@"
234 > }
238 > }
235 $ cd repo.mtn-hg
239 $ cd repo.mtn-hg
236 $ hg up -C
240 $ hg up -C
237 11 files updated, 0 files merged, 0 files removed, 0 files unresolved
241 11 files updated, 0 files merged, 0 files removed, 0 files unresolved
238 $ glog
242 $ glog
239 @ 13 "divergentdirmove2" files: dir7-2/c dir7/c dir7/dir9/b dir7/dir9/dir8/a dir8-2/a dir9-2/b
243 @ 13 "divergentdirmove2" files: dir7-2/c dir7/c dir7/dir9/b dir7/dir9/dir8/a dir8-2/a dir9-2/b
240 |
244 |
241 o 12 "divergentdirmove" files: dir7/c dir7/dir9/b dir7/dir9/dir8/a
245 o 12 "divergentdirmove" files: dir7/c dir7/dir9/b dir7/dir9/dir8/a
242 |
246 |
243 o 11 "dirdirmove2" files: dir4/a dir6/dir4/a
247 o 11 "dirdirmove2" files: dir4/a dir6/dir4/a
244 |
248 |
245 o 10 "dirdirmove" files: dir4/a
249 o 10 "dirdirmove" files: dir4/a
246 |
250 |
247 o 9 "dirfilemove2" files: dir3/a dir3/d2/a
251 o 9 "dirfilemove2" files: dir3/a dir3/d2/a
248 |
252 |
249 o 8 "dirfilemove" files: dir3/a
253 o 8 "dirfilemove" files: dir3/a
250 |
254 |
251 o 7 "dropdirectory" files: dir2/dir/subdir/f
255 o 7 "dropdirectory" files: dir2/dir/subdir/f
252 |
256 |
253 o 6 "emptydir" files: dir2/dir/subdir/f
257 o 6 "emptydir" files: dir2/dir/subdir/f
254 |
258 |
255 o 5 "movedir" files: dir/a dir/d dir2/a dir2/newfile
259 o 5 "movedir" files: dir/a dir/d dir2/a dir2/newfile
256 |
260 |
257 o 4 "movedir1" files: dir1/subdir1/file1 dir1/subdir2/file1
261 o 4 "movedir1" files: dir1/subdir1/file1 dir1/subdir2/file1
258 |
262 |
259 o 3 "createdir1" files: dir1/subdir1/file1 dir1/subdir2_other/file1
263 o 3 "createdir1" files: dir1/subdir1/file1 dir1/subdir2_other/file1
260 |
264 |
261 o 2 "update2 "with" quotes" files: bin bin2 dir/b e
265 o 2 "update2 "with" quotes" files: bin bin2 dir/b e
262 |
266 |
263 o 1 "update1" files: a bin c dir/a dir/b
267 o 1 "update1" files: a bin c dir/a dir/b
264 |
268 |
265 o 0 "initialize" files: a bin c dir/b dir/d
269 o 0 "initialize" files: a bin c dir/b dir/d
266
270
267
271
268 manifest
272 manifest
269
273
270 $ hg manifest
274 $ hg manifest
271 bin2
275 bin2
272 dir1/subdir2/file1
276 dir1/subdir2/file1
273 dir1/subdir2_other/file1
277 dir1/subdir2_other/file1
274 dir2/a
278 dir2/a
275 dir2/newfile
279 dir2/newfile
276 dir3/d2/a
280 dir3/d2/a
277 dir6/dir4/a
281 dir6/dir4/a
278 dir7-2/c
282 dir7-2/c
279 dir8-2/a
283 dir8-2/a
280 dir9-2/b
284 dir9-2/b
281 e
285 e
282
286
283 contents
287 contents
284
288
285 $ cat dir2/a
289 $ cat dir2/a
286 a
290 a
287 a
291 a
288 $ test -d dir2/dir && echo 'removed dir2/dir is still there!'
292 $ test -d dir2/dir && echo 'removed dir2/dir is still there!'
289 [1]
293 [1]
290
294
291 file move
295 file move
292
296
293 $ hg log -v -C -r 1 | grep copies
297 $ hg log -v -C -r 1 | grep copies
294 copies: dir/a (a)
298 copies: dir/a (a)
295
299
296 check directory move
300 check directory move
297
301
298 $ hg manifest -r 4
302 $ hg manifest -r 4
299 bin2
303 bin2
300 dir/a
304 dir/a
301 dir/d
305 dir/d
302 dir1/subdir2/file1
306 dir1/subdir2/file1
303 dir1/subdir2_other/file1
307 dir1/subdir2_other/file1
304 e
308 e
305 $ test -d dir1/subdir2 || echo 'new dir1/subdir2 does not exist!'
309 $ test -d dir1/subdir2 || echo 'new dir1/subdir2 does not exist!'
306 $ test -d dir1/subdir1 && echo 'renamed dir1/subdir1 is still there!'
310 $ test -d dir1/subdir1 && echo 'renamed dir1/subdir1 is still there!'
307 [1]
311 [1]
308 $ hg log -v -C -r 4 | grep copies
312 $ hg log -v -C -r 4 | grep copies
309 copies: dir1/subdir2/file1 (dir1/subdir1/file1)
313 copies: dir1/subdir2/file1 (dir1/subdir1/file1)
310
314
311 check file remove with directory move
315 check file remove with directory move
312
316
313 $ hg manifest -r 5
317 $ hg manifest -r 5
314 bin2
318 bin2
315 dir1/subdir2/file1
319 dir1/subdir2/file1
316 dir1/subdir2_other/file1
320 dir1/subdir2_other/file1
317 dir2/a
321 dir2/a
318 dir2/newfile
322 dir2/newfile
319 e
323 e
320
324
321 check file move with directory move
325 check file move with directory move
322
326
323 $ hg manifest -r 9
327 $ hg manifest -r 9
324 bin2
328 bin2
325 dir1/subdir2/file1
329 dir1/subdir2/file1
326 dir1/subdir2_other/file1
330 dir1/subdir2_other/file1
327 dir2/a
331 dir2/a
328 dir2/newfile
332 dir2/newfile
329 dir3/d2/a
333 dir3/d2/a
330 e
334 e
331
335
332 check file directory directory move
336 check file directory directory move
333
337
334 $ hg manifest -r 11
338 $ hg manifest -r 11
335 bin2
339 bin2
336 dir1/subdir2/file1
340 dir1/subdir2/file1
337 dir1/subdir2_other/file1
341 dir1/subdir2_other/file1
338 dir2/a
342 dir2/a
339 dir2/newfile
343 dir2/newfile
340 dir3/d2/a
344 dir3/d2/a
341 dir6/dir4/a
345 dir6/dir4/a
342 e
346 e
343
347
344 check divergent directory moves
348 check divergent directory moves
345
349
346 $ hg manifest -r 13
350 $ hg manifest -r 13
347 bin2
351 bin2
348 dir1/subdir2/file1
352 dir1/subdir2/file1
349 dir1/subdir2_other/file1
353 dir1/subdir2_other/file1
350 dir2/a
354 dir2/a
351 dir2/newfile
355 dir2/newfile
352 dir3/d2/a
356 dir3/d2/a
353 dir6/dir4/a
357 dir6/dir4/a
354 dir7-2/c
358 dir7-2/c
355 dir8-2/a
359 dir8-2/a
356 dir9-2/b
360 dir9-2/b
357 e
361 e
362
363 check branch closing
364
365 $ hg branches -a
366 $ hg branches -c
367 com.selenic.test 13:* (closed) (glob)
368
General Comments 0
You need to be logged in to leave comments. Login now