370 """Return target file lines, or its content as a single line |
370 """Return target file lines, or its content as a single line |
371 for symlinks. |
371 for symlinks. |
372 """ |
372 """ |
373 raise NotImplementedError |
373 raise NotImplementedError |
374 |
374 |
375 def writelines(self, fname, lines, mode): |
375 def setfile(self, fname, lines, mode): |
376 """Write lines to target file. mode is a (islink, isexec) |
376 """Write lines to target file. mode is a (islink, isexec) |
377 tuple, or None if there is no mode information. |
377 tuple, or None if there is no mode information. If lines is None, |
|
378 the file must exists and its content is left unchanged. |
378 """ |
379 """ |
379 raise NotImplementedError |
380 raise NotImplementedError |
380 |
381 |
381 def unlink(self, fname): |
382 def unlink(self, fname): |
382 """Unlink target file.""" |
383 """Unlink target file.""" |
395 directory. |
396 directory. |
396 """ |
397 """ |
397 raise NotImplementedError |
398 raise NotImplementedError |
398 |
399 |
399 def exists(self, fname): |
400 def exists(self, fname): |
400 raise NotImplementedError |
|
401 |
|
402 def setmode(self, fname, islink, isexec): |
|
403 """Change target file mode.""" |
|
404 raise NotImplementedError |
401 raise NotImplementedError |
405 |
402 |
406 class fsbackend(abstractbackend): |
403 class fsbackend(abstractbackend): |
407 def __init__(self, ui, basedir): |
404 def __init__(self, ui, basedir): |
408 super(fsbackend, self).__init__(ui) |
405 super(fsbackend, self).__init__(ui) |
418 try: |
415 try: |
419 return list(fp) |
416 return list(fp) |
420 finally: |
417 finally: |
421 fp.close() |
418 fp.close() |
422 |
419 |
423 def writelines(self, fname, lines, mode): |
420 def setfile(self, fname, lines, mode): |
|
421 if lines is None: |
|
422 if mode: |
|
423 util.setflags(self._join(fname), mode[0], mode[1]) |
|
424 return |
424 if not mode: |
425 if not mode: |
425 # Preserve mode information |
426 # Preserve mode information |
426 isexec, islink = False, False |
427 isexec, islink = False, False |
427 try: |
428 try: |
428 isexec = os.lstat(self._join(fname)).st_mode & 0100 != 0 |
429 isexec = os.lstat(self._join(fname)).st_mode & 0100 != 0 |
473 util.copyfile(abssrc, absdst) |
474 util.copyfile(abssrc, absdst) |
474 |
475 |
475 def exists(self, fname): |
476 def exists(self, fname): |
476 return os.path.lexists(self._join(fname)) |
477 return os.path.lexists(self._join(fname)) |
477 |
478 |
478 def setmode(self, fname, islink, isexec): |
|
479 util.setflags(self._join(fname), islink, isexec) |
|
480 |
|
481 class workingbackend(fsbackend): |
479 class workingbackend(fsbackend): |
482 def __init__(self, ui, repo, similarity): |
480 def __init__(self, ui, repo, similarity): |
483 super(workingbackend, self).__init__(ui, repo.root) |
481 super(workingbackend, self).__init__(ui, repo.root) |
484 self.repo = repo |
482 self.repo = repo |
485 self.similarity = similarity |
483 self.similarity = similarity |
486 self.removed = set() |
484 self.removed = set() |
487 self.changed = set() |
485 self.changed = set() |
488 self.copied = [] |
486 self.copied = [] |
489 |
487 |
490 def writelines(self, fname, lines, mode): |
488 def setfile(self, fname, lines, mode): |
491 super(workingbackend, self).writelines(fname, lines, mode) |
489 super(workingbackend, self).setfile(fname, lines, mode) |
492 self.changed.add(fname) |
490 self.changed.add(fname) |
493 |
491 |
494 def unlink(self, fname): |
492 def unlink(self, fname): |
495 super(workingbackend, self).unlink(fname) |
493 super(workingbackend, self).unlink(fname) |
496 self.removed.add(fname) |
494 self.removed.add(fname) |
498 |
496 |
499 def copy(self, src, dst): |
497 def copy(self, src, dst): |
500 super(workingbackend, self).copy(src, dst) |
498 super(workingbackend, self).copy(src, dst) |
501 self.copied.append((src, dst)) |
499 self.copied.append((src, dst)) |
502 self.changed.add(dst) |
500 self.changed.add(dst) |
503 |
|
504 def setmode(self, fname, islink, isexec): |
|
505 super(workingbackend, self).setmode(fname, islink, isexec) |
|
506 self.changed.add(fname) |
|
507 |
501 |
508 def close(self): |
502 def close(self): |
509 wctx = self.repo[None] |
503 wctx = self.repo[None] |
510 addremoved = set(self.changed) |
504 addremoved = set(self.changed) |
511 for src, dst in self.copied: |
505 for src, dst in self.copied: |
583 if l and l[-1] == '\n': |
577 if l and l[-1] == '\n': |
584 l = l[:-1] + eol |
578 l = l[:-1] + eol |
585 rawlines.append(l) |
579 rawlines.append(l) |
586 lines = rawlines |
580 lines = rawlines |
587 |
581 |
588 self.backend.writelines(fname, lines, mode) |
582 self.backend.setfile(fname, lines, mode) |
589 |
583 |
590 def printfile(self, warn): |
584 def printfile(self, warn): |
591 if self.fileprinted: |
585 if self.fileprinted: |
592 return |
586 return |
593 if warn or self.ui.verbose: |
587 if warn or self.ui.verbose: |
1250 backend.unlink(path) |
1244 backend.unlink(path) |
1251 continue |
1245 continue |
1252 if gp.op == 'RENAME': |
1246 if gp.op == 'RENAME': |
1253 backend.unlink(pstrip(gp.oldpath)) |
1247 backend.unlink(pstrip(gp.oldpath)) |
1254 if gp.mode and not first_hunk: |
1248 if gp.mode and not first_hunk: |
|
1249 data = None |
1255 if gp.op == 'ADD': |
1250 if gp.op == 'ADD': |
1256 # Added files without content have no hunk and must be created |
1251 # Added files without content have no hunk and |
1257 backend.writelines(path, [], gp.mode) |
1252 # must be created |
1258 else: |
1253 data = [] |
1259 backend.setmode(path, gp.mode[0], gp.mode[1]) |
1254 backend.setfile(path, data, gp.mode) |
1260 if not first_hunk: |
1255 if not first_hunk: |
1261 continue |
1256 continue |
1262 try: |
1257 try: |
1263 mode = gp and gp.mode or None |
1258 mode = gp and gp.mode or None |
1264 current_file, missing = selectfile(backend, afile, bfile, |
1259 current_file, missing = selectfile(backend, afile, bfile, |