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