move stuff around
This commit is contained in:
115
user-lisp/magit-ediff-all.el
Normal file
115
user-lisp/magit-ediff-all.el
Normal file
@@ -0,0 +1,115 @@
|
||||
;;; magit-ediff-all.el --- Compare all changed files between revisions using Ediff -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2025 The Magit Project Contributors
|
||||
|
||||
;; Author: [Your Name]
|
||||
;; Maintainer: [Your Name]
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This library extends Magit's ediff support by adding a command to
|
||||
;; compare all changed files between two revisions using an ediff
|
||||
;; session group.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'magit)
|
||||
(require 'magit-ediff)
|
||||
(require 'ediff)
|
||||
(require 'cl-lib)
|
||||
|
||||
;; Define the new suffix key and description
|
||||
(defvar magit-ediff-all-key "A"
|
||||
"Key binding for the ediff all command in the magit-ediff transient.")
|
||||
|
||||
(defvar magit-ediff-all-description "All changed files (between revisions)"
|
||||
"Description for the ediff all command in the magit-ediff transient.")
|
||||
|
||||
(defun magit-ediff-all--write-file (temp-files temp-buffers rev dir file)
|
||||
(let* ((rel-path (if (file-name-absolute-p file)
|
||||
(file-relative-name file (magit-toplevel))
|
||||
file))
|
||||
(rel-file (expand-file-name rel-path dir))
|
||||
;; Handle files that are added or removed - use empty buffer
|
||||
(buf (or (magit-find-file-noselect rev file)
|
||||
(generate-new-buffer " *empty*"))))
|
||||
;; Create necessary subdirectories
|
||||
(let ((dir-part (file-name-directory rel-file)))
|
||||
(when dir-part
|
||||
(make-directory dir-part t)))
|
||||
(push rel-file temp-files)
|
||||
(push buf temp-buffers)
|
||||
(with-current-buffer buf
|
||||
(write-region (point-min) (point-max) rel-file nil 'quiet)
|
||||
(add-hook 'ediff-prepare-buffer-hook
|
||||
(lambda ()
|
||||
(rename-buffer (format "%s~%s~" rel-file rev)))
|
||||
0 t))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-ediff-all-files (revA revB)
|
||||
"Compare all changed files between REVA and REVB using Ediff.
|
||||
|
||||
This creates an Ediff session group that allows you to navigate
|
||||
through all changed files between the two revisions and compare
|
||||
them one at a time."
|
||||
(interactive
|
||||
(pcase-let ((`(,a ,b) (magit-ediff-compare--read-revisions nil)))
|
||||
(list a b)))
|
||||
|
||||
(when (or (not revA) (not revB))
|
||||
(user-error "Both revisions must be specified"))
|
||||
|
||||
(magit-with-toplevel
|
||||
(let* ((changed-files (magit-changed-files revA revB))
|
||||
(dirA (make-temp-file (format "magit-ediff-%s-" revA) t))
|
||||
(dirB (make-temp-file (format "magit-ediff-%s-" revB) t))
|
||||
temp-files
|
||||
temp-buffers)
|
||||
|
||||
(message "Preparing %d files for comparison..." (length changed-files))
|
||||
|
||||
;; Create temporary files for each revision
|
||||
(dolist (file changed-files)
|
||||
(magit-ediff-all--write-file temp-files temp-buffers revA dirA file)
|
||||
(magit-ediff-all--write-file temp-files temp-buffers revB dirB file))
|
||||
|
||||
|
||||
;; Define cleanup function
|
||||
(cl-labels
|
||||
((magit-ediff-all--cleanup ()
|
||||
(dolist (file temp-files)
|
||||
(when (file-exists-p file)
|
||||
(delete-file file)))
|
||||
;; Kill any buffers visiting files in the temp directories
|
||||
(dolist (buf (buffer-list))
|
||||
(when-let ((filename (buffer-file-name buf)))
|
||||
(when (or (string-prefix-p (expand-file-name dirA) filename)
|
||||
(string-prefix-p (expand-file-name dirB) filename))
|
||||
(when (buffer-live-p buf)
|
||||
(kill-buffer buf)))))
|
||||
(when (file-exists-p dirA)
|
||||
(delete-directory dirA t))
|
||||
(when (file-exists-p dirB)
|
||||
(delete-directory dirB t))
|
||||
(dolist (buf temp-buffers)
|
||||
(when (buffer-live-p buf)
|
||||
(kill-buffer buf)))
|
||||
(remove-hook 'ediff-quit-session-group-hook #'magit-ediff-all--cleanup)))
|
||||
|
||||
;; Register hooks
|
||||
(add-hook 'ediff-quit-session-group-hook #'magit-ediff-all--cleanup)
|
||||
|
||||
;; Open ediff on the two directories
|
||||
(message "Opening Ediff session group...")
|
||||
(ediff-directories dirA dirB nil)))))
|
||||
|
||||
;; Add the command to the magit-ediff transient
|
||||
(with-eval-after-load 'magit-ediff
|
||||
(transient-append-suffix 'magit-ediff "r"
|
||||
`(,magit-ediff-all-key ,magit-ediff-all-description magit-ediff-all-files)))
|
||||
|
||||
(provide 'magit-ediff-all)
|
||||
;;; magit-ediff-all.el ends here
|
||||
Reference in New Issue
Block a user