changeset 105010:b3c2589ed19e

* vc.el (top): print-log method now takes an optional SHORTLOG argument. Add a new method: root. * vc-hooks.el (vc-prefix-map, vc-menu-map): Add bindings for vc-print-root-log and vc-print-root-diff. * vc-bzr.el (vc-bzr-log-view-mode, vc-bzr-print-log): * vc-git.el (vc-git-print-log, vc-git-log-view-mode): * vc-hg.el (vc-hg-print-log, vc-hg-log-view-mode): Add support for short logs. * vc-cvs.el (vc-cvs-print-log): * vc-mtn.el (vc-mtn-print-log): * vc-rcs.el (vc-rcs-print-log): * vc-sccs.el (vc-sccs-print-log): * vc-svn.el (vc-svn-print-log): Add an optional argument shortlog that is ignored for now.
author Dan Nicolaescu <dann@ics.uci.edu>
date Mon, 14 Sep 2009 04:38:49 +0000
parents b520d55cdd72
children 8acc6fb9ffc9
files etc/NEWS lisp/ChangeLog lisp/vc-bzr.el lisp/vc-cvs.el lisp/vc-git.el lisp/vc-hg.el lisp/vc-hooks.el lisp/vc-mtn.el lisp/vc-rcs.el lisp/vc-sccs.el lisp/vc-svn.el lisp/vc.el
diffstat 12 files changed, 176 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS	Mon Sep 14 01:22:42 2009 +0000
+++ b/etc/NEWS	Mon Sep 14 04:38:49 2009 +0000
@@ -155,6 +155,9 @@
 
 ** VC and related modes
 
+*** FIXME: add info about the new VC functions: vc-root-diff and
+vc-root-print-log once they stabilize.
+
 *** When a file is not found, VC will not try to check it out of RCS anymore.
 
 *** vc-git changes
--- a/lisp/ChangeLog	Mon Sep 14 01:22:42 2009 +0000
+++ b/lisp/ChangeLog	Mon Sep 14 04:38:49 2009 +0000
@@ -1,3 +1,27 @@
+2009-09-14  Dan Nicolaescu  <dann@ics.uci.edu>
+
+	* vc.el (top): print-log method now takes an optional SHORTLOG
+	argument.  Add a new method: root.
+
+	(vc-root-diff, vc-print-root-log): New functions.
+	(vc-log-short-style): New variable.
+	(vc-print-log-internal): Add support for showing short logs.
+
+	* vc-hooks.el (vc-prefix-map, vc-menu-map): Add bindings for
+	vc-print-root-log and vc-print-root-diff.
+
+	* vc-bzr.el (vc-bzr-log-view-mode, vc-bzr-print-log):
+	* vc-git.el (vc-git-print-log, vc-git-log-view-mode):
+	* vc-hg.el (vc-hg-print-log, vc-hg-log-view-mode): Add support for
+	short logs.
+
+	* vc-cvs.el (vc-cvs-print-log):
+	* vc-mtn.el (vc-mtn-print-log):
+	* vc-rcs.el (vc-rcs-print-log):
+	* vc-sccs.el (vc-sccs-print-log):
+	* vc-svn.el (vc-svn-print-log): Add an optional argument shortlog
+	that is ignored for now.
+
 2009-09-14  Stefan Monnier  <monnier@iro.umontreal.ca>
 
 	* simple.el: Add mapping for backspace/delete/clear/tab/escape/return
--- a/lisp/vc-bzr.el	Mon Sep 14 01:22:42 2009 +0000
+++ b/lisp/vc-bzr.el	Mon Sep 14 04:38:49 2009 +0000
@@ -453,6 +453,7 @@
 (defvar log-view-font-lock-keywords)
 (defvar log-view-current-tag-function)
 (defvar log-view-per-file-logs)
+(defvar vc-short-log)
 
 (define-derived-mode vc-bzr-log-view-mode log-view-mode "Bzr-Log-View"
   (remove-hook 'log-view-mode-hook 'vc-bzr-log-view-mode) ;Deactivate the hack.
@@ -460,19 +461,27 @@
   (set (make-local-variable 'log-view-per-file-logs) nil)
   (set (make-local-variable 'log-view-file-re) "\\`a\\`")
   (set (make-local-variable 'log-view-message-re)
-       "^ *\\(?:revno: \\([0-9.]+\\)\\|merged: .+\\)")
+       (if vc-short-log
+	   "^ +\\([0-9]+\\) \\(.*?\\)[ \t]+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\)\\( \\[merge\\]\\)?"
+	 "^ *\\(?:revno: \\([0-9.]+\\)\\|merged: .+\\)"))
   (set (make-local-variable 'log-view-font-lock-keywords)
        ;; log-view-font-lock-keywords is careful to use the buffer-local
        ;; value of log-view-message-re only since Emacs-23.
-       (append `((,log-view-message-re . 'log-view-message-face))
-               ;; log-view-font-lock-keywords
-               '(("^ *committer: \
+       (if vc-short-log
+	 (append `((,log-view-message-re
+		    (1 'log-view-message-face)
+		    (2 'change-log-name)
+		    (3 'change-log-date)
+		    (4 'change-log-list))))
+	 (append `((,log-view-message-re . 'log-view-message-face))
+		 ;; log-view-font-lock-keywords
+		 '(("^ *committer: \
 \\([^<(]+?\\)[  ]*[(<]\\([[:alnum:]_.+-]+@[[:alnum:]_.-]+\\)[>)]"
-                  (1 'change-log-name)
-                  (2 'change-log-email))
-                 ("^ *timestamp: \\(.*\\)" (1 'change-log-date-face))))))
+		    (1 'change-log-name)
+		    (2 'change-log-email))
+		   ("^ *timestamp: \\(.*\\)" (1 'change-log-date-face)))))))
 
-(defun vc-bzr-print-log (files &optional buffer) ; get buffer arg in Emacs 22
+(defun vc-bzr-print-log (files &optional buffer shortlog) ; get buffer arg in Emacs 22
   "Get bzr change log for FILES into specified BUFFER."
   ;; `vc-do-command' creates the buffer, but we need it before running
   ;; the command.
@@ -484,6 +493,7 @@
   ;; way of getting the above regexps working.
   (with-current-buffer buffer
     (apply 'vc-bzr-command "log" buffer 'async files
+	   (if shortlog "--short")
 	   (if (stringp vc-bzr-log-switches)
 	       (list vc-bzr-log-switches)
 	     vc-bzr-log-switches))))
--- a/lisp/vc-cvs.el	Mon Sep 14 01:22:42 2009 +0000
+++ b/lisp/vc-cvs.el	Mon Sep 14 04:38:49 2009 +0000
@@ -496,7 +496,7 @@
 
 (declare-function vc-rcs-print-log-cleanup "vc-rcs" ())
 
-(defun vc-cvs-print-log (files &optional buffer)
+(defun vc-cvs-print-log (files &optional buffer shortlog)
   "Get change logs associated with FILES."
   (require 'vc-rcs)
   ;; It's just the catenation of the individual logs.
--- a/lisp/vc-git.el	Mon Sep 14 01:22:42 2009 +0000
+++ b/lisp/vc-git.el	Mon Sep 14 04:38:49 2009 +0000
@@ -471,7 +471,7 @@
 
 ;;; HISTORY FUNCTIONS
 
-(defun vc-git-print-log (files &optional buffer)
+(defun vc-git-print-log (files &optional buffer shortlog)
   "Get change log associated with FILES."
   (let ((coding-system-for-read git-commits-coding-system)
 	;; Support both the old print-log interface that passes a
@@ -485,22 +485,38 @@
     (let ((inhibit-read-only t))
       (with-current-buffer
           buffer
+	(if shortlog
 	(vc-git-command buffer 'async files
-			"rev-list" "--pretty" "HEAD" "--")))))
+			    "log" ;; "--graph"
+			    "--date=short" "--pretty=format:%h  %ad  %s" "--abbrev-commit"
+			    "--")
+	  (vc-git-command buffer 'async files
+			  "rev-list" ;; "--graph"
+			  "--pretty" "HEAD" "--"))))))
 
 (defvar log-view-message-re)
 (defvar log-view-file-re)
 (defvar log-view-font-lock-keywords)
 (defvar log-view-per-file-logs)
 
+;; Dynamically bound.
+(defvar vc-short-log)
+
 (define-derived-mode vc-git-log-view-mode log-view-mode "Git-Log-View"
   (require 'add-log) ;; we need the faces add-log
   ;; Don't have file markers, so use impossible regexp.
   (set (make-local-variable 'log-view-file-re) "\\`a\\`")
   (set (make-local-variable 'log-view-per-file-logs) nil)
   (set (make-local-variable 'log-view-message-re)
-       "^commit *\\([0-9a-z]+\\)")
+       (if vc-short-log
+	 "^\\(?:[*/\\| ]+ \\)?\\([0-9a-z]+\\)  \\([-a-z0-9]+\\)  \\(.*\\)"
+	 "^[ */\\|]+commit *\\([0-9a-z]+\\)"))
   (set (make-local-variable 'log-view-font-lock-keywords)
+       (if vc-short-log
+	   (append
+	    `((,log-view-message-re
+	       (1 'change-log-acknowledgement)
+	       (2 'change-log-date))))
        (append
         `((,log-view-message-re  (1 'change-log-acknowledgement)))
         ;; Handle the case:
@@ -521,7 +537,8 @@
            (1 'change-log-acknowledgement)
            (2 'change-log-acknowledgement))
           ("^Date:   \\(.+\\)" (1 'change-log-date))
-          ("^summary:[ \t]+\\(.+\\)" (1 'log-view-message))))))
+	    ("^summary:[ \t]+\\(.+\\)" (1 'log-view-message)))))))
+
 
 (defun vc-git-show-log-entry (revision)
   "Move to the log entry for REVISION.
@@ -678,6 +695,9 @@
 
 (defun vc-git-extra-status-menu () vc-git-extra-menu-map)
 
+(defun vc-git-root (file)
+  (vc-find-root file ".git"))
+
 (defun vc-git-toggle-signoff ()
   (interactive)
   (setq vc-git-add-signoff (not vc-git-add-signoff)))
@@ -763,9 +783,6 @@
 
 ;;; Internal commands
 
-(defun vc-git-root (file)
-  (vc-find-root file ".git"))
-
 (defun vc-git-command (buffer okstatus file-or-list &rest flags)
   "A wrapper around `vc-do-command' for use in vc-git.el.
 The difference to vc-do-command is that this function always invokes `git'."
--- a/lisp/vc-hg.el	Mon Sep 14 01:22:42 2009 +0000
+++ b/lisp/vc-hg.el	Mon Sep 14 04:38:49 2009 +0000
@@ -68,7 +68,7 @@
 ;; - merge-news (file)                         NEEDED
 ;; - steal-lock (file &optional revision)      NOT NEEDED
 ;; HISTORY FUNCTIONS
-;; * print-log (files &optional buffer)        OK
+;; * print-log (files &optional buffer shortlog)OK
 ;; - log-view-mode ()                          OK
 ;; - show-log-entry (revision)                 NOT NEEDED, DEFAULT IS GOOD
 ;; - comment-history (file)                    NOT NEEDED
@@ -217,7 +217,7 @@
                  (repeat :tag "Argument List" :value ("") string))
   :group 'vc-hg)
 
-(defun vc-hg-print-log (files &optional buffer)
+(defun vc-hg-print-log (files &optional buffer shortlog)
   "Get change log associated with FILES."
   ;; `log-view-mode' needs to have the file names in order to function
   ;; correctly. "hg log" does not print it, so we insert it here by
@@ -231,20 +231,31 @@
   (let ((inhibit-read-only t))
     (with-current-buffer
 	buffer
-      (apply 'vc-hg-command buffer 0 files "log" vc-hg-log-switches))))
+      (apply 'vc-hg-command buffer 0 files "log"
+	     (if shortlog '("--style" "compact"))
+	     vc-hg-log-switches))))
 
 (defvar log-view-message-re)
 (defvar log-view-file-re)
 (defvar log-view-font-lock-keywords)
 (defvar log-view-per-file-logs)
+(defvar vc-short-log)
 
 (define-derived-mode vc-hg-log-view-mode log-view-mode "Hg-Log-View"
   (require 'add-log) ;; we need the add-log faces
   (set (make-local-variable 'log-view-file-re) "\\`a\\`")
   (set (make-local-variable 'log-view-per-file-logs) nil)
   (set (make-local-variable 'log-view-message-re)
-       "^changeset:[ \t]*\\([0-9]+\\):\\(.+\\)")
+       (if vc-short-log
+	   "^\\([0-9]+\\)\\(?:\\[.*\\]\\)? +\\([0-9a-z]\\{12\\}\\) +\\(\\(?:[0-9]+\\)-\\(?:[0-9]+\\)-\\(?:[0-9]+\\) \\(?:[0-9]+\\):\\(?:[0-9]+\\) \\(?:[-+0-9]+\\)\\) +\\(.*\\)$"
+	 "^changeset:[ \t]*\\([0-9]+\\):\\(.+\\)"))
   (set (make-local-variable 'log-view-font-lock-keywords)
+       (if vc-short-log
+	   (append `((,log-view-message-re
+		      (1 'log-view-message-face)
+		      (2 'log-view-message-face)
+		      (3 'change-log-date)
+		      (4 'change-log-name))))
        (append
 	log-view-font-lock-keywords
 	'(
@@ -260,7 +271,7 @@
 	  ("^user:[ \t]+\\([A-Za-z0-9_.+-]+\\(?:@[A-Za-z0-9_.-]+\\)?\\)"
 	   (1 'change-log-email))
 	  ("^date: \\(.+\\)" (1 'change-log-date))
-	  ("^summary:[ \t]+\\(.+\\)" (1 'log-view-message))))))
+	    ("^summary:[ \t]+\\(.+\\)" (1 'log-view-message)))))))
 
 (defun vc-hg-diff (files &optional oldvers newvers buffer)
   "Get a difference report using hg between two revisions of FILES."
--- a/lisp/vc-hooks.el	Mon Sep 14 01:22:42 2009 +0000
+++ b/lisp/vc-hooks.el	Mon Sep 14 04:38:49 2009 +0000
@@ -938,6 +938,7 @@
     (define-key map "h" 'vc-insert-headers)
     (define-key map "i" 'vc-register)
     (define-key map "l" 'vc-print-log)
+    (define-key map "L" 'vc-print-root-log)
     (define-key map "m" 'vc-merge)
     (define-key map "r" 'vc-retrieve-tag)
     (define-key map "s" 'vc-create-tag)
@@ -945,6 +946,7 @@
     (define-key map "v" 'vc-next-action)
     (define-key map "+" 'vc-update)
     (define-key map "=" 'vc-diff)
+    (define-key map "D" 'vc-root-diff)
     (define-key map "~" 'vc-revision-other-window)
     map))
 (fset 'vc-prefix-map vc-prefix-map)
@@ -973,12 +975,18 @@
     (define-key map [vc-diff]
       '(menu-item "Compare with Base Version" vc-diff
 		  :help "Compare file set with the base version"))
+    (define-key map [vc-root-diff]
+      '(menu-item "Compare Tree with Base Version" vc-root-diff
+		  :help "Compare current tree with the base version"))
     (define-key map [vc-update-change-log]
       '(menu-item "Update ChangeLog" vc-update-change-log
 		  :help "Find change log file and add entries from recent version control logs"))
     (define-key map [vc-print-log]
       '(menu-item "Show History" vc-print-log
 		  :help "List the change log of the current file set in a window"))
+    (define-key map [vc-print-root-log]
+      '(menu-item "Show Top of the Tree History " vc-print-root-log
+		  :help "List the change log for the current tree in a window"))
     (define-key map [separator2] '("----"))
     (define-key map [vc-insert-header]
       '(menu-item "Insert Header" vc-insert-headers
--- a/lisp/vc-mtn.el	Mon Sep 14 01:22:42 2009 +0000
+++ b/lisp/vc-mtn.el	Mon Sep 14 04:38:49 2009 +0000
@@ -188,7 +188,7 @@
 ;; (defun vc-mtn-roolback (files)
 ;;   )
 
-(defun vc-mtn-print-log (files &optional buffer)
+(defun vc-mtn-print-log (files &optional buffer shortlog)
   (vc-mtn-command buffer 0 files "log"))
 
 (defvar log-view-message-re)
--- a/lisp/vc-rcs.el	Mon Sep 14 01:22:42 2009 +0000
+++ b/lisp/vc-rcs.el	Mon Sep 14 04:38:49 2009 +0000
@@ -549,7 +549,7 @@
     (when (looking-at "[\b\t\n\v\f\r ]+")
       (delete-char (- (match-end 0) (match-beginning 0))))))
 
-(defun vc-rcs-print-log (files &optional buffer)
+(defun vc-rcs-print-log (files &optional buffer shortlog)
   "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 Sep 14 01:22:42 2009 +0000
+++ b/lisp/vc-sccs.el	Mon Sep 14 04:38:49 2009 +0000
@@ -331,7 +331,7 @@
 ;;; History functions
 ;;;
 
-(defun vc-sccs-print-log (files &optional buffer)
+(defun vc-sccs-print-log (files &optional buffer shortlog)
   "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 Sep 14 01:22:42 2009 +0000
+++ b/lisp/vc-svn.el	Mon Sep 14 04:38:49 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 &optional buffer)
+(defun vc-svn-print-log (files &optional buffer shortlog)
   "Get change log(s) associated with FILES."
   (save-current-buffer
     (vc-setup-buffer buffer)
--- a/lisp/vc.el	Mon Sep 14 01:22:42 2009 +0000
+++ b/lisp/vc.el	Mon Sep 14 04:38:49 2009 +0000
@@ -346,11 +346,12 @@
 ;;
 ;; HISTORY FUNCTIONS
 ;;
-;; * print-log (files &optional buffer)
+;; * print-log (files &optional buffer shortlog)
 ;;
 ;;   Insert the revision log for FILES into BUFFER, or the *vc* buffer
 ;;   if BUFFER is nil.  (Note: older versions of this function expected
 ;;   only a single file argument.)
+;;   If SHORTLOG is true insert a short version of the log.
 ;;
 ;; - log-view-mode ()
 ;;
@@ -461,6 +462,9 @@
 ;;   `revert' operations itself, without calling the backend system.  The
 ;;   default implementation always returns nil.
 ;;
+;; - root (file)
+;;   Return the root of the VC controlled hierarchy for file.
+;;
 ;; - repository-hostname (dirname)
 ;;
 ;;   Return the hostname that the backend will have to contact
@@ -1597,6 +1601,33 @@
     (vc-diff-internal t (vc-deduce-fileset) nil nil (interactive-p))))
 
 ;;;###autoload
+(defun vc-root-diff (historic &optional not-urgent)
+  "Display diffs between file revisions.
+Normally this compares the currently selected fileset with their
+working revisions.  With a prefix argument HISTORIC, it reads two revision
+designators specifying which revisions to compare.
+
+The optional argument NOT-URGENT non-nil means it is ok to say no to
+saving the buffer."
+  (interactive (list current-prefix-arg t))
+  (if historic
+      ;; FIXME: this does not work right, `vc-version-diff' ends up
+      ;; calling `vc-deduce-fileset' to find the files to diff, and
+      ;; that's not what we want here, we want the diff for the VC root dir.
+      (call-interactively 'vc-version-diff)
+    (when buffer-file-name (vc-buffer-sync not-urgent))
+    (let ((backend
+	   (cond ((derived-mode-p 'vc-dir-mode)  vc-dir-backend)
+		 (vc-mode (vc-backend buffer-file-name))))
+	  rootdir working-revision)
+      (unless backend
+	(error "Buffer is not version controlled"))
+      (setq rootdir (vc-call-backend backend 'root default-directory))
+      (setq working-revision (vc-working-revision rootdir))
+      (vc-diff-internal
+       t (list backend (list rootdir) working-revision) nil nil (interactive-p)))))
+
+;;;###autoload
 (defun vc-revision-other-window (rev)
   "Visit revision REV of the current file in another window.
 If the current file is named `F', the revision is named `F.~REV~'.
@@ -1822,23 +1853,43 @@
 
 ;; Miscellaneous other entry points
 
+;; FIXME: this should be a defcustom
+;; FIXME: maybe add another choice:
+;; `root-directory' (or somesuch), which would mean show a short log
+;; for the root directory.
+(defvar vc-log-short-style '(directory)
+  "Whether or not to show a short log.
+If it contains `directory' then if the fileset contains a directory show a short log.
+If it contains `file' then show short logs for files.
+Not all VC backends support short logs!")
+
 (defun vc-print-log-internal (backend files working-revision)
   ;; 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.
-  (vc-call-backend backend 'print-log files "*vc-change-log*")
-  (pop-to-buffer "*vc-change-log*")
-  (vc-exec-after
-   `(let ((inhibit-read-only t))
-      (vc-call-backend ',backend 'log-view-mode)
-      (set (make-local-variable 'log-view-vc-backend) ',backend)
-      (set (make-local-variable 'log-view-vc-fileset) ',files)
+  (let ((dir-present nil)
+	(vc-short-log nil))
+    (dolist (file files)
+      (when (file-directory-p file)
+	(setq dir-present t)))
+    (setq vc-short-log
+	  (not (null (if dir-present
+			 (memq 'directory vc-log-short-style)
+		       (memq 'file vc-log-short-style)))))
+    (vc-call-backend backend 'print-log files "*vc-change-log*" vc-short-log)
+    (pop-to-buffer "*vc-change-log*")
+    (vc-exec-after
+     `(let ((inhibit-read-only t)
+	    (vc-short-log ,vc-short-log))
+	(vc-call-backend ',backend 'log-view-mode)
+	(set (make-local-variable 'log-view-vc-backend) ',backend)
+	(set (make-local-variable 'log-view-vc-fileset) ',files)
 
-      (shrink-window-if-larger-than-buffer)
-      ;; move point to the log entry for the working revision
-      (vc-call-backend ',backend 'show-log-entry ',working-revision)
-      (setq vc-sentinel-movepoint (point))
-      (set-buffer-modified-p nil))))
+	(shrink-window-if-larger-than-buffer)
+	;; move point to the log entry for the working revision
+	(vc-call-backend ',backend 'show-log-entry ',working-revision)
+	(setq vc-sentinel-movepoint (point))
+	(set-buffer-modified-p nil)))))
 
 ;;;###autoload
 (defun vc-print-log (&optional working-revision)
@@ -1852,6 +1903,20 @@
     (vc-print-log-internal backend files working-revision)))
 
 ;;;###autoload
+(defun vc-print-root-log ()
+  "List the change log of for the current VC controlled tree in a window."
+  (interactive)
+  (let ((backend
+	 (cond ((derived-mode-p 'vc-dir-mode)  vc-dir-backend)
+	       (vc-mode (vc-backend buffer-file-name))))
+	rootdir working-revision)
+    (unless backend
+      (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)))
+
+;;;###autoload
 (defun vc-revert ()
   "Revert working copies of the selected fileset to their repository contents.
 This asks for confirmation if the buffer contents are not identical