grep Added --blame so that grep can show result tagged with blame entries
PATCH 2/2 grep Added --blame so that grep can show result tagged with blame entries
This part:-
1) Implementation & man for grep --blame option
---
Documentation/git-grep.txt | 5 ++ builtin-grep.c | 10 ++++- grep.c | 98 ++++++++++++++++++++++++++++++++++++------- grep.h | 1 + 4 files changed, 96 insertions(+), 18 deletions(-)
Documentation/git-grep.txt +5 -1
@@ -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
builtin-grep.c +5 -0
@@ -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") ||
grep.c +1 -0
@@ -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;grep.h +1 -0
@@ -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);
Signature · 1 line
1.5.4.3
Quoted 2 lines · pi song
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"?
Quoted 15 lines
Signed-off-by Pi Song <[email protected]>---
Documentation/git-grep.txt | 5 ++ builtin-grep.c | 10 ++++- grep.c | 98 ++++++++++++++++++++++++++++++++++++------- grep.h | 1 + 4 files changed, 96 insertions(+), 18 deletions(-)Documentation/git-grep.txt +0
-0
Documentation/git-grep.txt SYNOPSIS · line 21
Quoted 4 lines
Documentation/git-grep.txt +1
-0@@ -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.
Documentation/git-grep.txt OPTIONS · line 112
Quoted 11 lines
Documentation/git-grep.txt +4
-0[-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.
Quoted 48 lines
Documentation/git-grep.txt +0
-1-[ABC] <context>:: Show `context` trailing (`A` -- after), or leading (`B` -- before), or both (`C` -- context) lines, and place abuiltin-grep.c +5
-0@@ -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") ||grep.c +1
-0@@ -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,grep.c +2
-1- 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);grep.c +3
-1+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);
Quoted 1 line
}
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?
Quoted 27 lines
grep.c +8
-0@@ -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){
grep.c +1
-0@@ -457,6 +469,7 @@ static int grep_buffer_1(struct grep_opt *opt, constchar *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)) {
grep.c static int grep_buffer_1(struct grep_opt *opt, const · line 495
Quoted 6 lines
grep.c +2
-0@@ -477,6 +490,8 @@ static int grep_buffer_1(struct grep_opt *opt, constchar *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.
grep.c static int grep_buffer_1(struct grep_opt *opt, · line 527
Quoted 12 lines
grep.c +0
-0while (left) {char *eol, ch;int hit;grep.c +4
-0@@ -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) {Quoted 5 lines
grep.c +5
-0+struct blame_stat blame_stat ; +struct rev_info revs; +char filename[128 ] ; +char revId[41 ] ; +char *splitterPtr ;
grep.c static int grep_buffer_1(struct grep_opt *opt, · line 542
Quoted 10 lines
grep.c +9
-0+ + 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 {grep.c static int grep_buffer_1(struct grep_opt *opt, · line 550
Quoted 8 lines
grep.c +7
-0+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.
Quoted 7 lines
grep.c +3
-0+ blame_calculated =1 ; + } +if (hit) { count++;if (opt->status_only)
grep.c static int grep_buffer_1(struct grep_opt *opt, · line 584
Quoted 9 lines
grep.c +4
-1@@ -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) {Quoted 53 lines
grep.c +26
-13pcl = &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));
grep.c static int grep_buffer_1(struct grep_opt *opt, · line 641
Quoted 9 lines
grep.c +5
-0@@ -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;
Quoted 16 lines
grep.c +0
-0free (prev);if (collect_hits)return 0;grep.h +1
-0@@ -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_tokent);