Commit bd698e98 authored by Michael Kifer's avatar Michael Kifer
Browse files

new version

parent a18ed129
......@@ -68,8 +68,7 @@ to a shell that you are not using or, better, fix your shell's startup file."
"*Options to pass to `ediff-diff-program'.
If diff\(1\) is used as `ediff-diff-program', then the most useful options are
`-w', to ignore space, and `-i', to ignore case of letters.
At present, the option `-c' is ignored, since Ediff doesn't understand this
type of output."
At present, the option `-c' is not allowed."
:type 'string
:group 'ediff-diff)
......@@ -158,9 +157,8 @@ one optional arguments, diff-number to refine.")
;; ediff-setup-diff-regions-function, which can also have the value
;; ediff-setup-diff-regions3, which takes 4 arguments.
(defun ediff-setup-diff-regions (file-A file-B file-C)
;;; ;; Force all minibuffers to display ediff's messages.
;;; ;; When xemacs implements minibufferless frames, this won't be necessary
;;; (if ediff-xemacs-p (setq synchronize-minibuffers t))
(if (string-match "c" ediff-diff-options)
(error "Option `-c' is not allowed in `ediff-diff-options'"))
;; create, if it doesn't exist
(or (ediff-buffer-live-p ediff-diff-buffer)
......@@ -210,7 +208,6 @@ one optional arguments, diff-number to refine.")
diff-buffer
'synchronize
ediff-diff-options file1 file2)
;;(message "Computing differences ... done")
(message "")
(ediff-with-current-buffer diff-buffer
(buffer-size))))))
......@@ -1043,11 +1040,6 @@ one optional arguments, diff-number to refine.")
;; File-C is either the third file to compare (in case of 3-way comparison)
;; or it is the ancestor file.
(defun ediff-setup-diff-regions3 (file-A file-B file-C)
;;; ;; force all minibuffers to display ediff's messages.
;;; ;; when xemacs implements minibufferless frames, this won't be necessary
;;; (if ediff-xemacs-p (setq synchronize-minibuffers t))
(or (ediff-buffer-live-p ediff-diff-buffer)
(setq ediff-diff-buffer
(get-buffer-create (ediff-unique-buffer-name "*ediff-diff" "*"))))
......
......@@ -155,10 +155,15 @@ directories.")
;; history var to use for filtering groups
(defvar ediff-filtering-regexp-history nil "")
;; This has the form ((ctl-buf file1 file2) (stl-buf file1 file2) ...)
;; If ctl-buf is nil, the file-pair wasn't processed yet. If it is
;; This has the form ((meta-buf regexp dir1 dir2 dir3 merge-auto-store-dir)
;; (ctl-buf session-status (file1 . eq-status) (file2 . eq-status) (file3
;; . eq-status)) (ctl-buf session-status (file1 . eq-status) (file2
;; . eq-status)) ...)
;; If ctl-buf is nil, the file-pair hasn't processed yet. If it is
;; killed-buffer object, the file pair has been processed. If it is a live
;; buffer, this means ediff is still working on the pair
;; buffer, this means ediff is still working on the pair.
;; Eq-status of a file is t if the file equals some other file in the same
;; group.
(ediff-defvar-local ediff-meta-list nil "")
......@@ -204,40 +209,40 @@ buffers."
;;; API for ediff-meta-list
;; group buffer/regexp
(defun ediff-get-group-buffer (meta-list)
(defsubst ediff-get-group-buffer (meta-list)
(nth 0 (car meta-list)))
(defun ediff-get-group-regexp (meta-list)
(defsubst ediff-get-group-regexp (meta-list)
(nth 1 (car meta-list)))
;; group objects
(defun ediff-get-group-objA (meta-list)
(defsubst ediff-get-group-objA (meta-list)
(nth 2 (car meta-list)))
(defun ediff-get-group-objB (meta-list)
(defsubst ediff-get-group-objB (meta-list)
(nth 3 (car meta-list)))
(defun ediff-get-group-objC (meta-list)
(defsubst ediff-get-group-objC (meta-list)
(nth 4 (car meta-list)))
(defun ediff-get-group-merge-autostore-dir (meta-list)
(defsubst ediff-get-group-merge-autostore-dir (meta-list)
(nth 5 (car meta-list)))
;; session buffer
(defun ediff-get-session-buffer (elt)
(defsubst ediff-get-session-buffer (elt)
(nth 0 elt))
(defun ediff-get-session-status (elt)
(defsubst ediff-get-session-status (elt)
(nth 1 elt))
(defun ediff-set-session-status (session-info new-status)
(defsubst ediff-set-session-status (session-info new-status)
(setcar (cdr session-info) new-status))
;; session objects
(defun ediff-get-session-objA (elt)
(defsubst ediff-get-session-objA (elt)
(nth 2 elt))
(defun ediff-get-session-objB (elt)
(defsubst ediff-get-session-objB (elt)
(nth 3 elt))
(defun ediff-get-session-objC (elt)
(defsubst ediff-get-session-objC (elt)
(nth 4 elt))
(defun ediff-get-session-objA-name (elt)
(defsubst ediff-get-session-objA-name (elt)
(car (nth 2 elt)))
(defun ediff-get-session-objB-name (elt)
(defsubst ediff-get-session-objB-name (elt)
(car (nth 3 elt)))
(defun ediff-get-session-objC-name (elt)
(defsubst ediff-get-session-objC-name (elt)
(car (nth 4 elt)))
;; equality indicators
(defsubst ediff-get-file-eqstatus (elt)
......@@ -245,6 +250,15 @@ buffers."
(defsubst ediff-set-file-eqstatus (elt value)
(setcar (cdr elt) value))
;; checks if the session is a meta session
(defun ediff-meta-session-p (session-info)
(and (stringp (ediff-get-session-objA-name session-info))
(file-directory-p (ediff-get-session-objA-name session-info))
(stringp (ediff-get-session-objB-name session-info))
(file-directory-p (ediff-get-session-objB-name session-info))
(if (stringp (ediff-get-session-objC-name session-info))
(file-directory-p (ediff-get-session-objC-name session-info)) t)))
;; set up the keymap in the meta buffer
(defun ediff-setup-meta-map()
(setq ediff-meta-buffer-map (make-sparse-keymap))
......@@ -1122,22 +1136,33 @@ Useful commands:
(marksym ?*)
(numMarked 0)
(sessionNum 0)
elt)
(diff-buffer ediff-meta-diff-buffer)
session-buf elt)
(while meta-list
(setq elt (car meta-list)
meta-list (cdr meta-list)
sessionNum (1+ sessionNum))
(if (eq (ediff-get-session-status elt) marksym)
(save-excursion
(setq numMarked (1+ numMarked))
(funcall operation elt sessionNum))))
(cond ((eq (ediff-get-session-status elt) marksym)
(save-excursion
(setq numMarked (1+ numMarked))
(funcall operation elt sessionNum)))
((and (ediff-meta-session-p elt)
(ediff-buffer-live-p
(setq session-buf (ediff-get-session-buffer elt))))
(setq numMarked
(+ numMarked
(ediff-with-current-buffer session-buf
;; pass meta-diff along
(setq ediff-meta-diff-buffer diff-buffer)
;; collect diffs in child group
(ediff-operate-on-marked-sessions operation)))))))
(ediff-update-meta-buffer grp-buf) ; just in case
numMarked
))
(defun ediff-append-custom-diff (session sessionNum)
(or (ediff-collect-diffs-metajob)
(error "Sorry, I don't do this for everyone..."))
(error "Hmm, I'd hate to do it to you ..."))
(let ((session-buf (ediff-get-session-buffer session))
(meta-diff-buff ediff-meta-diff-buffer)
(metajob ediff-metajob-name)
......@@ -1256,9 +1281,7 @@ all marked sessions must be active."
;; First handle sessions involving directories (which are themselves
;; session groups)
;; After that handle individual sessions
(cond ((and (file-directory-p file1)
(stringp file2) (file-directory-p file2)
(if (stringp file3) (file-directory-p file1) t))
(cond ((ediff-meta-session-p info)
;; do ediff/ediff-merge on subdirectories
(if (ediff-buffer-live-p session-buf)
(ediff-show-meta-buffer session-buf)
......
......@@ -81,18 +81,26 @@ See also `ediff-backup-specs'."
:type 'string
:group 'ediff-ptch)
(defun ediff-test-patch-utility ()
(cond ((zerop (call-process ediff-patch-program nil nil nil "-z." "-b"))
;; GNU `patch' v. >= 2.2
'gnu)
((zerop (call-process ediff-patch-program nil nil nil "-b"))
'posix)
(t 'traditional)))
(defcustom ediff-backup-specs
(cond
((zerop (call-process ediff-patch-program nil nil nil "-z." "-b"))
;; GNU `patch' v. >= 2.2
(format "-z%s -b" ediff-backup-extension))
((zerop (call-process ediff-patch-program nil nil nil "-b"))
;; POSIX `patch' -- ediff-backup-extension must be ".orig"
(setq ediff-backup-extension ediff-default-backup-extension)
"-b")
(t
;; traditional `patch'
(format "-b %s" ediff-backup-extension)))
(let ((type (ediff-test-patch-utility)))
(cond ((eq type 'gnu)
;; GNU `patch' v. >= 2.2
(format "-z%s -b" ediff-backup-extension))
((eq type 'posix)
;; POSIX `patch' -- ediff-backup-extension must be ".orig"
(setq ediff-backup-extension ediff-default-backup-extension)
"-b")
(t
;; traditional `patch'
(format "-b %s" ediff-backup-extension))))
"*Backup directives to pass to the patch program.
Ediff requires that the old version of the file \(before applying the patch\)
be saved in a file named `the-patch-file.extension'. Usually `extension' is
......@@ -107,7 +115,11 @@ versions of GNU patch require `-b -z backup-extension'.
Note that both `ediff-backup-extension' and `ediff-backup-specs'
must be set properly. If your patch program takes the option `-b',
but not `-b extension', the variable `ediff-backup-extension' must
still be set so Ediff will know which extension to use."
still be set so Ediff will know which extension to use.
Ediff tries to guess the appropriate value for this variables. It is believed
to be working for `traditional' patch, all versions of GNU patch, and for POSIX
patch. So, don't change these variables, unless the default doesn't work."
:type 'string
:group 'ediff-ptch)
......@@ -278,10 +290,8 @@ program."
(princ
(format "
The patch file contains a context diff for
%s
%s
However, Ediff cannot infer the name of the actual file
to be patched on your system. If you know the correct file name,
please enter it now.
......@@ -336,7 +346,7 @@ other files, enter /dev/null
Ediff has inferred that
%s
%s
are possible targets for applying the patch.
are two possible targets for applying the patch.
Both files seem to be plausible alternatives.
Please advice:
......@@ -351,17 +361,19 @@ Please advice:
(f1-exists (setcar triple file1))
(t
(with-output-to-temp-buffer ediff-msg-buffer
(princ (format "
Ediff inferred that
(princ "\nEdiff has inferred that")
(if (string= file1 file2)
(princ (format "
%s
is the target for this patch. However, this file does not exist."
file1))
(princ (format "
%s
are possible alternative targets for this patch.
However, these files do not exist.
Please enter an alternative patch target ...
"
file1 file2)))
%s
are two possible targets for this patch. However, these files do not exist."
file1 file2)))
(princ "
\nPlease enter an alternative patch target ...\n"))
(let ((directory t)
target)
(while directory
......@@ -392,12 +404,21 @@ Else, read patch file into a new buffer."
(ediff-use-last-dir ediff-last-dir-patch)
(t default-directory)))
patch-buf)
(if (y-or-n-p "Is the patch already in a buffer? ")
(if (let ((last-nonmenu-event t) ; Emacs: don't use dialog box
last-command-event) ; XEmacs: don't use dialog box
(y-or-n-p "Is the patch already in a buffer? "))
(setq patch-buf
(get-buffer
(read-buffer
"Which buffer contains the patch? "
(current-buffer) 'must-match)))
(ediff-other-buffer
(if (eq (next-window (selected-window)) (selected-window))
;; only one window in frame --- don't skip current buff
""
;; >1 window --- skip current buff, assuming this is the one
;; to patch, not the one that has the patch
(current-buffer)))
'must-match)))
(setq patch-buf
(find-file-noselect
(read-file-name "Which file contains the patch? "
......@@ -433,56 +454,71 @@ Else, read patch file into a new buffer."
))
(defun ediff-patch-buffer-internal (patch-buf buf-to-patch-name
&optional startup-hooks)
;; When patching a buffer, never change the orig file. Instead, create a new
;; buffer, ***_patched, even if the buff visits a file.
;; Users who want to actually patch the buffer should use
;; ediff-patch-file, not ediff-patch-buffer.
(defun ediff-patch-buffer-internal (patch-buf
buf-to-patch-name
&optional startup-hooks)
(let* ((buf-to-patch (get-buffer buf-to-patch-name))
(file-name-ok (if buf-to-patch (buffer-file-name buf-to-patch)))
(visited-file (if buf-to-patch (buffer-file-name buf-to-patch)))
(buf-mod-status (buffer-modified-p buf-to-patch))
(multifile-patch-p (> (length (ediff-with-current-buffer patch-buf
ediff-patch-map)) 1))
default-dir file-name ctl-buf)
(if file-name-ok
(setq file-name file-name-ok)
(if multifile-patch-p
(error
"Can't apply multi-file patches to buffers that visit no files"))
(ediff-with-current-buffer buf-to-patch
(setq default-dir default-directory)
(setq file-name (ediff-make-temp-file buf-to-patch))
(set-visited-file-name file-name)
(setq buffer-auto-save-file-name nil) ; don't create auto-save file
;;don't confuse the user with a new bufname
(rename-buffer buf-to-patch-name)
(set-buffer-modified-p nil)
(set-visited-file-modtime) ; sync buffer and temp file
(setq default-directory default-dir)
))
(if multifile-patch-p
(error
"Can't apply multi-file patches to buffers that visit no files"))
;; create a temp file to patch
(ediff-with-current-buffer buf-to-patch
(setq default-dir default-directory)
(setq file-name (ediff-make-temp-file buf-to-patch))
;; temporarily switch visited file name, if any
(set-visited-file-name file-name)
;; don't create auto-save file, if buff was visiting a file
(or visited-file
(setq buffer-auto-save-file-name nil))
;; don't confuse the user with a new bufname
(rename-buffer buf-to-patch-name)
(set-buffer-modified-p nil)
(set-visited-file-modtime) ; sync buffer and temp file
(setq default-directory default-dir)
)
;; dispatch a patch function
(setq ctl-buf (ediff-dispatch-file-patching-job
patch-buf file-name startup-hooks))
(if file-name-ok
()
;; buffer wasn't visiting any file,
;; so we will not run meta-level ediff here
(ediff-with-current-buffer ctl-buf
(delete-file (buffer-file-name ediff-buffer-A))
(delete-file (buffer-file-name ediff-buffer-B))
(ediff-with-current-buffer ediff-buffer-A
(if default-dir (setq default-directory default-dir))
(set-visited-file-name nil)
(rename-buffer buf-to-patch-name)
(set-buffer-modified-p buf-mod-status))
(ediff-with-current-buffer ediff-buffer-B
(setq buffer-auto-save-file-name nil) ; don't create auto-save file
(if default-dir (setq default-directory default-dir))
(set-visited-file-name nil)
(rename-buffer (ediff-unique-buffer-name
(concat buf-to-patch-name "_patched") ""))
(set-buffer-modified-p t))))
(ediff-with-current-buffer ctl-buf
(delete-file (buffer-file-name ediff-buffer-A))
(delete-file (buffer-file-name ediff-buffer-B))
(ediff-with-current-buffer ediff-buffer-A
(if default-dir (setq default-directory default-dir))
(set-visited-file-name visited-file) ; visited-file might be nil
(rename-buffer buf-to-patch-name)
(set-buffer-modified-p buf-mod-status))
(ediff-with-current-buffer ediff-buffer-B
(setq buffer-auto-save-file-name nil) ; don't create auto-save file
(if default-dir (setq default-directory default-dir))
(set-visited-file-name nil)
(rename-buffer (ediff-unique-buffer-name
(concat buf-to-patch-name "_patched") ""))
(set-buffer-modified-p t)))
))
;; Traditional patch has weird return codes.
;; GNU and Posix return 1 if some hanks failed and 2 in case of trouble.
;; 0 is a good code in all cases.
;; We'll do the concervative thing.
(defun ediff-patch-return-code-ok (code)
(eq code 0))
;;; (if (eq (ediff-test-patch-utility) 'traditional)
;;; (eq code 0)
;;; (not (eq code 2))))
(defun ediff-patch-file-internal (patch-buf source-filename
&optional startup-hooks)
(setq source-filename (expand-file-name source-filename))
......@@ -498,7 +534,7 @@ Else, read patch file into a new buffer."
target-buf buf-to-patch file-name-magic-p
patch-return-code ctl-buf backup-style aux-wind)
(if (string-match "-V" ediff-patch-options)
(if (string-match "V" ediff-patch-options)
(error
"Ediff doesn't take the -V option in `ediff-patch-options'--sorry"))
......@@ -550,26 +586,29 @@ Else, read patch file into a new buffer."
(switch-to-buffer patch-diagnostics)
(sit-for 0) ; synchronize - let the user see diagnostics
(or (and (eq patch-return-code 0) ; patch reported success
(or (and (ediff-patch-return-code-ok patch-return-code)
(file-exists-p
(concat true-source-filename ediff-backup-extension)))
(progn
(with-output-to-temp-buffer ediff-msg-buffer
(princ (format
"Patch program has failed due to a bad patch file OR
because it couldn't create the backup for the file to be patched.
"Patch program has failed due to a bad patch file,
it couldn't apply all hunks, OR
it couldn't create the backup for the file being patched.
The former could be caused by a corrupt patch file or because the %S
program doesn't understand the format of the patch file in use.
The second problem might be due to an incompatibility among these settings:
ediff-patch-program = %S
ediff-patch-options = %S
ediff-backup-extension = %S
ediff-backup-specs = %S
ediff-patch-program = %S ediff-patch-options = %S
ediff-backup-extension = %S ediff-backup-specs = %S
See Ediff on-line manual for more details on these variables.
In particular, check the documentation for `ediff-backup-specs'. "
In particular, check the documentation for `ediff-backup-specs'.
In any of the above cases, Ediff doesn't compare files automatically.
However, if the patch was applied partially and the backup file was created,
you can still examine the changes via M-x ediff-files"
ediff-patch-program
ediff-patch-program
ediff-patch-options
......
......@@ -145,10 +145,11 @@ to invocation.")
(define-key ediff-mode-map "p" 'ediff-previous-difference)
(define-key ediff-mode-map "\C-?" 'ediff-previous-difference)
(define-key ediff-mode-map [backspace] 'ediff-previous-difference)
(define-key ediff-mode-map [delete] 'ediff-previous-difference)
(define-key ediff-mode-map "\C-h" (if ediff-no-emacs-help-in-control-buffer
'ediff-previous-difference nil))
;; must come after C-h, or else C-h wipes out backspace's binding in XEmacs
(define-key ediff-mode-map [backspace] 'ediff-previous-difference)
(define-key ediff-mode-map "n" 'ediff-next-difference)
(define-key ediff-mode-map " " 'ediff-next-difference)
(define-key ediff-mode-map "j" 'ediff-jump-to-difference)
......@@ -687,10 +688,6 @@ if necessary."
Reestablish the default three-window display."
(interactive)
(ediff-barf-if-not-control-buffer)
;; ;; No longer needed: XEmacs has surrogate minibuffers now.
;; (if ediff-xemacs-p (setq synchronize-minibuffers t))
(let (buffer-read-only)
(if (and (ediff-buffer-live-p ediff-buffer-A)
(ediff-buffer-live-p ediff-buffer-B)
......@@ -2918,6 +2915,15 @@ Hit \\[ediff-recenter] to reset the windows afterward."
(error "Buffer out of sync for file %s" buffer-file-name))))
(defun ediff-file-compressed-p (file)
(require 'jka-compr)
(string-match (jka-compr-build-file-regexp) file))
(defun ediff-filename-magic-p (file)
(or (ediff-file-compressed-p file)
(ediff-file-remote-p file)))
(defun ediff-save-buffer (arg)
"Safe way of saving buffers A, B, C, and the diff output.
`wa' saves buffer A, `wb' saves buffer B, `wc' saves buffer C,
......@@ -3314,17 +3320,23 @@ Ediff Control Panel to restore highlighting."
;; other insignificant buffers (those beginning with "^[ *]").
;; Gets one arg--buffer name or a list of buffer names (it won't return
;; these buffers).
(defun ediff-other-buffer (buff)
(if (not (listp buff)) (setq buff (list buff)))
(defun ediff-other-buffer (buff-lst)
(or (listp buff-lst) (setq buff-lst (list buff-lst)))
(let* ((frame-buffers (buffer-list))
(buff-name-list
(mapcar
(function (lambda (b)
(cond ((stringp b) b)
((bufferp b) (buffer-name b)))))
buff-lst))
(significant-buffers
(mapcar
(function (lambda (x)
(cond ((member (buffer-name x) buff)
nil)
((not (ediff-get-visible-buffer-window x))
nil)
((string-match "^ " (buffer-name x))
(cond ((member (buffer-name x) buff-name-list) nil)
((not (ediff-get-visible-buffer-window x)) nil)
((string-match "^[ *]" (buffer-name x)) nil)
((memq (ediff-with-current-buffer x major-mode)
'(dired-mode))
nil)
(t x))))
frame-buffers))
......@@ -3338,8 +3350,12 @@ Ediff Control Panel to restore highlighting."
(mapcar
(function
(lambda (x)
(cond ((member (buffer-name x) buff) nil)
(cond ((member (buffer-name x) buff-name-list) nil)
((string-match "^[ *]" (buffer-name x)) nil)
((memq
(ediff-with-current-buffer x major-mode)
'(dired-mode))
nil)
(t x))))
frame-buffers)))
(car less-significant-buffers))
......
......@@ -7,7 +7,7 @@
;; Keywords: comparing, merging, patching, version control.
(defconst ediff-version "2.67" "The current version of Ediff")
(defconst ediff-date "August 7, 1997" "Date of last update")
(defconst ediff-date "September 3, 1997" "Date of last update")
;; This file is part of GNU Emacs.
......@@ -275,7 +275,7 @@
;; deleted.
(defun ediff-find-file (file-var buffer-name &optional last-dir hooks-var)
(let* ((file (symbol-value file-var))
(file-magic (find-file-name-handler file 'find-file-noselect))
(file-magic (ediff-filename-magic-p file))
(temp-file-name-prefix (file-name-nondirectory file)))
(cond ((not (file-readable-p file))
(error "File `%s' does not exist or is not readable" file))
......@@ -1182,7 +1182,8 @@ file and then run `run-ediff-from-cvs-buffer'."
(t default-directory)))
(setq source-file
;; the default is the directory, not the visited file name
(ediff-read-file-name "Which file to patch? " source-dir source-dir))
(ediff-read-file-name
"Which file to patch? " source-dir (ediff-get-default-file-name)))
(ediff-dispatch-file-patching-job patch-buf source-file)))
;;;###autoload
......@@ -1196,7 +1197,7 @@ file and then run `run-ediff-from-cvs-buffer'."
patch-buf
(read-buffer "Which buffer to patch? "
(cond ((eq patch-buf (current-buffer))
(window-buffer (other-window 1)))
(ediff-other-buffer (current-buffer)))
(t (current-buffer)))
'must-match))))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment