/[emacs]/emacs/lisp/ediff-ptch.el
ViewVC logotype

Diff of /emacs/lisp/ediff-ptch.el

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.25 by ttn, Sat Aug 6 22:13:42 2005 UTC revision 1.26 by kifer, Tue Sep 20 17:47:28 2005 UTC
# Line 163  program." Line 163  program."
163  ;; strip prefix from filename  ;; strip prefix from filename
164  ;; returns /dev/null, if can't strip prefix  ;; returns /dev/null, if can't strip prefix
165  (defsubst ediff-file-name-sans-prefix (filename prefix)  (defsubst ediff-file-name-sans-prefix (filename prefix)
166    (save-match-data    (if prefix
167      (if (string-match (concat "^" (regexp-quote prefix)) filename)        (save-match-data
168          (substring filename (match-end 0))          (if (string-match (concat "^" (if (stringp prefix)
169        (concat "/null/" filename))))                                            (regexp-quote prefix)
170                                            ""))
171                              filename)
172                (substring filename (match-end 0))
173              (concat "/null/" filename)))
174        filename)
175      )
176    
177    
178    
# Line 260  program." Line 266  program."
266        count)))        count)))
267    
268  ;; Fix up the file names in the list using the argument FILENAME  ;; Fix up the file names in the list using the argument FILENAME
269  ;; Algorithm: find the first file's directory and cut it out from each file  ;; Algorithm: find the files' directories in the patch and, if a directory is
270  ;; name in the patch.  Prepend the directory of FILENAME to each file in the  ;; absolute, cut it out from the corresponding file name in the patch.
271  ;; patch.  In addition, the first file in the patch is replaced by FILENAME.  ;; Relative directories are not cut out.
272  ;; Each file is actually a file-pair of files found in the context diff header  ;; Prepend the directory of FILENAME to each resulting file (which came
273  ;; In the end, for each pair, we select the shortest existing file.  ;; originally from the patch).
274    ;; In addition, the first file in the patch document is replaced by FILENAME.
275    ;; Each file is actually a pair of files found in the context diff header
276    ;; In the end, for each pair, we ask the user which file to patch.
277  ;; Note: Ediff doesn't recognize multi-file patches that are separated  ;; Note: Ediff doesn't recognize multi-file patches that are separated
278  ;; with the `Index:' line.  It treats them as a single-file patch.  ;; with the `Index:' line.  It treats them as a single-file patch.
279  ;;  ;;
# Line 275  program." Line 284  program."
284                          ;; directory part of filename                          ;; directory part of filename
285                          (file-name-as-directory filename)                          (file-name-as-directory filename)
286                        (file-name-directory filename)))                        (file-name-directory filename)))
287          ;; Filename-spec is objA; at this point it is represented as          ;; In case 2 files are possible patch targets, the user will be offered
288          ;; (file1 . file2). We get it using ediff-get-session-objA          ;; to choose file1 or file2.  In a multifile patch, if the user chooses
289          ;; directory part of the first file in the patch          ;; 1 or 2, this choice is preserved to decide future alternatives.
290          (base-dir1 (file-name-directory          chosen-alternative
                     (car (ediff-get-session-objA-name (car ediff-patch-map)))))  
         ;; directory part of the 2nd file in the patch  
         (base-dir2 (file-name-directory  
                     (cdr (ediff-get-session-objA-name (car ediff-patch-map)))))  
291          )          )
292    
293      ;; chop off base-dirs      ;; chop off base-dirs
294      (mapcar (lambda (session-info)      (mapcar (lambda (session-info)
295                (let ((proposed-file-names                (let* ((proposed-file-names
296                       (ediff-get-session-objA-name session-info)))                        ;; Filename-spec is objA; it is represented as
297                          ;; (file1 . file2). Get it using ediff-get-session-objA.
298                          (ediff-get-session-objA-name session-info))
299                         ;; base-dir1 is  the dir part of the 1st file in the patch
300                         (base-dir1 (file-name-directory (car proposed-file-names)))
301                         ;; directory part of the 2nd file in the patch
302                         (base-dir2 (file-name-directory (cdr proposed-file-names)))
303                         )
304                    ;; If both base-dir1 and base-dir2 are relative, assume that
305                    ;; these dirs lead to the actual files starting at the present
306                    ;; directory. So, we don't strip these relative dirs from the
307                    ;; file names. This is a heuristic intended to improve guessing
308                    (unless (or (file-name-absolute-p base-dir1)
309                                (file-name-absolute-p base-dir2))
310                      (setq base-dir1 ""
311                            base-dir2 ""))
312                  (or (string= (car proposed-file-names) "/dev/null")                  (or (string= (car proposed-file-names) "/dev/null")
313                      (setcar proposed-file-names                      (setcar proposed-file-names
314                              (ediff-file-name-sans-prefix                              (ediff-file-name-sans-prefix
315                               (car proposed-file-names) base-dir1)))                               (car proposed-file-names) base-dir1)))
316                (or (string=                  (or (string=
317                     (cdr proposed-file-names) "/dev/null")                       (cdr proposed-file-names) "/dev/null")
318                    (setcdr proposed-file-names                      (setcdr proposed-file-names
319                            (ediff-file-name-sans-prefix                              (ediff-file-name-sans-prefix
320                             (cdr proposed-file-names) base-dir2)))                               (cdr proposed-file-names) base-dir2)))
321                ))                  ))
322              ediff-patch-map)              ediff-patch-map)
323    
324      ;; take the given file name into account      ;; take the given file name into account
# Line 314  program." Line 334  program."
334                       (ediff-get-session-objA-name session-info)))                       (ediff-get-session-objA-name session-info)))
335                  (if (and (string-match "^/null/" (car proposed-file-names))                  (if (and (string-match "^/null/" (car proposed-file-names))
336                           (string-match "^/null/" (cdr proposed-file-names)))                           (string-match "^/null/" (cdr proposed-file-names)))
337                      ;; couldn't strip base-dir1 and base-dir2                      ;; couldn't intuit the file name to patch, so
338                      ;; hence, something is wrong                      ;; something is amiss
339                      (progn                      (progn
340                        (with-output-to-temp-buffer ediff-msg-buffer                        (with-output-to-temp-buffer ediff-msg-buffer
341                          (ediff-with-current-buffer standard-output                          (ediff-with-current-buffer standard-output
# Line 367  other files, enter /dev/null Line 387  other files, enter /dev/null
387                       (f1-exists (file-exists-p file1))                       (f1-exists (file-exists-p file1))
388                       (f2-exists (file-exists-p file2)))                       (f2-exists (file-exists-p file2)))
389                  (cond                  (cond
390                   ((and (< (length file2) (length file1))                   ((and
391                         f2-exists)                     ;; The patch program prefers the shortest file as the patch
392                       ;; target. However, this is a questionable heuristic. In an
393                       ;; interactive program, like ediff, we can offer the user a
394                       ;; choice.
395                       ;; (< (length file2) (length file1))
396                       (not f1-exists)
397                       f2-exists)
398                    ;; replace file-pair with the winning file2                    ;; replace file-pair with the winning file2
399                    (setcar session-file-object file2))                    (setcar session-file-object file2))
400                   ((and (< (length file1) (length file2))                   ((and
401                         f1-exists)                     ;; (< (length file1) (length file2))
402                       (not f2-exists)
403                       f1-exists)
404                    ;; replace file-pair with the winning file1                    ;; replace file-pair with the winning file1
405                    (setcar session-file-object file1))                    (setcar session-file-object file1))
406                   ((and f1-exists f2-exists                   ((and f1-exists f2-exists
407                         (string= file1 file2))                         (string= file1 file2))
408                    (setcar session-file-object file1))                    (setcar session-file-object file1))
409                     ((and f1-exists f2-exists (eq chosen-alternative 1))
410                      (setcar session-file-object file1))
411                     ((and f1-exists f2-exists (eq chosen-alternative 2))
412                      (setcar session-file-object file2))
413                   ((and f1-exists f2-exists)                   ((and f1-exists f2-exists)
414                    (with-output-to-temp-buffer ediff-msg-buffer                    (with-output-to-temp-buffer ediff-msg-buffer
415                      (ediff-with-current-buffer standard-output                      (ediff-with-current-buffer standard-output
# Line 393  Please advice: Line 425  Please advice:
425      Type `y' to use %s as the target;      Type `y' to use %s as the target;
426      Type `n' to use %s as the target.      Type `n' to use %s as the target.
427  "  "
428                                     file1 file2 file2 file1)))                                     file1 file2 file1 file2)))
429                    (setcar session-file-object                    (setcar session-file-object
430                            (if (y-or-n-p (format "Use %s ? " file2))                            (if (y-or-n-p (format "Use %s ? " file1))
431                                file2 file1)))                                (progn
432                                    (setq chosen-alternative 1)
433                                    file1)
434                                (setq chosen-alternative 2)
435                                file2))
436                      )
437                   (f2-exists (setcar session-file-object file2))                   (f2-exists (setcar session-file-object file2))
438                   (f1-exists (setcar session-file-object file1))                   (f1-exists (setcar session-file-object file1))
439                   (t                   (t
# Line 407  Please advice: Line 444  Please advice:
444                      (if (string= file1 file2)                      (if (string= file1 file2)
445                          (princ (format "                          (princ (format "
446          %s          %s
447  is the target for this patch.  However, this file does not exist."  is assumed to be the target for this patch.  However, this file does not exist."
448                                         file1))                                         file1))
449                        (princ (format "                        (princ (format "
450          %s          %s
# Line 441  are two possible targets for this patch. Line 478  are two possible targets for this patch.
478    
479  ;; prompt for file, get the buffer  ;; prompt for file, get the buffer
480  (defun ediff-prompt-for-patch-file ()  (defun ediff-prompt-for-patch-file ()
481    (let ((dir (cond (ediff-patch-default-directory) ; try patch default dir    (let ((dir (cond (ediff-use-last-dir ediff-last-dir-patch)
482                     (ediff-use-last-dir ediff-last-dir-patch)                     (ediff-patch-default-directory) ; try patch default dir
483                     (t default-directory)))                     (t default-directory)))
484          (coding-system-for-read ediff-coding-system-for-read))          (coding-system-for-read ediff-coding-system-for-read)
485      (find-file-noselect          patch-file-name)
486       (read-file-name      (setq patch-file-name
487        (format "Patch is in file:%s "            (read-file-name
488                (cond ((and buffer-file-name             (format "Patch is in file:%s "
489                            (equal (expand-file-name dir)                     (cond ((and buffer-file-name
490                                   (file-name-directory buffer-file-name)))                                 (equal (expand-file-name dir)
491                       (concat                                        (file-name-directory buffer-file-name)))
492                        " (default "                            (concat
493                        (file-name-nondirectory buffer-file-name)                             " (default "
494                        ")"))                             (file-name-nondirectory buffer-file-name)
495                      (t "")))                             ")"))
496        dir buffer-file-name 'must-match))                           (t "")))
497               dir buffer-file-name 'must-match))
498        (if (file-directory-p patch-file-name)
499            (error "Patch file cannot be a directory: %s" patch-file-name)
500          (find-file-noselect patch-file-name))
501      ))      ))
502    
503    
# Line 647  optional argument, then use it." Line 688  optional argument, then use it."
688      (ediff-maybe-checkout buf-to-patch)      (ediff-maybe-checkout buf-to-patch)
689    
690      (ediff-with-current-buffer patch-diagnostics      (ediff-with-current-buffer patch-diagnostics
691        (insert-buffer patch-buf)        (insert-buffer-substring patch-buf)
692        (message "Applying patch ... ")        (message "Applying patch ... ")
693        ;; fix environment for gnu patch, so it won't make numbered extensions        ;; fix environment for gnu patch, so it won't make numbered extensions
694        (setq backup-style (getenv "VERSION_CONTROL"))        (setq backup-style (getenv "VERSION_CONTROL"))

Legend:
Removed from v.1.25  
changed lines
  Added in v.1.26

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26