##// END OF EJS Templates
rewriteutil: add devel warning if precheck is called with contexts...
Martin von Zweigbergk -
r47780:8ad2f43f default
parent child Browse files
Show More
@@ -1,138 +1,143 b''
1 1 # rewriteutil.py - utility functions for rewriting changesets
2 2 #
3 3 # Copyright 2017 Octobus <contact@octobus.net>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import re
11 11
12 12 from .i18n import _
13 13 from .node import (
14 14 hex,
15 15 nullrev,
16 16 )
17 17
18 18 from . import (
19 19 error,
20 20 obsolete,
21 21 obsutil,
22 22 revset,
23 23 scmutil,
24 util,
24 25 )
25 26
26 27
27 28 NODE_RE = re.compile(br'\b[0-9a-f]{6,64}\b')
28 29
29 30
30 31 def precheck(repo, revs, action=b'rewrite'):
31 32 """check if revs can be rewritten
32 33 action is used to control the error message.
33 34
34 35 Make sure this function is called after taking the lock.
35 36 """
36 37 if nullrev in revs:
37 38 msg = _(b"cannot %s the null revision") % action
38 39 hint = _(b"no changeset checked out")
39 40 raise error.InputError(msg, hint=hint)
40 41
42 if any(util.safehasattr(r, 'rev') for r in revs):
43 repo.ui.develwarn(b"rewriteutil.precheck called with ctx not revs")
44 revs = (r.rev() for r in revs)
45
41 46 if len(repo[None].parents()) > 1:
42 47 raise error.StateError(_(b"cannot %s while merging") % action)
43 48
44 49 publicrevs = repo.revs(b'%ld and public()', revs)
45 50 if publicrevs:
46 51 msg = _(b"cannot %s public changesets") % action
47 52 hint = _(b"see 'hg help phases' for details")
48 53 raise error.InputError(msg, hint=hint)
49 54
50 55 newunstable = disallowednewunstable(repo, revs)
51 56 if newunstable:
52 57 raise error.InputError(_(b"cannot %s changeset with children") % action)
53 58
54 59
55 60 def disallowednewunstable(repo, revs):
56 61 """Checks whether editing the revs will create new unstable changesets and
57 62 are we allowed to create them.
58 63
59 64 To allow new unstable changesets, set the config:
60 65 `experimental.evolution.allowunstable=True`
61 66 """
62 67 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
63 68 if allowunstable:
64 69 return revset.baseset()
65 70 return repo.revs(b"(%ld::) - %ld", revs, revs)
66 71
67 72
68 73 def skip_empty_successor(ui, command):
69 74 empty_successor = ui.config(b'rewrite', b'empty-successor')
70 75 if empty_successor == b'skip':
71 76 return True
72 77 elif empty_successor == b'keep':
73 78 return False
74 79 else:
75 80 raise error.ConfigError(
76 81 _(
77 82 b"%s doesn't know how to handle config "
78 83 b"rewrite.empty-successor=%s (only 'skip' and 'keep' are "
79 84 b"supported)"
80 85 )
81 86 % (command, empty_successor)
82 87 )
83 88
84 89
85 90 def update_hash_refs(repo, commitmsg, pending=None):
86 91 """Replace all obsolete commit hashes in the message with the current hash.
87 92
88 93 If the obsolete commit was split or is divergent, the hash is not replaced
89 94 as there's no way to know which successor to choose.
90 95
91 96 For commands that update a series of commits in the current transaction, the
92 97 new obsolete markers can be considered by setting ``pending`` to a mapping
93 98 of ``pending[oldnode] = [successor_node1, successor_node2,..]``.
94 99 """
95 100 if not pending:
96 101 pending = {}
97 102 cache = {}
98 103 hashes = re.findall(NODE_RE, commitmsg)
99 104 unfi = repo.unfiltered()
100 105 for h in hashes:
101 106 fullnode = scmutil.resolvehexnodeidprefix(unfi, h)
102 107 if fullnode is None:
103 108 continue
104 109 ctx = unfi[fullnode]
105 110 if not ctx.obsolete():
106 111 successors = pending.get(fullnode)
107 112 if successors is None:
108 113 continue
109 114 # obsutil.successorssets() returns a list of list of nodes
110 115 successors = [successors]
111 116 else:
112 117 successors = obsutil.successorssets(repo, ctx.node(), cache=cache)
113 118
114 119 # We can't make any assumptions about how to update the hash if the
115 120 # cset in question was split or diverged.
116 121 if len(successors) == 1 and len(successors[0]) == 1:
117 122 successor = successors[0][0]
118 123 if successor is not None:
119 124 newhash = hex(successor)
120 125 commitmsg = commitmsg.replace(h, newhash[: len(h)])
121 126 else:
122 127 repo.ui.note(
123 128 _(
124 129 b'The stale commit message reference to %s could '
125 130 b'not be updated\n(The referenced commit was dropped)\n'
126 131 )
127 132 % h
128 133 )
129 134 else:
130 135 repo.ui.note(
131 136 _(
132 137 b'The stale commit message reference to %s could '
133 138 b'not be updated\n'
134 139 )
135 140 % h
136 141 )
137 142
138 143 return commitmsg
General Comments 0
You need to be logged in to leave comments. Login now