##// END OF EJS Templates
repair.py: don't import commands.py
Alexis S. L. Carvalho -
r5898:52cfe86e default
parent child Browse files
Show More
@@ -1,127 +1,130 b''
1 1 # repair.py - functions for repository repair for mercurial
2 2 #
3 3 # Copyright 2005, 2006 Chris Mason <mason@suse.com>
4 4 # Copyright 2007 Matt Mackall
5 5 #
6 6 # This software may be used and distributed according to the terms
7 7 # of the GNU General Public License, incorporated herein by reference.
8 8
9 import changegroup, revlog, os, commands
9 import changegroup, revlog, os
10 10
11 11 def strip(ui, repo, rev, backup="all"):
12 12 def limitheads(chlog, stop):
13 13 """return the list of all nodes that have no children"""
14 14 p = {}
15 15 h = []
16 16 stoprev = 0
17 17 if stop in chlog.nodemap:
18 18 stoprev = chlog.rev(stop)
19 19
20 20 for r in xrange(chlog.count() - 1, -1, -1):
21 21 n = chlog.node(r)
22 22 if n not in p:
23 23 h.append(n)
24 24 if n == stop:
25 25 break
26 26 if r < stoprev:
27 27 break
28 28 for pn in chlog.parents(n):
29 29 p[pn] = 1
30 30 return h
31 31
32 32 def bundle(repo, bases, heads, rev, suffix):
33 33 cg = repo.changegroupsubset(bases, heads, 'strip')
34 34 backupdir = repo.join("strip-backup")
35 35 if not os.path.isdir(backupdir):
36 36 os.mkdir(backupdir)
37 37 name = os.path.join(backupdir, "%s-%s" % (revlog.short(rev), suffix))
38 38 ui.warn("saving bundle to %s\n" % name)
39 39 return changegroup.writebundle(cg, name, "HG10BZ")
40 40
41 41 def stripall(revnum):
42 42 mm = repo.changectx(rev).manifest()
43 43 seen = {}
44 44
45 45 for x in xrange(revnum, repo.changelog.count()):
46 46 for f in repo.changectx(x).files():
47 47 if f in seen:
48 48 continue
49 49 seen[f] = 1
50 50 if f in mm:
51 51 filerev = mm[f]
52 52 else:
53 53 filerev = 0
54 54 seen[f] = filerev
55 55 # we go in two steps here so the strip loop happens in a
56 56 # sensible order. When stripping many files, this helps keep
57 57 # our disk access patterns under control.
58 58 seen_list = seen.keys()
59 59 seen_list.sort()
60 60 for f in seen_list:
61 61 ff = repo.file(f)
62 62 filerev = seen[f]
63 63 if filerev != 0:
64 64 if filerev in ff.nodemap:
65 65 filerev = ff.rev(filerev)
66 66 else:
67 67 filerev = 0
68 68 ff.strip(filerev, revnum)
69 69
70 70 chlog = repo.changelog
71 71 # TODO delete the undo files, and handle undo of merge sets
72 72 pp = chlog.parents(rev)
73 73 revnum = chlog.rev(rev)
74 74
75 75 # save is a list of all the branches we are truncating away
76 76 # that we actually want to keep. changegroup will be used
77 77 # to preserve them and add them back after the truncate
78 78 saveheads = []
79 79 savebases = {}
80 80
81 81 heads = limitheads(chlog, rev)
82 82 seen = {}
83 83
84 84 # search through all the heads, finding those where the revision
85 85 # we want to strip away is an ancestor. Also look for merges
86 86 # that might be turned into new heads by the strip.
87 87 while heads:
88 88 h = heads.pop()
89 89 n = h
90 90 while True:
91 91 seen[n] = 1
92 92 pp = chlog.parents(n)
93 93 if pp[1] != revlog.nullid:
94 94 for p in pp:
95 95 if chlog.rev(p) > revnum and p not in seen:
96 96 heads.append(p)
97 97 if pp[0] == revlog.nullid:
98 98 break
99 99 if chlog.rev(pp[0]) < revnum:
100 100 break
101 101 n = pp[0]
102 102 if n == rev:
103 103 break
104 104 r = chlog.reachable(h, rev)
105 105 if rev not in r:
106 106 saveheads.append(h)
107 107 for x in r:
108 108 if chlog.rev(x) > revnum:
109 109 savebases[x] = 1
110 110
111 111 # create a changegroup for all the branches we need to keep
112 112 if backup == "all":
113 113 bundle(repo, [rev], chlog.heads(), rev, 'backup')
114 114 if saveheads:
115 115 chgrpfile = bundle(repo, savebases.keys(), saveheads, rev, 'temp')
116 116
117 117 stripall(revnum)
118 118
119 119 change = chlog.read(rev)
120 120 chlog.strip(revnum, revnum)
121 121 repo.manifest.strip(repo.manifest.rev(change[0]), revnum)
122 122 if saveheads:
123 123 ui.status("adding branch\n")
124 commands.unbundle(ui, repo, "file:%s" % chgrpfile, update=False)
124 f = open(chgrpfile, "rb")
125 gen = changegroup.readbundle(f, chgrpfile)
126 repo.addchangegroup(gen, 'strip', 'bundle:' + chgrpfile)
127 f.close()
125 128 if backup != "strip":
126 129 os.unlink(chgrpfile)
127 130
@@ -1,458 +1,455 b''
1 1 % help
2 2 mq extension - patch management and development
3 3
4 4 This extension lets you work with a stack of patches in a Mercurial
5 5 repository. It manages two stacks of patches - all known patches, and
6 6 applied patches (subset of known patches).
7 7
8 8 Known patches are represented as patch files in the .hg/patches
9 9 directory. Applied patches are both patch files and changesets.
10 10
11 11 Common tasks (use "hg help command" for more details):
12 12
13 13 prepare repository to work with patches qinit
14 14 create new patch qnew
15 15 import existing patch qimport
16 16
17 17 print patch series qseries
18 18 print applied patches qapplied
19 19 print name of top applied patch qtop
20 20
21 21 add known patch to applied stack qpush
22 22 remove patch from applied stack qpop
23 23 refresh contents of top applied patch qrefresh
24 24
25 25 list of commands:
26 26
27 27 qapplied print the patches already applied
28 28 qclone clone main and patch repository at same time
29 29 qcommit commit changes in the queue repository
30 30 qdelete remove patches from queue
31 31 qdiff diff of the current patch
32 32 qfold fold the named patches into the current patch
33 33 qgoto push or pop patches until named patch is at top of stack
34 34 qguard set or print guards for a patch
35 35 qheader Print the header of the topmost or specified patch
36 36 qimport import a patch
37 37 qinit init a new queue repository
38 38 qnew create a new patch
39 39 qnext print the name of the next patch
40 40 qpop pop the current patch off the stack
41 41 qprev print the name of the previous patch
42 42 qpush push the next patch onto the stack
43 43 qrefresh update the current patch
44 44 qrename rename a patch
45 45 qrestore restore the queue state saved by a rev
46 46 qsave save current queue state
47 47 qselect set or print guarded patches to push
48 48 qseries print the entire series file
49 49 qtop print the name of the current patch
50 50 qunapplied print the patches not yet applied
51 51 strip strip a revision and all later revs on the same branch
52 52
53 53 use "hg -v help mq" to show aliases and global options
54 54 adding a
55 55 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
56 56 adding b/z
57 57 % qinit
58 58 % -R qinit
59 59 % qinit -c
60 60 A .hgignore
61 61 A series
62 62 % qnew implies add
63 63 A .hgignore
64 64 A series
65 65 A test.patch
66 66 % qinit; qinit -c
67 67 .hgignore:
68 68 syntax: glob
69 69 status
70 70 guards
71 71 series:
72 72 abort: repository already exists!
73 73 % qinit; <stuff>; qinit -c
74 74 adding .hg/patches/A
75 75 adding .hg/patches/B
76 76 A .hgignore
77 77 A A
78 78 A B
79 79 A series
80 80 .hgignore:
81 81 status
82 82 bleh
83 83 series:
84 84 A
85 85 B
86 86 % qnew with uncommitted changes
87 87 abort: local changes found, refresh first
88 88 A somefile
89 89 % qnew with uncommitted changes and missing file (issue 803)
90 90 someotherfile: No such file or directory
91 91 A somefile
92 92 issue803.patch
93 93 Patch queue now empty
94 94 % qnew -m
95 95 foo bar
96 96 % qrefresh
97 97 foo bar
98 98
99 99 diff -r xa
100 100 --- a/a
101 101 +++ b/a
102 102 @@ -1,1 +1,2 @@
103 103 a
104 104 +a
105 105 % empty qrefresh
106 106 revision:
107 107 patch:
108 108 foo bar
109 109
110 110 working dir diff:
111 111 --- a/a
112 112 +++ b/a
113 113 @@ -1,1 +1,2 @@
114 114 a
115 115 +a
116 116 % qpop
117 117 Patch queue now empty
118 118 % qpush
119 119 applying test.patch
120 120 Now at: test.patch
121 121 % pop/push outside repo
122 122 Patch queue now empty
123 123 applying test.patch
124 124 Now at: test.patch
125 125 % qrefresh in subdir
126 126 % pop/push -a in subdir
127 127 Patch queue now empty
128 128 applying test.patch
129 129 applying test2.patch
130 130 Now at: test2.patch
131 131 % qseries
132 132 test.patch
133 133 test2.patch
134 134 Now at: test.patch
135 135 0 A test.patch: foo bar
136 136 1 U test2.patch:
137 137 applying test2.patch
138 138 Now at: test2.patch
139 139 % qapplied
140 140 test.patch
141 141 test2.patch
142 142 % qtop
143 143 test2.patch
144 144 % qprev
145 145 test.patch
146 146 % qnext
147 147 All patches applied
148 148 % pop, qnext, qprev, qapplied
149 149 Now at: test.patch
150 150 test2.patch
151 151 Only one patch applied
152 152 test.patch
153 153 % commit should fail
154 154 abort: cannot commit over an applied mq patch
155 155 % push should fail
156 156 pushing to ../../k
157 157 abort: source has mq patches applied
158 158 % qunapplied
159 159 test2.patch
160 160 % qpush/qpop with index
161 161 applying test2.patch
162 162 Now at: test2.patch
163 163 Now at: test.patch
164 164 applying test1b.patch
165 165 Now at: test1b.patch
166 166 applying test2.patch
167 167 Now at: test2.patch
168 168 Now at: test1b.patch
169 169 Now at: test.patch
170 170 applying test1b.patch
171 171 applying test2.patch
172 172 Now at: test2.patch
173 173 % push should succeed
174 174 Patch queue now empty
175 175 pushing to ../../k
176 176 searching for changes
177 177 adding changesets
178 178 adding manifests
179 179 adding file changes
180 180 added 1 changesets with 1 changes to 1 files
181 181 % qpush/qpop error codes
182 182 applying test.patch
183 183 applying test1b.patch
184 184 applying test2.patch
185 185 Now at: test2.patch
186 186 % pops all patches and succeeds
187 187 Patch queue now empty
188 188 qpop -a succeeds
189 189 % does nothing and succeeds
190 190 no patches applied
191 191 qpop -a succeeds
192 192 % fails - nothing else to pop
193 193 no patches applied
194 194 qpop fails
195 195 % pushes a patch and succeeds
196 196 applying test.patch
197 197 Now at: test.patch
198 198 qpush succeeds
199 199 % pops a patch and succeeds
200 200 Patch queue now empty
201 201 qpop succeeds
202 202 % pushes up to test1b.patch and succeeds
203 203 applying test.patch
204 204 applying test1b.patch
205 205 Now at: test1b.patch
206 206 qpush test1b.patch succeeds
207 207 % does nothing and succeeds
208 208 qpush: test1b.patch is already at the top
209 209 qpush test1b.patch succeeds
210 210 % does nothing and succeeds
211 211 qpop: test1b.patch is already at the top
212 212 qpop test1b.patch succeeds
213 213 % fails - can't push to this patch
214 214 abort: cannot push to a previous patch: test.patch
215 215 qpush test.patch fails
216 216 % fails - can't pop to this patch
217 217 abort: patch test2.patch is not applied
218 218 qpop test2.patch fails
219 219 % pops up to test.patch and succeeds
220 220 Now at: test.patch
221 221 qpop test.patch succeeds
222 222 % pushes all patches and succeeds
223 223 applying test1b.patch
224 224 applying test2.patch
225 225 Now at: test2.patch
226 226 qpush -a succeeds
227 227 % does nothing and succeeds
228 228 all patches are currently applied
229 229 qpush -a succeeds
230 230 % fails - nothing else to push
231 231 patch series already fully applied
232 232 qpush fails
233 233 % does nothing and succeeds
234 234 all patches are currently applied
235 235 qpush test2.patch succeeds
236 236 % strip
237 237 adding x
238 238 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
239 239 saving bundle to
240 240 adding changesets
241 241 adding manifests
242 242 adding file changes
243 243 added 1 changesets with 1 changes to 1 files
244 244 (run 'hg update' to get a working copy)
245 245 % cd b; hg qrefresh
246 246 adding a
247 247 foo
248 248
249 249 diff -r cb9a9f314b8b a
250 250 --- a/a
251 251 +++ b/a
252 252 @@ -1,1 +1,2 @@
253 253 a
254 254 +a
255 255 diff -r cb9a9f314b8b b/f
256 256 --- /dev/null
257 257 +++ b/b/f
258 258 @@ -0,0 +1,1 @@
259 259 +f
260 260 % hg qrefresh .
261 261 foo
262 262
263 263 diff -r cb9a9f314b8b b/f
264 264 --- /dev/null
265 265 +++ b/b/f
266 266 @@ -0,0 +1,1 @@
267 267 +f
268 268 M a
269 269 % qpush failure
270 270 Patch queue now empty
271 271 applying foo
272 272 applying bar
273 273 file foo already exists
274 274 1 out of 1 hunk FAILED -- saving rejects to file foo.rej
275 275 patch failed, unable to continue (try -v)
276 276 patch failed, rejects left in working dir
277 277 Errors during apply, please fix and refresh bar
278 278 ? foo
279 279 ? foo.rej
280 280 % mq tags
281 281 0 qparent
282 282 1 qbase foo
283 283 2 qtip bar tip
284 284 new file
285 285
286 286 diff --git a/new b/new
287 287 new file mode 100755
288 288 --- /dev/null
289 289 +++ b/new
290 290 @@ -0,0 +1,1 @@
291 291 +foo
292 292 copy file
293 293
294 294 diff --git a/new b/copy
295 295 copy from new
296 296 copy to copy
297 297 Now at: new
298 298 applying copy
299 299 Now at: copy
300 300 diff --git a/new b/copy
301 301 copy from new
302 302 copy to copy
303 303 diff --git a/new b/copy
304 304 copy from new
305 305 copy to copy
306 306 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
307 307 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
308 308 adding branch
309 309 adding changesets
310 310 adding manifests
311 311 adding file changes
312 312 added 1 changesets with 1 changes to 1 files
313 (run 'hg update' to get a working copy)
314 313 Patch queue now empty
315 314 applying bar
316 315 Now at: bar
317 316 diff --git a/bar b/bar
318 317 new file mode 100644
319 318 --- /dev/null
320 319 +++ b/bar
321 320 @@ -0,0 +1,1 @@
322 321 +bar
323 322 diff --git a/foo b/baz
324 323 rename from foo
325 324 rename to baz
326 325 2 baz (foo)
327 326 diff --git a/bar b/bar
328 327 new file mode 100644
329 328 --- /dev/null
330 329 +++ b/bar
331 330 @@ -0,0 +1,1 @@
332 331 +bar
333 332 diff --git a/foo b/baz
334 333 rename from foo
335 334 rename to baz
336 335 2 baz (foo)
337 336 diff --git a/bar b/bar
338 337 diff --git a/foo b/baz
339 338
340 339 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
341 340 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
342 341 adding branch
343 342 adding changesets
344 343 adding manifests
345 344 adding file changes
346 345 added 1 changesets with 1 changes to 1 files
347 (run 'hg update' to get a working copy)
348 346 Patch queue now empty
349 347 applying bar
350 348 Now at: bar
351 349 diff --git a/foo b/bleh
352 350 rename from foo
353 351 rename to bleh
354 352 diff --git a/quux b/quux
355 353 new file mode 100644
356 354 --- /dev/null
357 355 +++ b/quux
358 356 @@ -0,0 +1,1 @@
359 357 +bar
360 358 3 bleh (foo)
361 359 diff --git a/foo b/barney
362 360 rename from foo
363 361 rename to barney
364 362 diff --git a/fred b/fred
365 363 new file mode 100644
366 364 --- /dev/null
367 365 +++ b/fred
368 366 @@ -0,0 +1,1 @@
369 367 +bar
370 368 3 barney (foo)
371 369 % refresh omitting an added file
372 370 C newfile
373 371 A newfile
374 372 Now at: bar
375 373 % create a git patch
376 374 diff --git a/alexander b/alexander
377 375 % create a git binary patch
378 376 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus
379 377 diff --git a/bucephalus b/bucephalus
380 378 % check binary patches can be popped and pushed
381 379 Now at: addalexander
382 380 applying addbucephalus
383 381 Now at: addbucephalus
384 382 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus
385 383 % strip again
386 384 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
387 385 merging foo
388 386 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
389 387 (branch merge, don't forget to commit)
390 388 changeset: 3:99615015637b
391 389 tag: tip
392 390 parent: 2:20cbbe65cff7
393 391 parent: 1:d2871fc282d4
394 392 user: test
395 393 date: Thu Jan 01 00:00:00 1970 +0000
396 394 summary: merge
397 395
398 396 changeset: 2:20cbbe65cff7
399 397 parent: 0:53245c60e682
400 398 user: test
401 399 date: Thu Jan 01 00:00:00 1970 +0000
402 400 summary: change foo 2
403 401
404 402 changeset: 1:d2871fc282d4
405 403 user: test
406 404 date: Thu Jan 01 00:00:00 1970 +0000
407 405 summary: change foo 1
408 406
409 407 changeset: 0:53245c60e682
410 408 user: test
411 409 date: Thu Jan 01 00:00:00 1970 +0000
412 410 summary: add foo
413 411
414 412 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
415 413 saving bundle to
416 414 saving bundle to
417 415 adding branch
418 416 adding changesets
419 417 adding manifests
420 418 adding file changes
421 419 added 1 changesets with 1 changes to 1 files
422 (run 'hg update' to get a working copy)
423 420 changeset: 1:20cbbe65cff7
424 421 tag: tip
425 422 user: test
426 423 date: Thu Jan 01 00:00:00 1970 +0000
427 424 summary: change foo 2
428 425
429 426 changeset: 0:53245c60e682
430 427 user: test
431 428 date: Thu Jan 01 00:00:00 1970 +0000
432 429 summary: add foo
433 430
434 431 % qclone
435 432 abort: versioned patch repository not found (see qinit -c)
436 433 adding .hg/patches/patch1
437 434 main repo:
438 435 rev 1: change foo
439 436 rev 0: add foo
440 437 patch repo:
441 438 rev 0: checkpoint
442 439 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
443 440 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
444 441 main repo:
445 442 rev 0: add foo
446 443 patch repo:
447 444 rev 0: checkpoint
448 445 Patch queue now empty
449 446 main repo:
450 447 rev 0: add foo
451 448 patch repo:
452 449 rev 0: checkpoint
453 450 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
454 451 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
455 452 main repo:
456 453 rev 0: add foo
457 454 patch repo:
458 455 rev 0: checkpoint
General Comments 0
You need to be logged in to leave comments. Login now