equal
deleted
inserted
replaced
68 # we never need the user, so we use a |
68 # we never need the user, so we use a |
69 # generic user for all shelve operations |
69 # generic user for all shelve operations |
70 shelveuser = b'shelve@localhost' |
70 shelveuser = b'shelve@localhost' |
71 |
71 |
72 |
72 |
|
73 class ShelfDir(object): |
|
74 def __init__(self, repo, for_backups=False): |
|
75 if for_backups: |
|
76 self.vfs = vfsmod.vfs(repo.vfs.join(backupdir)) |
|
77 else: |
|
78 self.vfs = vfsmod.vfs(repo.vfs.join(shelvedir)) |
|
79 |
|
80 def get(self, name): |
|
81 return Shelf(self.vfs, name) |
|
82 |
|
83 |
73 class Shelf(object): |
84 class Shelf(object): |
74 """Represents a shelf, including possibly multiple files storing it. |
85 """Represents a shelf, including possibly multiple files storing it. |
75 |
86 |
76 Old shelves will have a .patch and a .hg file. Newer shelves will |
87 Old shelves will have a .patch and a .hg file. Newer shelves will |
77 also have a .shelve file. This class abstracts away some of the |
88 also have a .shelve file. This class abstracts away some of the |
79 """ |
90 """ |
80 |
91 |
81 def __init__(self, vfs, name): |
92 def __init__(self, vfs, name): |
82 self.vfs = vfs |
93 self.vfs = vfs |
83 self.name = name |
94 self.name = name |
84 |
|
85 @staticmethod |
|
86 def open(repo, name): |
|
87 return Shelf(vfsmod.vfs(repo.vfs.join(shelvedir)), name) |
|
88 |
|
89 @staticmethod |
|
90 def open_backup(repo, name): |
|
91 return Shelf(vfsmod.vfs(repo.vfs.join(backupdir)), name) |
|
92 |
95 |
93 def exists(self): |
96 def exists(self): |
94 return self.vfs.exists(self.name + b'.patch') and self.vfs.exists( |
97 return self.vfs.exists(self.name + b'.patch') and self.vfs.exists( |
95 self.name + b'.hg' |
98 self.name + b'.hg' |
96 ) |
99 ) |
379 # filenames must not start with '.' as it should not be hidden |
382 # filenames must not start with '.' as it should not be hidden |
380 if label.startswith(b'.'): |
383 if label.startswith(b'.'): |
381 label = label.replace(b'.', b'_', 1) |
384 label = label.replace(b'.', b'_', 1) |
382 |
385 |
383 if name: |
386 if name: |
384 if Shelf.open(repo, name).exists(): |
387 if ShelfDir(repo).get(name).exists(): |
385 e = _(b"a shelved change named '%s' already exists") % name |
388 e = _(b"a shelved change named '%s' already exists") % name |
386 raise error.Abort(e) |
389 raise error.Abort(e) |
387 |
390 |
388 # ensure we are not creating a subdirectory or a hidden file |
391 # ensure we are not creating a subdirectory or a hidden file |
389 if b'/' in name or b'\\' in name: |
392 if b'/' in name or b'\\' in name: |
392 ) |
395 ) |
393 if name.startswith(b'.'): |
396 if name.startswith(b'.'): |
394 raise error.Abort(_(b"shelved change names can not start with '.'")) |
397 raise error.Abort(_(b"shelved change names can not start with '.'")) |
395 |
398 |
396 else: |
399 else: |
|
400 shelf_dir = ShelfDir(repo) |
397 for n in gennames(): |
401 for n in gennames(): |
398 if not Shelf.open(repo, n).exists(): |
402 if not shelf_dir.get(n).exists(): |
399 name = n |
403 name = n |
400 break |
404 break |
401 |
405 |
402 return name |
406 return name |
403 |
407 |
469 ui.status(_(b"nothing changed\n")) |
473 ui.status(_(b"nothing changed\n")) |
470 |
474 |
471 |
475 |
472 def _shelvecreatedcommit(repo, node, name, match): |
476 def _shelvecreatedcommit(repo, node, name, match): |
473 info = {b'node': hex(node)} |
477 info = {b'node': hex(node)} |
474 shelf = Shelf.open(repo, name) |
478 shelf = ShelfDir(repo).get(name) |
475 shelf.writeinfo(info) |
479 shelf.writeinfo(info) |
476 bases = list(mutableancestors(repo[node])) |
480 bases = list(mutableancestors(repo[node])) |
477 shelf.writebundle(repo, bases, node) |
481 shelf.writebundle(repo, bases, node) |
478 with shelf.open_patch(b'wb') as fp: |
482 with shelf.open_patch(b'wb') as fp: |
479 cmdutil.exportfile( |
483 cmdutil.exportfile( |
612 if not pats: |
616 if not pats: |
613 raise error.InputError(_(b'no shelved changes specified!')) |
617 raise error.InputError(_(b'no shelved changes specified!')) |
614 with repo.wlock(): |
618 with repo.wlock(): |
615 backupvfs = vfsmod.vfs(repo.vfs.join(backupdir)) |
619 backupvfs = vfsmod.vfs(repo.vfs.join(backupdir)) |
616 for name in pats: |
620 for name in pats: |
617 shelf = Shelf.open(repo, name) |
621 shelf = ShelfDir(repo).get(name) |
618 if not shelf.exists(): |
622 if not shelf.exists(): |
619 raise error.InputError( |
623 raise error.InputError( |
620 _(b"shelved change '%s' not found") % name |
624 _(b"shelved change '%s' not found") % name |
621 ) |
625 ) |
622 shelf.movetobackup(backupvfs) |
626 shelf.movetobackup(backupvfs) |
653 if not ui.plain(): |
657 if not ui.plain(): |
654 width = ui.termwidth() |
658 width = ui.termwidth() |
655 namelabel = b'shelve.newest' |
659 namelabel = b'shelve.newest' |
656 ui.pager(b'shelve') |
660 ui.pager(b'shelve') |
657 vfs = vfsmod.vfs(repo.vfs.join(shelvedir)) |
661 vfs = vfsmod.vfs(repo.vfs.join(shelvedir)) |
|
662 shelf_dir = ShelfDir(repo) |
658 for mtime, name in listshelves(vfs): |
663 for mtime, name in listshelves(vfs): |
659 if pats and name not in pats: |
664 if pats and name not in pats: |
660 continue |
665 continue |
661 ui.write(name, label=namelabel) |
666 ui.write(name, label=namelabel) |
662 namelabel = b'shelve.name' |
667 namelabel = b'shelve.name' |
668 date = dateutil.makedate(mtime) |
673 date = dateutil.makedate(mtime) |
669 age = b'(%s)' % templatefilters.age(date, abbrev=True) |
674 age = b'(%s)' % templatefilters.age(date, abbrev=True) |
670 ui.write(age, label=b'shelve.age') |
675 ui.write(age, label=b'shelve.age') |
671 ui.write(b' ' * (12 - len(age))) |
676 ui.write(b' ' * (12 - len(age))) |
672 used += 12 |
677 used += 12 |
673 with Shelf.open(repo, name).open_patch() as fp: |
678 with shelf_dir.get(name).open_patch() as fp: |
674 while True: |
679 while True: |
675 line = fp.readline() |
680 line = fp.readline() |
676 if not line: |
681 if not line: |
677 break |
682 break |
678 if not line.startswith(b'#'): |
683 if not line.startswith(b'#'): |
701 if not shelves: |
706 if not shelves: |
702 raise error.Abort(_(b"there are no shelves to show")) |
707 raise error.Abort(_(b"there are no shelves to show")) |
703 mtime, name = shelves[0] |
708 mtime, name = shelves[0] |
704 pats = [name] |
709 pats = [name] |
705 |
710 |
|
711 shelf_dir = ShelfDir(repo) |
706 for shelfname in pats: |
712 for shelfname in pats: |
707 if not Shelf.open(repo, shelfname).exists(): |
713 if not shelf_dir.get(shelfname).exists(): |
708 raise error.Abort(_(b"cannot find shelf %s") % shelfname) |
714 raise error.Abort(_(b"cannot find shelf %s") % shelfname) |
709 |
715 |
710 listcmd(ui, repo, pats, opts) |
716 listcmd(ui, repo, pats, opts) |
711 |
717 |
712 |
718 |
794 |
800 |
795 def unshelvecleanup(ui, repo, name, opts): |
801 def unshelvecleanup(ui, repo, name, opts): |
796 """remove related files after an unshelve""" |
802 """remove related files after an unshelve""" |
797 if not opts.get(b'keep'): |
803 if not opts.get(b'keep'): |
798 backupvfs = vfsmod.vfs(repo.vfs.join(backupdir)) |
804 backupvfs = vfsmod.vfs(repo.vfs.join(backupdir)) |
799 Shelf.open(repo, name).movetobackup(backupvfs) |
805 ShelfDir(repo).get(name).movetobackup(backupvfs) |
800 cleanupoldbackups(repo) |
806 cleanupoldbackups(repo) |
801 |
807 |
802 |
808 |
803 def unshelvecontinue(ui, repo, state, opts): |
809 def unshelvecontinue(ui, repo, state, opts): |
804 """subcommand to continue an in-progress unshelve""" |
810 """subcommand to continue an in-progress unshelve""" |
894 |
900 |
895 def _unshelverestorecommit(ui, repo, tr, basename): |
901 def _unshelverestorecommit(ui, repo, tr, basename): |
896 """Recreate commit in the repository during the unshelve""" |
902 """Recreate commit in the repository during the unshelve""" |
897 repo = repo.unfiltered() |
903 repo = repo.unfiltered() |
898 node = None |
904 node = None |
899 shelf = Shelf.open(repo, basename) |
905 shelf = ShelfDir(repo).get(basename) |
900 if shelf.hasinfo(): |
906 if shelf.hasinfo(): |
901 node = shelf.readinfo()[b'node'] |
907 node = shelf.readinfo()[b'node'] |
902 if node is None or node not in repo: |
908 if node is None or node not in repo: |
903 with ui.configoverride({(b'ui', b'quiet'): True}): |
909 with ui.configoverride({(b'ui', b'quiet'): True}): |
904 shelvectx = shelf.applybundle(repo, tr) |
910 shelvectx = shelf.applybundle(repo, tr) |
1124 basename = shelved[0][1] |
1130 basename = shelved[0][1] |
1125 ui.status(_(b"unshelving change '%s'\n") % basename) |
1131 ui.status(_(b"unshelving change '%s'\n") % basename) |
1126 else: |
1132 else: |
1127 basename = shelved[0] |
1133 basename = shelved[0] |
1128 |
1134 |
1129 if not Shelf.open(repo, basename).exists(): |
1135 if not ShelfDir(repo).get(basename).exists(): |
1130 raise error.InputError(_(b"shelved change '%s' not found") % basename) |
1136 raise error.InputError(_(b"shelved change '%s' not found") % basename) |
1131 |
1137 |
1132 return _dounshelve(ui, repo, basename, opts) |
1138 return _dounshelve(ui, repo, basename, opts) |
1133 |
1139 |
1134 |
1140 |