Mercurial > hg
comparison mercurial/commands.py @ 20232:5fe4c1a9dc34
commands.bookmarks: hold wlock for write operations
Any invocations of bookmarks other than a plain 'hg bookmarks' will likely
cause a write to the bookmark store. These should be guarded by the wlock.
The repo._bookmarks read should be similarly guarded by the wlock if we're
going to be subsequently writing to it.
author | Siddharth Agarwal <sid0@fb.com> |
---|---|
date | Tue, 19 Nov 2013 12:33:14 -0800 |
parents | 1053f5a7bbc6 |
children | 410193f11422 |
comparison
equal
deleted
inserted
replaced
20231:1053f5a7bbc6 | 20232:5fe4c1a9dc34 |
---|---|
806 delete = opts.get('delete') | 806 delete = opts.get('delete') |
807 rename = opts.get('rename') | 807 rename = opts.get('rename') |
808 inactive = opts.get('inactive') | 808 inactive = opts.get('inactive') |
809 | 809 |
810 hexfn = ui.debugflag and hex or short | 810 hexfn = ui.debugflag and hex or short |
811 marks = repo._bookmarks | |
812 cur = repo.changectx('.').node() | 811 cur = repo.changectx('.').node() |
813 | 812 |
814 def checkformat(mark): | 813 def checkformat(mark): |
815 mark = mark.strip() | 814 mark = mark.strip() |
816 if not mark: | 815 if not mark: |
860 if rename and rev: | 859 if rename and rev: |
861 raise util.Abort(_("--rev is incompatible with --rename")) | 860 raise util.Abort(_("--rev is incompatible with --rename")) |
862 if not names and (delete or rev): | 861 if not names and (delete or rev): |
863 raise util.Abort(_("bookmark name required")) | 862 raise util.Abort(_("bookmark name required")) |
864 | 863 |
865 if delete: | 864 if delete or rename or names or inactive: |
866 for mark in names: | 865 wlock = repo.wlock() |
867 if mark not in marks: | 866 try: |
868 raise util.Abort(_("bookmark '%s' does not exist") % mark) | 867 marks = repo._bookmarks |
869 if mark == repo._bookmarkcurrent: | 868 if delete: |
870 bookmarks.unsetcurrent(repo) | 869 for mark in names: |
871 del marks[mark] | 870 if mark not in marks: |
872 marks.write() | 871 raise util.Abort(_("bookmark '%s' does not exist") % |
873 | 872 mark) |
874 elif rename: | 873 if mark == repo._bookmarkcurrent: |
875 if not names: | 874 bookmarks.unsetcurrent(repo) |
876 raise util.Abort(_("new bookmark name required")) | 875 del marks[mark] |
877 elif len(names) > 1: | 876 marks.write() |
878 raise util.Abort(_("only one new bookmark name allowed")) | 877 |
879 mark = checkformat(names[0]) | 878 elif rename: |
880 if rename not in marks: | 879 if not names: |
881 raise util.Abort(_("bookmark '%s' does not exist") % rename) | 880 raise util.Abort(_("new bookmark name required")) |
882 checkconflict(repo, mark, force) | 881 elif len(names) > 1: |
883 marks[mark] = marks[rename] | 882 raise util.Abort(_("only one new bookmark name allowed")) |
884 if repo._bookmarkcurrent == rename and not inactive: | 883 mark = checkformat(names[0]) |
885 bookmarks.setcurrent(repo, mark) | 884 if rename not in marks: |
886 del marks[rename] | 885 raise util.Abort(_("bookmark '%s' does not exist") % rename) |
887 marks.write() | 886 checkconflict(repo, mark, force) |
888 | 887 marks[mark] = marks[rename] |
889 elif names: | 888 if repo._bookmarkcurrent == rename and not inactive: |
890 newact = None | 889 bookmarks.setcurrent(repo, mark) |
891 for mark in names: | 890 del marks[rename] |
892 mark = checkformat(mark) | 891 marks.write() |
893 if newact is None: | 892 |
894 newact = mark | 893 elif names: |
895 if inactive and mark == repo._bookmarkcurrent: | 894 newact = None |
896 bookmarks.unsetcurrent(repo) | 895 for mark in names: |
897 return | 896 mark = checkformat(mark) |
898 tgt = cur | 897 if newact is None: |
899 if rev: | 898 newact = mark |
900 tgt = scmutil.revsingle(repo, rev).node() | 899 if inactive and mark == repo._bookmarkcurrent: |
901 checkconflict(repo, mark, force, tgt) | 900 bookmarks.unsetcurrent(repo) |
902 marks[mark] = tgt | 901 return |
903 if not inactive and cur == marks[newact] and not rev: | 902 tgt = cur |
904 bookmarks.setcurrent(repo, newact) | 903 if rev: |
905 elif cur != tgt and newact == repo._bookmarkcurrent: | 904 tgt = scmutil.revsingle(repo, rev).node() |
906 bookmarks.unsetcurrent(repo) | 905 checkconflict(repo, mark, force, tgt) |
907 marks.write() | 906 marks[mark] = tgt |
908 | 907 if not inactive and cur == marks[newact] and not rev: |
909 elif inactive: | 908 bookmarks.setcurrent(repo, newact) |
910 if len(marks) == 0: | 909 elif cur != tgt and newact == repo._bookmarkcurrent: |
911 ui.status(_("no bookmarks set\n")) | 910 bookmarks.unsetcurrent(repo) |
912 elif not repo._bookmarkcurrent: | 911 marks.write() |
913 ui.status(_("no active bookmark\n")) | 912 |
914 else: | 913 elif inactive: |
915 bookmarks.unsetcurrent(repo) | 914 if len(marks) == 0: |
916 | 915 ui.status(_("no bookmarks set\n")) |
916 elif not repo._bookmarkcurrent: | |
917 ui.status(_("no active bookmark\n")) | |
918 else: | |
919 bookmarks.unsetcurrent(repo) | |
920 finally: | |
921 wlock.release() | |
917 else: # show bookmarks | 922 else: # show bookmarks |
923 marks = repo._bookmarks | |
918 if len(marks) == 0: | 924 if len(marks) == 0: |
919 ui.status(_("no bookmarks set\n")) | 925 ui.status(_("no bookmarks set\n")) |
920 else: | 926 else: |
921 for bmark, n in sorted(marks.iteritems()): | 927 for bmark, n in sorted(marks.iteritems()): |
922 current = repo._bookmarkcurrent | 928 current = repo._bookmarkcurrent |