comparison lisp/ediff/ediff-ptch.el @ 187:b405438285a2 r20-3b20

Import from CVS: tag r20-3b20
author cvs
date Mon, 13 Aug 2007 09:56:28 +0200
parents bfd6434d15b3
children
comparison
equal deleted inserted replaced
186:24ac94803b48 187:b405438285a2
79 "Backup extension used by the patch program. 79 "Backup extension used by the patch program.
80 See also `ediff-backup-specs'." 80 See also `ediff-backup-specs'."
81 :type 'string 81 :type 'string
82 :group 'ediff-ptch) 82 :group 'ediff-ptch)
83 83
84 (defun ediff-test-patch-utility ()
85 (cond ((zerop (call-process ediff-patch-program nil nil nil "-z." "-b"))
86 ;; GNU `patch' v. >= 2.2
87 'gnu)
88 ((zerop (call-process ediff-patch-program nil nil nil "-b"))
89 'posix)
90 (t 'traditional)))
91
84 (defcustom ediff-backup-specs 92 (defcustom ediff-backup-specs
85 (cond 93 (let ((type (ediff-test-patch-utility)))
86 ((zerop (call-process ediff-patch-program nil nil nil "-z." "-b")) 94 (cond ((eq type 'gnu)
87 ;; GNU `patch' v. >= 2.2 95 ;; GNU `patch' v. >= 2.2
88 (format "-z%s -b" ediff-backup-extension)) 96 (format "-z%s -b" ediff-backup-extension))
89 ((zerop (call-process ediff-patch-program nil nil nil "-b")) 97 ((eq type 'posix)
90 ;; POSIX `patch' -- ediff-backup-extension must be ".orig" 98 ;; POSIX `patch' -- ediff-backup-extension must be ".orig"
91 (setq ediff-backup-extension ediff-default-backup-extension) 99 (setq ediff-backup-extension ediff-default-backup-extension)
92 "-b") 100 "-b")
93 (t 101 (t
94 ;; traditional `patch' 102 ;; traditional `patch'
95 (format "-b %s" ediff-backup-extension))) 103 (format "-b %s" ediff-backup-extension))))
96 "*Backup directives to pass to the patch program. 104 "*Backup directives to pass to the patch program.
97 Ediff requires that the old version of the file \(before applying the patch\) 105 Ediff requires that the old version of the file \(before applying the patch\)
98 be saved in a file named `the-patch-file.extension'. Usually `extension' is 106 be saved in a file named `the-patch-file.extension'. Usually `extension' is
99 `.orig', but this can be changed by the user and may depend on the system. 107 `.orig', but this can be changed by the user and may depend on the system.
100 Therefore, Ediff needs to know the backup extension used by the patch program. 108 Therefore, Ediff needs to know the backup extension used by the patch program.
105 versions of GNU patch require `-b -z backup-extension'. 113 versions of GNU patch require `-b -z backup-extension'.
106 114
107 Note that both `ediff-backup-extension' and `ediff-backup-specs' 115 Note that both `ediff-backup-extension' and `ediff-backup-specs'
108 must be set properly. If your patch program takes the option `-b', 116 must be set properly. If your patch program takes the option `-b',
109 but not `-b extension', the variable `ediff-backup-extension' must 117 but not `-b extension', the variable `ediff-backup-extension' must
110 still be set so Ediff will know which extension to use." 118 still be set so Ediff will know which extension to use.
119
120 Ediff tries to guess the appropriate value for this variables. It is believed
121 to be working for `traditional' patch, all versions of GNU patch, and for POSIX
122 patch. So, don't change these variables, unless the default doesn't work."
111 :type 'string 123 :type 'string
112 :group 'ediff-ptch) 124 :group 'ediff-ptch)
113 125
114 126
115 (defcustom ediff-patch-default-directory nil 127 (defcustom ediff-patch-default-directory nil
276 (progn 288 (progn
277 (with-output-to-temp-buffer ediff-msg-buffer 289 (with-output-to-temp-buffer ediff-msg-buffer
278 (princ 290 (princ
279 (format " 291 (format "
280 The patch file contains a context diff for 292 The patch file contains a context diff for
281
282 %s 293 %s
283 %s 294 %s
284
285 However, Ediff cannot infer the name of the actual file 295 However, Ediff cannot infer the name of the actual file
286 to be patched on your system. If you know the correct file name, 296 to be patched on your system. If you know the correct file name,
287 please enter it now. 297 please enter it now.
288 298
289 If you don't know and still would like to apply patches to 299 If you don't know and still would like to apply patches to
334 (with-output-to-temp-buffer ediff-msg-buffer 344 (with-output-to-temp-buffer ediff-msg-buffer
335 (princ (format " 345 (princ (format "
336 Ediff has inferred that 346 Ediff has inferred that
337 %s 347 %s
338 %s 348 %s
339 are possible targets for applying the patch. 349 are two possible targets for applying the patch.
340 Both files seem to be plausible alternatives. 350 Both files seem to be plausible alternatives.
341 351
342 Please advice: 352 Please advice:
343 Type `y' to use %s as the target; 353 Type `y' to use %s as the target;
344 Type `n' to use %s as the target. 354 Type `n' to use %s as the target.
349 file2 file1))) 359 file2 file1)))
350 (f2-exists (setcar triple file2)) 360 (f2-exists (setcar triple file2))
351 (f1-exists (setcar triple file1)) 361 (f1-exists (setcar triple file1))
352 (t 362 (t
353 (with-output-to-temp-buffer ediff-msg-buffer 363 (with-output-to-temp-buffer ediff-msg-buffer
354 (princ (format " 364 (princ "\nEdiff has inferred that")
355 Ediff inferred that 365 (if (string= file1 file2)
366 (princ (format "
367 %s
368 is the target for this patch. However, this file does not exist."
369 file1))
370 (princ (format "
356 %s 371 %s
357 %s 372 %s
358 are possible alternative targets for this patch. 373 are two possible targets for this patch. However, these files do not exist."
359 374 file1 file2)))
360 However, these files do not exist. 375 (princ "
361 376 \nPlease enter an alternative patch target ...\n"))
362 Please enter an alternative patch target ...
363 "
364 file1 file2)))
365 (let ((directory t) 377 (let ((directory t)
366 target) 378 target)
367 (while directory 379 (while directory
368 (setq target (read-file-name 380 (setq target (read-file-name
369 "Please enter a patch target: " 381 "Please enter a patch target: "
390 Else, read patch file into a new buffer." 402 Else, read patch file into a new buffer."
391 (let ((dir (cond (ediff-patch-default-directory) ; try patch default dir 403 (let ((dir (cond (ediff-patch-default-directory) ; try patch default dir
392 (ediff-use-last-dir ediff-last-dir-patch) 404 (ediff-use-last-dir ediff-last-dir-patch)
393 (t default-directory))) 405 (t default-directory)))
394 patch-buf) 406 patch-buf)
395 (if (y-or-n-p "Is the patch already in a buffer? ") 407 (if (let ((last-nonmenu-event t) ; Emacs: don't use dialog box
408 last-command-event) ; XEmacs: don't use dialog box
409 (y-or-n-p "Is the patch already in a buffer? "))
396 (setq patch-buf 410 (setq patch-buf
397 (get-buffer 411 (get-buffer
398 (read-buffer 412 (read-buffer
399 "Which buffer contains the patch? " 413 "Which buffer contains the patch? "
400 (current-buffer) 'must-match))) 414 (ediff-other-buffer
415 (if (eq (next-window (selected-window)) (selected-window))
416 ;; only one window in frame --- don't skip current buff
417 ""
418 ;; >1 window --- skip current buff, assuming this is the one
419 ;; to patch, not the one that has the patch
420 (current-buffer)))
421 'must-match)))
401 (setq patch-buf 422 (setq patch-buf
402 (find-file-noselect 423 (find-file-noselect
403 (read-file-name "Which file contains the patch? " 424 (read-file-name "Which file contains the patch? "
404 dir nil 'must-match)))) 425 dir nil 'must-match))))
405 426
431 startup-hooks) 452 startup-hooks)
432 (ediff-multi-patch-internal patch-buf startup-hooks)) 453 (ediff-multi-patch-internal patch-buf startup-hooks))
433 )) 454 ))
434 455
435 456
436 (defun ediff-patch-buffer-internal (patch-buf buf-to-patch-name 457 ;; When patching a buffer, never change the orig file. Instead, create a new
437 &optional startup-hooks) 458 ;; buffer, ***_patched, even if the buff visits a file.
459 ;; Users who want to actually patch the buffer should use
460 ;; ediff-patch-file, not ediff-patch-buffer.
461 (defun ediff-patch-buffer-internal (patch-buf
462 buf-to-patch-name
463 &optional startup-hooks)
438 (let* ((buf-to-patch (get-buffer buf-to-patch-name)) 464 (let* ((buf-to-patch (get-buffer buf-to-patch-name))
439 (file-name-ok (if buf-to-patch (buffer-file-name buf-to-patch))) 465 (visited-file (if buf-to-patch (buffer-file-name buf-to-patch)))
440 (buf-mod-status (buffer-modified-p buf-to-patch)) 466 (buf-mod-status (buffer-modified-p buf-to-patch))
441 (multifile-patch-p (> (length (ediff-with-current-buffer patch-buf 467 (multifile-patch-p (> (length (ediff-with-current-buffer patch-buf
442 ediff-patch-map)) 1)) 468 ediff-patch-map)) 1))
443 default-dir file-name ctl-buf) 469 default-dir file-name ctl-buf)
444 (if file-name-ok 470 (if multifile-patch-p
445 (setq file-name file-name-ok) 471 (error
446 (if multifile-patch-p 472 "Can't apply multi-file patches to buffers that visit no files"))
447 (error 473
448 "Can't apply multi-file patches to buffers that visit no files")) 474 ;; create a temp file to patch
449 (ediff-with-current-buffer buf-to-patch 475 (ediff-with-current-buffer buf-to-patch
450 (setq default-dir default-directory) 476 (setq default-dir default-directory)
451 (setq file-name (ediff-make-temp-file buf-to-patch)) 477 (setq file-name (ediff-make-temp-file buf-to-patch))
452 (set-visited-file-name file-name) 478 ;; temporarily switch visited file name, if any
453 (setq buffer-auto-save-file-name nil) ; don't create auto-save file 479 (set-visited-file-name file-name)
454 ;;don't confuse the user with a new bufname 480 ;; don't create auto-save file, if buff was visiting a file
455 (rename-buffer buf-to-patch-name) 481 (or visited-file
456 (set-buffer-modified-p nil) 482 (setq buffer-auto-save-file-name nil))
457 (set-visited-file-modtime) ; sync buffer and temp file 483 ;; don't confuse the user with a new bufname
458 (setq default-directory default-dir) 484 (rename-buffer buf-to-patch-name)
459 )) 485 (set-buffer-modified-p nil)
460 486 (set-visited-file-modtime) ; sync buffer and temp file
487 (setq default-directory default-dir)
488 )
489
461 ;; dispatch a patch function 490 ;; dispatch a patch function
462 (setq ctl-buf (ediff-dispatch-file-patching-job 491 (setq ctl-buf (ediff-dispatch-file-patching-job
463 patch-buf file-name startup-hooks)) 492 patch-buf file-name startup-hooks))
464 493
465 (if file-name-ok 494 (ediff-with-current-buffer ctl-buf
466 () 495 (delete-file (buffer-file-name ediff-buffer-A))
467 ;; buffer wasn't visiting any file, 496 (delete-file (buffer-file-name ediff-buffer-B))
468 ;; so we will not run meta-level ediff here 497 (ediff-with-current-buffer ediff-buffer-A
469 (ediff-with-current-buffer ctl-buf 498 (if default-dir (setq default-directory default-dir))
470 (delete-file (buffer-file-name ediff-buffer-A)) 499 (set-visited-file-name visited-file) ; visited-file might be nil
471 (delete-file (buffer-file-name ediff-buffer-B)) 500 (rename-buffer buf-to-patch-name)
472 (ediff-with-current-buffer ediff-buffer-A 501 (set-buffer-modified-p buf-mod-status))
473 (if default-dir (setq default-directory default-dir)) 502 (ediff-with-current-buffer ediff-buffer-B
474 (set-visited-file-name nil) 503 (setq buffer-auto-save-file-name nil) ; don't create auto-save file
475 (rename-buffer buf-to-patch-name) 504 (if default-dir (setq default-directory default-dir))
476 (set-buffer-modified-p buf-mod-status)) 505 (set-visited-file-name nil)
477 (ediff-with-current-buffer ediff-buffer-B 506 (rename-buffer (ediff-unique-buffer-name
478 (setq buffer-auto-save-file-name nil) ; don't create auto-save file 507 (concat buf-to-patch-name "_patched") ""))
479 (if default-dir (setq default-directory default-dir)) 508 (set-buffer-modified-p t)))
480 (set-visited-file-name nil)
481 (rename-buffer (ediff-unique-buffer-name
482 (concat buf-to-patch-name "_patched") ""))
483 (set-buffer-modified-p t))))
484 )) 509 ))
510
511
512 ;; Traditional patch has weird return codes.
513 ;; GNU and Posix return 1 if some hanks failed and 2 in case of trouble.
514 ;; 0 is a good code in all cases.
515 ;; We'll do the concervative thing.
516 (defun ediff-patch-return-code-ok (code)
517 (eq code 0))
518 ;;; (if (eq (ediff-test-patch-utility) 'traditional)
519 ;;; (eq code 0)
520 ;;; (not (eq code 2))))
485 521
486 (defun ediff-patch-file-internal (patch-buf source-filename 522 (defun ediff-patch-file-internal (patch-buf source-filename
487 &optional startup-hooks) 523 &optional startup-hooks)
488 (setq source-filename (expand-file-name source-filename)) 524 (setq source-filename (expand-file-name source-filename))
489 525
496 (true-source-filename source-filename) 532 (true-source-filename source-filename)
497 (target-filename source-filename) 533 (target-filename source-filename)
498 target-buf buf-to-patch file-name-magic-p 534 target-buf buf-to-patch file-name-magic-p
499 patch-return-code ctl-buf backup-style aux-wind) 535 patch-return-code ctl-buf backup-style aux-wind)
500 536
501 (if (string-match "-V" ediff-patch-options) 537 (if (string-match "V" ediff-patch-options)
502 (error 538 (error
503 "Ediff doesn't take the -V option in `ediff-patch-options'--sorry")) 539 "Ediff doesn't take the -V option in `ediff-patch-options'--sorry"))
504 540
505 ;; Make a temp file, if source-filename has a magic file handler (or if 541 ;; Make a temp file, if source-filename has a magic file handler (or if
506 ;; it is handled via auto-mode-alist and similar magic). 542 ;; it is handled via auto-mode-alist and similar magic).
548 (message "") 584 (message "")
549 585
550 (switch-to-buffer patch-diagnostics) 586 (switch-to-buffer patch-diagnostics)
551 (sit-for 0) ; synchronize - let the user see diagnostics 587 (sit-for 0) ; synchronize - let the user see diagnostics
552 588
553 (or (and (eq patch-return-code 0) ; patch reported success 589 (or (and (ediff-patch-return-code-ok patch-return-code)
554 (file-exists-p 590 (file-exists-p
555 (concat true-source-filename ediff-backup-extension))) 591 (concat true-source-filename ediff-backup-extension)))
556 (progn 592 (progn
557 (with-output-to-temp-buffer ediff-msg-buffer 593 (with-output-to-temp-buffer ediff-msg-buffer
558 (princ (format 594 (princ (format
559 "Patch program has failed due to a bad patch file OR 595 "Patch program has failed due to a bad patch file,
560 because it couldn't create the backup for the file to be patched. 596 it couldn't apply all hunks, OR
597 it couldn't create the backup for the file being patched.
561 598
562 The former could be caused by a corrupt patch file or because the %S 599 The former could be caused by a corrupt patch file or because the %S
563 program doesn't understand the format of the patch file in use. 600 program doesn't understand the format of the patch file in use.
564 601
565 The second problem might be due to an incompatibility among these settings: 602 The second problem might be due to an incompatibility among these settings:
566 ediff-patch-program = %S 603 ediff-patch-program = %S ediff-patch-options = %S
567 ediff-patch-options = %S 604 ediff-backup-extension = %S ediff-backup-specs = %S
568 ediff-backup-extension = %S
569 ediff-backup-specs = %S
570 605
571 See Ediff on-line manual for more details on these variables. 606 See Ediff on-line manual for more details on these variables.
572 In particular, check the documentation for `ediff-backup-specs'. " 607 In particular, check the documentation for `ediff-backup-specs'.
608
609 In any of the above cases, Ediff doesn't compare files automatically.
610 However, if the patch was applied partially and the backup file was created,
611 you can still examine the changes via M-x ediff-files"
573 ediff-patch-program 612 ediff-patch-program
574 ediff-patch-program 613 ediff-patch-program
575 ediff-patch-options 614 ediff-patch-options
576 ediff-backup-extension 615 ediff-backup-extension
577 ediff-backup-specs 616 ediff-backup-specs