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 |
|
|
400 | st = repo.status(node1a, node2, matcher, listsubrepos=subrepos) | |
434 |
|
|
401 | mod_a, add_a, rem_a = set(st.modified), set(st.added), set(st.removed) | |
435 |
|
|
402 | if do3way: | |
@@ -445,23 +412,13 b' def dodiff(ui, repo, cmdline, pats, opts' | |||||
445 |
|
|
412 | common = modadd | rem_a | rem_b | |
446 |
|
|
413 | if not common: | |
447 |
|
|
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 |
|
|
415 | # Always make a copy of node1a (and node1b, if applicable) | |
457 |
|
|
416 | dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a) | |
458 |
|
|
417 | dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot, subrepos)[0] | |
459 |
|
|
418 | rev1a = b'@%d' % repo[node1a].rev() | |
460 |
|
|
419 | if do3way: | |
461 |
|
|
420 | dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b) | |
462 |
|
|
421 | dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot, subrepos)[0] | |
463 | 0 |
|
|||
464 | ] |
|
|||
465 |
|
|
422 | rev1b = b'@%d' % repo[node1b].rev() | |
466 |
|
|
423 | else: | |
467 |
|
|
424 | dir1b = None | |
@@ -480,9 +437,7 b' def dodiff(ui, repo, cmdline, pats, opts' | |||||
480 |
|
|
437 | # the working dir in this case (because the other cases | |
481 |
|
|
438 | # are: diffing 2 revisions or single file -- in which case | |
482 |
|
|
439 | # the file is already directly passed to the diff tool). | |
483 |
|
|
440 | dir2, fnsandstat = snapshot(ui, repo, modadd, None, tmproot, subrepos) | |
484 | ui, repo, modadd, None, tmproot, subrepos |
|
|||
485 | ) |
|
|||
486 |
|
|
441 | else: | |
487 |
|
|
442 | # This lets the diff tool open the changed file directly | |
488 |
|
|
443 | dir2 = b'' | |
@@ -508,7 +463,7 b' def dodiff(ui, repo, cmdline, pats, opts' | |||||
508 |
|
|
463 | dir2 = os.path.join(dir2root, dir2, common_file) | |
509 |
|
|
464 | label2 = common_file + rev2 | |
510 |
|
465 | |||
511 |
|
|
466 | if not opts.get(b'per_file'): | |
512 |
|
|
467 | # Run the external tool on the 2 temp directories or the patches | |
513 |
|
|
468 | cmdline = formatcmdline( | |
514 |
|
|
469 | cmdline, | |
@@ -521,9 +476,7 b' def dodiff(ui, repo, cmdline, pats, opts' | |||||
521 |
|
|
476 | child=dir2, | |
522 |
|
|
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 |
|
|
480 | ui.system(cmdline, cwd=tmproot, blockedtag=b'extdiff') | |
528 |
|
|
481 | else: | |
529 |
|
|
482 | # Run the external tool once for each pair of files | |
@@ -533,7 +486,7 b' def dodiff(ui, repo, cmdline, pats, opts' | |||||
533 |
|
|
486 | ui, | |
534 |
|
|
487 | guitool=guitool, | |
535 |
|
|
488 | do3way=do3way, | |
536 |
|
|
489 | confirm=opts.get(b'confirm'), | |
537 |
|
|
490 | commonfiles=common, | |
538 |
|
|
491 | tmproot=tmproot, | |
539 |
|
|
492 | dir1a=dir1a, | |
@@ -566,6 +519,72 b' def dodiff(ui, repo, cmdline, pats, opts' | |||||
566 |
|
|
519 | util.copyfile(copy_fn, working_fn) | |
567 |
|
520 | |||
568 |
|
|
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