Commit d1e4c403 authored by Dan Nicolaescu's avatar Dan Nicolaescu

Make vc-annotate work through copies and renames.

* vc-annotate.el (vc-annotate-extract-revision-at-line): Return
the file name too.
(vc-annotate-revision-at-line)
(vc-annotate-find-revision-at-line)
(vc-annotate-revision-previous-to-line)
(vc-annotate-show-log-revision-at-line): Update to get the file
name from vc-annotate-extract-revision-at-line.
(vc-annotate-show-diff-revision-at-line-internal): Change the
argument to mean whether to show a file diff or not.  Get the file
name from vc-annotate-extract-revision-at-line.
(vc-annotate-show-diff-revision-at-line): Update
vc-annotate-show-diff-revision-at-line call.
(vc-annotate-warp-revision): Add an optional file argument.

* vc-git.el (vc-git-annotate-command): Pass -C -C to the blame command.
(vc-git-annotate-extract-revision-at-line): Also return the file
name if found.

* vc-hg.el (vc-hg-annotate-command): Pass --follow to the annotate
command.  Remove unused code.
(vc-hg-annotate-re): Update to match --follow output.
(vc-hg-annotate-extract-revision-at-line): Also return the file
name if found.

* vc.el: Update annotate-extract-revision-at-line documentation.
parent d7306fe6
......@@ -193,6 +193,11 @@ file.
*** FIXME: add info about the new VC functions: vc-root-diff and
vc-root-print-log once they stabilize.
*** vc-annotate supports annotations through file copies and renames,
it displays the old names for the files and it can show logs/diffs for
the corresponding lines. Currently only Git and Mercurial take
advantage of this feature.
*** When a file is not found, VC will not try to check it out of RCS anymore.
*** vc-git changes
......
2009-10-19 Dan Nicolaescu <dann@ics.uci.edu>
Make vc-annotate work through copies and renames.
* vc-annotate.el (vc-annotate-extract-revision-at-line): Return
the file name too.
(vc-annotate-revision-at-line)
(vc-annotate-find-revision-at-line)
(vc-annotate-revision-previous-to-line)
(vc-annotate-show-log-revision-at-line): Update to get the file
name from vc-annotate-extract-revision-at-line.
(vc-annotate-show-diff-revision-at-line-internal): Change the
argument to mean whether to show a file diff or not. Get the file
name from vc-annotate-extract-revision-at-line.
(vc-annotate-show-diff-revision-at-line): Update
vc-annotate-show-diff-revision-at-line call.
(vc-annotate-warp-revision): Add an optional file argument.
* vc-git.el (vc-git-annotate-command): Pass -C -C to the blame command.
(vc-git-annotate-extract-revision-at-line): Also return the file
name if found.
* vc-hg.el (vc-hg-annotate-command): Pass --follow to the annotate
command. Remove unused code.
(vc-hg-annotate-re): Update to match --follow output.
(vc-hg-annotate-extract-revision-at-line): Also return the file
name if found.
* vc.el: Update annotate-extract-revision-at-line documentation.
2009-10-18 Kevin Ryde <user42@zip.com.au>
* ibuffer.el (ibuffer-confirm-operation-on): Correction to error
......
......@@ -430,9 +430,14 @@ revisions after."
(vc-annotate-warp-revision warp-rev)))))
(defun vc-annotate-extract-revision-at-line ()
"Extract the revision number of the current line."
"Extract the revision number of the current line.
Return a cons (REV . FILENAME)."
;; This function must be invoked from a buffer in vc-annotate-mode
(vc-call-backend vc-annotate-backend 'annotate-extract-revision-at-line))
(let ((rev (vc-call-backend vc-annotate-backend
'annotate-extract-revision-at-line)))
(if (or (null rev) (consp rev))
rev
(cons rev vc-annotate-parent-file))))
(defun vc-annotate-revision-at-line ()
"Visit the annotation of the revision identified in the current line."
......@@ -442,9 +447,9 @@ revisions after."
(let ((rev-at-line (vc-annotate-extract-revision-at-line)))
(if (not rev-at-line)
(message "Cannot extract revision number from the current line")
(if (equal rev-at-line vc-annotate-parent-rev)
(if (equal (car rev-at-line) vc-annotate-parent-rev)
(message "Already at revision %s" rev-at-line)
(vc-annotate-warp-revision rev-at-line))))))
(vc-annotate-warp-revision (car rev-at-line) (cdr rev-at-line)))))))
(defun vc-annotate-find-revision-at-line ()
"Visit the revision identified in the current line."
......@@ -454,21 +459,24 @@ revisions after."
(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-revision-other-window rev-at-line)))))
(switch-to-buffer-other-window
(vc-find-revision (cdr rev-at-line) (car rev-at-line)))))))
(defun vc-annotate-revision-previous-to-line ()
"Visit the annotation of the revision before the revision at line."
(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))
(prev-rev nil))
(let* ((rev-at-line (vc-annotate-extract-revision-at-line))
(prev-rev nil)
(rev (car rev-at-line))
(fname (cdr rev-at-line)))
(if (not rev-at-line)
(message "Cannot extract revision number from the current line")
(setq prev-rev
(vc-call-backend vc-annotate-backend 'previous-revision
vc-annotate-parent-file rev-at-line))
(vc-annotate-warp-revision prev-rev)))))
fname rev))
(vc-annotate-warp-revision rev fname)))))
(defun vc-annotate-show-log-revision-at-line ()
"Visit the log of the revision at line."
......@@ -478,33 +486,39 @@ revisions after."
(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 rev-at-line)))))
(vc-print-log-internal
vc-annotate-backend (list (cdr rev-at-line)) (car rev-at-line))))))
(defun vc-annotate-show-diff-revision-at-line-internal (fileset)
(defun vc-annotate-show-diff-revision-at-line-internal (filediff)
(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))
(prev-rev nil))
(let* ((rev-at-line (vc-annotate-extract-revision-at-line))
(prev-rev nil)
(rev (car rev-at-line))
(fname (cdr rev-at-line)))
(if (not rev-at-line)
(message "Cannot extract revision number from the current line")
(setq prev-rev
(vc-call-backend vc-annotate-backend 'previous-revision
vc-annotate-parent-file rev-at-line))
fname rev))
(if (not prev-rev)
(message "Cannot diff from any revision prior to %s" rev-at-line)
(message "Cannot diff from any revision prior to %s" rev)
(save-window-excursion
(vc-diff-internal
nil
;; The value passed here should follow what
;; `vc-deduce-fileset' returns.
(cons vc-annotate-backend (cons fileset nil))
prev-rev rev-at-line))
(list vc-annotate-backend
(if filediff
(list fname)
nil))
prev-rev rev))
(switch-to-buffer "*vc-diff*"))))))
(defun vc-annotate-show-diff-revision-at-line ()
"Visit the diff of the revision at line from its previous revision."
(interactive)
(vc-annotate-show-diff-revision-at-line-internal (list vc-annotate-parent-file)))
(vc-annotate-show-diff-revision-at-line-internal t))
(defun vc-annotate-show-changeset-diff-revision-at-line ()
"Visit the diff of the revision at line from its previous revision for all files in the changeset."
......@@ -513,7 +527,7 @@ revisions after."
(error "The %s backend does not support changeset diffs" vc-annotate-backend))
(vc-annotate-show-diff-revision-at-line-internal nil))
(defun vc-annotate-warp-revision (revspec)
(defun vc-annotate-warp-revision (revspec &optional file)
"Annotate the revision described by REVSPEC.
If REVSPEC is a positive integer, warp that many revisions forward,
......@@ -532,7 +546,7 @@ describes a revision number, so warp to that revision."
(setq newrev vc-annotate-parent-rev)
(while (and (> revspec 0) newrev)
(setq newrev (vc-call-backend vc-annotate-backend 'next-revision
vc-annotate-parent-file newrev))
(or file vc-annotate-parent-file) newrev))
(setq revspec (1- revspec)))
(unless newrev
(message "Cannot increment %d revisions from revision %s"
......@@ -541,7 +555,7 @@ describes a revision number, so warp to that revision."
(setq newrev vc-annotate-parent-rev)
(while (and (< revspec 0) newrev)
(setq newrev (vc-call-backend vc-annotate-backend 'previous-revision
vc-annotate-parent-file newrev))
(or file vc-annotate-parent-file) newrev))
(setq revspec (1+ revspec)))
(unless newrev
(message "Cannot decrement %d revisions from revision %s"
......@@ -549,7 +563,7 @@ describes a revision number, so warp to that revision."
((stringp revspec) (setq newrev revspec))
(t (error "Invalid argument to vc-annotate-warp-revision")))
(when newrev
(vc-annotate vc-annotate-parent-file newrev
(vc-annotate (or file vc-annotate-parent-file) newrev
vc-annotate-parent-display-mode
buf
;; Pass the current line so that vc-annotate will
......
......@@ -610,7 +610,7 @@ or BRANCH^ (where \"^\" can be repeated)."
(defun vc-git-annotate-command (file buf &optional rev)
(let ((name (file-relative-name file)))
(vc-git-command buf 'async name "blame" "--date=iso" rev "--")))
(vc-git-command buf 'async name "blame" "--date=iso" "-C" "-C" rev)))
(declare-function vc-annotate-convert-time "vc-annotate" (time))
......@@ -624,8 +624,11 @@ or BRANCH^ (where \"^\" can be repeated)."
(defun vc-git-annotate-extract-revision-at-line ()
(save-excursion
(move-beginning-of-line 1)
(and (looking-at "[0-9a-f^][0-9a-f]+")
(buffer-substring-no-properties (match-beginning 0) (match-end 0)))))
(when (looking-at "\\([0-9a-f^][0-9a-f]+\\) \\(\\([^(]+\\) \\)?")
(let ((revision (match-string-no-properties 1)))
(if (match-beginning 2)
(cons revision (expand-file-name (match-string-no-properties 3)))
revision)))))
;;; TAG SYSTEM
......
......@@ -313,12 +313,8 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches."
(defun vc-hg-annotate-command (file buffer &optional revision)
"Execute \"hg annotate\" on FILE, inserting the contents in BUFFER.
Optional arg REVISION is a revision to annotate from."
(vc-hg-command buffer 0 file "annotate" "-d" "-n"
(when revision (concat "-r" revision)))
(with-current-buffer buffer
(goto-char (point-min))
(re-search-forward "^[ \t]*[0-9]")
(delete-region (point-min) (match-beginning 0))))
(vc-hg-command buffer 0 file "annotate" "-d" "-n" "--follow"
(when revision (concat "-r" revision))))
(declare-function vc-annotate-convert-time "vc-annotate" (time))
......@@ -329,7 +325,7 @@ Optional arg REVISION is a revision to annotate from."
;;215 Wed Jun 20 21:22:58 2007 -0700 foo.c: CONTENTS
;; i.e. VERSION_NUMBER DATE FILENAME: CONTENTS
(defconst vc-hg-annotate-re
"^[ \t]*\\([0-9]+\\) \\(.\\{30\\}\\)[^:\n]*\\(:[^ \n][^:\n]*\\)*: ")
"^[ \t]*\\([0-9]+\\) \\(.\\{30\\}\\)\\(?:\\(: \\)\\|\\(?: +\\(.+\\): \\)\\)")
(defun vc-hg-annotate-time ()
(when (looking-at vc-hg-annotate-re)
......@@ -340,7 +336,11 @@ Optional arg REVISION is a revision to annotate from."
(defun vc-hg-annotate-extract-revision-at-line ()
(save-excursion
(beginning-of-line)
(when (looking-at vc-hg-annotate-re) (match-string-no-properties 1))))
(when (looking-at vc-hg-annotate-re)
(if (match-beginning 3)
(match-string-no-properties 1)
(cons (match-string-no-properties 1)
(expand-file-name (match-string-no-properties 4)))))))
(defun vc-hg-previous-revision (file rev)
(let ((newrev (1- (string-to-number rev))))
......
......@@ -418,6 +418,9 @@
;; Invoked from a buffer in vc-annotate-mode, return the revision
;; corresponding to the current line, or nil if there is no revision
;; corresponding to the current line.
;; If the backend supports annotating through copies and renames,
;; and displays a file name and a revision, then return a cons
;; (REVISION . FILENAME).
;;
;; TAG SYSTEM
;;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment