Show More
@@ -13,6 +13,7 b' from .i18n import _' | |||
|
13 | 13 | from .node import ( |
|
14 | 14 | bin, |
|
15 | 15 | hex, |
|
16 | short, | |
|
16 | 17 | ) |
|
17 | 18 | from . import ( |
|
18 | 19 | encoding, |
@@ -156,6 +157,61 b' class bmstore(dict):' | |||
|
156 | 157 | raise error.Abort(_("no active bookmark")) |
|
157 | 158 | return bname |
|
158 | 159 | |
|
160 | def checkconflict(self, mark, force=False, target=None): | |
|
161 | """check repo for a potential clash of mark with an existing bookmark, | |
|
162 | branch, or hash | |
|
163 | ||
|
164 | If target is supplied, then check that we are moving the bookmark | |
|
165 | forward. | |
|
166 | ||
|
167 | If force is supplied, then forcibly move the bookmark to a new commit | |
|
168 | regardless if it is a move forward. | |
|
169 | """ | |
|
170 | cur = self._repo.changectx('.').node() | |
|
171 | if mark in self and not force: | |
|
172 | if target: | |
|
173 | if self[mark] == target and target == cur: | |
|
174 | # re-activating a bookmark | |
|
175 | return | |
|
176 | rev = self._repo[target].rev() | |
|
177 | anc = self._repo.changelog.ancestors([rev]) | |
|
178 | bmctx = self._repo[self[mark]] | |
|
179 | divs = [self._repo[b].node() for b in self | |
|
180 | if b.split('@', 1)[0] == mark.split('@', 1)[0]] | |
|
181 | ||
|
182 | # allow resolving a single divergent bookmark even if moving | |
|
183 | # the bookmark across branches when a revision is specified | |
|
184 | # that contains a divergent bookmark | |
|
185 | if bmctx.rev() not in anc and target in divs: | |
|
186 | deletedivergent(self._repo, [target], mark) | |
|
187 | return | |
|
188 | ||
|
189 | deletefrom = [b for b in divs | |
|
190 | if self._repo[b].rev() in anc or b == target] | |
|
191 | deletedivergent(self._repo, deletefrom, mark) | |
|
192 | if validdest(self._repo, bmctx, self._repo[target]): | |
|
193 | self._repo.ui.status( | |
|
194 | _("moving bookmark '%s' forward from %s\n") % | |
|
195 | (mark, short(bmctx.node()))) | |
|
196 | return | |
|
197 | raise error.Abort(_("bookmark '%s' already exists " | |
|
198 | "(use -f to force)") % mark) | |
|
199 | if ((mark in self._repo.branchmap() or | |
|
200 | mark == self._repo.dirstate.branch()) and not force): | |
|
201 | raise error.Abort( | |
|
202 | _("a bookmark cannot have the name of an existing branch")) | |
|
203 | if len(mark) > 3 and not force: | |
|
204 | try: | |
|
205 | shadowhash = (mark in self._repo) | |
|
206 | except error.LookupError: # ambiguous identifier | |
|
207 | shadowhash = False | |
|
208 | if shadowhash: | |
|
209 | self._repo.ui.warn( | |
|
210 | _("bookmark %s matches a changeset hash\n" | |
|
211 | "(did you leave a -r out of an 'hg bookmark' " | |
|
212 | "command?)\n") | |
|
213 | % mark) | |
|
214 | ||
|
159 | 215 | def _readactive(repo, marks): |
|
160 | 216 | """ |
|
161 | 217 | Get the active bookmark. We can have an active bookmark that updates |
@@ -957,48 +957,6 b' def bookmark(ui, repo, *names, **opts):' | |||
|
957 | 957 | rename = opts.get('rename') |
|
958 | 958 | inactive = opts.get('inactive') |
|
959 | 959 | |
|
960 | def checkconflict(repo, mark, cur, force=False, target=None): | |
|
961 | if mark in marks and not force: | |
|
962 | if target: | |
|
963 | if marks[mark] == target and target == cur: | |
|
964 | # re-activating a bookmark | |
|
965 | return | |
|
966 | anc = repo.changelog.ancestors([repo[target].rev()]) | |
|
967 | bmctx = repo[marks[mark]] | |
|
968 | divs = [repo[b].node() for b in marks | |
|
969 | if b.split('@', 1)[0] == mark.split('@', 1)[0]] | |
|
970 | ||
|
971 | # allow resolving a single divergent bookmark even if moving | |
|
972 | # the bookmark across branches when a revision is specified | |
|
973 | # that contains a divergent bookmark | |
|
974 | if bmctx.rev() not in anc and target in divs: | |
|
975 | bookmarks.deletedivergent(repo, [target], mark) | |
|
976 | return | |
|
977 | ||
|
978 | deletefrom = [b for b in divs | |
|
979 | if repo[b].rev() in anc or b == target] | |
|
980 | bookmarks.deletedivergent(repo, deletefrom, mark) | |
|
981 | if bookmarks.validdest(repo, bmctx, repo[target]): | |
|
982 | ui.status(_("moving bookmark '%s' forward from %s\n") % | |
|
983 | (mark, short(bmctx.node()))) | |
|
984 | return | |
|
985 | raise error.Abort(_("bookmark '%s' already exists " | |
|
986 | "(use -f to force)") % mark) | |
|
987 | if ((mark in repo.branchmap() or mark == repo.dirstate.branch()) | |
|
988 | and not force): | |
|
989 | raise error.Abort( | |
|
990 | _("a bookmark cannot have the name of an existing branch")) | |
|
991 | if len(mark) > 3 and not force: | |
|
992 | try: | |
|
993 | shadowhash = (mark in repo) | |
|
994 | except error.LookupError: # ambiguous identifier | |
|
995 | shadowhash = False | |
|
996 | if shadowhash: | |
|
997 | repo.ui.warn( | |
|
998 | _("bookmark %s matches a changeset hash\n" | |
|
999 | "(did you leave a -r out of an 'hg bookmark' command?)\n") | |
|
1000 | % mark) | |
|
1001 | ||
|
1002 | 960 | if delete and rename: |
|
1003 | 961 | raise error.Abort(_("--delete and --rename are incompatible")) |
|
1004 | 962 | if delete and rev: |
@@ -1035,7 +993,7 b' def bookmark(ui, repo, *names, **opts):' | |||
|
1035 | 993 | if rename not in marks: |
|
1036 | 994 | raise error.Abort(_("bookmark '%s' does not exist") |
|
1037 | 995 | % rename) |
|
1038 |
checkconflict( |
|
|
996 | marks.checkconflict(mark, force) | |
|
1039 | 997 | marks[mark] = marks[rename] |
|
1040 | 998 | if repo._activebookmark == rename and not inactive: |
|
1041 | 999 | bookmarks.activate(repo, mark) |
@@ -1053,7 +1011,7 b' def bookmark(ui, repo, *names, **opts):' | |||
|
1053 | 1011 | tgt = cur |
|
1054 | 1012 | if rev: |
|
1055 | 1013 | tgt = scmutil.revsingle(repo, rev).node() |
|
1056 |
checkconflict( |
|
|
1014 | marks.checkconflict(mark, force, tgt) | |
|
1057 | 1015 | marks[mark] = tgt |
|
1058 | 1016 | if not inactive and cur == marks[newact] and not rev: |
|
1059 | 1017 | bookmarks.activate(repo, newact) |
General Comments 0
You need to be logged in to leave comments.
Login now