@@ -778,6 +778,36 @@ reference revision."
778778 (with-current-buffer (or (buffer-base-buffer ) (current-buffer ))
779779 (diff-hl-diff-goto-hunk-1 nil diff-hl-reference-revision)))
780780
781+ (defun diff-hl-root-diff-reference-goto-hunk ()
782+ " Run VC diff command against the reference for the whole tree.
783+ And if the current buffer is visiting a file, and it has changes, the diff
784+ buffer will show the position corresponding to its current line."
785+ (interactive )
786+ (defvar vc-sentinel-movepoint )
787+ (with-current-buffer (or (buffer-base-buffer ) (current-buffer ))
788+ (let ((backend (vc-deduce-backend ))
789+ (default-directory default-directory)
790+ rootdir fileset
791+ relname)
792+ (if backend
793+ (setq rootdir (vc-call-backend backend 'root default-directory)
794+ default-directory rootdir
795+ fileset `(,backend (,rootdir ))
796+ relname (if buffer-file-name (file-relative-name buffer-file-name
797+ rootdir)))
798+ (error " Directory is not version controlled " ))
799+ (setq fileset (or fileset (vc-deduce-fileset )))
800+ (vc-buffer-sync-fileset fileset t )
801+ (let* ((line (line-number-at-pos )))
802+ (vc-diff-internal
803+ (if (boundp 'vc-allow-async-diff )
804+ vc-allow-async-diff
805+ t )
806+ fileset diff-hl-reference-revision nil t )
807+ (vc-run-delayed (when relname
808+ (diff-hl-diff-skip-to line relname)
809+ (setq vc-sentinel-movepoint (point ))))))))
810+
781811(defun diff-hl-diff-read-revisions (rev1-default )
782812 (let* ((file buffer-file-name)
783813 (files (list file))
@@ -807,13 +837,31 @@ reference revision."
807837 (when (string= rev2 " " ) (setq rev2 nil ))
808838 (cons rev1 rev2))))
809839
810- (defun diff-hl-diff-skip-to (line )
840+ (defun diff-hl-diff-skip-to (line &optional filename )
811841 " In `diff-mode' , skip to the hunk and line corresponding to LINE
812- in the source file, or the last line of the hunk above it."
842+ in the source file, or the last line of the hunk above it.
843+
844+ When passed FILENAME, ensure that the line is in the section belonging to
845+ that file, if it's present."
813846 (goto-char (point-min )) ; Counteract any similar behavior in diff-mode.
814- (diff-hunk-next )
815- (let (found)
816- (while (and (looking-at diff-hunk-header-re-unified) (not found))
847+ (let (found
848+ (end-pos (point-max )))
849+ (diff-hunk-next )
850+ (when filename
851+ (while (and (not (equal (diff-find-file-name nil t )
852+ filename))
853+ (not (eobp )))
854+ (diff-file-next ))
855+ (if (not (eobp ))
856+ ; ; Found our file in the changed set. Ensure that we don't go past.
857+ (setq end-pos (save-excursion
858+ (diff-end-of-file )
859+ (point )))
860+ (goto-char (point-min ))
861+ (setq line 0 )))
862+ (while (and (looking-at diff-hunk-header-re-unified)
863+ (not found)
864+ (< (point ) end-pos))
817865 (let ((hunk-line (string-to-number (match-string 3 )))
818866 (len (let ((m (match-string 4 )))
819867 (if m (string-to-number m) 1 ))))
@@ -827,7 +875,10 @@ in the source file, or the last line of the hunk above it."
827875 (while (cl-plusp to-go)
828876 (forward-line 1 )
829877 (unless (looking-at " ^[-\\ ]" )
830- (cl-decf to-go))))))))))
878+ (cl-decf to-go))))))))
879+ (when (> (point ) end-pos)
880+ (diff-hunk-prev )
881+ (diff-end-of-hunk ))))
831882
832883(defface diff-hl-reverted-hunk-highlight
833884 '((default :inverse-video t ))
0 commit comments