comparison mercurial/patch.py @ 2934:2f190e998eb3

Teach mq about git patches
author Brendan Cully <brendan@kublai.com>
date Wed, 16 Aug 2006 19:49:45 -0700
parents 439fd013360d
children 6ba3409f9725
comparison
equal deleted inserted replaced
2933:439fd013360d 2934:2f190e998eb3
341 if fp is None: 341 if fp is None:
342 fp = repo.ui 342 fp = repo.ui
343 343
344 if not node1: 344 if not node1:
345 node1 = repo.dirstate.parents()[0] 345 node1 = repo.dirstate.parents()[0]
346
347 clcache = {}
348 def getchangelog(n):
349 if n not in clcache:
350 clcache[n] = repo.changelog.read(n)
351 return clcache[n]
352 mcache = {}
353 def getmanifest(n):
354 if n not in mcache:
355 mcache[n] = repo.manifest.read(n)
356 return mcache[n]
357 fcache = {}
358 def getfile(f):
359 if f not in fcache:
360 fcache[f] = repo.file(f)
361 return fcache[f]
362
346 # reading the data for node1 early allows it to play nicely 363 # reading the data for node1 early allows it to play nicely
347 # with repo.status and the revlog cache. 364 # with repo.status and the revlog cache.
348 change = repo.changelog.read(node1) 365 change = getchangelog(node1)
349 mmap = repo.manifest.read(change[0]) 366 mmap = getmanifest(change[0])
350 date1 = util.datestr(change[2]) 367 date1 = util.datestr(change[2])
351 368
352 if not changes: 369 if not changes:
353 changes = repo.status(node1, node2, files, match=match)[:5] 370 changes = repo.status(node1, node2, files, match=match)[:5]
354 modified, added, removed, deleted, unknown = changes 371 modified, added, removed, deleted, unknown = changes
365 modified, added, removed = map(filterfiles, (modified, added, removed)) 382 modified, added, removed = map(filterfiles, (modified, added, removed))
366 383
367 if not modified and not added and not removed: 384 if not modified and not added and not removed:
368 return 385 return
369 386
387 def renamedbetween(f, n1, n2):
388 r1, r2 = map(repo.changelog.rev, (n1, n2))
389 src = None
390 while r2 > r1:
391 cl = getchangelog(n2)[0]
392 m = getmanifest(cl)
393 try:
394 src = getfile(f).renamed(m[f])
395 except KeyError:
396 return None
397 if src:
398 f = src[0]
399 n2 = repo.changelog.parents(n2)[0]
400 r2 = repo.changelog.rev(n2)
401 return src
402
370 if node2: 403 if node2:
371 change = repo.changelog.read(node2) 404 change = getchangelog(node2)
372 mmap2 = repo.manifest.read(change[0]) 405 mmap2 = getmanifest(change[0])
373 _date2 = util.datestr(change[2]) 406 _date2 = util.datestr(change[2])
374 def date2(f): 407 def date2(f):
375 return _date2 408 return _date2
376 def read(f): 409 def read(f):
377 return repo.file(f).read(mmap2[f]) 410 return getfile(f).read(mmap2[f])
378 def renamed(f): 411 def renamed(f):
379 src = repo.file(f).renamed(mmap2[f]) 412 return renamedbetween(f, node1, node2)
380 return src and src[0] or None
381 else: 413 else:
382 tz = util.makedate()[1] 414 tz = util.makedate()[1]
383 _date2 = util.datestr() 415 _date2 = util.datestr()
384 def date2(f): 416 def date2(f):
385 try: 417 try:
388 if err.errno != errno.ENOENT: raise 420 if err.errno != errno.ENOENT: raise
389 return _date2 421 return _date2
390 def read(f): 422 def read(f):
391 return repo.wread(f) 423 return repo.wread(f)
392 def renamed(f): 424 def renamed(f):
393 return repo.dirstate.copies.get(f) 425 src = repo.dirstate.copies.get(f)
426 parent = repo.dirstate.parents()[0]
427 if src:
428 f = src[0]
429 of = renamedbetween(f, node1, parent)
430 if of:
431 return of
432 elif src:
433 cl = getchangelog(parent)[0]
434 return (src, getmanifest(cl)[src])
435 else:
436 return None
394 437
395 if repo.ui.quiet: 438 if repo.ui.quiet:
396 r = None 439 r = None
397 else: 440 else:
398 hexfunc = repo.ui.verbose and hex or short 441 hexfunc = repo.ui.verbose and hex or short
402 copied = {} 445 copied = {}
403 for f in added: 446 for f in added:
404 src = renamed(f) 447 src = renamed(f)
405 if src: 448 if src:
406 copied[f] = src 449 copied[f] = src
407 srcs = [x[1] for x in copied.items()] 450 srcs = [x[1][0] for x in copied.items()]
408 451
409 all = modified + added + removed 452 all = modified + added + removed
410 all.sort() 453 all.sort()
411 for f in all: 454 for f in all:
412 to = None 455 to = None
413 tn = None 456 tn = None
414 dodiff = True 457 dodiff = True
415 if f in mmap: 458 if f in mmap:
416 to = repo.file(f).read(mmap[f]) 459 to = getfile(f).read(mmap[f])
417 if f not in removed: 460 if f not in removed:
418 tn = read(f) 461 tn = read(f)
419 if opts.git: 462 if opts.git:
420 def gitmode(x): 463 def gitmode(x):
421 return x and '100755' or '100644' 464 return x and '100755' or '100644'
430 if node2: 473 if node2:
431 mode = gitmode(mmap2.execf(f)) 474 mode = gitmode(mmap2.execf(f))
432 else: 475 else:
433 mode = gitmode(util.is_exec(repo.wjoin(f), None)) 476 mode = gitmode(util.is_exec(repo.wjoin(f), None))
434 if f in copied: 477 if f in copied:
435 a = copied[f] 478 a, arev = copied[f]
436 omode = gitmode(mmap.execf(a)) 479 omode = gitmode(mmap.execf(a))
437 addmodehdr(header, omode, mode) 480 addmodehdr(header, omode, mode)
438 op = a in removed and 'rename' or 'copy' 481 op = a in removed and 'rename' or 'copy'
439 header.append('%s from %s\n' % (op, a)) 482 header.append('%s from %s\n' % (op, a))
440 header.append('%s to %s\n' % (op, f)) 483 header.append('%s to %s\n' % (op, f))
441 to = repo.file(a).read(mmap[a]) 484 to = getfile(a).read(arev)
442 else: 485 else:
443 header.append('new file mode %s\n' % mode) 486 header.append('new file mode %s\n' % mode)
444 elif f in removed: 487 elif f in removed:
445 if f in srcs: 488 if f in srcs:
446 dodiff = False 489 dodiff = False