Mercurial > hg > xemacs-beta
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 |