##// END OF EJS Templates
extdiff: refactor logic to diff revs of versions of files...
Pulkit Goyal -
r45687:da2e69a2 default
parent child Browse files
Show More
@@ -382,54 +382,21 b' def diffpatch(ui, repo, node1a, node2, t'
382 return 1
382 return 1
383
383
384
384
385 def dodiff(ui, repo, cmdline, pats, opts, guitool=False):
385 def diffrevs(
386 '''Do the actual diff:
386 ui,
387
387 repo,
388 - copy to a temp structure if diffing 2 internal revisions
388 node1a,
389 - copy to a temp structure if diffing working revision with
389 node1b,
390 another one and more than 1 file is changed
390 node2,
391 - just invoke the diff for a single file in the working dir
391 matcher,
392 '''
392 tmproot,
393
393 cmdline,
394 cmdutil.check_at_most_one_arg(opts, b'rev', b'change')
394 do3way,
395 revs = opts.get(b'rev')
395 guitool,
396 change = opts.get(b'change')
396 opts,
397 do3way = b'$parent2' in cmdline
397 ):
398
399 if change:
400 ctx2 = scmutil.revsingle(repo, change, None)
401 ctx1a, ctx1b = ctx2.p1(), ctx2.p2()
402 else:
403 ctx1a, ctx2 = scmutil.revpair(repo, revs)
404 if not revs:
405 ctx1b = repo[None].p2()
406 else:
407 ctx1b = repo[nullid]
408
409 perfile = opts.get(b'per_file')
410 confirm = opts.get(b'confirm')
411
412 node1a = ctx1a.node()
413 node1b = ctx1b.node()
414 node2 = ctx2.node()
415
416 # Disable 3-way merge if there is only one parent
417 if do3way:
418 if node1b == nullid:
419 do3way = False
420
398
421 subrepos = opts.get(b'subrepos')
399 subrepos = opts.get(b'subrepos')
422
423 matcher = scmutil.match(repo[node2], pats, opts)
424
425 if opts.get(b'patch'):
426 if subrepos:
427 raise error.Abort(_(b'--patch cannot be used with --subrepos'))
428 if perfile:
429 raise error.Abort(_(b'--patch cannot be used with --per-file'))
430 if node2 is None:
431 raise error.Abort(_(b'--patch requires two revisions'))
432 else:
433 st = repo.status(node1a, node2, matcher, listsubrepos=subrepos)
400 st = repo.status(node1a, node2, matcher, listsubrepos=subrepos)
434 mod_a, add_a, rem_a = set(st.modified), set(st.added), set(st.removed)
401 mod_a, add_a, rem_a = set(st.modified), set(st.added), set(st.removed)
435 if do3way:
402 if do3way:
@@ -445,23 +412,13 b' def dodiff(ui, repo, cmdline, pats, opts'
445 common = modadd | rem_a | rem_b
412 common = modadd | rem_a | rem_b
446 if not common:
413 if not common:
447 return 0
414 return 0
448
449 tmproot = pycompat.mkdtemp(prefix=b'extdiff.')
450 try:
451 if opts.get(b'patch'):
452 return diffpatch(
453 ui, repo, node1a, node2, tmproot, matcher, cmdline, do3way
454 )
455
456 # Always make a copy of node1a (and node1b, if applicable)
415 # Always make a copy of node1a (and node1b, if applicable)
457 dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a)
416 dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a)
458 dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot, subrepos)[0]
417 dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot, subrepos)[0]
459 rev1a = b'@%d' % repo[node1a].rev()
418 rev1a = b'@%d' % repo[node1a].rev()
460 if do3way:
419 if do3way:
461 dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b)
420 dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b)
462 dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot, subrepos)[
421 dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot, subrepos)[0]
463 0
464 ]
465 rev1b = b'@%d' % repo[node1b].rev()
422 rev1b = b'@%d' % repo[node1b].rev()
466 else:
423 else:
467 dir1b = None
424 dir1b = None
@@ -480,9 +437,7 b' def dodiff(ui, repo, cmdline, pats, opts'
480 # the working dir in this case (because the other cases
437 # the working dir in this case (because the other cases
481 # are: diffing 2 revisions or single file -- in which case
438 # are: diffing 2 revisions or single file -- in which case
482 # the file is already directly passed to the diff tool).
439 # the file is already directly passed to the diff tool).
483 dir2, fnsandstat = snapshot(
440 dir2, fnsandstat = snapshot(ui, repo, modadd, None, tmproot, subrepos)
484 ui, repo, modadd, None, tmproot, subrepos
485 )
486 else:
441 else:
487 # This lets the diff tool open the changed file directly
442 # This lets the diff tool open the changed file directly
488 dir2 = b''
443 dir2 = b''
@@ -508,7 +463,7 b' def dodiff(ui, repo, cmdline, pats, opts'
508 dir2 = os.path.join(dir2root, dir2, common_file)
463 dir2 = os.path.join(dir2root, dir2, common_file)
509 label2 = common_file + rev2
464 label2 = common_file + rev2
510
465
511 if not perfile:
466 if not opts.get(b'per_file'):
512 # Run the external tool on the 2 temp directories or the patches
467 # Run the external tool on the 2 temp directories or the patches
513 cmdline = formatcmdline(
468 cmdline = formatcmdline(
514 cmdline,
469 cmdline,
@@ -521,9 +476,7 b' def dodiff(ui, repo, cmdline, pats, opts'
521 child=dir2,
476 child=dir2,
522 clabel=label2,
477 clabel=label2,
523 )
478 )
524 ui.debug(
479 ui.debug(b'running %r in %s\n' % (pycompat.bytestr(cmdline), tmproot))
525 b'running %r in %s\n' % (pycompat.bytestr(cmdline), tmproot)
526 )
527 ui.system(cmdline, cwd=tmproot, blockedtag=b'extdiff')
480 ui.system(cmdline, cwd=tmproot, blockedtag=b'extdiff')
528 else:
481 else:
529 # Run the external tool once for each pair of files
482 # Run the external tool once for each pair of files
@@ -533,7 +486,7 b' def dodiff(ui, repo, cmdline, pats, opts'
533 ui,
486 ui,
534 guitool=guitool,
487 guitool=guitool,
535 do3way=do3way,
488 do3way=do3way,
536 confirm=confirm,
489 confirm=opts.get(b'confirm'),
537 commonfiles=common,
490 commonfiles=common,
538 tmproot=tmproot,
491 tmproot=tmproot,
539 dir1a=dir1a,
492 dir1a=dir1a,
@@ -566,6 +519,72 b' def dodiff(ui, repo, cmdline, pats, opts'
566 util.copyfile(copy_fn, working_fn)
519 util.copyfile(copy_fn, working_fn)
567
520
568 return 1
521 return 1
522
523
524 def dodiff(ui, repo, cmdline, pats, opts, guitool=False):
525 '''Do the actual diff:
526
527 - copy to a temp structure if diffing 2 internal revisions
528 - copy to a temp structure if diffing working revision with
529 another one and more than 1 file is changed
530 - just invoke the diff for a single file in the working dir
531 '''
532
533 cmdutil.check_at_most_one_arg(opts, b'rev', b'change')
534 revs = opts.get(b'rev')
535 change = opts.get(b'change')
536 do3way = b'$parent2' in cmdline
537
538 if change:
539 ctx2 = scmutil.revsingle(repo, change, None)
540 ctx1a, ctx1b = ctx2.p1(), ctx2.p2()
541 else:
542 ctx1a, ctx2 = scmutil.revpair(repo, revs)
543 if not revs:
544 ctx1b = repo[None].p2()
545 else:
546 ctx1b = repo[nullid]
547
548 node1a = ctx1a.node()
549 node1b = ctx1b.node()
550 node2 = ctx2.node()
551
552 # Disable 3-way merge if there is only one parent
553 if do3way:
554 if node1b == nullid:
555 do3way = False
556
557 matcher = scmutil.match(repo[node2], pats, opts)
558
559 if opts.get(b'patch'):
560 if opts.get(b'subrepos'):
561 raise error.Abort(_(b'--patch cannot be used with --subrepos'))
562 if opts.get(b'per_file'):
563 raise error.Abort(_(b'--patch cannot be used with --per-file'))
564 if node2 is None:
565 raise error.Abort(_(b'--patch requires two revisions'))
566
567 tmproot = pycompat.mkdtemp(prefix=b'extdiff.')
568 try:
569 if opts.get(b'patch'):
570 return diffpatch(
571 ui, repo, node1a, node2, tmproot, matcher, cmdline, do3way
572 )
573
574 return diffrevs(
575 ui,
576 repo,
577 node1a,
578 node1b,
579 node2,
580 matcher,
581 tmproot,
582 cmdline,
583 do3way,
584 guitool,
585 opts,
586 )
587
569 finally:
588 finally:
570 ui.note(_(b'cleaning up temp directory\n'))
589 ui.note(_(b'cleaning up temp directory\n'))
571 shutil.rmtree(tmproot)
590 shutil.rmtree(tmproot)
General Comments 0
You need to be logged in to leave comments. Login now