Skip to contentSkip to conversation

grep Added --blame so that grep can show result tagged with blame entries

PATCH In review pi song 2 participants 2 messages Jun 15, 2016 Documentation

lore
Share & tools
lore

pi song

author
#0 lore raw

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
index 553da6c..23dae7f 100644
@@ -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
index 3f12ba3..c6cffa0 100644
@@ -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
index 062b2b6..0514384 100644
@@ -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
index 5102ce3..2e12e03 100644
@@ -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
#1 lore raw
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

---

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
index 553da6c..23dae7f 100644

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 a
builtin-grep.c +5 -0
index 3f12ba3..c6cffa0 100644
@@ -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
index 062b2b6..0514384 100644
@@ -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, 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)) {

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, 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.

grep.c static int grep_buffer_1(struct grep_opt *opt, · line 527

Quoted 12 lines
grep.c +0 -0
    while (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 -13
                    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));

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 -0
    free(prev);
    if (collect_hits)
        return 0;
grep.h +1 -0
index 5102ce3..2e12e03 100644
@@ -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);