##// END OF EJS Templates
rewriteutil: relax the sha1 hash references to handle future hash types...
Matt Harbison -
r45996:78861610 default
parent child Browse files
Show More
@@ -1,125 +1,125 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
14 14 from . import (
15 15 error,
16 16 node,
17 17 obsolete,
18 18 obsutil,
19 19 revset,
20 20 scmutil,
21 21 )
22 22
23 23
24 sha1re = re.compile(br'\b[0-9a-f]{6,40}\b')
24 NODE_RE = re.compile(br'\b[0-9a-f]{6,64}\b')
25 25
26 26
27 27 def precheck(repo, revs, action=b'rewrite'):
28 28 """check if revs can be rewritten
29 29 action is used to control the error message.
30 30
31 31 Make sure this function is called after taking the lock.
32 32 """
33 33 if node.nullrev in revs:
34 34 msg = _(b"cannot %s null changeset") % action
35 35 hint = _(b"no changeset checked out")
36 36 raise error.Abort(msg, hint=hint)
37 37
38 38 if len(repo[None].parents()) > 1:
39 39 raise error.Abort(_(b"cannot %s while merging") % action)
40 40
41 41 publicrevs = repo.revs(b'%ld and public()', revs)
42 42 if publicrevs:
43 43 msg = _(b"cannot %s public changesets") % action
44 44 hint = _(b"see 'hg help phases' for details")
45 45 raise error.Abort(msg, hint=hint)
46 46
47 47 newunstable = disallowednewunstable(repo, revs)
48 48 if newunstable:
49 49 raise error.Abort(_(b"cannot %s changeset with children") % action)
50 50
51 51
52 52 def disallowednewunstable(repo, revs):
53 53 """Checks whether editing the revs will create new unstable changesets and
54 54 are we allowed to create them.
55 55
56 56 To allow new unstable changesets, set the config:
57 57 `experimental.evolution.allowunstable=True`
58 58 """
59 59 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
60 60 if allowunstable:
61 61 return revset.baseset()
62 62 return repo.revs(b"(%ld::) - %ld", revs, revs)
63 63
64 64
65 65 def skip_empty_successor(ui, command):
66 66 empty_successor = ui.config(b'rewrite', b'empty-successor')
67 67 if empty_successor == b'skip':
68 68 return True
69 69 elif empty_successor == b'keep':
70 70 return False
71 71 else:
72 72 raise error.ConfigError(
73 73 _(
74 74 b"%s doesn't know how to handle config "
75 75 b"rewrite.empty-successor=%s (only 'skip' and 'keep' are "
76 76 b"supported)"
77 77 )
78 78 % (command, empty_successor)
79 79 )
80 80
81 81
82 82 def update_hash_refs(repo, commitmsg, pending=None):
83 83 """Replace all obsolete commit hashes in the message with the current hash.
84 84
85 85 If the obsolete commit was split or is divergent, the hash is not replaced
86 86 as there's no way to know which successor to choose.
87 87
88 88 For commands that update a series of commits in the current transaction, the
89 89 new obsolete markers can be considered by setting ``pending`` to a mapping
90 90 of ``pending[oldnode] = [successor_node1, successor_node2,..]``.
91 91 """
92 92 if not pending:
93 93 pending = {}
94 94 cache = {}
95 sha1s = re.findall(sha1re, commitmsg)
95 hashes = re.findall(NODE_RE, commitmsg)
96 96 unfi = repo.unfiltered()
97 for sha1 in sha1s:
98 fullnode = scmutil.resolvehexnodeidprefix(unfi, sha1)
97 for h in hashes:
98 fullnode = scmutil.resolvehexnodeidprefix(unfi, h)
99 99 if fullnode is None:
100 100 continue
101 101 ctx = unfi[fullnode]
102 102 if not ctx.obsolete():
103 103 successors = pending.get(fullnode)
104 104 if successors is None:
105 105 continue
106 106 # obsutil.successorssets() returns a list of list of nodes
107 107 successors = [successors]
108 108 else:
109 109 successors = obsutil.successorssets(repo, ctx.node(), cache=cache)
110 110
111 111 # We can't make any assumptions about how to update the hash if the
112 112 # cset in question was split or diverged.
113 113 if len(successors) == 1 and len(successors[0]) == 1:
114 newsha1 = node.hex(successors[0][0])
115 commitmsg = commitmsg.replace(sha1, newsha1[: len(sha1)])
114 newhash = node.hex(successors[0][0])
115 commitmsg = commitmsg.replace(h, newhash[: len(h)])
116 116 else:
117 117 repo.ui.note(
118 118 _(
119 119 b'The stale commit message reference to %s could '
120 120 b'not be updated\n'
121 121 )
122 % sha1
122 % h
123 123 )
124 124
125 125 return commitmsg
General Comments 0
You need to be logged in to leave comments. Login now