##// END OF EJS Templates
dirstate: do not ignore current directory '.' (issue 1078)
Patrick Mezard -
r6479:31abcae3 default
parent child Browse files
Show More
@@ -1,635 +1,637 b''
1 1 """
2 2 dirstate.py - working directory tracking for mercurial
3 3
4 4 Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
5 5
6 6 This software may be used and distributed according to the terms
7 7 of the GNU General Public License, incorporated herein by reference.
8 8 """
9 9
10 10 from node import nullid
11 11 from i18n import _
12 12 import struct, os, bisect, stat, strutil, util, errno, ignore
13 13 import cStringIO, osutil, sys
14 14
15 15 _unknown = ('?', 0, 0, 0)
16 16 _format = ">cllll"
17 17
18 18 class dirstate(object):
19 19
20 20 def __init__(self, opener, ui, root):
21 21 self._opener = opener
22 22 self._root = root
23 23 self._dirty = False
24 24 self._dirtypl = False
25 25 self._ui = ui
26 26
27 27 def __getattr__(self, name):
28 28 if name == '_map':
29 29 self._read()
30 30 return self._map
31 31 elif name == '_copymap':
32 32 self._read()
33 33 return self._copymap
34 34 elif name == '_branch':
35 35 try:
36 36 self._branch = (self._opener("branch").read().strip()
37 37 or "default")
38 38 except IOError:
39 39 self._branch = "default"
40 40 return self._branch
41 41 elif name == '_pl':
42 42 self._pl = [nullid, nullid]
43 43 try:
44 44 st = self._opener("dirstate").read(40)
45 45 if len(st) == 40:
46 46 self._pl = st[:20], st[20:40]
47 47 except IOError, err:
48 48 if err.errno != errno.ENOENT: raise
49 49 return self._pl
50 50 elif name == '_dirs':
51 51 self._dirs = {}
52 52 for f in self._map:
53 53 if self[f] != 'r':
54 54 self._incpath(f)
55 55 return self._dirs
56 56 elif name == '_ignore':
57 57 files = [self._join('.hgignore')]
58 58 for name, path in self._ui.configitems("ui"):
59 59 if name == 'ignore' or name.startswith('ignore.'):
60 60 files.append(os.path.expanduser(path))
61 61 self._ignore = ignore.ignore(self._root, files, self._ui.warn)
62 62 return self._ignore
63 63 elif name == '_slash':
64 64 self._slash = self._ui.configbool('ui', 'slash') and os.sep != '/'
65 65 return self._slash
66 66 elif name == '_checkexec':
67 67 self._checkexec = util.checkexec(self._root)
68 68 return self._checkexec
69 69 else:
70 70 raise AttributeError, name
71 71
72 72 def _join(self, f):
73 73 return os.path.join(self._root, f)
74 74
75 75 def getcwd(self):
76 76 cwd = os.getcwd()
77 77 if cwd == self._root: return ''
78 78 # self._root ends with a path separator if self._root is '/' or 'C:\'
79 79 rootsep = self._root
80 80 if not util.endswithsep(rootsep):
81 81 rootsep += os.sep
82 82 if cwd.startswith(rootsep):
83 83 return cwd[len(rootsep):]
84 84 else:
85 85 # we're outside the repo. return an absolute path.
86 86 return cwd
87 87
88 88 def pathto(self, f, cwd=None):
89 89 if cwd is None:
90 90 cwd = self.getcwd()
91 91 path = util.pathto(self._root, cwd, f)
92 92 if self._slash:
93 93 return util.normpath(path)
94 94 return path
95 95
96 96 def __getitem__(self, key):
97 97 ''' current states:
98 98 n normal
99 99 m needs merging
100 100 r marked for removal
101 101 a marked for addition
102 102 ? not tracked'''
103 103 return self._map.get(key, ("?",))[0]
104 104
105 105 def __contains__(self, key):
106 106 return key in self._map
107 107
108 108 def __iter__(self):
109 109 a = self._map.keys()
110 110 a.sort()
111 111 for x in a:
112 112 yield x
113 113
114 114 def parents(self):
115 115 return self._pl
116 116
117 117 def branch(self):
118 118 return self._branch
119 119
120 120 def setparents(self, p1, p2=nullid):
121 121 self._dirty = self._dirtypl = True
122 122 self._pl = p1, p2
123 123
124 124 def setbranch(self, branch):
125 125 self._branch = branch
126 126 self._opener("branch", "w").write(branch + '\n')
127 127
128 128 def _read(self):
129 129 self._map = {}
130 130 self._copymap = {}
131 131 if not self._dirtypl:
132 132 self._pl = [nullid, nullid]
133 133 try:
134 134 st = self._opener("dirstate").read()
135 135 except IOError, err:
136 136 if err.errno != errno.ENOENT: raise
137 137 return
138 138 if not st:
139 139 return
140 140
141 141 if not self._dirtypl:
142 142 self._pl = [st[:20], st[20: 40]]
143 143
144 144 # deref fields so they will be local in loop
145 145 dmap = self._map
146 146 copymap = self._copymap
147 147 unpack = struct.unpack
148 148 e_size = struct.calcsize(_format)
149 149 pos1 = 40
150 150 l = len(st)
151 151
152 152 # the inner loop
153 153 while pos1 < l:
154 154 pos2 = pos1 + e_size
155 155 e = unpack(">cllll", st[pos1:pos2]) # a literal here is faster
156 156 pos1 = pos2 + e[4]
157 157 f = st[pos2:pos1]
158 158 if '\0' in f:
159 159 f, c = f.split('\0')
160 160 copymap[f] = c
161 161 dmap[f] = e # we hold onto e[4] because making a subtuple is slow
162 162
163 163 def invalidate(self):
164 164 for a in "_map _copymap _branch _pl _dirs _ignore".split():
165 165 if a in self.__dict__:
166 166 delattr(self, a)
167 167 self._dirty = False
168 168
169 169 def copy(self, source, dest):
170 170 self._dirty = True
171 171 self._copymap[dest] = source
172 172
173 173 def copied(self, file):
174 174 return self._copymap.get(file, None)
175 175
176 176 def copies(self):
177 177 return self._copymap
178 178
179 179 def _incpath(self, path):
180 180 c = path.rfind('/')
181 181 if c >= 0:
182 182 dirs = self._dirs
183 183 base = path[:c]
184 184 if base not in dirs:
185 185 self._incpath(base)
186 186 dirs[base] = 1
187 187 else:
188 188 dirs[base] += 1
189 189
190 190 def _decpath(self, path):
191 191 c = path.rfind('/')
192 192 if c >= 0:
193 193 base = path[:c]
194 194 dirs = self._dirs
195 195 if dirs[base] == 1:
196 196 del dirs[base]
197 197 self._decpath(base)
198 198 else:
199 199 dirs[base] -= 1
200 200
201 201 def _incpathcheck(self, f):
202 202 if '\r' in f or '\n' in f:
203 203 raise util.Abort(_("'\\n' and '\\r' disallowed in filenames: %r")
204 204 % f)
205 205 # shadows
206 206 if f in self._dirs:
207 207 raise util.Abort(_('directory %r already in dirstate') % f)
208 208 for c in strutil.rfindall(f, '/'):
209 209 d = f[:c]
210 210 if d in self._dirs:
211 211 break
212 212 if d in self._map and self[d] != 'r':
213 213 raise util.Abort(_('file %r in dirstate clashes with %r') %
214 214 (d, f))
215 215 self._incpath(f)
216 216
217 217 def _changepath(self, f, newstate, relaxed=False):
218 218 # handle upcoming path changes
219 219 oldstate = self[f]
220 220 if oldstate not in "?r" and newstate in "?r":
221 221 if "_dirs" in self.__dict__:
222 222 self._decpath(f)
223 223 return
224 224 if oldstate in "?r" and newstate not in "?r":
225 225 if relaxed and oldstate == '?':
226 226 # XXX
227 227 # in relaxed mode we assume the caller knows
228 228 # what it is doing, workaround for updating
229 229 # dir-to-file revisions
230 230 if "_dirs" in self.__dict__:
231 231 self._incpath(f)
232 232 return
233 233 self._incpathcheck(f)
234 234 return
235 235
236 236 def normal(self, f):
237 237 'mark a file normal and clean'
238 238 self._dirty = True
239 239 self._changepath(f, 'n', True)
240 240 s = os.lstat(self._join(f))
241 241 self._map[f] = ('n', s.st_mode, s.st_size, s.st_mtime, 0)
242 242 if f in self._copymap:
243 243 del self._copymap[f]
244 244
245 245 def normallookup(self, f):
246 246 'mark a file normal, but possibly dirty'
247 247 if self._pl[1] != nullid and f in self._map:
248 248 # if there is a merge going on and the file was either
249 249 # in state 'm' or dirty before being removed, restore that state.
250 250 entry = self._map[f]
251 251 if entry[0] == 'r' and entry[2] in (-1, -2):
252 252 source = self._copymap.get(f)
253 253 if entry[2] == -1:
254 254 self.merge(f)
255 255 elif entry[2] == -2:
256 256 self.normaldirty(f)
257 257 if source:
258 258 self.copy(source, f)
259 259 return
260 260 if entry[0] == 'm' or entry[0] == 'n' and entry[2] == -2:
261 261 return
262 262 self._dirty = True
263 263 self._changepath(f, 'n', True)
264 264 self._map[f] = ('n', 0, -1, -1, 0)
265 265 if f in self._copymap:
266 266 del self._copymap[f]
267 267
268 268 def normaldirty(self, f):
269 269 'mark a file normal, but dirty'
270 270 self._dirty = True
271 271 self._changepath(f, 'n', True)
272 272 self._map[f] = ('n', 0, -2, -1, 0)
273 273 if f in self._copymap:
274 274 del self._copymap[f]
275 275
276 276 def add(self, f):
277 277 'mark a file added'
278 278 self._dirty = True
279 279 self._changepath(f, 'a')
280 280 self._map[f] = ('a', 0, -1, -1, 0)
281 281 if f in self._copymap:
282 282 del self._copymap[f]
283 283
284 284 def remove(self, f):
285 285 'mark a file removed'
286 286 self._dirty = True
287 287 self._changepath(f, 'r')
288 288 size = 0
289 289 if self._pl[1] != nullid and f in self._map:
290 290 entry = self._map[f]
291 291 if entry[0] == 'm':
292 292 size = -1
293 293 elif entry[0] == 'n' and entry[2] == -2:
294 294 size = -2
295 295 self._map[f] = ('r', 0, size, 0, 0)
296 296 if size == 0 and f in self._copymap:
297 297 del self._copymap[f]
298 298
299 299 def merge(self, f):
300 300 'mark a file merged'
301 301 self._dirty = True
302 302 s = os.lstat(self._join(f))
303 303 self._changepath(f, 'm', True)
304 304 self._map[f] = ('m', s.st_mode, s.st_size, s.st_mtime, 0)
305 305 if f in self._copymap:
306 306 del self._copymap[f]
307 307
308 308 def forget(self, f):
309 309 'forget a file'
310 310 self._dirty = True
311 311 try:
312 312 self._changepath(f, '?')
313 313 del self._map[f]
314 314 except KeyError:
315 315 self._ui.warn(_("not in dirstate: %s\n") % f)
316 316
317 317 def clear(self):
318 318 self._map = {}
319 319 if "_dirs" in self.__dict__:
320 320 delattr(self, "_dirs");
321 321 self._copymap = {}
322 322 self._pl = [nullid, nullid]
323 323 self._dirty = True
324 324
325 325 def rebuild(self, parent, files):
326 326 self.clear()
327 327 for f in files:
328 328 if files.execf(f):
329 329 self._map[f] = ('n', 0777, -1, 0, 0)
330 330 else:
331 331 self._map[f] = ('n', 0666, -1, 0, 0)
332 332 self._pl = (parent, nullid)
333 333 self._dirty = True
334 334
335 335 def write(self):
336 336 if not self._dirty:
337 337 return
338 338 st = self._opener("dirstate", "w", atomictemp=True)
339 339
340 340 try:
341 341 gran = int(self._ui.config('dirstate', 'granularity', 1))
342 342 except ValueError:
343 343 gran = 1
344 344 limit = sys.maxint
345 345 if gran > 0:
346 346 limit = util.fstat(st).st_mtime - gran
347 347
348 348 cs = cStringIO.StringIO()
349 349 copymap = self._copymap
350 350 pack = struct.pack
351 351 write = cs.write
352 352 write("".join(self._pl))
353 353 for f, e in self._map.iteritems():
354 354 if f in copymap:
355 355 f = "%s\0%s" % (f, copymap[f])
356 356 if e[3] > limit and e[0] == 'n':
357 357 e = (e[0], 0, -1, -1, 0)
358 358 e = pack(_format, e[0], e[1], e[2], e[3], len(f))
359 359 write(e)
360 360 write(f)
361 361 st.write(cs.getvalue())
362 362 st.rename()
363 363 self._dirty = self._dirtypl = False
364 364
365 365 def _filter(self, files):
366 366 ret = {}
367 367 unknown = []
368 368
369 369 for x in files:
370 370 if x == '.':
371 371 return self._map.copy()
372 372 if x not in self._map:
373 373 unknown.append(x)
374 374 else:
375 375 ret[x] = self._map[x]
376 376
377 377 if not unknown:
378 378 return ret
379 379
380 380 b = self._map.keys()
381 381 b.sort()
382 382 blen = len(b)
383 383
384 384 for x in unknown:
385 385 bs = bisect.bisect(b, "%s%s" % (x, '/'))
386 386 while bs < blen:
387 387 s = b[bs]
388 388 if len(s) > len(x) and s.startswith(x):
389 389 ret[s] = self._map[s]
390 390 else:
391 391 break
392 392 bs += 1
393 393 return ret
394 394
395 395 def _supported(self, f, mode, verbose=False):
396 396 if stat.S_ISREG(mode) or stat.S_ISLNK(mode):
397 397 return True
398 398 if verbose:
399 399 kind = 'unknown'
400 400 if stat.S_ISCHR(mode): kind = _('character device')
401 401 elif stat.S_ISBLK(mode): kind = _('block device')
402 402 elif stat.S_ISFIFO(mode): kind = _('fifo')
403 403 elif stat.S_ISSOCK(mode): kind = _('socket')
404 404 elif stat.S_ISDIR(mode): kind = _('directory')
405 405 self._ui.warn(_('%s: unsupported file type (type is %s)\n')
406 406 % (self.pathto(f), kind))
407 407 return False
408 408
409 409 def _dirignore(self, f):
410 if f == '.':
411 return False
410 412 if self._ignore(f):
411 413 return True
412 414 for c in strutil.findall(f, '/'):
413 415 if self._ignore(f[:c]):
414 416 return True
415 417 return False
416 418
417 419 def walk(self, files=None, match=util.always, badmatch=None):
418 420 # filter out the stat
419 421 for src, f, st in self.statwalk(files, match, badmatch=badmatch):
420 422 yield src, f
421 423
422 424 def statwalk(self, files=None, match=util.always, unknown=True,
423 425 ignored=False, badmatch=None, directories=False):
424 426 '''
425 427 walk recursively through the directory tree, finding all files
426 428 matched by the match function
427 429
428 430 results are yielded in a tuple (src, filename, st), where src
429 431 is one of:
430 432 'f' the file was found in the directory tree
431 433 'd' the file is a directory of the tree
432 434 'm' the file was only in the dirstate and not in the tree
433 435 'b' file was not found and matched badmatch
434 436
435 437 and st is the stat result if the file was found in the directory.
436 438 '''
437 439
438 440 # walk all files by default
439 441 if not files:
440 442 files = ['.']
441 443 dc = self._map.copy()
442 444 else:
443 445 files = util.unique(files)
444 446 dc = self._filter(files)
445 447
446 448 def imatch(file_):
447 449 if file_ not in dc and self._ignore(file_):
448 450 return False
449 451 return match(file_)
450 452
451 453 # TODO: don't walk unknown directories if unknown and ignored are False
452 454 ignore = self._ignore
453 455 dirignore = self._dirignore
454 456 if ignored:
455 457 imatch = match
456 458 ignore = util.never
457 459 dirignore = util.never
458 460
459 461 # self._root may end with a path separator when self._root == '/'
460 462 common_prefix_len = len(self._root)
461 463 if not util.endswithsep(self._root):
462 464 common_prefix_len += 1
463 465
464 466 normpath = util.normpath
465 467 listdir = osutil.listdir
466 468 lstat = os.lstat
467 469 bisect_left = bisect.bisect_left
468 470 isdir = os.path.isdir
469 471 pconvert = util.pconvert
470 472 join = os.path.join
471 473 s_isdir = stat.S_ISDIR
472 474 supported = self._supported
473 475 _join = self._join
474 476 known = {'.hg': 1}
475 477
476 478 # recursion free walker, faster than os.walk.
477 479 def findfiles(s):
478 480 work = [s]
479 481 wadd = work.append
480 482 found = []
481 483 add = found.append
482 484 if directories:
483 485 add((normpath(s[common_prefix_len:]), 'd', lstat(s)))
484 486 while work:
485 487 top = work.pop()
486 488 entries = listdir(top, stat=True)
487 489 # nd is the top of the repository dir tree
488 490 nd = normpath(top[common_prefix_len:])
489 491 if nd == '.':
490 492 nd = ''
491 493 else:
492 494 # do not recurse into a repo contained in this
493 495 # one. use bisect to find .hg directory so speed
494 496 # is good on big directory.
495 497 names = [e[0] for e in entries]
496 498 hg = bisect_left(names, '.hg')
497 499 if hg < len(names) and names[hg] == '.hg':
498 500 if isdir(join(top, '.hg')):
499 501 continue
500 502 for f, kind, st in entries:
501 503 np = pconvert(join(nd, f))
502 504 if np in known:
503 505 continue
504 506 known[np] = 1
505 507 p = join(top, f)
506 508 # don't trip over symlinks
507 509 if kind == stat.S_IFDIR:
508 510 if not ignore(np):
509 511 wadd(p)
510 512 if directories:
511 513 add((np, 'd', st))
512 514 if np in dc and match(np):
513 515 add((np, 'm', st))
514 516 elif imatch(np):
515 517 if supported(np, st.st_mode):
516 518 add((np, 'f', st))
517 519 elif np in dc:
518 520 add((np, 'm', st))
519 521 found.sort()
520 522 return found
521 523
522 524 # step one, find all files that match our criteria
523 525 files.sort()
524 526 for ff in files:
525 527 nf = normpath(ff)
526 528 f = _join(ff)
527 529 try:
528 530 st = lstat(f)
529 531 except OSError, inst:
530 532 found = False
531 533 for fn in dc:
532 534 if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'):
533 535 found = True
534 536 break
535 537 if not found:
536 538 if inst.errno != errno.ENOENT or not badmatch:
537 539 self._ui.warn('%s: %s\n' %
538 540 (self.pathto(ff), inst.strerror))
539 541 elif badmatch and badmatch(ff) and imatch(nf):
540 542 yield 'b', ff, None
541 543 continue
542 544 if s_isdir(st.st_mode):
543 545 if not dirignore(nf):
544 546 for f, src, st in findfiles(f):
545 547 yield src, f, st
546 548 else:
547 549 if nf in known:
548 550 continue
549 551 known[nf] = 1
550 552 if match(nf):
551 553 if supported(ff, st.st_mode, verbose=True):
552 554 yield 'f', nf, st
553 555 elif ff in dc:
554 556 yield 'm', nf, st
555 557
556 558 # step two run through anything left in the dc hash and yield
557 559 # if we haven't already seen it
558 560 ks = dc.keys()
559 561 ks.sort()
560 562 for k in ks:
561 563 if k in known:
562 564 continue
563 565 known[k] = 1
564 566 if imatch(k):
565 567 yield 'm', k, None
566 568
567 569 def status(self, files, match, list_ignored, list_clean, list_unknown=True):
568 570 lookup, modified, added, unknown, ignored = [], [], [], [], []
569 571 removed, deleted, clean = [], [], []
570 572
571 573 files = files or []
572 574 _join = self._join
573 575 lstat = os.lstat
574 576 cmap = self._copymap
575 577 dmap = self._map
576 578 ladd = lookup.append
577 579 madd = modified.append
578 580 aadd = added.append
579 581 uadd = unknown.append
580 582 iadd = ignored.append
581 583 radd = removed.append
582 584 dadd = deleted.append
583 585 cadd = clean.append
584 586
585 587 for src, fn, st in self.statwalk(files, match, unknown=list_unknown,
586 588 ignored=list_ignored):
587 589 if fn in dmap:
588 590 type_, mode, size, time, foo = dmap[fn]
589 591 else:
590 592 if (list_ignored or fn in files) and self._dirignore(fn):
591 593 if list_ignored:
592 594 iadd(fn)
593 595 elif list_unknown:
594 596 uadd(fn)
595 597 continue
596 598 if src == 'm':
597 599 nonexistent = True
598 600 if not st:
599 601 try:
600 602 st = lstat(_join(fn))
601 603 except OSError, inst:
602 604 if inst.errno not in (errno.ENOENT, errno.ENOTDIR):
603 605 raise
604 606 st = None
605 607 # We need to re-check that it is a valid file
606 608 if st and self._supported(fn, st.st_mode):
607 609 nonexistent = False
608 610 # XXX: what to do with file no longer present in the fs
609 611 # who are not removed in the dirstate ?
610 612 if nonexistent and type_ in "nma":
611 613 dadd(fn)
612 614 continue
613 615 # check the common case first
614 616 if type_ == 'n':
615 617 if not st:
616 618 st = lstat(_join(fn))
617 619 if (size >= 0 and
618 620 (size != st.st_size
619 621 or ((mode ^ st.st_mode) & 0100 and self._checkexec))
620 622 or size == -2
621 623 or fn in self._copymap):
622 624 madd(fn)
623 625 elif time != int(st.st_mtime):
624 626 ladd(fn)
625 627 elif list_clean:
626 628 cadd(fn)
627 629 elif type_ == 'm':
628 630 madd(fn)
629 631 elif type_ == 'a':
630 632 aadd(fn)
631 633 elif type_ == 'r':
632 634 radd(fn)
633 635
634 636 return (lookup, modified, added, removed, deleted, unknown, ignored,
635 637 clean)
@@ -1,67 +1,71 b''
1 1 #!/bin/sh
2 2
3 3 hg init
4 4
5 5 # Test issue 562: .hgignore requires newline at end
6 6 touch foo
7 7 touch bar
8 8 touch baz
9 9 cat > makeignore.py <<EOF
10 10 f = open(".hgignore", "w")
11 11 f.write("ignore\n")
12 12 f.write("foo\n")
13 13 # No EOL here
14 14 f.write("bar")
15 15 f.close()
16 16 EOF
17 17
18 18 python makeignore.py
19 19 echo % should display baz only
20 20 hg status
21 21 rm foo bar baz .hgignore makeignore.py
22 22
23 23 touch a.o
24 24 touch a.c
25 25 touch syntax
26 26 mkdir dir
27 27 touch dir/a.o
28 28 touch dir/b.o
29 29 touch dir/c.o
30 30
31 31 hg add dir/a.o
32 32 hg commit -m 0
33 33 hg add dir/b.o
34 34
35 35 echo "--" ; hg status
36 36
37 37 echo "*.o" > .hgignore
38 38 echo "--" ; hg status 2>&1 | sed -e 's/abort: .*\.hgignore:/abort: .hgignore:/'
39 39
40 40 echo ".*\.o" > .hgignore
41 41 echo "--" ; hg status
42 42
43 # Check it does not ignore the current directory '.'
44 echo "^\." > .hgignore
45 echo "--" ; hg status
46
43 47 echo "glob:**.o" > .hgignore
44 48 echo "--" ; hg status
45 49
46 50 echo "glob:*.o" > .hgignore
47 51 echo "--" ; hg status
48 52
49 53 echo "syntax: glob" > .hgignore
50 54 echo "re:.*\.o" >> .hgignore
51 55 echo "--" ; hg status
52 56
53 57 echo "syntax: invalid" > .hgignore
54 58 echo "--" ; hg status 2>&1 | sed -e 's/.*\.hgignore:/.hgignore:/'
55 59
56 60 echo "syntax: glob" > .hgignore
57 61 echo "*.o" >> .hgignore
58 62 echo "--" ; hg status
59 63
60 64 echo "relglob:syntax*" > .hgignore
61 65 echo "--" ; hg status
62 66
63 67 echo "relglob:*" > .hgignore
64 68 echo "--" ; hg status
65 69
66 70 cd dir
67 71 echo "--" ; hg status .
@@ -1,53 +1,59 b''
1 1 % should display baz only
2 2 ? baz
3 3 --
4 4 A dir/b.o
5 5 ? a.c
6 6 ? a.o
7 7 ? dir/c.o
8 8 ? syntax
9 9 --
10 10 abort: .hgignore: invalid pattern (relre): *.o
11 11 --
12 12 A dir/b.o
13 13 ? .hgignore
14 14 ? a.c
15 15 ? syntax
16 16 --
17 17 A dir/b.o
18 ? a.c
19 ? a.o
20 ? dir/c.o
21 ? syntax
22 --
23 A dir/b.o
18 24 ? .hgignore
19 25 ? a.c
20 26 ? syntax
21 27 --
22 28 A dir/b.o
23 29 ? .hgignore
24 30 ? a.c
25 31 ? syntax
26 32 --
27 33 A dir/b.o
28 34 ? .hgignore
29 35 ? a.c
30 36 ? syntax
31 37 --
32 38 .hgignore: ignoring invalid syntax 'invalid'
33 39 A dir/b.o
34 40 ? .hgignore
35 41 ? a.c
36 42 ? a.o
37 43 ? dir/c.o
38 44 ? syntax
39 45 --
40 46 A dir/b.o
41 47 ? .hgignore
42 48 ? a.c
43 49 ? syntax
44 50 --
45 51 A dir/b.o
46 52 ? .hgignore
47 53 ? a.c
48 54 ? a.o
49 55 ? dir/c.o
50 56 --
51 57 A dir/b.o
52 58 --
53 59 A b.o
General Comments 0
You need to be logged in to leave comments. Login now