comparison mercurial/bookmarks.py @ 33513:904894edb205

bookmark: use 'divergent2delete' in checkconflict checkconflict used to also do some bookmark deletion in case of divergence. It is a bit suspicious given the function name, but it's not the goal of this series. In order to unify bookmarks changing, checkconflict now return the list of divergent bookmarks to clean up and the callers must clean them by calling applyphases.
author Boris Feld <boris.feld@octobus.net>
date Mon, 10 Jul 2017 20:02:32 +0200
parents 1424a769f31b
children 169c97bbd94c
comparison
equal deleted inserted replaced
33512:1424a769f31b 33513:904894edb205
181 If target is supplied, then check that we are moving the bookmark 181 If target is supplied, then check that we are moving the bookmark
182 forward. 182 forward.
183 183
184 If force is supplied, then forcibly move the bookmark to a new commit 184 If force is supplied, then forcibly move the bookmark to a new commit
185 regardless if it is a move forward. 185 regardless if it is a move forward.
186
187 If divergent bookmark are to be deleted, they will be returned as list.
186 """ 188 """
187 cur = self._repo.changectx('.').node() 189 cur = self._repo.changectx('.').node()
188 if mark in self and not force: 190 if mark in self and not force:
189 if target: 191 if target:
190 if self[mark] == target and target == cur: 192 if self[mark] == target and target == cur:
191 # re-activating a bookmark 193 # re-activating a bookmark
192 return 194 return []
193 rev = self._repo[target].rev() 195 rev = self._repo[target].rev()
194 anc = self._repo.changelog.ancestors([rev]) 196 anc = self._repo.changelog.ancestors([rev])
195 bmctx = self._repo[self[mark]] 197 bmctx = self._repo[self[mark]]
196 divs = [self._repo[b].node() for b in self 198 divs = [self._repo[b].node() for b in self
197 if b.split('@', 1)[0] == mark.split('@', 1)[0]] 199 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
198 200
199 # allow resolving a single divergent bookmark even if moving 201 # allow resolving a single divergent bookmark even if moving
200 # the bookmark across branches when a revision is specified 202 # the bookmark across branches when a revision is specified
201 # that contains a divergent bookmark 203 # that contains a divergent bookmark
202 if bmctx.rev() not in anc and target in divs: 204 if bmctx.rev() not in anc and target in divs:
203 deletedivergent(self._repo, [target], mark) 205 return divergent2delete(self._repo, [target], mark)
204 return
205 206
206 deletefrom = [b for b in divs 207 deletefrom = [b for b in divs
207 if self._repo[b].rev() in anc or b == target] 208 if self._repo[b].rev() in anc or b == target]
208 deletedivergent(self._repo, deletefrom, mark) 209 delbms = divergent2delete(self._repo, deletefrom, mark)
209 if validdest(self._repo, bmctx, self._repo[target]): 210 if validdest(self._repo, bmctx, self._repo[target]):
210 self._repo.ui.status( 211 self._repo.ui.status(
211 _("moving bookmark '%s' forward from %s\n") % 212 _("moving bookmark '%s' forward from %s\n") %
212 (mark, short(bmctx.node()))) 213 (mark, short(bmctx.node())))
213 return 214 return delbms
214 raise error.Abort(_("bookmark '%s' already exists " 215 raise error.Abort(_("bookmark '%s' already exists "
215 "(use -f to force)") % mark) 216 "(use -f to force)") % mark)
216 if ((mark in self._repo.branchmap() or 217 if ((mark in self._repo.branchmap() or
217 mark == self._repo.dirstate.branch()) and not force): 218 mark == self._repo.dirstate.branch()) and not force):
218 raise error.Abort( 219 raise error.Abort(
226 self._repo.ui.warn( 227 self._repo.ui.warn(
227 _("bookmark %s matches a changeset hash\n" 228 _("bookmark %s matches a changeset hash\n"
228 "(did you leave a -r out of an 'hg bookmark' " 229 "(did you leave a -r out of an 'hg bookmark' "
229 "command?)\n") 230 "command?)\n")
230 % mark) 231 % mark)
232 return []
231 233
232 def _readactive(repo, marks): 234 def _readactive(repo, marks):
233 """ 235 """
234 Get the active bookmark. We can have an active bookmark that updates 236 Get the active bookmark. We can have an active bookmark that updates
235 itself as we commit. This function returns the name of that bookmark. 237 itself as we commit. This function returns the name of that bookmark.
745 """ 747 """
746 marks = repo._bookmarks 748 marks = repo._bookmarks
747 mark = checkformat(repo, new) 749 mark = checkformat(repo, new)
748 if old not in marks: 750 if old not in marks:
749 raise error.Abort(_("bookmark '%s' does not exist") % old) 751 raise error.Abort(_("bookmark '%s' does not exist") % old)
750 marks.checkconflict(mark, force) 752 changes = []
751 changes = [(mark, marks[old]), (old, None)] 753 for bm in marks.checkconflict(mark, force):
754 changes.append((bm, None))
755 changes.extend([(mark, marks[old]), (old, None)])
752 marks.applychanges(repo, tr, changes) 756 marks.applychanges(repo, tr, changes)
753 if repo._activebookmark == old and not inactive: 757 if repo._activebookmark == old and not inactive:
754 activate(repo, mark) 758 activate(repo, mark)
755 759
756 def addbookmarks(repo, tr, names, rev=None, force=False, inactive=False): 760 def addbookmarks(repo, tr, names, rev=None, force=False, inactive=False):
776 deactivate(repo) 780 deactivate(repo)
777 return 781 return
778 tgt = cur 782 tgt = cur
779 if rev: 783 if rev:
780 tgt = scmutil.revsingle(repo, rev).node() 784 tgt = scmutil.revsingle(repo, rev).node()
781 marks.checkconflict(mark, force, tgt) 785 for bm in marks.checkconflict(mark, force, tgt):
786 changes.append((bm, None))
782 changes.append((mark, tgt)) 787 changes.append((mark, tgt))
783 marks.applychanges(repo, tr, changes) 788 marks.applychanges(repo, tr, changes)
784 if not inactive and cur == marks[newact] and not rev: 789 if not inactive and cur == marks[newact] and not rev:
785 activate(repo, newact) 790 activate(repo, newact)
786 elif cur != tgt and newact == repo._activebookmark: 791 elif cur != tgt and newact == repo._activebookmark: