Changeset 3894 for trunk/lisp/ediff-ptch.el
- Timestamp:
- 10/02/05 09:47:43 (3 years ago)
- Files:
-
- trunk/lisp/ediff-ptch.el (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/lisp/ediff-ptch.el
r3809 r3894 164 164 ;; returns /dev/null, if can't strip prefix 165 165 (defsubst ediff-file-name-sans-prefix (filename prefix) 166 (save-match-data 167 (if (string-match (concat "^" (regexp-quote prefix)) filename) 168 (substring filename (match-end 0)) 169 (concat "/null/" filename)))) 166 (if prefix 167 (save-match-data 168 (if (string-match (concat "^" (if (stringp prefix) 169 (regexp-quote prefix) 170 "")) 171 filename) 172 (substring filename (match-end 0)) 173 (concat "/null/" filename))) 174 filename) 175 ) 170 176 171 177 … … 261 267 262 268 ;; Fix up the file names in the list using the argument FILENAME 263 ;; Algorithm: find the first file's directory and cut it out from each file 264 ;; name in the patch. Prepend the directory of FILENAME to each file in the 265 ;; patch. In addition, the first file in the patch is replaced by FILENAME. 266 ;; Each file is actually a file-pair of files found in the context diff header 267 ;; In the end, for each pair, we select the shortest existing file. 269 ;; Algorithm: find the files' directories in the patch and, if a directory is 270 ;; absolute, cut it out from the corresponding file name in the patch. 271 ;; Relative directories are not cut out. 272 ;; Prepend the directory of FILENAME to each resulting file (which came 273 ;; 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. 268 277 ;; Note: Ediff doesn't recognize multi-file patches that are separated 269 278 ;; with the `Index:' line. It treats them as a single-file patch. … … 276 285 (file-name-as-directory filename) 277 286 (file-name-directory filename))) 278 ;; Filename-spec is objA; at this point it is represented as 279 ;; (file1 . file2). We get it using ediff-get-session-objA 280 ;; directory part of the first file in the patch 281 (base-dir1 (file-name-directory 282 (car (ediff-get-session-objA-name (car ediff-patch-map))))) 283 ;; directory part of the 2nd file in the patch 284 (base-dir2 (file-name-directory 285 (cdr (ediff-get-session-objA-name (car ediff-patch-map))))) 287 ;; In case 2 files are possible patch targets, the user will be offered 288 ;; to choose file1 or file2. In a multifile patch, if the user chooses 289 ;; 1 or 2, this choice is preserved to decide future alternatives. 290 chosen-alternative 286 291 ) 287 292 288 293 ;; chop off base-dirs 289 294 (mapcar (lambda (session-info) 290 (let ((proposed-file-names 291 (ediff-get-session-objA-name session-info))) 295 (let* ((proposed-file-names 296 ;; 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 "")) 292 312 (or (string= (car proposed-file-names) "/dev/null") 293 313 (setcar proposed-file-names 294 314 (ediff-file-name-sans-prefix 295 315 (car proposed-file-names) base-dir1))) 296 (or (string=297 (cdr proposed-file-names) "/dev/null")298 (setcdr proposed-file-names299 (ediff-file-name-sans-prefix300 (cdr proposed-file-names) base-dir2)))301 ))316 (or (string= 317 (cdr proposed-file-names) "/dev/null") 318 (setcdr proposed-file-names 319 (ediff-file-name-sans-prefix 320 (cdr proposed-file-names) base-dir2))) 321 )) 302 322 ediff-patch-map) 303 323 … … 315 335 (if (and (string-match "^/null/" (car proposed-file-names)) 316 336 (string-match "^/null/" (cdr proposed-file-names))) 317 ;; couldn't strip base-dir1 and base-dir2318 ;; hence, something is wrong337 ;; couldn't intuit the file name to patch, so 338 ;; something is amiss 319 339 (progn 320 340 (with-output-to-temp-buffer ediff-msg-buffer … … 368 388 (f2-exists (file-exists-p file2))) 369 389 (cond 370 ((and (< (length file2) (length file1)) 371 f2-exists) 390 ((and 391 ;; 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) 372 398 ;; replace file-pair with the winning file2 373 399 (setcar session-file-object file2)) 374 ((and (< (length file1) (length file2)) 375 f1-exists) 400 ((and 401 ;; (< (length file1) (length file2)) 402 (not f2-exists) 403 f1-exists) 376 404 ;; replace file-pair with the winning file1 377 405 (setcar session-file-object file1)) … … 379 407 (string= file1 file2)) 380 408 (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)) 381 413 ((and f1-exists f2-exists) 382 414 (with-output-to-temp-buffer ediff-msg-buffer … … 394 426 Type `n' to use %s as the target. 395 427 " 396 file1 file2 file 2 file1)))428 file1 file2 file1 file2))) 397 429 (setcar session-file-object 398 (if (y-or-n-p (format "Use %s ? " file2)) 399 file2 file1))) 430 (if (y-or-n-p (format "Use %s ? " file1)) 431 (progn 432 (setq chosen-alternative 1) 433 file1) 434 (setq chosen-alternative 2) 435 file2)) 436 ) 400 437 (f2-exists (setcar session-file-object file2)) 401 438 (f1-exists (setcar session-file-object file1)) … … 408 445 (princ (format " 409 446 %s 410 is the target for this patch. However, this file does not exist."447 is assumed to be the target for this patch. However, this file does not exist." 411 448 file1)) 412 449 (princ (format " … … 442 479 ;; prompt for file, get the buffer 443 480 (defun ediff-prompt-for-patch-file () 444 (let ((dir (cond (ediff- patch-default-directory) ; try patch default dir445 (ediff- use-last-dir ediff-last-dir-patch)481 (let ((dir (cond (ediff-use-last-dir ediff-last-dir-patch) 482 (ediff-patch-default-directory) ; try patch default dir 446 483 (t default-directory))) 447 (coding-system-for-read ediff-coding-system-for-read)) 448 (find-file-noselect 449 (read-file-name 450 (format "Patch is in file:%s " 451 (cond ((and buffer-file-name 452 (equal (expand-file-name dir) 453 (file-name-directory buffer-file-name))) 454 (concat 455 " (default " 456 (file-name-nondirectory buffer-file-name) 457 ")")) 458 (t ""))) 459 dir buffer-file-name 'must-match)) 484 (coding-system-for-read ediff-coding-system-for-read) 485 patch-file-name) 486 (setq patch-file-name 487 (read-file-name 488 (format "Patch is in file%s: " 489 (cond ((and buffer-file-name 490 (equal (expand-file-name dir) 491 (file-name-directory buffer-file-name))) 492 (concat 493 " (default " 494 (file-name-nondirectory buffer-file-name) 495 ")")) 496 (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)) 460 501 )) 461 502 … … 648 689 649 690 (ediff-with-current-buffer patch-diagnostics 650 (insert-buffer patch-buf)691 (insert-buffer-substring patch-buf) 651 692 (message "Applying patch ... ") 652 693 ;; fix environment for gnu patch, so it won't make numbered extensions
