# [RFC PATCH] Implement vc-git-annotate-show-diff-revision-at-line for emacs vc-git

5 messages from 2008-02-22 to 2008-02-23. Participants: Alex Bennee, Alexandre Julliard, Junio C Hamano.
Thread: https://gitlist.dev/t/12262

## Alex Bennee, 2008-02-22 18:58

Subject: [RFC PATCH] Implement vc-git-annotate-show-diff-revision-at-line for emacs vc-git
Message-ID: <1203706693.7552.56.camel@alexjb-desktop.transitives.com>
URL: https://gitlist.dev/e/1203706693.7552.56.camel%40alexjb-desktop.transitives.com

```
Hi,

I've had an initial stab at doing this for jumping to the commit in
annotate mode. You can manually call it with M-x
vc-git-annotate-show-diff-revision-at-line and it all works fine.
However the vc logic wants vc-git-previous-version to exist before it
will call it directly from the mode. I considered evil key-rebinding
hacks but that seems to nasty.

Whats the easiest command to show the parent commit of a given commit id
(the closest analogy I can think of)? I tried:

 git-show 486a974a --pretty="format:%P"

But that shows the whole commit as well. Anyway here is the current form
of the patch. As you can probably tell elisp is not my first language:

>From 84ef7155339b60c21851eab72842cb5c4e8b3d47 Mon Sep 17 00:00:00 2001
From: Alex Bennee <alex@bennee.com>
Date: Fri, 22 Feb 2008 18:51:43 +0000
Subject: [PATCH] Attempt to implement annotate-jump-to-diff for vc-git.el

---
 contrib/emacs/vc-git.el |   46 ++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/contrib/emacs/vc-git.el b/contrib/emacs/vc-git.el
index b8f6be5..67cca95 100644
--- a/contrib/emacs/vc-git.el
+++ b/contrib/emacs/vc-git.el
@@ -38,6 +38,16 @@
 (defvar git-commits-coding-system 'utf-8
   "Default coding system for git commits.")
 
+;; Helper functions
+;
+; These are helper functions that don't hook into vc-mode as git's
+; view of the versioned world is a little different to vc's
+
+(defun git-show-commit-diff (commit-id &optional buffer)
+  "Show a given commit id in patch form in a buffer"
+  (let ((buf (or buffer "*vc-diff*")))
+    (vc-do-command buf t "git" nil "show" commit-id)))
+
 (defun vc-git--run-command-string (file &rest args)
   "Run a git command on FILE and return its output as string."
   (let* ((ok t)
@@ -196,6 +206,34 @@ Returns nil if not possible."
                               (concat (or rev "HEAD") ":" fullname)))))
     (vc-git--run-command file "checkout" (or rev "HEAD"))))
 
+;; Not really useful since we can't do anything with the revision yet
+(defun vc-git-annotate-extract-revision-at-line ()
+  (save-excursion
+    (move-beginning-of-line 1)
+    (and (looking-at "[0-9a-f]+")
+         (buffer-substring (match-beginning 0) (match-end 0)))))
+
+;;Jump to the diff for a given revision
+;
+; The internal vc logic has the concept of prev and next, GIT worries
+; about commit ids. If we are in a git-annotate-view we really want to
+; be doing this ourselves.
+(defun vc-git-annotate-show-diff-revision-at-line ()
+  "Visit the diff of the version at line (git version)."
+  (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")
+	(save-window-excursion
+	  (git-show-commit-diff rev-at-line))
+	(switch-to-buffer "*vc-diff*")))))
+
+(defun vc-git-previous-version (file rev)
+  0)
+
+;; Do the annotate for VC
 (defun vc-git-annotate-command (file buf &optional rev)
   ; FIXME: rev is ignored
   (let ((name (file-relative-name file)))
@@ -206,11 +244,7 @@ Returns nil if not possible."
        (vc-annotate-convert-time
         (apply #'encode-time (mapcar (lambda (match) (string-to-number (match-string match))) '(6 5 4 3 2 1 7))))))
 
-;; Not really useful since we can't do anything with the revision yet
-;;(defun vc-annotate-extract-revision-at-line ()
-;;  (save-excursion
-;;    (move-beginning-of-line 1)
-;;    (and (looking-at "[0-9a-f]+")
-;;         (buffer-substring (match-beginning 0) (match-end 0)))))
+
+
 
 (provide 'vc-git)
-- 
1.5.2.5



-- 
Alex, homepage: http://www.bennee.com/~alex/
Hire me? http://www.bennee.com/~alex/cv.php
netgod: My calculator has more registers than the x86, and -- thats- sad

```

## Alexandre Julliard, 2008-02-22 20:17

Subject: Re: [RFC PATCH] Implement vc-git-annotate-show-diff-revision-at-line for emacs vc-git
Message-ID: <87ejb4kaob.fsf@wine.dyndns.org>
URL: https://gitlist.dev/e/87ejb4kaob.fsf%40wine.dyndns.org
In-Reply-To: <1203706693.7552.56.camel@alexjb-desktop.transitives.com>

```
Alex Bennee <kernel-hacker@bennee.com> writes:

> I've had an initial stab at doing this for jumping to the commit in
> annotate mode. You can manually call it with M-x
> vc-git-annotate-show-diff-revision-at-line and it all works fine.
> However the vc logic wants vc-git-previous-version to exist before it
> will call it directly from the mode. I considered evil key-rebinding
> hacks but that seems to nasty.

vc-git is now maintained in the main Emacs repository, so that's the
version you should look at; it does have a vc-git-previous-version
implementation. The vc-git.el in the git repository is an older version
that is not being updated anymore.

-- 
Alexandre Julliard
julliard@winehq.org

```

## Junio C Hamano, 2008-02-22 20:30

Subject: Re: [RFC PATCH] Implement vc-git-annotate-show-diff-revision-at-line for emacs vc-git
Message-ID: <7voda891jr.fsf@gitster.siamese.dyndns.org>
URL: https://gitlist.dev/e/7voda891jr.fsf%40gitster.siamese.dyndns.org
In-Reply-To: <1203706693.7552.56.camel@alexjb-desktop.transitives.com>

```
Alex Bennee <kernel-hacker@bennee.com> writes:

> Whats the easiest command to show the parent commit of a given commit id
> (the closest analogy I can think of)? I tried:
>
>  git-show 486a974a --pretty="format:%P"

 * Have rev before option, like "git show --pretty=... 486a974"

 * Use -s to squelch diff output.

You should check how the %P format shows parents for a merge and
decide which parent you would want to follow.

```

## Junio C Hamano, 2008-02-22 20:51

Subject: Re: [RFC PATCH] Implement vc-git-annotate-show-diff-revision-at-line for emacs vc-git
Message-ID: <7vbq6890km.fsf@gitster.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vbq6890km.fsf%40gitster.siamese.dyndns.org
In-Reply-To: <1203706693.7552.56.camel@alexjb-desktop.transitives.com>

```
Alex Bennee <kernel-hacker@bennee.com> writes:

> +(defun vc-git-annotate-extract-revision-at-line ()
> +  (save-excursion
> +    (move-beginning-of-line 1)
> +    (and (looking-at "[0-9a-f]+")
> +         (buffer-substring (match-beginning 0) (match-end 0)))))

Does this grab the commit object name from the annotation
of a _full_ file?  How is the annotation done?  With "blame"
without frills?

It may be interesting to run:

	git blame -w -n -f -C -- $path

which would give you the code movement (ignoring whitespace
changes) across files, so that you can view where the line
really originated from.

You can also throw in -L line range limiter like this:

	git blame -L$lineno-10,+20 -w -n -f -C -- $path

which would limit the output to lines around the current line,
and that would be slightly less expensive than annotating the
whole file, if you do this on-demand.

E.g.

	$ git blame -L48,+20 -w -n -f -C -- block/blk-exec.c

would give you something like:

    165125e1 block/ll_rw_blk.c         2585 (Jens Axboe       2007-07-2...
    f1970baf drivers/block/ll_rw_blk.c 2255 (James Bottomley  2005-06-2...
    8ffdc655 block/ll_rw_blk.c         2320 (Tejun Heo        2006-01-0...
    f1970baf drivers/block/ll_rw_blk.c 2257 (James Bottomley  2005-06-2...
    f1970baf drivers/block/ll_rw_blk.c 2258 (James Bottomley  2005-06-2...
    f1970baf drivers/block/ll_rw_blk.c 2259 (James Bottomley  2005-06-2...
    f1970baf drivers/block/ll_rw_blk.c 2260 (James Bottomley  2005-06-2...
    4aff5e23 block/ll_rw_blk.c         2530 (Jens Axboe       2006-08-1...
    f1970baf drivers/block/ll_rw_blk.c 2262 (James Bottomley  2005-06-2...
    4c5d0bbd block/ll_rw_blk.c         2480 (Andrew Morton    2006-03-2...
    4c5d0bbd block/ll_rw_blk.c         2481 (Andrew Morton    2006-03-2...
    4c5d0bbd block/ll_rw_blk.c         2482 (Andrew Morton    2006-03-2...
    4c5d0bbd block/ll_rw_blk.c         2483 (Andrew Morton    2006-03-2...
    4c5d0bbd block/ll_rw_blk.c         2484 (Andrew Morton    2006-03-2...
    f1970baf drivers/block/ll_rw_blk.c 2265 (James Bottomley  2005-06-2...
    6e39b69e block/ll_rw_blk.c         2309 (Mike Christie    2005-11-1...
    6e39b69e block/ll_rw_blk.c         2310 (Mike Christie    2005-11-1...
    637b48c8 drivers/block/ll_rw_blk.c 1872 (Jens Axboe       2004-03-1...
    637b48c8 drivers/block/ll_rw_blk.c 1873 (Jens Axboe       2004-03-1...
    637b48c8 drivers/block/ll_rw_blk.c 1874 (Jens Axboe       2004-03-1...

```

## Alex Bennee, 2008-02-23 09:09

Subject: Re: [RFC PATCH] Implement vc-git-annotate-show-diff-revision-at-line for emacs vc-git
Message-ID: <b2cdc9f30802230109x27af2b90qf27cd6f92dd767e@mail.gmail.com>
URL: https://gitlist.dev/e/b2cdc9f30802230109x27af2b90qf27cd6f92dd767e%40mail.gmail.com
In-Reply-To: <87ejb4kaob.fsf@wine.dyndns.org>

```
On 2/22/08, Alexandre Julliard <julliard@winehq.org> wrote:
> Alex Bennee <kernel-hacker@bennee.com> writes:
>
>  > I've had an initial stab at doing this for jumping to the commit in
>  > annotate mode.
<snip>
> vc-git is now maintained in the main Emacs repository, so that's the
>  version you should look at; it does have a vc-git-previous-version
>  implementation. The vc-git.el in the git repository is an older version
>  that is not being updated anymore.

Perhaps it would be worth mirroring the updates to vc-git.el in the
git repo for people that don't
run bleeding edge emacs but do track git development? Or does it need
changes that have been made to vc.el in the mainline?

--
Alex, homepage: http://www.bennee.com/~alex/

```
