Mercurial > hg
comparison hgext/hbisect.py @ 5732:2060cad9fabd
bisect: simplify state handling and init
- use a single bisect.state file
- unify init and reset (delete the state)
- move write into good/bad
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Thu, 27 Dec 2007 23:55:39 -0600 |
parents | 19691160d7f5 |
children | 47ec288456bb |
comparison
equal
deleted
inserted
replaced
5731:19691160d7f5 | 5732:2060cad9fabd |
---|---|
12 | 12 |
13 class bisect(object): | 13 class bisect(object): |
14 """dichotomic search in the DAG of changesets""" | 14 """dichotomic search in the DAG of changesets""" |
15 def __init__(self, ui, repo): | 15 def __init__(self, ui, repo): |
16 self.repo = repo | 16 self.repo = repo |
17 self.path = repo.join("bisect") | |
18 self.opener = util.opener(self.path) | |
19 self.ui = ui | 17 self.ui = ui |
20 self.goodnodes = [] | 18 self.goodnodes = [] |
21 self.badnode = None | 19 self.badnode = None |
22 self.good_path = "good" | 20 |
23 self.bad_path = "bad" | 21 p = self.repo.join("bisect.state") |
24 self.is_reset = False | 22 if os.path.exists(p): |
25 | 23 for l in self.repo.opener("bisect.state"): |
26 if os.path.exists(os.path.join(self.path, self.good_path)): | 24 type, node = l[:-1].split() |
27 self.goodnodes = self.opener(self.good_path).read().splitlines() | 25 node = self.repo.lookup(node) |
28 self.goodnodes = [hg.bin(x) for x in self.goodnodes] | 26 if type == "good": |
29 if os.path.exists(os.path.join(self.path, self.bad_path)): | 27 self.goodnodes.append(node) |
30 r = self.opener(self.bad_path).read().splitlines() | 28 elif type == "bad": |
31 if r: | 29 self.badnode = node |
32 self.badnode = hg.bin(r.pop(0)) | |
33 | 30 |
34 def write(self): | 31 def write(self): |
35 if self.is_reset: | 32 f = self.repo.opener("bisect.state", "w") |
36 return | 33 for n in self.goodnodes: |
37 if not os.path.isdir(self.path): | 34 f.write("good %s\n" % hg.hex(n)) |
38 os.mkdir(self.path) | |
39 f = self.opener(self.good_path, "w") | |
40 f.write("\n".join([hg.hex(r) for r in self.goodnodes])) | |
41 if len(self.goodnodes) > 0: | |
42 f.write("\n") | |
43 f = self.opener(self.bad_path, "w") | |
44 if self.badnode: | 35 if self.badnode: |
45 f.write(hg.hex(self.badnode) + "\n") | 36 f.write("bad %s\n" % hg.hex(self.badnode)) |
46 | 37 |
47 def init(self): | 38 def init(self): |
48 """start a new bisection""" | 39 """start a new bisection""" |
49 if os.path.isdir(self.path): | 40 p = self.repo.join("bisect.state") |
50 raise util.Abort(_("bisect directory already exists\n")) | 41 if os.path.exists(p): |
51 os.mkdir(self.path) | 42 os.unlink(p) |
52 return 0 | |
53 | |
54 def reset(self): | |
55 """finish a bisection""" | |
56 if os.path.isdir(self.path): | |
57 sl = [os.path.join(self.path, p) | |
58 for p in [self.bad_path, self.good_path]] | |
59 for s in sl: | |
60 if os.path.exists(s): | |
61 os.unlink(s) | |
62 os.rmdir(self.path) | |
63 # Not sure about this | |
64 #self.ui.write("Going back to tip\n") | |
65 #self.repo.update(self.repo.changelog.tip()) | |
66 self.is_reset = True | |
67 return 0 | |
68 | 43 |
69 def bisect(self): | 44 def bisect(self): |
70 cl = self.repo.changelog | 45 cl = self.repo.changelog |
71 clparents = cl.parentrevs | 46 clparents = cl.parentrevs |
72 bad = self.badnode | 47 bad = self.badnode |
156 return hg.clean(self.repo, node) | 131 return hg.clean(self.repo, node) |
157 | 132 |
158 def good(self, rev=None): | 133 def good(self, rev=None): |
159 """mark revision as good and update to the next revision to test""" | 134 """mark revision as good and update to the next revision to test""" |
160 self.goodnodes.append(self.repo.lookup(rev or '.')) | 135 self.goodnodes.append(self.repo.lookup(rev or '.')) |
136 self.write() | |
161 if self.badnode: | 137 if self.badnode: |
162 return self.next() | 138 return self.next() |
163 | 139 |
164 def bad(self, rev=None): | 140 def bad(self, rev=None): |
165 """mark revision as bad and update to the next revision to test""" | 141 """mark revision as bad and update to the next revision to test""" |
166 self.badnode = self.repo.lookup(rev or '.') | 142 self.badnode = self.repo.lookup(rev or '.') |
143 self.write() | |
167 if self.goodnodes: | 144 if self.goodnodes: |
168 self.next() | 145 self.next() |
169 | 146 |
170 def bisect_run(ui, repo, cmd=None, *args): | 147 def bisect_run(ui, repo, cmd=None, *args): |
171 """Subdivision search of changesets | 148 """Subdivision search of changesets |
205 bisectcmdtable = { | 182 bisectcmdtable = { |
206 "init": (b.init, 0, _("hg bisect init")), | 183 "init": (b.init, 0, _("hg bisect init")), |
207 "bad": (b.bad, 1, _("hg bisect bad [<rev>]")), | 184 "bad": (b.bad, 1, _("hg bisect bad [<rev>]")), |
208 "good": (b.good, 1, _("hg bisect good [<rev>]")), | 185 "good": (b.good, 1, _("hg bisect good [<rev>]")), |
209 "next": (b.next, 0, _("hg bisect next")), | 186 "next": (b.next, 0, _("hg bisect next")), |
210 "reset": (b.reset, 0, _("hg bisect reset")), | |
211 "help": (help_, 1, _("hg bisect help [<subcommand>]")), | 187 "help": (help_, 1, _("hg bisect help [<subcommand>]")), |
212 } | 188 } |
189 | |
190 if cmd == "reset": | |
191 cmd = "init" | |
213 | 192 |
214 if not bisectcmdtable.has_key(cmd): | 193 if not bisectcmdtable.has_key(cmd): |
215 ui.warn(_("bisect: Unknown sub-command\n")) | 194 ui.warn(_("bisect: Unknown sub-command\n")) |
216 return help_() | 195 return help_() |
217 if len(args) > bisectcmdtable[cmd][1]: | 196 if len(args) > bisectcmdtable[cmd][1]: |
218 ui.warn(_("bisect: Too many arguments\n")) | 197 ui.warn(_("bisect: Too many arguments\n")) |
219 return help_() | 198 return help_() |
220 ret = bisectcmdtable[cmd][0](*args) | 199 ret = bisectcmdtable[cmd][0](*args) |
221 b.write() | |
222 return ret | 200 return ret |
223 | 201 |
224 cmdtable = { | 202 cmdtable = { |
225 "bisect": (bisect_run, [], _("hg bisect [help|init|reset|next|good|bad]")), | 203 "bisect": (bisect_run, [], _("hg bisect [help|init|reset|next|good|bad]")), |
226 #"bisect-test": (test, [], "hg bisect-test rev"), | 204 #"bisect-test": (test, [], "hg bisect-test rev"), |