[net.emacs] .el code to merge GNU diffs follows

schwrtze@acf8.UUCP (E. Schwartz group) (05/04/86)

Here is a .el program I wrote to work on a dist directory and provided diffs
it will make the changes to the appropriate source files. Make a vanilla dir
with the dist in it i.e. No modifications to the source since THis method will
fail because it uses absolute line numbers. A sequence would be

eval-region on the lisp code. Then invoke differ by the <esc><esc> line i.e.
(differ "d.46.48")

I did not want to recombine 600k of contextual diffs so I wrote this program
is there an easier way? Perhaps the diffs could be in ed file format?

Hedley Rainnie.
hedley@alaya
{seismo|ihnp4|allegra}!cmcl2!alaya!hedley

(212)-807-0303


;
; given a string that is the diff file name this code will attempt to
; generate a new version of emacs.
; differ was written by Hedley Rainnie hedley@alaya.arpa or
; {seismo|ihnp4|allegra}!cmcl2!alaya!hedley
;
; OR (212)-807-0303
;
; A typical invocation is 
; (differ "d.46.48") 
; (differ "d.48.49") 
; (differ "d.49.55") 
; (differ "d.55.60") 
; (differ "d.60.61") 
; (differ "d.61.62")
; It is going to work on "dist" so beware perhaps make a copy.
; Woe be tied if you have made local hacks to diffed files...
; I am now at .62 through the above exchange. I could not find an
; easy way to combine the contextual diffs so I wrote this. Hope 
; someone finds it useful.
;
(defvar diff0 0)
(defvar diff1 0)
(defvar doff 0)
(defvar i 0)
(defun differ(s)
  (interactive "p")
  (let ((new-mode t)(beg 0)(end 0)(start 0) (finish 0) (diff-mode t)
	(file-name "")(ss nil)(dec 0)(dirty 0))
    (find-file s)
    (beginning-of-buffer)
    ; switch to the diff file and first extract the new files
    ; newfiles are characterised by a lot of === signs followed by a path
    ;
    (setq new-mode
	  (re-search-forward 
	   "====Replacement file \\|====New file " (point-max) 0))
    (while new-mode
      (setq beg (point))
      (end-of-line)
      (setq end (point))
      (copy-region-as-kill beg end)
      ;
      ; Create and copy the text to the new file
      ;
      (beginning-of-line 2)
      (setq start (point))
      (search-forward "==========") ; get to the next file or diffs
      (beginning-of-line)
      (setq finish (point))
      (write-region start finish (concat "dist/" (car kill-ring)))
      (goto-char finish)
      (setq new-mode
	    (re-search-forward 
	     "====Replacement file \\|====New file " (point-max) 0))
      )
    ;
    ; Now incorporate the diffs into the files in question
    ;
    (goto-char (point-min))
    (setq diff-mode (re-search-forward "^\\*\\*\\*\\*\\*\\*" (point-max) 0))
    (while diff-mode
      (setq beg (point)) ; save where we are
      (forward-line -3)
      (if (looking-at "diff -rc") (progn()
					(if (= dirty 1) (progn()
							      (switch-to-buffer ss)
							      (save-buffer)
							      (kill-buffer ss)
							      )
					  (switch-to-buffer s)
					  )
					(end-of-line)
					(setq end (point))
					(search-backward " ")
					(forward-char 1)
					(copy-region-as-kill (point) end)
					(setq filename (car kill-ring))
					(find-file filename)
					(message (concat "Processing: " filename))
					(setq ss (buffer-name))
					(switch-to-buffer s)
					(setq doff 0)
					)
	)
      ;
      ; Create and copy the text to the new file
      ;
      ; 
      (setq dirty 1)
      (goto-char beg)
      (forward-line 1)
      (search-forward " ")
      (setq start (point))
      (search-forward ",")
      (backward-char)
      (copy-region-as-kill start (point))
      (setq diff0 (string-to-int (car kill-ring)))
      (forward-char)
      (setq start (point))
      (end-of-line)
      (copy-region-as-kill start (point))
      (setq diff1 (string-to-int (car kill-ring)))
      (switch-to-buffer ss)
      (setq n (+ doff diff0))
      (goto-line n)
      (setq i (1+ (- diff1 diff0)))
      (switch-to-buffer s)
      (forward-line 1)
      (setq dec 0)
      (while (> i 0)
	(if (looking-at "! ") (progn() ; handle the ! condition
				    (switch-to-buffer ss)
				    (beginning-of-line)
				    (delete-line)
				    (setq doff (1- doff))
				    ))
	(switch-to-buffer s)
	(if (looking-at "- ") (progn() ; handle the - condition
				    (switch-to-buffer ss)
				    (beginning-of-line)
				    (delete-line)
				    (setq doff (1- doff))
				    (setq dec 1) ; was deleting t
				    ))
	(switch-to-buffer s)
	(if (looking-at "  ")  (progn ()
				     (switch-to-buffer ss)
				     (forward-line 1)
				     ))
	(switch-to-buffer s)	
	(forward-line 1)
	(setq i (1- i)))
      (switch-to-buffer s)
      (re-search-forward "^--- ")
      (setq start (point))
      (search-forward ",")
      (backward-char)
      (copy-region-as-kill start (point))
      (setq diff0 (string-to-int (car kill-ring)))
      (forward-char)
      (setq start (point))
      (search-forward " ")
      (backward-char)
      (copy-region-as-kill start (point))
      (setq diff1 (string-to-int (car kill-ring)))
      (setq i (1+ (- diff1 diff0)))
      (switch-to-buffer ss)
      (goto-line diff0)
      (switch-to-buffer s)
      (forward-line 1)
      (if (= dec 1) (setq i 0)) ; If - then go on 
      (while (> i 0)
	(if (looking-at "! ") (progn() ; handle the ! condition
				    (forward-char 2)
				    (setq start (point))
				    (end-of-line)
				    (copy-region-as-kill start (point))
				    (switch-to-buffer ss)
				    (beginning-of-line)
				    (open-line 1)
				    (insert-string (car kill-ring))
				    (forward-line 1)
				    (setq doff (1+ doff))
				    ))
	(switch-to-buffer s)
	(if (looking-at "+ ") (progn() ; handle the + condition
				    (forward-char 2)
				    (setq start (point))
				    (end-of-line)
				    (copy-region-as-kill start (point))
				    (switch-to-buffer ss)
				    (beginning-of-line)
				    (open-line 1)
				    (insert-string (car kill-ring))
				    (forward-line 1)
				    (setq doff (1+ doff))
				    ))
	(switch-to-buffer s)
	(if (looking-at "  ") (progn()
				    (switch-to-buffer ss)
				    (forward-line 1)
				    ))
	(setq i (1- i))
	(switch-to-buffer s)
	(forward-line 1)
	)
      (setq diff-mode (re-search-forward "^\\*\\*\\*\\*" (point-max) 0))
      )
    (if ss (progn ()
		  (switch-to-buffer ss)
		  (save-buffer)
		  (kill-buffer ss)
		  )
      )
    )
  "Done!"
)
(defun delete-line()
  (let ((beg 0))
    (setq beg (point))
    (forward-line 1)
    (kill-region beg (point))))