Mercurial > emacs
comparison lisp/ediff.el @ 26263:4f315ca65976
*** empty log message ***
author | Michael Kifer <kifer@cs.stonybrook.edu> |
---|---|
date | Mon, 01 Nov 1999 07:16:15 +0000 |
parents | 5c9c0bd0a408 |
children | 3ec5a485d0ab |
comparison
equal
deleted
inserted
replaced
26262:c416a18b0a5d | 26263:4f315ca65976 |
---|---|
1 ;;; ediff.el --- a comprehensive visual interface to diff & patch | 1 ;;; ediff.el --- a comprehensive visual interface to diff & patch |
2 | 2 |
3 ;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. | 3 ;; Copyright (C) 1994 -- 1999 Free Software Foundation, Inc. |
4 | 4 |
5 ;; Author: Michael Kifer <kifer@cs.sunysb.edu> | 5 ;; Author: Michael Kifer <kifer@cs.sunysb.edu> |
6 ;; Created: February 2, 1994 | 6 ;; Created: February 2, 1994 |
7 ;; Keywords: comparing, merging, patching, version control. | 7 ;; Keywords: comparing, merging, patching, version control. |
8 | 8 |
9 (defconst ediff-version "2.70.2" "The current version of Ediff") | 9 (defconst ediff-version "2.74" "The current version of Ediff") |
10 (defconst ediff-date "May 21, 1998" "Date of last update") | 10 (defconst ediff-date "October 31, 1999" "Date of last update") |
11 | 11 |
12 | 12 |
13 ;; This file is part of GNU Emacs. | 13 ;; This file is part of GNU Emacs. |
14 | 14 |
15 ;; GNU Emacs is free software; you can redistribute it and/or modify | 15 ;; GNU Emacs is free software; you can redistribute it and/or modify |
40 ;; separate frames), and the differences are highlighted as you step | 40 ;; separate frames), and the differences are highlighted as you step |
41 ;; through them. You can also copy difference regions from one buffer to | 41 ;; through them. You can also copy difference regions from one buffer to |
42 ;; another (and recover old differences if you change your mind). | 42 ;; another (and recover old differences if you change your mind). |
43 | 43 |
44 ;; Ediff also supports merging operations on files and buffers, including | 44 ;; Ediff also supports merging operations on files and buffers, including |
45 ;; merging using ancestor versions. Both comparison and merging operations can | 45 ;; merging using ancestor versions. Both comparison and merging operations can |
46 ;; be performed on directories, i.e., by pairwise comparison of files in those | 46 ;; be performed on directories, i.e., by pairwise comparison of files in those |
47 ;; directories. | 47 ;; directories. |
48 | 48 |
49 ;; In addition, Ediff can apply a patch to a file and then let you step | 49 ;; In addition, Ediff can apply a patch to a file and then let you step |
50 ;; though both files, the patched and the original one, simultaneously, | 50 ;; though both files, the patched and the original one, simultaneously, |
54 ;; effect, apply patches selectively (i.e., you can copy a difference | 54 ;; effect, apply patches selectively (i.e., you can copy a difference |
55 ;; region from file_orig to file, thereby undoing any particular patch that | 55 ;; region from file_orig to file, thereby undoing any particular patch that |
56 ;; you don't like). | 56 ;; you don't like). |
57 | 57 |
58 ;; Ediff is aware of version control, which lets the user compare | 58 ;; Ediff is aware of version control, which lets the user compare |
59 ;; files with their older versions. Ediff can also work with remote and | 59 ;; files with their older versions. Ediff can also work with remote and |
60 ;; compressed files. Details are given below. | 60 ;; compressed files. Details are given below. |
61 | 61 |
62 ;; Finally, Ediff supports directory-level comparison, merging and patching. | 62 ;; Finally, Ediff supports directory-level comparison, merging and patching. |
63 ;; See the on-line manual for details. | 63 ;; See the on-line manual for details. |
64 | 64 |
65 ;; This package builds upon the ideas borrowed from emerge.el and several | 65 ;; This package builds upon the ideas borrowed from emerge.el and several |
66 ;; Ediff's functions are adaptations from emerge.el. Much of the functionality | 66 ;; Ediff's functions are adaptations from emerge.el. Much of the functionality |
67 ;; Ediff provides is also influenced by emerge.el. | 67 ;; Ediff provides is also influenced by emerge.el. |
68 | 68 |
69 ;; The present version of Ediff supersedes Emerge. It provides a superior user | 69 ;; The present version of Ediff supersedes Emerge. It provides a superior user |
70 ;; interface and has numerous major features not found in Emerge. In | 70 ;; interface and has numerous major features not found in Emerge. In |
71 ;; particular, it can do patching, and 2-way and 3-way file comparison, | 71 ;; particular, it can do patching, and 2-way and 3-way file comparison, |
72 ;; merging, and directory operations. | 72 ;; merging, and directory operations. |
73 | 73 |
74 | 74 |
75 | 75 |
76 ;;; Bugs: | 76 ;;; Bugs: |
77 | 77 |
78 ;; 1. The undo command doesn't restore deleted regions well. That is, if | 78 ;; 1. The undo command doesn't restore deleted regions well. That is, if |
79 ;; you delete all characters in a difference region and then invoke | 79 ;; you delete all characters in a difference region and then invoke |
80 ;; `undo', the reinstated text will most likely be inserted outside of | 80 ;; `undo', the reinstated text will most likely be inserted outside of |
81 ;; what Ediff thinks is the current difference region. (This problem | 81 ;; what Ediff thinks is the current difference region. (This problem |
82 ;; doesn't seem to exist with XEmacs.) | 82 ;; doesn't seem to exist with XEmacs.) |
83 ;; | 83 ;; |
84 ;; If at any point you feel that difference regions are no longer correct, | 84 ;; If at any point you feel that difference regions are no longer correct, |
85 ;; you can hit '!' to recompute the differences. | 85 ;; you can hit '!' to recompute the differences. |
86 | 86 |
87 ;; 2. On a monochrome display, the repertoire of faces with which to | 87 ;; 2. On a monochrome display, the repertoire of faces with which to |
88 ;; highlight fine differences is limited. By default, Ediff is using | 88 ;; highlight fine differences is limited. By default, Ediff is using |
89 ;; underlining. However, if the region is already underlined by some other | 89 ;; underlining. However, if the region is already underlined by some other |
90 ;; overlays, there is no simple way to temporarily remove that residual | 90 ;; overlays, there is no simple way to temporarily remove that residual |
91 ;; underlining. This problem occurs when a buffer is highlighted with | 91 ;; underlining. This problem occurs when a buffer is highlighted with |
92 ;; hilit19.el or font-lock.el packages. If this residual highlighting gets | 92 ;; hilit19.el or font-lock.el packages. If this residual highlighting gets |
93 ;; in the way, you can do the following. Both font-lock.el and hilit19.el | 93 ;; in the way, you can do the following. Both font-lock.el and hilit19.el |
94 ;; provide commands for unhighlighting buffers. You can either place these | 94 ;; provide commands for unhighlighting buffers. You can either place these |
95 ;; commands in `ediff-prepare-buffer-hook' (which will unhighlight every | 95 ;; commands in `ediff-prepare-buffer-hook' (which will unhighlight every |
96 ;; buffer used by Ediff) or you can execute them interactively, at any time | 96 ;; buffer used by Ediff) or you can execute them interactively, at any time |
97 ;; and on any buffer. | 97 ;; and on any buffer. |
98 | 98 |
99 | 99 |
100 ;;; Acknowledgements: | 100 ;;; Acknowledgements: |
101 | 101 |
102 ;; Ediff was inspired by Dale R. Worley's <drw@math.mit.edu> emerge.el. | 102 ;; Ediff was inspired by Dale R. Worley's <drw@math.mit.edu> emerge.el. |
103 ;; Ediff would not have been possible without the help and encouragement of | 103 ;; Ediff would not have been possible without the help and encouragement of |
104 ;; its many users. See Ediff on-line Info for the full list of those who | 104 ;; its many users. See Ediff on-line Info for the full list of those who |
105 ;; helped. Improved defaults in Ediff file-name reading commands. | 105 ;; helped. Improved defaults in Ediff file-name reading commands. |
106 | 106 |
107 ;;; Code: | 107 ;;; Code: |
108 | 108 |
109 (provide 'ediff) | 109 (provide 'ediff) |
110 | 110 |
267 ;; Visit FILE and arrange its buffer to Ediff's liking. | 267 ;; Visit FILE and arrange its buffer to Ediff's liking. |
268 ;; FILE is actually a variable symbol that must contain a true file name. | 268 ;; FILE is actually a variable symbol that must contain a true file name. |
269 ;; BUFFER-NAME is a variable symbol, which will get the buffer object into | 269 ;; BUFFER-NAME is a variable symbol, which will get the buffer object into |
270 ;; which FILE is read. | 270 ;; which FILE is read. |
271 ;; LAST-DIR is the directory variable symbol where FILE's | 271 ;; LAST-DIR is the directory variable symbol where FILE's |
272 ;; directory name should be returned. HOOKS-VAR is a variable symbol that will | 272 ;; directory name should be returned. HOOKS-VAR is a variable symbol that will |
273 ;; be assigned the hook to be executed after `ediff-startup' is finished. | 273 ;; be assigned the hook to be executed after `ediff-startup' is finished. |
274 ;; `ediff-find-file' arranges that the temp files it might create will be | 274 ;; `ediff-find-file' arranges that the temp files it might create will be |
275 ;; deleted. | 275 ;; deleted. |
276 (defun ediff-find-file (file-var buffer-name &optional last-dir hooks-var) | 276 (defun ediff-find-file (file-var buffer-name &optional last-dir hooks-var) |
277 (let* ((file (symbol-value file-var)) | 277 (let* ((file (symbol-value file-var)) |
457 | 457 |
458 | 458 |
459 ;;;###autoload | 459 ;;;###autoload |
460 (defun ediff-directories (dir1 dir2 regexp) | 460 (defun ediff-directories (dir1 dir2 regexp) |
461 "Run Ediff on a pair of directories, DIR1 and DIR2, comparing files that have | 461 "Run Ediff on a pair of directories, DIR1 and DIR2, comparing files that have |
462 the same name in both. The third argument, REGEXP, is a regular expression that | 462 the same name in both. The third argument, REGEXP, is a regular expression |
463 can be used to filter out certain file names." | 463 that can be used to filter out certain file names." |
464 (interactive | 464 (interactive |
465 (let ((dir-A (ediff-get-default-directory-name)) | 465 (let ((dir-A (ediff-get-default-directory-name)) |
466 f) | 466 f) |
467 (list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil)) | 467 (list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil)) |
468 (ediff-read-file-name "Directory B to compare:" | 468 (ediff-read-file-name "Directory B to compare:" |
483 | 483 |
484 ;;;###autoload | 484 ;;;###autoload |
485 (defun ediff-directory-revisions (dir1 regexp) | 485 (defun ediff-directory-revisions (dir1 regexp) |
486 "Run Ediff on a directory, DIR1, comparing its files with their revisions. | 486 "Run Ediff on a directory, DIR1, comparing its files with their revisions. |
487 The second argument, REGEXP, is a regular expression that filters the file | 487 The second argument, REGEXP, is a regular expression that filters the file |
488 names. Only the files that are under revision control are taken into account." | 488 names. Only the files that are under revision control are taken into account." |
489 (interactive | 489 (interactive |
490 (let ((dir-A (ediff-get-default-directory-name))) | 490 (let ((dir-A (ediff-get-default-directory-name))) |
491 (list (ediff-read-file-name | 491 (list (ediff-read-file-name |
492 "Directory to compare with revision:" dir-A nil) | 492 "Directory to compare with revision:" dir-A nil) |
493 (read-string "Filter through regular expression: " | 493 (read-string "Filter through regular expression: " |
502 | 502 |
503 | 503 |
504 ;;;###autoload | 504 ;;;###autoload |
505 (defun ediff-directories3 (dir1 dir2 dir3 regexp) | 505 (defun ediff-directories3 (dir1 dir2 dir3 regexp) |
506 "Run Ediff on three directories, DIR1, DIR2, and DIR3, comparing files that | 506 "Run Ediff on three directories, DIR1, DIR2, and DIR3, comparing files that |
507 have the same name in all three. The last argument, REGEXP, is a regular | 507 have the same name in all three. The last argument, REGEXP, is a regular |
508 expression that can be used to filter out certain file names." | 508 expression that can be used to filter out certain file names." |
509 (interactive | 509 (interactive |
510 (let ((dir-A (ediff-get-default-directory-name)) | 510 (let ((dir-A (ediff-get-default-directory-name)) |
511 f) | 511 f) |
512 (list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil)) | 512 (list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil)) |
529 | 529 |
530 ;;;###autoload | 530 ;;;###autoload |
531 (defalias 'edirs3 'ediff-directories3) | 531 (defalias 'edirs3 'ediff-directories3) |
532 | 532 |
533 ;;;###autoload | 533 ;;;###autoload |
534 (defun ediff-merge-directories (dir1 dir2 regexp) | 534 (defun ediff-merge-directories (dir1 dir2 regexp &optional merge-autostore-dir) |
535 "Run Ediff on a pair of directories, DIR1 and DIR2, merging files that have | 535 "Run Ediff on a pair of directories, DIR1 and DIR2, merging files that have |
536 the same name in both. The third argument, REGEXP, is a regular expression that | 536 the same name in both. The third argument, REGEXP, is a regular expression |
537 can be used to filter out certain file names." | 537 that can be used to filter out certain file names." |
538 (interactive | 538 (interactive |
539 (let ((dir-A (ediff-get-default-directory-name)) | 539 (let ((dir-A (ediff-get-default-directory-name)) |
540 f) | 540 f) |
541 (list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil)) | 541 (list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil)) |
542 (ediff-read-file-name "Directory B to merge:" | 542 (ediff-read-file-name "Directory B to merge:" |
547 (read-string "Filter through regular expression: " | 547 (read-string "Filter through regular expression: " |
548 nil 'ediff-filtering-regexp-history) | 548 nil 'ediff-filtering-regexp-history) |
549 ))) | 549 ))) |
550 (ediff-directories-internal | 550 (ediff-directories-internal |
551 dir1 dir2 nil regexp 'ediff-merge-files 'ediff-merge-directories | 551 dir1 dir2 nil regexp 'ediff-merge-files 'ediff-merge-directories |
552 nil merge-autostore-dir | |
552 )) | 553 )) |
553 | 554 |
554 ;;;###autoload | 555 ;;;###autoload |
555 (defalias 'edirs-merge 'ediff-merge-directories) | 556 (defalias 'edirs-merge 'ediff-merge-directories) |
556 | 557 |
557 ;;;###autoload | 558 ;;;###autoload |
558 (defun ediff-merge-directories-with-ancestor (dir1 dir2 ancestor-dir regexp) | 559 (defun ediff-merge-directories-with-ancestor (dir1 dir2 ancestor-dir regexp |
560 &optional | |
561 merge-autostore-dir) | |
559 "Merge files in directories DIR1 and DIR2 using files in ANCESTOR-DIR as ancestors. | 562 "Merge files in directories DIR1 and DIR2 using files in ANCESTOR-DIR as ancestors. |
560 Ediff merges files that have identical names in DIR1, DIR2. If a pair of files | 563 Ediff merges files that have identical names in DIR1, DIR2. If a pair of files |
561 in DIR1 and DIR2 doesn't have an ancestor in ANCESTOR-DIR, Ediff will merge | 564 in DIR1 and DIR2 doesn't have an ancestor in ANCESTOR-DIR, Ediff will merge |
562 without ancestor. The fourth argument, REGEXP, is a regular expression that | 565 without ancestor. The fourth argument, REGEXP, is a regular expression that |
563 can be used to filter out certain file names." | 566 can be used to filter out certain file names." |
564 (interactive | 567 (interactive |
565 (let ((dir-A (ediff-get-default-directory-name)) | 568 (let ((dir-A (ediff-get-default-directory-name)) |
566 f) | 569 f) |
567 (list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil)) | 570 (list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil)) |
579 nil 'ediff-filtering-regexp-history) | 582 nil 'ediff-filtering-regexp-history) |
580 ))) | 583 ))) |
581 (ediff-directories-internal | 584 (ediff-directories-internal |
582 dir1 dir2 ancestor-dir regexp | 585 dir1 dir2 ancestor-dir regexp |
583 'ediff-merge-files-with-ancestor 'ediff-merge-directories-with-ancestor | 586 'ediff-merge-files-with-ancestor 'ediff-merge-directories-with-ancestor |
587 nil merge-autostore-dir | |
584 )) | 588 )) |
585 | 589 |
586 ;;;###autoload | 590 ;;;###autoload |
587 (defun ediff-merge-directory-revisions (dir1 regexp) | 591 (defun ediff-merge-directory-revisions (dir1 regexp |
592 &optional merge-autostore-dir) | |
588 "Run Ediff on a directory, DIR1, merging its files with their revisions. | 593 "Run Ediff on a directory, DIR1, merging its files with their revisions. |
589 The second argument, REGEXP, is a regular expression that filters the file | 594 The second argument, REGEXP, is a regular expression that filters the file |
590 names. Only the files that are under revision control are taken into account." | 595 names. Only the files that are under revision control are taken into account." |
591 (interactive | 596 (interactive |
592 (let ((dir-A (ediff-get-default-directory-name))) | 597 (let ((dir-A (ediff-get-default-directory-name))) |
593 (list (ediff-read-file-name | 598 (list (ediff-read-file-name |
594 "Directory to merge with revisions:" dir-A nil) | 599 "Directory to merge with revisions:" dir-A nil) |
595 (read-string "Filter through regular expression: " | 600 (read-string "Filter through regular expression: " |
596 nil 'ediff-filtering-regexp-history) | 601 nil 'ediff-filtering-regexp-history) |
597 ))) | 602 ))) |
598 (ediff-directory-revisions-internal | 603 (ediff-directory-revisions-internal |
599 dir1 regexp 'ediff-merge-revisions 'ediff-merge-directory-revisions | 604 dir1 regexp 'ediff-merge-revisions 'ediff-merge-directory-revisions |
605 nil merge-autostore-dir | |
600 )) | 606 )) |
601 | 607 |
602 ;;;###autoload | 608 ;;;###autoload |
603 (defalias 'edir-merge-revisions 'ediff-merge-directory-revisions) | 609 (defalias 'edir-merge-revisions 'ediff-merge-directory-revisions) |
604 | 610 |
605 ;;;###autoload | 611 ;;;###autoload |
606 (defun ediff-merge-directory-revisions-with-ancestor (dir1 regexp) | 612 (defun ediff-merge-directory-revisions-with-ancestor (dir1 regexp |
613 &optional | |
614 merge-autostore-dir) | |
607 "Run Ediff on a directory, DIR1, merging its files with their revisions and ancestors. | 615 "Run Ediff on a directory, DIR1, merging its files with their revisions and ancestors. |
608 The second argument, REGEXP, is a regular expression that filters the file | 616 The second argument, REGEXP, is a regular expression that filters the file |
609 names. Only the files that are under revision control are taken into account." | 617 names. Only the files that are under revision control are taken into account." |
610 (interactive | 618 (interactive |
611 (let ((dir-A (ediff-get-default-directory-name))) | 619 (let ((dir-A (ediff-get-default-directory-name))) |
612 (list (ediff-read-file-name | 620 (list (ediff-read-file-name |
613 "Directory to merge with revisions and ancestors:" dir-A nil) | 621 "Directory to merge with revisions and ancestors:" dir-A nil) |
614 (read-string "Filter through regular expression: " | 622 (read-string "Filter through regular expression: " |
615 nil 'ediff-filtering-regexp-history) | 623 nil 'ediff-filtering-regexp-history) |
616 ))) | 624 ))) |
617 (ediff-directory-revisions-internal | 625 (ediff-directory-revisions-internal |
618 dir1 regexp 'ediff-merge-revisions-with-ancestor | 626 dir1 regexp 'ediff-merge-revisions-with-ancestor |
619 'ediff-merge-directory-revisions-with-ancestor | 627 'ediff-merge-directory-revisions-with-ancestor |
628 nil merge-autostore-dir | |
620 )) | 629 )) |
621 | 630 |
622 ;;;###autoload | 631 ;;;###autoload |
623 (defalias | 632 (defalias |
624 'edir-merge-revisions-with-ancestor | 633 'edir-merge-revisions-with-ancestor |
630 ;; Run ediff-action (ediff-files, ediff-merge, ediff-merge-with-ancestors) | 639 ;; Run ediff-action (ediff-files, ediff-merge, ediff-merge-with-ancestors) |
631 ;; on a pair of directories (three directories, in case of ancestor). | 640 ;; on a pair of directories (three directories, in case of ancestor). |
632 ;; The third argument, REGEXP, is a regular expression that can be used to | 641 ;; The third argument, REGEXP, is a regular expression that can be used to |
633 ;; filter out certain file names. | 642 ;; filter out certain file names. |
634 ;; JOBNAME is the symbol indicating the meta-job to be performed. | 643 ;; JOBNAME is the symbol indicating the meta-job to be performed. |
635 ;; MERGE-DIR is the directory in which to store merged files. | 644 ;; MERGE-AUTOSTORE-DIR is the directory in which to store merged files. |
636 (defun ediff-directories-internal (dir1 dir2 dir3 regexp action jobname | 645 (defun ediff-directories-internal (dir1 dir2 dir3 regexp action jobname |
637 &optional startup-hooks) | 646 &optional startup-hooks |
647 merge-autostore-dir) | |
638 ;; ediff-read-file-name is set to attach a previously entered file name if | 648 ;; ediff-read-file-name is set to attach a previously entered file name if |
639 ;; the currently entered file is a directory. This code takes care of that. | 649 ;; the currently entered file is a directory. This code takes care of that. |
640 (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1)) | 650 (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1)) |
641 dir2 (if (file-directory-p dir2) dir2 (file-name-directory dir2))) | 651 dir2 (if (file-directory-p dir2) dir2 (file-name-directory dir2))) |
642 | 652 |
643 (if (stringp dir3) | 653 (if (stringp dir3) |
644 (setq dir3 (if (file-directory-p dir3) dir3 (file-name-directory dir3)))) | 654 (setq dir3 (if (file-directory-p dir3) dir3 (file-name-directory dir3)))) |
650 (error "Directories A and C are the same: %s" dir1)) | 660 (error "Directories A and C are the same: %s" dir1)) |
651 ((and (eq jobname 'ediff-directories3) | 661 ((and (eq jobname 'ediff-directories3) |
652 (string= dir2 dir3)) | 662 (string= dir2 dir3)) |
653 (error "Directories B and C are the same: %s" dir1))) | 663 (error "Directories B and C are the same: %s" dir1))) |
654 | 664 |
665 (if merge-autostore-dir | |
666 (or (stringp merge-autostore-dir) | |
667 (error "%s: Directory for storing merged files must be a string" | |
668 jobname))) | |
655 (let (diffs ; var where ediff-intersect-directories returns the diff list | 669 (let (diffs ; var where ediff-intersect-directories returns the diff list |
656 merge-autostore-dir | |
657 file-list meta-buf) | 670 file-list meta-buf) |
658 (if (and ediff-autostore-merges (ediff-merge-metajob jobname)) | 671 (if (and ediff-autostore-merges |
672 (ediff-merge-metajob jobname) | |
673 (not merge-autostore-dir)) | |
659 (setq merge-autostore-dir | 674 (setq merge-autostore-dir |
660 (ediff-read-file-name "Directory to save merged files:" | 675 (read-file-name "Save merged files in directory: " |
661 (if ediff-use-last-dir | 676 (if ediff-use-last-dir |
662 ediff-last-merge-autostore-dir | 677 ediff-last-merge-autostore-dir |
663 (ediff-strip-last-dir dir1)) | 678 (ediff-strip-last-dir dir1)) |
664 nil))) | 679 nil |
680 'must-match))) | |
665 ;; verify we are not merging into an orig directory | 681 ;; verify we are not merging into an orig directory |
666 (if (stringp merge-autostore-dir) | 682 (if merge-autostore-dir |
667 (cond ((and (stringp dir1) (string= merge-autostore-dir dir1)) | 683 (cond ((and (stringp dir1) (string= merge-autostore-dir dir1)) |
668 (or (y-or-n-p "Merge directory same as directory A, sure? ") | 684 (or (y-or-n-p |
685 "Directory for saving merged files = Directory A. Sure? ") | |
669 (error "Directory merge aborted"))) | 686 (error "Directory merge aborted"))) |
670 ((and (stringp dir2) (string= merge-autostore-dir dir2)) | 687 ((and (stringp dir2) (string= merge-autostore-dir dir2)) |
671 (or (y-or-n-p "Merge directory same as directory B, sure? ") | 688 (or (y-or-n-p |
689 "Directory for saving merged files = Directory B. Sure? ") | |
672 (error "Directory merge aborted"))) | 690 (error "Directory merge aborted"))) |
673 ((and (stringp dir3) (string= merge-autostore-dir dir3)) | 691 ((and (stringp dir3) (string= merge-autostore-dir dir3)) |
674 (or (y-or-n-p | 692 (or (y-or-n-p |
675 "Merge directory same as ancestor directory, sure? ") | 693 "Directory for saving merged files = Ancestor Directory. Sure? ") |
676 (error "Directory merge aborted"))))) | 694 (error "Directory merge aborted"))))) |
677 | 695 |
678 (setq file-list (ediff-intersect-directories | 696 (setq file-list (ediff-intersect-directories |
679 jobname 'diffs | 697 jobname 'diffs |
680 regexp dir1 dir2 dir3 merge-autostore-dir)) | 698 regexp dir1 dir2 dir3 merge-autostore-dir)) |
695 jobname | 713 jobname |
696 startup-hooks)) | 714 startup-hooks)) |
697 (ediff-show-meta-buffer meta-buf) | 715 (ediff-show-meta-buffer meta-buf) |
698 )) | 716 )) |
699 | 717 |
718 ;; MERGE-AUTOSTORE-DIR can be given to tell ediff where to store the merged | |
719 ;; files | |
700 (defun ediff-directory-revisions-internal (dir1 regexp action jobname | 720 (defun ediff-directory-revisions-internal (dir1 regexp action jobname |
701 &optional startup-hooks) | 721 &optional startup-hooks |
722 merge-autostore-dir) | |
702 (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1))) | 723 (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1))) |
703 | 724 |
704 (let (file-list meta-buf merge-autostore-dir) | 725 (if merge-autostore-dir |
705 (if (and ediff-autostore-merges (ediff-merge-metajob jobname)) | 726 (or (stringp merge-autostore-dir) |
727 (error "%S: Directory for storing merged files must be a string" | |
728 jobname))) | |
729 (let (file-list meta-buf) | |
730 (if (and ediff-autostore-merges | |
731 (ediff-merge-metajob jobname) | |
732 (not merge-autostore-dir)) | |
706 (setq merge-autostore-dir | 733 (setq merge-autostore-dir |
707 (ediff-read-file-name "Directory to save merged files:" | 734 (read-file-name "Save merged files in directory: " |
708 (if ediff-use-last-dir | 735 (if ediff-use-last-dir |
709 ediff-last-merge-autostore-dir | 736 ediff-last-merge-autostore-dir |
710 (ediff-strip-last-dir dir1)) | 737 (ediff-strip-last-dir dir1)) |
711 nil))) | 738 nil |
739 'must-match))) | |
712 ;; verify merge-autostore-dir != dir1 | 740 ;; verify merge-autostore-dir != dir1 |
713 (if (and (stringp merge-autostore-dir) | 741 (if (and merge-autostore-dir |
714 (stringp dir1) | 742 (stringp dir1) |
715 (string= merge-autostore-dir dir1)) | 743 (string= merge-autostore-dir dir1)) |
716 (or (y-or-n-p | 744 (or (y-or-n-p |
717 "Directory for saving merges is the same as directory A. Sure? ") | 745 "Directory for saving merged file = directory A. Sure? ") |
718 (error "Merge of directory revisions aborted"))) | 746 (error "Merge of directory revisions aborted"))) |
719 | 747 |
720 (setq file-list | 748 (setq file-list |
721 (ediff-get-directory-files-under-revision | 749 (ediff-get-directory-files-under-revision |
722 jobname regexp dir1 merge-autostore-dir)) | 750 jobname regexp dir1 merge-autostore-dir)) |
795 ;;;###autoload | 823 ;;;###autoload |
796 (defun ediff-regions-wordwise (buffer-A buffer-B &optional startup-hooks) | 824 (defun ediff-regions-wordwise (buffer-A buffer-B &optional startup-hooks) |
797 "Run Ediff on a pair of regions in two different buffers. | 825 "Run Ediff on a pair of regions in two different buffers. |
798 Regions \(i.e., point and mark\) are assumed to be set in advance. | 826 Regions \(i.e., point and mark\) are assumed to be set in advance. |
799 This function is effective only for relatively small regions, up to 200 | 827 This function is effective only for relatively small regions, up to 200 |
800 lines. For large regions, use `ediff-regions-linewise'." | 828 lines. For large regions, use `ediff-regions-linewise'." |
801 (interactive | 829 (interactive |
802 (let (bf) | 830 (let (bf) |
803 (list (setq bf (read-buffer "Region's A buffer: " | 831 (list (setq bf (read-buffer "Region's A buffer: " |
804 (ediff-other-buffer "") t)) | 832 (ediff-other-buffer "") t)) |
805 (read-buffer "Region's B buffer: " | 833 (read-buffer "Region's B buffer: " |
833 (defun ediff-regions-linewise (buffer-A buffer-B &optional startup-hooks) | 861 (defun ediff-regions-linewise (buffer-A buffer-B &optional startup-hooks) |
834 "Run Ediff on a pair of regions in two different buffers. | 862 "Run Ediff on a pair of regions in two different buffers. |
835 Regions \(i.e., point and mark\) are assumed to be set in advance. | 863 Regions \(i.e., point and mark\) are assumed to be set in advance. |
836 Each region is enlarged to contain full lines. | 864 Each region is enlarged to contain full lines. |
837 This function is effective for large regions, over 100-200 | 865 This function is effective for large regions, over 100-200 |
838 lines. For small regions, use `ediff-regions-wordwise'." | 866 lines. For small regions, use `ediff-regions-wordwise'." |
839 (interactive | 867 (interactive |
840 (let (bf) | 868 (let (bf) |
841 (list (setq bf (read-buffer "Region A's buffer: " | 869 (list (setq bf (read-buffer "Region A's buffer: " |
842 (ediff-other-buffer "") t)) | 870 (ediff-other-buffer "") t)) |
843 (read-buffer "Region B's buffer: " | 871 (read-buffer "Region B's buffer: " |
1169 (if (stringp file) | 1197 (if (stringp file) |
1170 (file-name-nondirectory file) "current buffer"))) | 1198 (file-name-nondirectory file) "current buffer"))) |
1171 ancestor-rev | 1199 ancestor-rev |
1172 (read-string | 1200 (read-string |
1173 (format | 1201 (format |
1174 "Ancestor version (default: %s): " | 1202 "Ancestor version (default: %s's base revision): " |
1175 (if (stringp file) | 1203 (if (stringp file) |
1176 (file-name-nondirectory file) "current buffer")))) | 1204 (file-name-nondirectory file) "current buffer")))) |
1177 (ediff-load-version-control) | 1205 (ediff-load-version-control) |
1178 (funcall | 1206 (funcall |
1179 (intern (format "ediff-%S-merge-internal" ediff-version-control-package)) | 1207 (intern (format "ediff-%S-merge-internal" ediff-version-control-package)) |
1180 rev1 rev2 ancestor-rev startup-hooks merge-buffer-file))) | 1208 rev1 rev2 ancestor-rev startup-hooks merge-buffer-file))) |
1181 | 1209 |
1182 ;;;###autoload | 1210 ;;;###autoload |
1183 (defun run-ediff-from-cvs-buffer (pos) | 1211 (defun run-ediff-from-cvs-buffer (pos) |
1184 "Run Ediff-merge on appropriate revisions of the selected file. | 1212 "Run Ediff-merge on appropriate revisions of the selected file. |
1185 First run after `M-x cvs-update'. Then place the cursor on a line describing a | 1213 First run after `M-x cvs-update'. Then place the cursor on a line describing a |
1186 file and then run `run-ediff-from-cvs-buffer'." | 1214 file and then run `run-ediff-from-cvs-buffer'." |
1187 (interactive "d") | 1215 (interactive "d") |
1188 (ediff-load-version-control) | 1216 (ediff-load-version-control) |
1189 (let ((tin (tin-locate cvs-cookie-handle pos))) | 1217 (let ((tin (tin-locate cvs-cookie-handle pos))) |
1190 (if tin | 1218 (if tin |
1193 | 1221 |
1194 | 1222 |
1195 ;;; Apply patch | 1223 ;;; Apply patch |
1196 | 1224 |
1197 ;;;###autoload | 1225 ;;;###autoload |
1198 (defun ediff-patch-file () | 1226 (defun ediff-patch-file (&optional arg patch-buf) |
1199 "Run Ediff by patching SOURCE-FILENAME." | 1227 "Run Ediff by patching SOURCE-FILENAME. |
1200 ;; This now returns the control buffer | 1228 If optional PATCH-BUF is given, use the patch in that buffer |
1201 (interactive) | 1229 and don't ask the user. |
1202 (let (source-dir source-file patch-buf) | 1230 If prefix argument, then: if even argument, assume that the patch is in a |
1231 buffer. If odd -- assume it is in a file." | |
1232 (interactive "P") | |
1233 (let (source-dir source-file) | |
1203 (require 'ediff-ptch) | 1234 (require 'ediff-ptch) |
1204 (setq patch-buf (ediff-get-patch-buffer)) | 1235 (setq patch-buf |
1236 (ediff-get-patch-buffer | |
1237 (if arg (prefix-numeric-value arg)) patch-buf)) | |
1205 (setq source-dir (cond (ediff-use-last-dir ediff-last-dir-patch) | 1238 (setq source-dir (cond (ediff-use-last-dir ediff-last-dir-patch) |
1206 ((and (not ediff-patch-default-directory) | 1239 ((and (not ediff-patch-default-directory) |
1207 (buffer-file-name patch-buf)) | 1240 (buffer-file-name patch-buf)) |
1208 (file-name-directory | 1241 (file-name-directory |
1209 (expand-file-name | 1242 (expand-file-name |
1210 (buffer-file-name patch-buf)))) | 1243 (buffer-file-name patch-buf)))) |
1211 (t default-directory))) | 1244 (t default-directory))) |
1212 (setq source-file | 1245 (setq source-file |
1213 ;; the default is the directory, not the visited file name | 1246 ;; the default is the directory, not the visited file name |
1214 (ediff-read-file-name | 1247 (read-file-name |
1215 "Which file to patch? " source-dir (ediff-get-default-file-name))) | 1248 "File to patch (directory, if multifile patch): " |
1249 source-dir (ediff-get-default-file-name))) | |
1216 (ediff-dispatch-file-patching-job patch-buf source-file))) | 1250 (ediff-dispatch-file-patching-job patch-buf source-file))) |
1217 | 1251 |
1218 ;;;###autoload | 1252 ;;;###autoload |
1219 (defun ediff-patch-buffer () | 1253 (defun ediff-patch-buffer (&optional arg patch-buf) |
1220 "Run Ediff by patching BUFFER-NAME." | 1254 "Run Ediff by patching BUFFER-NAME." |
1221 (interactive) | 1255 (interactive "P") |
1222 (let (patch-buf) | 1256 (require 'ediff-ptch) |
1223 (require 'ediff-ptch) | 1257 (setq patch-buf |
1224 (setq patch-buf (ediff-get-patch-buffer)) | 1258 (ediff-get-patch-buffer |
1225 (ediff-patch-buffer-internal | 1259 (if arg (prefix-numeric-value arg)) patch-buf)) |
1226 patch-buf | 1260 (ediff-patch-buffer-internal |
1227 (read-buffer "Which buffer to patch? " | 1261 patch-buf |
1228 (cond ((eq patch-buf (current-buffer)) | 1262 (read-buffer |
1229 (ediff-other-buffer (current-buffer))) | 1263 "Which buffer to patch? " |
1230 (t (current-buffer))) | 1264 (ediff-prompt-for-patch-buffer)))) |
1231 'must-match)))) | |
1232 | 1265 |
1266 | |
1233 ;;;###autoload | 1267 ;;;###autoload |
1234 (defalias 'epatch 'ediff-patch-file) | 1268 (defalias 'epatch 'ediff-patch-file) |
1235 ;;;###autoload | 1269 ;;;###autoload |
1236 (defalias 'epatch-buffer 'ediff-patch-buffer) | 1270 (defalias 'epatch-buffer 'ediff-patch-buffer) |
1237 | 1271 |
1242 | 1276 |
1243 ;;;###autoload | 1277 ;;;###autoload |
1244 (defun ediff-revision (&optional file startup-hooks) | 1278 (defun ediff-revision (&optional file startup-hooks) |
1245 "Run Ediff by comparing versions of a file. | 1279 "Run Ediff by comparing versions of a file. |
1246 The file is an optional FILE argument or the file visited by the current | 1280 The file is an optional FILE argument or the file visited by the current |
1247 buffer. Use `vc.el' or `rcs.el' depending on `ediff-version-control-package'." | 1281 buffer. Use `vc.el' or `rcs.el' depending on `ediff-version-control-package'." |
1248 ;; if buffer is non-nil, use that buffer instead of the current buffer | 1282 ;; if buffer is non-nil, use that buffer instead of the current buffer |
1249 (interactive "P") | 1283 (interactive "P") |
1250 (if (stringp file) (find-file file)) | 1284 (if (stringp file) (find-file file)) |
1251 (let (rev1 rev2) | 1285 (let (rev1 rev2) |
1252 (setq rev1 | 1286 (setq rev1 |
1278 (if (locate-library (symbol-name ediff-version-control-package)) | 1312 (if (locate-library (symbol-name ediff-version-control-package)) |
1279 (progn | 1313 (progn |
1280 (message "") ; kill the message from `locate-library' | 1314 (message "") ; kill the message from `locate-library' |
1281 (require ediff-version-control-package)) | 1315 (require ediff-version-control-package)) |
1282 (or silent | 1316 (or silent |
1283 (error "Version control package %S.el not found. Use vc.el instead" | 1317 (error "Version control package %S.el not found. Use vc.el instead" |
1284 ediff-version-control-package))))) | 1318 ediff-version-control-package))))) |
1285 | 1319 |
1286 | 1320 |
1287 ;;;###autoload | 1321 ;;;###autoload |
1288 (defun ediff-version () | 1322 (defun ediff-version () |
1328 ;;; eval: (put 'ediff-with-current-buffer 'edebug-form-spec '(form body)) | 1362 ;;; eval: (put 'ediff-with-current-buffer 'edebug-form-spec '(form body)) |
1329 ;;; End: | 1363 ;;; End: |
1330 | 1364 |
1331 (require 'ediff-util) | 1365 (require 'ediff-util) |
1332 | 1366 |
1367 (run-hooks 'ediff-load-hook) | |
1368 | |
1333 ;;; ediff.el ends here | 1369 ;;; ediff.el ends here |