From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Dan Nicolaescu Newsgroups: gmane.emacs.devel Subject: Re: VC top of the tree diff and log Date: Sat, 29 Aug 2009 12:13:09 -0700 (PDT) Message-ID: <200908291913.n7TJD9wq003979@godzilla.ics.uci.edu> References: <200907071845.n67IjHUH004088@godzilla.ics.uci.edu> <200907230543.n6N5hI6p029191@godzilla.ics.uci.edu> <200907300718.n6U7I3pi027881@godzilla.ics.uci.edu> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1251573313 373 80.91.229.12 (29 Aug 2009 19:15:13 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 29 Aug 2009 19:15:13 +0000 (UTC) Cc: emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Aug 29 21:15:05 2009 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1MhTOA-0003En-K4 for ged-emacs-devel@m.gmane.org; Sat, 29 Aug 2009 21:15:04 +0200 Original-Received: from localhost ([127.0.0.1]:57288 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MhTO9-00011k-RG for ged-emacs-devel@m.gmane.org; Sat, 29 Aug 2009 15:15:01 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MhTO3-00011Q-PJ for emacs-devel@gnu.org; Sat, 29 Aug 2009 15:14:55 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MhTNy-00010Q-Eb for emacs-devel@gnu.org; Sat, 29 Aug 2009 15:14:55 -0400 Original-Received: from [199.232.76.173] (port=41320 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MhTNy-00010N-7z for emacs-devel@gnu.org; Sat, 29 Aug 2009 15:14:50 -0400 Original-Received: from sallyv2.ics.uci.edu ([128.195.1.120]:43721) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_3DES_EDE_CBC_SHA1:24) (Exim 4.60) (envelope-from ) id 1MhTNx-00066d-Nb for emacs-devel@gnu.org; Sat, 29 Aug 2009 15:14:50 -0400 Original-Received: from godzilla.ics.uci.edu (godzilla.ics.uci.edu [128.195.10.101]) by sallyv2.ics.uci.edu (8.13.8+Sun/8.13.8) with ESMTP id n7TJD9hL014146; Sat, 29 Aug 2009 12:13:09 -0700 (PDT) Original-Received: (from dann@localhost) by godzilla.ics.uci.edu (8.13.8+Sun/8.13.6/Submit) id n7TJD9wq003979; Sat, 29 Aug 2009 12:13:09 -0700 (PDT) In-Reply-To: <200907300718.n6U7I3pi027881@godzilla.ics.uci.edu> (Dan Nicolaescu's message of "Thu, 30 Jul 2009 00:18:03 -0700 (PDT)") Original-Lines: 368 X-ICS-MailScanner-Information: Please contact the ISP for more information X-ICS-MailScanner-ID: n7TJD9hL014146 X-ICS-MailScanner: Found to be clean X-ICS-MailScanner-SpamCheck: not spam, SpamAssassin (score=-0.34, required 5, autolearn=disabled, ALL_TRUSTED -1.44, FM_MULTI_ODD2 1.10) X-ICS-MailScanner-From: dann@godzilla.ics.uci.edu X-detected-operating-system: by monty-python.gnu.org: Solaris 10 (beta) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:114844 Archived-At: Dan Nicolaescu writes: > Dan Nicolaescu writes: > > > Stefan Monnier writes: > > > > > > Key bindings: > > > > for log we could have C-x v L (should be intuitive given that > > > > vc-print-log uses C-x v l) > > > > > > It might be a good idea. > > > > > > > not sure what would be a good one for diff > > > > > > I don't understand: why not just use the capitalized = sign? > > > > Sorry, I probably use one of those antique keyboards that don't have > > such a sign... > > > > See what I currently have. What do you think? > > Here's an updated version that implements both top of the tree log and > diff and adds an option to show short logs. > As it is now it short logs will be shown when a directory is present in > the fileset. Adding `file' to `vc-log-short-style' will make C-x v l > show short logs for files too. > > vc-git.el was changed to support short logs, and vc-cvs.el to ignore the > extra option (all vc backends need a similar change) > > WDYT? Ping. Any reason not to install this? > Index: vc-cvs.el > =================================================================== > RCS file: /cvsroot/emacs/emacs/lisp/vc-cvs.el,v > retrieving revision 1.165 > diff -u -3 -p -r1.165 vc-cvs.el > --- vc-cvs.el 7 Jul 2009 15:06:03 -0000 1.165 > +++ vc-cvs.el 30 Jul 2009 06:57:41 -0000 > @@ -492,7 +492,7 @@ Will fail unless you have administrative > ;;; History functions > ;;; > > -(defun vc-cvs-print-log (files &optional buffer) > +(defun vc-cvs-print-log (files &optional buffer shortlog) > "Get change logs associated with FILES." > ;; It's just the catenation of the individual logs. > (vc-cvs-command > Index: vc-git.el > =================================================================== > RCS file: /cvsroot/emacs/emacs/lisp/vc-git.el,v > retrieving revision 1.85 > diff -u -3 -p -r1.85 vc-git.el > --- vc-git.el 28 Jul 2009 08:06:40 -0000 1.85 > +++ vc-git.el 30 Jul 2009 06:57:41 -0000 > @@ -77,7 +77,7 @@ > ;; - merge-news (file) see `merge' > ;; - 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) OK > ;; - comment-history (file) ?? > @@ -460,7 +460,7 @@ If nil, use the value of `vc-diff-switch > > ;;; 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 > @@ -474,43 +474,59 @@ If nil, use the value of `vc-diff-switch > (let ((inhibit-read-only t)) > (with-current-buffer > buffer > - (vc-git-command buffer 'async files > - "rev-list" "--pretty" "HEAD" "--"))))) > + (if shortlog > + (vc-git-command buffer 'async files > + "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) > - (append > - `((,log-view-message-re (1 'change-log-acknowledgement))) > - ;; Handle the case: > - ;; user: foo@bar > - '(("^Author:[ \t]+\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)" > - (1 'change-log-email)) > - ;; Handle the case: > - ;; user: FirstName LastName > - ("^Author:[ \t]+\\([^<(]+?\\)[ \t]*[(<]\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)[>)]" > - (1 'change-log-name) > - (2 'change-log-email)) > - ("^ +\\(?:\\(?:[Aa]cked\\|[Ss]igned-[Oo]ff\\)-[Bb]y:\\)[ \t]+\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)" > - (1 'change-log-name)) > - ("^ +\\(?:\\(?:[Aa]cked\\|[Ss]igned-[Oo]ff\\)-[Bb]y:\\)[ \t]+\\([^<(]+?\\)[ \t]*[(<]\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)[>)]" > - (1 'change-log-name) > - (2 'change-log-email)) > - ("^Merge: \\([0-9a-z]+\\) \\([0-9a-z]+\\)" > - (1 'change-log-acknowledgement) > - (2 'change-log-acknowledgement)) > - ("^Date: \\(.+\\)" (1 'change-log-date)) > - ("^summary:[ \t]+\\(.+\\)" (1 'log-view-message)))))) > + (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: > + ;; user: foo@bar > + '((" Author:[ \t]+\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)" > + (1 'change-log-email)) > + ;; Handle the case: > + ;; user: FirstName LastName > + (" Author:[ \t]+\\([^<(]+?\\)[ \t]*[(<]\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)[>)]" > + (1 'change-log-name) > + (2 'change-log-email)) > + ("^ +\\(?:\\(?:[Aa]cked\\|[Ss]igned-[Oo]ff\\)-[Bb]y:\\)[ \t]+\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)" > + (1 'change-log-name)) > + ("^ +\\(?:\\(?:[Aa]cked\\|[Ss]igned-[Oo]ff\\)-[Bb]y:\\)[ \t]+\\([^<(]+?\\)[ \t]*[(<]\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)[>)]" > + (1 'change-log-name) > + (2 'change-log-email)) > + (" Merge: \\([0-9a-z]+\\) \\([0-9a-z]+\\)" > + (1 'change-log-acknowledgement) > + (2 'change-log-acknowledgement)) > + (" Date: \\(.+\\)" (1 'change-log-date)) > + (" summary:[ \t]+\\(.+\\)" (1 'log-view-message))))))) > + > > (defun vc-git-show-log-entry (revision) > "Move to the log entry for REVISION. > Index: vc-hooks.el > =================================================================== > RCS file: /cvsroot/emacs/emacs/lisp/vc-hooks.el,v > retrieving revision 1.279 > diff -u -3 -p -r1.279 vc-hooks.el > --- vc-hooks.el 26 Jun 2009 23:54:00 -0000 1.279 > +++ vc-hooks.el 30 Jul 2009 06:57:41 -0000 > @@ -934,6 +934,7 @@ current, and kill the buffer that visits > (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) > @@ -941,6 +942,7 @@ current, and kill the buffer that visits > (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) > @@ -969,12 +971,18 @@ current, and kill the buffer that visits > (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 > Index: vc.el > =================================================================== > RCS file: /cvsroot/emacs/emacs/lisp/vc.el,v > retrieving revision 1.722 > diff -u -3 -p -r1.722 vc.el > --- vc.el 23 Jul 2009 05:41:28 -0000 1.722 > +++ vc.el 30 Jul 2009 06:57:41 -0000 > @@ -350,11 +350,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 () > ;; > @@ -465,6 +466,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 > @@ -1594,6 +1598,33 @@ saving the buffer." > (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~'. > @@ -1817,34 +1848,54 @@ allowed and simply skipped)." > > ;; 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) > - > - ;; FIXME: this seems to apply only to RCS/CVS, it doesn't quite > - ;; belong here in the generic code. > - (goto-char (point-max)) > - (forward-line -1) > - (while (looking-at "=*\n") > - (delete-char (- (match-end 0) (match-beginning 0))) > - (forward-line -1)) > - (goto-char (point-min)) > - (when (looking-at "[\b\t\n\v\f\r ]+") > - (delete-char (- (match-end 0) (match-beginning 0)))) > - > - (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)))) > + (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) > + > + ;; FIXME: this seems to apply only to RCS/CVS, it doesn't quite > + ;; belong here in the generic code. > + (goto-char (point-max)) > + (forward-line -1) > + (while (looking-at "=*\n") > + (delete-char (- (match-end 0) (match-beginning 0))) > + (forward-line -1)) > + (goto-char (point-min)) > + (when (looking-at "[\b\t\n\v\f\r ]+") > + (delete-char (- (match-end 0) (match-beginning 0)))) > + > + (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) > @@ -1858,6 +1909,20 @@ If WORKING-REVISION is non-nil, leave th > (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