emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: make vc-annotate work through copies and renames


From: Dan Nicolaescu
Subject: Re: make vc-annotate work through copies and renames
Date: Fri, 16 Oct 2009 23:18:36 -0700 (PDT)

Stefan Monnier <address@hidden> writes:

  > > vc-annotate.el assumes that the file name is always the same.  This is
  > > not true when showing copies/renames.
  > 
  > This varies a lot between backends.  E.g. IIRC in Svn and Arch, the
  > file-name is basically ignored (replaced by some notion of file identity
  > that is preserved by renaming), so in your example the f.csh file is the
  > only name that would appear and revision "14d0ca93" of that file simply
  > had the name "t.csh" at that time, but you don't need to know about it
  > to get the `annotate' output, or the `diff' output or ...

Arch does not support vc-annotate, so ... 
For Svn nothing should change, it does not display the file names in the
annotate output, and it does not need them, the vc-annotate
functionality does not change in that case.

Here's a complete patch.  It works with copying/renaming for Hg and Git.  
And it continues to work as before for all the other backends.

OK to check in?


Index: vc-annotate.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/vc-annotate.el,v
retrieving revision 1.9
diff -u -3 -p -r1.9 vc-annotate.el
--- vc-annotate.el      11 Sep 2009 10:58:58 -0000      1.9
+++ vc-annotate.el      17 Oct 2009 05:51:41 -0000
@@ -432,7 +432,11 @@ revisions after."
 (defun vc-annotate-extract-revision-at-line ()
   "Extract the revision number of the current line."
   ;; 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 +446,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 +458,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 +485,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 +526,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 +545,7 @@ describes a revision number, so warp to 
        (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 +554,7 @@ describes a revision number, so warp to 
        (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 +562,7 @@ describes a revision number, so warp to 
        ((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
Index: vc-git.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/vc-git.el,v
retrieving revision 1.95
diff -u -3 -p -r1.95 vc-git.el
--- vc-git.el   14 Oct 2009 06:28:03 -0000      1.95
+++ vc-git.el   17 Oct 2009 05:51:41 -0000
@@ -610,7 +620,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 +634,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
 
Index: vc-hg.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/vc-hg.el,v
retrieving revision 1.103
diff -u -3 -p -r1.103 vc-hg.el
--- vc-hg.el    5 Oct 2009 15:12:32 -0000       1.103
+++ vc-hg.el    17 Oct 2009 05:51:41 -0000
@@ -313,12 +317,15 @@ If nil, use the value of `vc-diff-switch
 (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"
+  (vc-hg-command buffer 0 file "annotate" "-d" "-n" "--follow"
                  (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))))
+    ;; This stuff does not seem to do anything.
+    ;; (goto-char (point-min))
+    ;; (re-search-forward "^[ \t]*[0-9]")
+    ;; (delete-region (point-min) (match-beginning 0))
+    )
+  )
 
 (declare-function vc-annotate-convert-time "vc-annotate" (time))
 
@@ -329,7 +337,7 @@ Optional arg REVISION is a revision to a
 ;;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 +348,11 @@ Optional arg REVISION is a revision to a
 (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))))
Index: vc.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/vc.el,v
retrieving revision 1.734
diff -u -3 -p -r1.734 vc.el
--- vc.el       14 Oct 2009 06:08:53 -0000      1.734
+++ vc.el       17 Oct 2009 05:51:42 -0000
@@ -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
 ;;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]