git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 2/2] grep Added --blame so that grep can show result tagged with blame entries
@ 2009-03-09 13:20 pi song
  2009-03-09 21:22 ` René Scharfe
  0 siblings, 1 reply; 2+ messages in thread
From: pi song @ 2009-03-09 13:20 UTC (permalink / raw
  To: git, gitster

This part:-
1) Implementation & man for grep --blame option

Signed-off-by: Pi Song <pi.songs@gmail.com>
---
 Documentation/git-grep.txt |    5 ++
 builtin-grep.c             |   10 ++++-
 grep.c                     |   98 
++++++++++++++++++++++++++++++++++++-------
 grep.h                     |    1 +
 4 files changed, 96 insertions(+), 18 deletions(-)

diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
index 553da6c..23dae7f 100644
--- a/Documentation/git-grep.txt
+++ b/Documentation/git-grep.txt
@@ -18,6 +18,7 @@ SYNOPSIS
        [-z | --null]
        [-c | --count] [--all-match]
        [-A <post-context>] [-B <pre-context>] [-C <context>]
+       [-b | --blame ]
        [-f <file>] [-e] <pattern>
        [--and|--or|--not|(|)|-e <pattern>...] [<tree>...]
        [--] [<path>...]
@@ -105,6 +106,10 @@ OPTIONS
     Instead of showing every matched line, show the number of
     lines that match.
 
+-b::
+--blame::
+    Show blame of every matched line and context
+
 -[ABC] <context>::
     Show `context` trailing (`A` -- after), or leading (`B`
     -- before), or both (`C` -- context) lines, and place a
diff --git a/builtin-grep.c b/builtin-grep.c
index 3f12ba3..c6cffa0 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -630,6 +630,11 @@ int cmd_grep(int argc, const char **argv, const 
char *prefix)
             opt.word_regexp = 1;
             continue;
         }
+                if (!strcmp("-b", arg) ||
+            !strcmp("--blame", arg)) {
+            opt.include_blame = 1;
+            continue;
+        }
         if (!prefixcmp(arg, "-A") ||
             !prefixcmp(arg, "-B") ||
             !prefixcmp(arg, "-C") ||
diff --git a/grep.c b/grep.c
index 062b2b6..0514384 100644
--- a/grep.c
+++ b/grep.c
@@ -1,3 +1,4 @@
+#include "blame.h"
 #include "cache.h"
 #include "grep.h"
 #include "xdiff-interface.h"
@@ -252,14 +253,17 @@ static int word_char(char ch)
 }
 
 static void show_line(struct grep_opt *opt, const char *bol, const char 
*eol,
-              const char *name, unsigned lno, char sign)
+              const char *name, unsigned lno, char sign,
+                      char sign2, char* suspect)
 {
     if (opt->null_following_name)
         sign = '\0';
     if (opt->pathname)
         printf("%s%c", name, sign);
+        if ((opt->include_blame) && (suspect!=NULL))
+        printf("%s%c", suspect);
     if (opt->linenum)
-        printf("%d%c", lno, sign);
+        printf("%d%c", lno, sign2);
     printf("%.*s\n", (int)(eol-bol), bol);
 }
 
@@ -442,6 +446,14 @@ static int match_line(struct grep_opt *opt, char 
*bol, char *eol,
     return 0;
 }
 
+static int setup_revision_by_revId(char *revId, struct rev_info *revs)
+{
+    const char *args[] = {"grep", revId};
+    init_revisions(revs, NULL);
+    setup_revisions(2, args, revs, NULL);
+    return 1 ;
+};
+
 static int grep_buffer_1(struct grep_opt *opt, const char *name,
              char *buf, unsigned long size, int collect_hits)
 {
@@ -457,6 +469,7 @@ static int grep_buffer_1(struct grep_opt *opt, const 
char *name,
     int binary_match_only = 0;
     const char *hunk_mark = "";
     unsigned count = 0;
+        int blame_calculated = 0 ;
     enum grep_context ctx = GREP_CONTEXT_HEAD;
 
     if (buffer_is_binary(buf, size)) {
@@ -477,6 +490,8 @@ static int grep_buffer_1(struct grep_opt *opt, const 
char *name,
     if (opt->pre_context || opt->post_context)
         hunk_mark = "--\n";
 
+        /* List of blame tags */
+        struct blame_tag *blame_tags  = NULL;
     while (left) {
         char *eol, ch;
         int hit;
@@ -505,6 +520,35 @@ static int grep_buffer_1(struct grep_opt *opt, 
const char *name,
                 return 0;
             goto next_line;
         }
+
+                /* Calculate blame if necessary */
+                if (hit && opt->include_blame && !blame_calculated)
+                {
+                    struct blame_stat blame_stat ;
+                    struct rev_info revs;
+                    char filename[128] ;
+                    char revId[41] ;
+                    char *splitterPtr ;
+                   
+                    if ((splitterPtr=strstr(name, ":")) != NULL)
+                    {
+                        strcpy(filename, splitterPtr + 1) ;
+                        strncpy(revId, name, splitterPtr - name) ;
+                        revId[40] = '\0' ;
+                        setup_revision_by_revId(revId, &revs) ;
+                    }
+                    else
+                    {
+                        const char *args[] = {};
+                        strcpy(filename, name) ;
+                        init_revisions(&revs, NULL);
+                        setup_revisions(0, args, &revs, NULL);
+                    }
+
+                    blame_tags = retrieve_blame_tags(&revs, 
&blame_stat, filename) ;
+                    blame_calculated = 1 ;
+                }
+
         if (hit) {
             count++;
             if (opt->status_only)
@@ -533,30 +577,47 @@ static int grep_buffer_1(struct grep_opt *opt, 
const char *name,
                     from = last_shown + 1;
                 if (last_shown && from != last_shown + 1)
                     fputs(hunk_mark, stdout);
-                while (from < lno) {
+
+                                /* This prints the precontext*/
+                while (from < lno)
+                                {
                     pcl = &prev[lno-from-1];
                     show_line(opt, pcl->bol, pcl->eol,
-                          name, from, '-');
+                          name, from, ':', '-',
+                                                  blame_tags==NULL?
+                                                  NULL: 
blame_tags[from-1].author);
                     from++;
                 }
                 last_shown = lno-1;
             }
             if (last_shown && lno != last_shown + 1)
                 fputs(hunk_mark, stdout);
-            if (!opt->count)
-                show_line(opt, bol, eol, name, lno, ':');
+
+            if (!opt->count) {
+                                /* The matching line */
+                                show_line(opt, bol, eol, name, lno,
+                                          ':', ':',
+                                        blame_tags==NULL?
+                                        NULL:blame_tags[lno-1].author);
+                        }
+               
             last_shown = last_hit = lno;
         }
-        else if (last_hit &&
-             lno <= last_hit + opt->post_context) {
-            /* If the last hit is within the post context,
-             * we need to show this line.
-             */
-            if (last_shown && lno != last_shown + 1)
-                fputs(hunk_mark, stdout);
-            show_line(opt, bol, eol, name, lno, '-');
-            last_shown = lno;
-        }
+                else if (last_hit && lno <= last_hit + opt->post_context)
+                {
+                            /* If the last hit is within the post context,
+                             * we need to show this line.
+                             */
+                            if (last_shown && lno != last_shown + 1)
+                                    fputs(hunk_mark, stdout);
+
+                            show_line(opt, bol, eol, name, lno, ':', '-',
+                                     blame_tags==NULL?
+                                     NULL:blame_tags[lno-1].author);
+                           
+                            last_shown = lno;
+                }
+
         if (opt->pre_context) {
             memmove(prev+1, prev,
                 (opt->pre_context-1) * sizeof(*prev));
@@ -572,6 +633,11 @@ static int grep_buffer_1(struct grep_opt *opt, 
const char *name,
         lno++;
     }
 
+        if (blame_calculated)
+        {
+                free(blame_tags) ;
+        }
+
     free(prev);
     if (collect_hits)
         return 0;
diff --git a/grep.h b/grep.h
index 5102ce3..2e12e03 100644
--- a/grep.h
+++ b/grep.h
@@ -79,6 +79,7 @@ struct grep_opt {
     int regflags;
     unsigned pre_context;
     unsigned post_context;
+        unsigned include_blame;
 };
 
 extern void append_grep_pattern(struct grep_opt *opt, const char *pat, 
const char *origin, int no, enum grep_pat_token t);
-- 
1.5.4.3

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH 2/2] grep Added --blame so that grep can show result tagged with blame entries
  2009-03-09 13:20 [PATCH 2/2] grep Added --blame so that grep can show result tagged with blame entries pi song
@ 2009-03-09 21:22 ` René Scharfe
  0 siblings, 0 replies; 2+ messages in thread
From: René Scharfe @ 2009-03-09 21:22 UTC (permalink / raw
  To: pi song; +Cc: git, gitster

pi song schrieb:
> This part:-
> 1) Implementation & man for grep --blame option

I read the list via Gmane and I can't find patch 1/2.  But if this here
is part 1, perhaps there is no "1/2"?

> 
> Signed-off-by: Pi Song <pi.songs@gmail.com>
> ---
> Documentation/git-grep.txt |    5 ++
> builtin-grep.c             |   10 ++++-
> grep.c                     |   98
> ++++++++++++++++++++++++++++++++++++-------
> grep.h                     |    1 +
> 4 files changed, 96 insertions(+), 18 deletions(-)
> 
> diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
> index 553da6c..23dae7f 100644
> --- a/Documentation/git-grep.txt
> +++ b/Documentation/git-grep.txt
> @@ -18,6 +18,7 @@ SYNOPSIS
>        [-z | --null]
>        [-c | --count] [--all-match]
>        [-A <post-context>] [-B <pre-context>] [-C <context>]
> +       [-b | --blame ]

Your mailer seems to have butchered all tabs.  There is a paragraph in
Documentation/SubmittingPatches about Gmail; seeing your email address I
think it might interest you.

>        [-f <file>] [-e] <pattern>
>        [--and|--or|--not|(|)|-e <pattern>...] [<tree>...]
>        [--] [<path>...]
> @@ -105,6 +106,10 @@ OPTIONS
>     Instead of showing every matched line, show the number of
>     lines that match.
> 
> +-b::
> +--blame::
> +    Show blame of every matched line and context
> +

Sounds interesting and useful.

> -[ABC] <context>::
>     Show `context` trailing (`A` -- after), or leading (`B`
>     -- before), or both (`C` -- context) lines, and place a
> diff --git a/builtin-grep.c b/builtin-grep.c
> index 3f12ba3..c6cffa0 100644
> --- a/builtin-grep.c
> +++ b/builtin-grep.c
> @@ -630,6 +630,11 @@ int cmd_grep(int argc, const char **argv, const
> char *prefix)
>             opt.word_regexp = 1;
>             continue;
>         }
> +                if (!strcmp("-b", arg) ||
> +            !strcmp("--blame", arg)) {
> +            opt.include_blame = 1;
> +            continue;
> +        }
>         if (!prefixcmp(arg, "-A") ||
>             !prefixcmp(arg, "-B") ||
>             !prefixcmp(arg, "-C") ||
> diff --git a/grep.c b/grep.c
> index 062b2b6..0514384 100644
> --- a/grep.c
> +++ b/grep.c
> @@ -1,3 +1,4 @@
> +#include "blame.h"
> #include "cache.h"
> #include "grep.h"
> #include "xdiff-interface.h"
> @@ -252,14 +253,17 @@ static int word_char(char ch)
> }
> 
> static void show_line(struct grep_opt *opt, const char *bol, const char
> *eol,
> -              const char *name, unsigned lno, char sign)
> +              const char *name, unsigned lno, char sign,
> +                      char sign2, char* suspect)
> {
>     if (opt->null_following_name)
>         sign = '\0';
>     if (opt->pathname)
>         printf("%s%c", name, sign);
> +        if ((opt->include_blame) && (suspect!=NULL))
> +        printf("%s%c", suspect);
>     if (opt->linenum)
> -        printf("%d%c", lno, sign);
> +        printf("%d%c", lno, sign2);
>     printf("%.*s\n", (int)(eol-bol), bol);
> }

Please be aware of recent changes to that code to add match coloring (in
next and pu).  Could you please rebase your changes on top of next?

> 
> @@ -442,6 +446,14 @@ static int match_line(struct grep_opt *opt, char
> *bol, char *eol,
>     return 0;
> }
> 
> +static int setup_revision_by_revId(char *revId, struct rev_info *revs)
> +{
> +    const char *args[] = {"grep", revId};
> +    init_revisions(revs, NULL);
> +    setup_revisions(2, args, revs, NULL);
> +    return 1 ;
> +};
> +
> static int grep_buffer_1(struct grep_opt *opt, const char *name,
>              char *buf, unsigned long size, int collect_hits)
> {
> @@ -457,6 +469,7 @@ static int grep_buffer_1(struct grep_opt *opt, const
> char *name,
>     int binary_match_only = 0;
>     const char *hunk_mark = "";
>     unsigned count = 0;
> +        int blame_calculated = 0 ;
>     enum grep_context ctx = GREP_CONTEXT_HEAD;
> 
>     if (buffer_is_binary(buf, size)) {
> @@ -477,6 +490,8 @@ static int grep_buffer_1(struct grep_opt *opt, const
> char *name,
>     if (opt->pre_context || opt->post_context)
>         hunk_mark = "--\n";
> 
> +        /* List of blame tags */
> +        struct blame_tag *blame_tags  = NULL;

Please put declarations at the start of a block to make the code
compatible with older (non-C99) compilers.

>     while (left) {
>         char *eol, ch;
>         int hit;
> @@ -505,6 +520,35 @@ static int grep_buffer_1(struct grep_opt *opt,
> const char *name,
>                 return 0;
>             goto next_line;
>         }
> +
> +                /* Calculate blame if necessary */
> +                if (hit && opt->include_blame && !blame_calculated)
> +                {

Style:
	if (condition) {
	
> +                    struct blame_stat blame_stat ;
> +                    struct rev_info revs;
> +                    char filename[128] ;
> +                    char revId[41] ;
> +                    char *splitterPtr ;
> +                   +                    if ((splitterPtr=strstr(name,
> ":")) != NULL)
> +                    {
> +                        strcpy(filename, splitterPtr + 1) ;
> +                        strncpy(revId, name, splitterPtr - name) ;
> +                        revId[40] = '\0' ;
> +                        setup_revision_by_revId(revId, &revs) ;
> +                    }
> +                    else
> +                    {

Style:
	} else {

> +                        const char *args[] = {};
> +                        strcpy(filename, name) ;
> +                        init_revisions(&revs, NULL);
> +                        setup_revisions(0, args, &revs, NULL);
> +                    }
> +
> +                    blame_tags = retrieve_blame_tags(&revs,
> &blame_stat, filename) ;

retrieve_blame_tags() doesn't exist currently, so I guess it is
introduced in patch 1/2.

> +                    blame_calculated = 1 ;
> +                }
> +
>         if (hit) {
>             count++;
>             if (opt->status_only)
> @@ -533,30 +577,47 @@ static int grep_buffer_1(struct grep_opt *opt,
> const char *name,
>                     from = last_shown + 1;
>                 if (last_shown && from != last_shown + 1)
>                     fputs(hunk_mark, stdout);
> -                while (from < lno) {
> +
> +                                /* This prints the precontext*/
> +                while (from < lno)
> +                                {

Style:
	while (condition) {

>                     pcl = &prev[lno-from-1];
>                     show_line(opt, pcl->bol, pcl->eol,
> -                          name, from, '-');
> +                          name, from, ':', '-',
> +                                                  blame_tags==NULL?
> +                                                  NULL:
> blame_tags[from-1].author);
>                     from++;
>                 }
>                 last_shown = lno-1;
>             }
>             if (last_shown && lno != last_shown + 1)
>                 fputs(hunk_mark, stdout);
> -            if (!opt->count)
> -                show_line(opt, bol, eol, name, lno, ':');
> +
> +            if (!opt->count) {
> +                                /* The matching line */
> +                                show_line(opt, bol, eol, name, lno,
> +                                          ':', ':',
> +                                        blame_tags==NULL?
> +                                        NULL:blame_tags[lno-1].author);
> +                        }
> +                           last_shown = last_hit = lno;
>         }
> -        else if (last_hit &&
> -             lno <= last_hit + opt->post_context) {
> -            /* If the last hit is within the post context,
> -             * we need to show this line.
> -             */
> -            if (last_shown && lno != last_shown + 1)
> -                fputs(hunk_mark, stdout);
> -            show_line(opt, bol, eol, name, lno, '-');
> -            last_shown = lno;
> -        }
> +                else if (last_hit && lno <= last_hit + opt->post_context)
> +                {
> +                            /* If the last hit is within the post context,
> +                             * we need to show this line.
> +                             */
> +                            if (last_shown && lno != last_shown + 1)
> +                                    fputs(hunk_mark, stdout);
> +
> +                            show_line(opt, bol, eol, name, lno, ':', '-',
> +                                     blame_tags==NULL?
> +                                     NULL:blame_tags[lno-1].author);
> +                           +                            last_shown = lno;
> +                }
> +
>         if (opt->pre_context) {
>             memmove(prev+1, prev,
>                 (opt->pre_context-1) * sizeof(*prev));
> @@ -572,6 +633,11 @@ static int grep_buffer_1(struct grep_opt *opt,
> const char *name,
>         lno++;
>     }
> 
> +        if (blame_calculated)
> +        {
> +                free(blame_tags) ;
> +        }
> +

Style:
	if (condition)
		single_line_expression;

>     free(prev);
>     if (collect_hits)
>         return 0;
> diff --git a/grep.h b/grep.h
> index 5102ce3..2e12e03 100644
> --- a/grep.h
> +++ b/grep.h
> @@ -79,6 +79,7 @@ struct grep_opt {
>     int regflags;
>     unsigned pre_context;
>     unsigned post_context;
> +        unsigned include_blame;
> };
> 
> extern void append_grep_pattern(struct grep_opt *opt, const char *pat,
> const char *origin, int no, enum grep_pat_token t);

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-03-09 21:24 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-09 13:20 [PATCH 2/2] grep Added --blame so that grep can show result tagged with blame entries pi song
2009-03-09 21:22 ` René Scharfe

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).