changeset 106472:6e0f1038bc44

Support showing a single log entry from vc-annotate. * vc.el (print-log): Add a new argument: START-REVISION. (vc-print-log-internal): Add a new optional argument and pass it to the backend. (vc-print-log, vc-print-root-log): Adjust callers. * vc-annotate.el (vc-annotate-show-log-revision-at-line): If a buffer already displays the requested log entry, use it. Otherwise display only the log entry in question. * vc-svn.el (vc-svn-print-log): * vc-mtn.el (log-view-file-re): * vc-hg.el (vc-hg-state): * vc-git.el (vc-git-print-log): Add support for new argument START-REVISION. (vc-git-show-log-entry): Return t on success. * vc-bzr.el (vc-bzr-print-log): Add support new argument START-REVISION. (vc-bzr-show-log-entry): Return t on success. * vc-rcs.el (vc-rcs-print-log): * vc-sccs.el (vc-sccs-print-log): * vc-cvs.el (vc-cvs-print-log): Add new argument, ignore it.
author Dan Nicolaescu <dann@ics.uci.edu>
date Mon, 07 Dec 2009 09:02:11 +0000
parents 9fe246ccb486
children dfb27937da01
files etc/NEWS lisp/ChangeLog lisp/vc-annotate.el lisp/vc-bzr.el lisp/vc-cvs.el lisp/vc-git.el lisp/vc-hg.el lisp/vc-mtn.el lisp/vc-rcs.el lisp/vc-sccs.el lisp/vc-svn.el lisp/vc.el
diffstat 12 files changed, 126 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS	Mon Dec 07 06:56:40 2009 +0000
+++ b/etc/NEWS	Mon Dec 07 09:02:11 2009 +0000
@@ -267,6 +267,10 @@
 the corresponding lines.  Currently only Git and Mercurial take
 advantage of this feature.
 
+*** The log command in vc-annotate can display a single log entry
+instead of redisplaying the full log.  The RCS, CVS and SCCS VC
+backends do not support this.
+
 *** When a file is not found, VC will not try to check it out of RCS anymore.
 
 *** Diff and log operations can be used from dired buffers.
--- a/lisp/ChangeLog	Mon Dec 07 06:56:40 2009 +0000
+++ b/lisp/ChangeLog	Mon Dec 07 09:02:11 2009 +0000
@@ -1,13 +1,34 @@
+2009-12-07  Dan Nicolaescu  <dann@ics.uci.edu>
+
+	Support showing a single log entry from vc-annotate.
+	* vc.el (print-log): Add a new argument: START-REVISION.
+	(vc-print-log-internal): Add a new optional argument and
+	pass it to the backend.
+	(vc-print-log, vc-print-root-log): Adjust callers.
+	* vc-annotate.el (vc-annotate-show-log-revision-at-line): If a
+	buffer already displays the requested log entry, use it.
+	Otherwise display only the log entry in question.
+	* vc-svn.el (vc-svn-print-log):
+	* vc-mtn.el (log-view-file-re):
+	* vc-hg.el (vc-hg-state):
+	* vc-git.el (vc-git-print-log): Add support for new argument START-REVISION.
+	(vc-git-show-log-entry): Return t on success.
+	* vc-bzr.el (vc-bzr-print-log): Add support new argument START-REVISION.
+	(vc-bzr-show-log-entry): Return t on success.
+	* vc-rcs.el (vc-rcs-print-log):
+	* vc-sccs.el (vc-sccs-print-log):
+	* vc-cvs.el (vc-cvs-print-log): Add new argument, ignore it.
+
 2009-12-07  Michael Kifer <kifer@cs.stonybrook.edu>
-	
-	* ediff-init.el (ediff-event-key): use event-to-character instead of
+
+	* ediff-init.el (ediff-event-key): Use event-to-character instead of
 	event-key.
-	
-	* ediff-mult.el (ediff-setup-meta-map, ediff-prepare-meta-buffer): add
+
+	* ediff-mult.el (ediff-setup-meta-map, ediff-prepare-meta-buffer): Add
 	menus to the meta mode. (Dan Nicolaescu's <dann@ics.uci.edu> patch.)
-	
-	* ediff.el (ediff-buffers-internal): add unwind-protect.
-	
+
+	* ediff.el (ediff-buffers-internal): Add unwind-protect.
+
 2009-12-07  Michael Albinus  <michael.albinus@gmx.de>
 
 	Handle prompt rules of ksh in OpenBSD 4.5.  Reported by Raphaƫl
--- a/lisp/vc-annotate.el	Mon Dec 07 06:56:40 2009 +0000
+++ b/lisp/vc-annotate.el	Mon Dec 07 09:02:11 2009 +0000
@@ -479,15 +479,37 @@
 	(vc-annotate-warp-revision prev-rev fname)))))
 
 (defun vc-annotate-show-log-revision-at-line ()
-  "Visit the log of the revision at line."
+  "Visit the log of the revision at line.
+If the VC backend supports it, only show the log entry for the revision.
+If a *vc-change-log* buffer exists and already shows a log for
+the file in question, search for the log entry required and move point ."
   (interactive)
   (if (not (equal major-mode 'vc-annotate-mode))
       (message "Cannot be invoked outside of a vc annotate buffer")
     (let ((rev-at-line (vc-annotate-extract-revision-at-line)))
       (if (not rev-at-line)
 	  (message "Cannot extract revision number from the current line")
-	(vc-print-log-internal
-	 vc-annotate-backend (list (cdr rev-at-line)) (car rev-at-line) nil)))))
+	(let ((backend vc-annotate-backend)
+	      (log-buf (get-buffer "*vc-change-log*"))
+	      pos)
+	  (if (and
+	       log-buf
+	       ;; Look for a log buffer that already displays the correct file.
+	       (with-current-buffer log-buf
+		 (and (eq backend log-view-vc-backend)
+		      (null (cdr log-view-vc-fileset))
+		      (string= (car log-view-vc-fileset) (cdr rev-at-line))
+		      ;; Check if the entry we require can be found.
+		      (vc-call-backend
+		       backend 'show-log-entry (car rev-at-line))
+		      (setq pos (point)))))
+	      (progn
+		(pop-to-buffer log-buf)
+		(goto-char pos))
+	    ;; Ask the backend to display a single log entry.
+	    (vc-print-log-internal
+	     vc-annotate-backend (list (cdr rev-at-line))
+	     (car rev-at-line) t 1)))))))
 
 (defun vc-annotate-show-diff-revision-at-line-internal (filediff)
   (if (not (equal major-mode 'vc-annotate-mode))
--- a/lisp/vc-bzr.el	Mon Dec 07 06:56:40 2009 +0000
+++ b/lisp/vc-bzr.el	Mon Dec 07 09:02:11 2009 +0000
@@ -481,7 +481,7 @@
 		    (2 'change-log-email))
 		   ("^ *timestamp: \\(.*\\)" (1 'change-log-date-face)))))))
 
-(defun vc-bzr-print-log (files buffer &optional shortlog limit)
+(defun vc-bzr-print-log (files buffer &optional shortlog start-revision limit)
   "Get bzr change log for FILES into specified BUFFER."
   ;; `vc-do-command' creates the buffer, but we need it before running
   ;; the command.
@@ -495,6 +495,7 @@
     (apply 'vc-bzr-command "log" buffer 'async files
 	   (append
 	    (when shortlog '("--short"))
+	    (when start-revision (list (format "-r..%s" start-revision)))
 	    (when limit (list "-l" (format "%s" limit)))
 	    (if (stringp vc-bzr-log-switches)
 		(list vc-bzr-log-switches)
@@ -504,7 +505,8 @@
   "Find entry for patch name REVISION in bzr change log buffer."
   (goto-char (point-min))
   (when revision
-    (let (case-fold-search)
+    (let (case-fold-search
+	  found)
       (if (re-search-forward
 	   ;; "revno:" can appear either at the beginning of a line,
 	   ;; or indented.
@@ -512,8 +514,11 @@
 		   ;; The revision can contain ".", quote it so that it
 		   ;; does not interfere with regexp matching.
 		   (regexp-quote revision) "$") nil t)
-	  (beginning-of-line 0)
-	(goto-char (point-min))))))
+	  (progn
+	    (beginning-of-line 0)
+	    (setq found t))
+	(goto-char (point-min)))
+      found)))
 
 (defun vc-bzr-diff (files &optional rev1 rev2 buffer)
   "VC bzr backend for diff."
--- a/lisp/vc-cvs.el	Mon Dec 07 06:56:40 2009 +0000
+++ b/lisp/vc-cvs.el	Mon Dec 07 09:02:11 2009 +0000
@@ -496,7 +496,7 @@
 
 (declare-function vc-rcs-print-log-cleanup "vc-rcs" ())
 
-(defun vc-cvs-print-log (files buffer &optional shortlog limit)
+(defun vc-cvs-print-log (files buffer &optional shortlog start-revision-ignored limit)
   "Get change logs associated with FILES."
   (require 'vc-rcs)
   ;; It's just the catenation of the individual logs.
--- a/lisp/vc-git.el	Mon Dec 07 06:56:40 2009 +0000
+++ b/lisp/vc-git.el	Mon Dec 07 09:02:11 2009 +0000
@@ -77,7 +77,7 @@
 ;; - merge-news (file)                     see `merge'
 ;; - steal-lock (file &optional revision)          NOT NEEDED
 ;; HISTORY FUNCTIONS
-;; * print-log (files buffer &optional shortlog limit)   OK
+;; * print-log (files buffer &optional shortlog start-revision limit)   OK
 ;; - log-view-mode ()                              OK
 ;; - show-log-entry (revision)                     OK
 ;; - comment-history (file)                        ??
@@ -540,7 +540,7 @@
 
 ;;; HISTORY FUNCTIONS
 
-(defun vc-git-print-log (files buffer &optional shortlog limit)
+(defun vc-git-print-log (files buffer &optional shortlog start-revision limit)
   "Get change log associated with FILES."
   (let ((coding-system-for-read git-commits-coding-system))
     ;; `vc-do-command' creates the buffer, but we need it before running
@@ -559,6 +559,7 @@
 		  '("--graph" "--decorate"
 		    "--date=short" "--pretty=format:%d%h  %ad  %s" "--abbrev-commit"))
 		(when limit (list "-n" (format "%s" limit)))
+		(when start-revision (list start-revision))
 		'("--")))))))
 
 (defvar log-view-message-re)
@@ -615,14 +616,17 @@
 REVISION may have the form BRANCH, BRANCH~N,
 or BRANCH^ (where \"^\" can be repeated)."
   (goto-char (point-min))
-  (when revision
-    (search-forward (format "\ncommit %s" revision) nil t
-		    (cond ((string-match "~\\([0-9]\\)$" revision)
-			   (1+ (string-to-number (match-string 1 revision))))
-			  ((string-match "\\^+$" revision)
-			   (1+ (length (match-string 0 revision))))
-			  (t nil))))
-  (beginning-of-line))
+  (let (found)
+    (when revision
+      (setq found
+	    (search-forward (format "\ncommit %s" revision) nil t
+			    (cond ((string-match "~\\([0-9]\\)$" revision)
+				   (1+ (string-to-number (match-string 1 revision))))
+				  ((string-match "\\^+$" revision)
+				   (1+ (length (match-string 0 revision))))
+				  (t nil)))))
+    (beginning-of-line)
+    found))
 
 (defun vc-git-diff (files &optional rev1 rev2 buffer)
   "Get a difference report using Git between two revisions of FILES."
--- a/lisp/vc-hg.el	Mon Dec 07 06:56:40 2009 +0000
+++ b/lisp/vc-hg.el	Mon Dec 07 09:02:11 2009 +0000
@@ -68,7 +68,7 @@
 ;; - merge-news (file)                         NEEDED
 ;; - steal-lock (file &optional revision)      NOT NEEDED
 ;; HISTORY FUNCTIONS
-;; * print-log (files buffer &optional shortlog) OK
+;; * print-log (files buffer &optional shortlog start-revision limit) OK
 ;; - log-view-mode ()                          OK
 ;; - show-log-entry (revision)                 NOT NEEDED, DEFAULT IS GOOD
 ;; - comment-history (file)                    NOT NEEDED
@@ -167,9 +167,13 @@
             (setq status
                   (condition-case nil
                       ;; Ignore all errors.
-                      (process-file
+		      (let ((process-environment
+			     ;; Avoid localization of messages so we can parse the output.
+			     (append (list "TERM=dumb" "LANGUAGE=C" "HGRC=") process-environment)))
+
+		      (process-file
                        "hg" nil t nil
-                       "status" "-A" (file-relative-name file))
+                       "status" "-A" (file-relative-name file)))
                     ;; Some problem happened.  E.g. We can't find an `hg'
                     ;; executable.
                     (error nil)))))))
@@ -219,7 +223,7 @@
                  (repeat :tag "Argument List" :value ("") string))
   :group 'vc-hg)
 
-(defun vc-hg-print-log (files buffer &optional shortlog limit)
+(defun vc-hg-print-log (files buffer &optional shortlog limit start-revision)
   "Get change log associated with FILES."
   ;; `vc-do-command' creates the buffer, but we need it before running
   ;; the command.
@@ -231,6 +235,7 @@
 	buffer
       (apply 'vc-hg-command buffer 0 files "log"
 	     (append
+	      (when start-revision (list (format "-r%s:" start-revision)))
 	      (when limit (list "-l" (format "%s" limit)))
 	      (when shortlog '("--style" "compact"))
 	      vc-hg-log-switches)))))
--- a/lisp/vc-mtn.el	Mon Dec 07 06:56:40 2009 +0000
+++ b/lisp/vc-mtn.el	Mon Dec 07 09:02:11 2009 +0000
@@ -188,9 +188,11 @@
 ;; (defun vc-mtn-roolback (files)
 ;;   )
 
-(defun vc-mtn-print-log (files buffer &optional shortlog limit)
+(defun vc-mtn-print-log (files buffer &optional shortlog start-revision limit)
   (apply 'vc-mtn-command buffer 0 files "log"
-	 (when limit (list "--last" (format "%s" limit)))))
+	 (append
+	  (when start-revision (list "--from" (format "%s" start-revision))
+	  (when limit (list "--last" (format "%s" limit)))))))
 
 (defvar log-view-message-re)
 (defvar log-view-file-re)
--- a/lisp/vc-rcs.el	Mon Dec 07 06:56:40 2009 +0000
+++ b/lisp/vc-rcs.el	Mon Dec 07 09:02:11 2009 +0000
@@ -559,7 +559,7 @@
     (when (looking-at "[\b\t\n\v\f\r ]+")
       (delete-char (- (match-end 0) (match-beginning 0))))))
 
-(defun vc-rcs-print-log (files buffer &optional shortlog limit)
+(defun vc-rcs-print-log (files buffer &optional shortlog start-revision-ignored limit)
   "Get change log associated with FILE.  If FILE is a
 directory the operation is applied to all registered files beneath it."
   (vc-do-command (or buffer "*vc*") 0 "rlog" (mapcar 'vc-name (vc-expand-dirs files)))
--- a/lisp/vc-sccs.el	Mon Dec 07 06:56:40 2009 +0000
+++ b/lisp/vc-sccs.el	Mon Dec 07 09:02:11 2009 +0000
@@ -335,7 +335,7 @@
 ;;; History functions
 ;;;
 
-(defun vc-sccs-print-log (files buffer &optional shortlog limit)
+(defun vc-sccs-print-log (files buffer &optional shortlog start-revision-ignored limit)
   "Get change log associated with FILES."
   (setq files (vc-expand-dirs files))
   (vc-sccs-do-command buffer 0 "prs" (mapcar 'vc-name files))
--- a/lisp/vc-svn.el	Mon Dec 07 06:56:40 2009 +0000
+++ b/lisp/vc-svn.el	Mon Dec 07 09:02:11 2009 +0000
@@ -462,7 +462,7 @@
   (require 'add-log)
   (set (make-local-variable 'log-view-per-file-logs) nil))
 
-(defun vc-svn-print-log (files buffer &optional shortlog limit)
+(defun vc-svn-print-log (files buffer &optional shortlog start-revision limit)
   "Get change log(s) associated with FILES."
   (save-current-buffer
     (vc-setup-buffer buffer)
@@ -478,15 +478,22 @@
 		   ;; (if (and (= (length files) 1) (vc-stay-local-p file 'SVN)) 'async 0)
 		   (list file)
 		   "log"
-		   ;; By default Subversion only shows the log up to the
-		   ;; working revision, whereas we also want the log of the
-		   ;; subsequent commits.  At least that's what the
-		   ;; vc-cvs.el code does.
-		   "-rHEAD:0"
-		   (when limit (list "-l" (format "%s" limit)))))
+		   (append
+		    (list
+		     (if start-revision
+			 (format "-r%s" start-revision)
+		       ;; By default Subversion only shows the log up to the
+		       ;; working revision, whereas we also want the log of the
+		       ;; subsequent commits.  At least that's what the
+		       ;; vc-cvs.el code does.
+		       "-rHEAD:0"))
+		    (when limit (list "-l" (format "%s" limit))))))
 	;; Dump log for the entire directory.
-	(apply 'vc-svn-command buffer 0 nil "log" "-rHEAD:0"
-	       (when limit (list "-l" (format "%s" limit))))))))
+	(apply 'vc-svn-command buffer 0 nil "log"
+	       (append
+		(list
+		 (if start-revision (format "-r%s" start-revision) "-rHEAD:0"))
+		(when limit (list "-l" (format "%s" limit)))))))))
 
 (defun vc-svn-diff (files &optional oldvers newvers buffer)
   "Get a difference report using SVN between two revisions of fileset FILES."
--- a/lisp/vc.el	Mon Dec 07 06:56:40 2009 +0000
+++ b/lisp/vc.el	Mon Dec 07 09:02:11 2009 +0000
@@ -333,13 +333,16 @@
 ;;
 ;; HISTORY FUNCTIONS
 ;;
-;; * print-log (files buffer &optional shortlog limit)
+;; * print-log (files buffer &optional shortlog start-revision limit)
 ;;
 ;;   Insert the revision log for FILES into BUFFER.
 ;;   If SHORTLOG is true insert a short version of the log.
 ;;   If LIMIT is true insert only insert LIMIT log entries.  If the
 ;;   backend does not support limiting the number of entries to show
 ;;   it should return `limit-unsupported'.
+;;   If START-REVISION is given, then show the log starting from the
+;;   revision.  At this point START-REVISION is only required to work
+;;   in conjunction with LIMIT = 1.
 ;;
 ;; - log-view-mode ()
 ;;
@@ -1863,7 +1866,7 @@
 (defvar log-view-vc-fileset)
 
 (defun vc-print-log-internal (backend files working-revision
-                                      &optional limit)
+                                      &optional is-start-revision limit)
   ;; Don't switch to the output buffer before running the command,
   ;; so that any buffer-local settings in the vc-controlled
   ;; buffer can be accessed by the command.
@@ -1878,8 +1881,9 @@
 			 (memq 'directory vc-log-short-style)
 		       (memq 'file vc-log-short-style)))))
 
-    (setq pl-return (vc-call-backend backend 'print-log files "*vc-change-log*"
-				     vc-short-log limit))
+    (setq pl-return (vc-call-backend
+		     backend 'print-log files "*vc-change-log*"
+		     vc-short-log (when is-start-revision working-revision) limit))
     (pop-to-buffer "*vc-change-log*")
     (let ((inhibit-read-only t))
       ;; log-view-mode used to be called with inhibit-read-only bound
@@ -1890,19 +1894,20 @@
 
     (vc-exec-after
      `(let ((inhibit-read-only t))
-	(when (and ,limit (not ,(eq 'limit-unsupported pl-return)))
+	(when (and ,limit (not ,(eq 'limit-unsupported pl-return))
+		   (not ,is-start-revision))
 	  (goto-char (point-max))
 	  (widget-create 'push-button
 			 :notify (lambda (&rest ignore)
 				   (vc-print-log-internal
-				    ',backend ',files ',working-revision (* 2 ,limit)))
+				    ',backend ',files ',working-revision nil (* 2 ,limit)))
 			 :help-echo "Show the log again, and double the number of log entries shown"
 			 "Show 2X entries")
 	  (widget-insert "    ")
 	  (widget-create 'push-button
 			 :notify (lambda (&rest ignore)
 				   (vc-print-log-internal
-				    ',backend ',files ',working-revision nil))
+				    ',backend ',files ',working-revision nil nil))
 			 :help-echo "Show the log again, showing all entries"
 			 "Show unlimited entries")
 	  (widget-setup))
@@ -1936,7 +1941,7 @@
 	 (backend (car vc-fileset))
 	 (files (cadr vc-fileset))
 	 (working-revision (or working-revision (vc-working-revision (car files)))))
-    (vc-print-log-internal backend files working-revision limit)))
+    (vc-print-log-internal backend files working-revision nil limit)))
 
 ;;;###autoload
 (defun vc-print-root-log (&optional limit)
@@ -1962,7 +1967,7 @@
       (error "Buffer is not version controlled"))
     (setq rootdir (vc-call-backend backend 'root default-directory))
     (setq working-revision (vc-working-revision rootdir))
-    (vc-print-log-internal backend (list rootdir) working-revision limit)))
+    (vc-print-log-internal backend (list rootdir) working-revision nil limit)))
 
 ;;;###autoload
 (defun vc-revert ()