{"thread":{"id":"5422","subject":"gitweb filter for patches by a specific person in a specific timeframe","startedAt":"2006-08-28T12:59:21Z","lastAt":"2006-09-18T00:40:56Z","messageCount":7,"participants":["Kai Blin","Jakub Narebski","Jeff King","Linus Torvalds","Jonas Fonseca","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"26041","messageId":"200608281459.26643.kai.blin@gmail.com","threadId":"5422","inReplyTo":null,"subject":"gitweb filter for patches by a specific person in a specific timeframe","fromName":"Kai Blin","fromEmail":"kai.blin@gmail.com","sentAt":"2006-08-28T12:59:21Z","receivedAt":"2006-08-28T12:59:21Z","isPatch":false,"sender":{"key":"kai.blin@gmail.com","avatar":null},"body":"Hi folks,\n\nI have just completed my Google Summer of Code[1] project[2] working for the \nWine project. Now, as I was submitting patches to a git repository, I don't \nhave a branch solely containing my patches or something like that. Google \nseems to want something like this, so I figured maybe I could get gitweb to \nfilter for my patches during the SoC period. Is that possible?\nIf not, does it sound like something feasible to add?\n\nCheers,\nKai\n\nPS: Please CC me, as I'm not on the list.\n\n[1] http://code.google.com/soc/\n[2] http://wiki.winehq.org/NtlmSigningAndSealing\n-- \nKai Blin, <kai Dot blin At gmail Dot com>\nWorldForge developer    http://www.worldforge.org/\nWine developer          http://wiki.winehq.org/KaiBlin/\n--\nWill code for cotton.\n"},{"id":"26042","messageId":"44f2ebff.71ddc839.5a4e.79a6@mx.gmail.com","threadId":"5422","inReplyTo":"200608281459.26643.kai.blin@gmail.com","subject":"Re: gitweb filter for patches by a specific person in a specific timeframe","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-28T13:13:43Z","receivedAt":"2006-08-28T13:13:43Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Kai Blin wrote:\n\n> I have just completed my Google Summer of Code[1] project[2] working for the \n> Wine project. Now, as I was submitting patches to a git repository, I don't \n> have a branch solely containing my patches or something like that. Google \n> seems to want something like this, so I figured maybe I could get gitweb to \n> filter for my patches during the SoC period. Is that possible?\n> If not, does it sound like something feasible to add?\n\nIt is possible. Simply enter \"author:Kai Blin\" (without space between ':' \nand your name as it appears in author field) in the searchbox, and you \nwould get an URL similar to the URL below:\n\n  http://www.kernel.org/git/?p=git%2Fgit.git&a=search&h=HEAD&s=author%3AJonas+Fonseca\n\nOf course you should first go to proper branch.  If you are giving the link,\nyou can write it in more human-friendly form, e.g.\n\n  http://www.kernel.org/git/?p=git/git.git;a=search;h=HEAD;s=author:Jonas+Fonseca\n\n\nOr you can just search for your name, which gives URL like this one\n\n  http://www.kernel.org/git/?p=git/git.git;a=search;h=HEAD;s=Jonas+Fonseca\n\nwhich will find all commits in the lineage of given branch (HEAD is \nthe current branch) which have specified phrase in commit log (which \nincludes signoff lines)\n\n> PS: Please CC me, as I'm not on the list.\n\nYou can always read the list using one of the many archives \nof git@vger.kernel.org list, or using Usenet (news) client via NNTP\ngateway at GMane (nntp://news.gmane.org/gmane.comp.version-control.git).\n\nSee http://git.or.cz/gitwiki/GitCommunity\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"26059","messageId":"20060828181626.GB2950@coredump.intra.peff.net","threadId":"5422","inReplyTo":"200608281459.26643.kai.blin@gmail.com","subject":"Re: gitweb filter for patches by a specific person in a specific timeframe","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2006-08-28T18:16:27Z","receivedAt":"2006-08-28T18:16:27Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Aug 28, 2006 at 02:59:21PM +0200, Kai Blin wrote:\n\n> I have just completed my Google Summer of Code[1] project[2] working for the \n> Wine project. Now, as I was submitting patches to a git repository, I don't \n> have a branch solely containing my patches or something like that. Google \n> seems to want something like this, so I figured maybe I could get gitweb to \n> filter for my patches during the SoC period. Is that possible?\n> If not, does it sound like something feasible to add?\n\nYou can create an mbox of all of the changes you made. Unfortunately\ngit-rev-list doesn't do author/committer matching, so you'll need a\nshort perl script:\n\n-- >8 --\n$ cat >match-who.pl <<'EOF'\n#!/usr/bin/perl\n\nmy $name = shift;\nmy $match = qr/$name/i;\n\nmy $commit;\nwhile(<>) {\n  chomp;\n  next unless $_;\n  next if /^\\s/;\n  my ($k, $v) = split / /, $_, 2;\n  if($k eq 'commit') {\n    $commit = $v;\n  }\n  if($commit && ($k eq 'author' || $k eq 'committer') && $v =~ $match) {\n    print \"$commit\\n\";\n    $commit = undef;\n  }\n}\n-- >8 --\n\nThen you should be able to do:\n$ git-rev-list --pretty=raw master |\n  perl match-who.pl kai.blin@gmail.com |\n  git-diff-tree -p --stdin --pretty=email \\\n  > my-patches\n\nYou can either look through that, or you can try applying the patches\nwith git-am (though if your patches depend on changes not by you that\nhappened in the intervening time, you'll probably have some rejects).\n\n-Peff\n"},{"id":"26063","messageId":"Pine.LNX.4.64.0608281147420.27779@g5.osdl.org","threadId":"5422","inReplyTo":"20060828181626.GB2950@coredump.intra.peff.net","subject":"Re: gitweb filter for patches by a specific person in a specific timeframe","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-08-28T19:04:28Z","receivedAt":"2006-08-28T19:04:28Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 28 Aug 2006, Jeff King wrote:\n> \n> You can create an mbox of all of the changes you made. Unfortunately\n> git-rev-list doesn't do author/committer matching, so you'll need a\n> short perl script:\n\nThe author/committer matching is something that people have talked about \nfor a long time, so maybe we should just add it? \n\nIt shouldn't be that hard at all. Just add logic to revision.c: \nget_revision(), something like the appended (fleshed out and fixed, of \ncourse, with all the command line flags added to actually allow setting of \n\"revs->author_pattern\" etc..)\n\nA good thing for some beginning git hacker to try doing. Hint, hint.\n\n(The only subtle thing might be to make sure that \"save_commit_buffer\" is \nset if author/committer matching is on, so that the \"commit->buffer\" thing \nis actually saved after parsing, so that you can match it)\n\nThis trivial approach doesn't allow \"gitk\" to show the results sanely, \nthough (to do that, you'd need to make the commit matching be part of the \nparent simplification instead - that would be extra bonus points for the \nintrpid git hacker-wannabe)\n\n\t\tLinus\n---\n\ndiff --git a/revision.c b/revision.c\nindex 1d89d72..88cc1e3 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1011,6 +1011,13 @@ static void mark_boundary_to_show(struct\n \t}\n }\n \n+static int commit_match(struct commit *commit, const char *field, const char *pattern)\n+{\n+\tif (!pattern)\n+\t\treturn 1;\n+\t.. match it here ..\n+}\n+\n struct commit *get_revision(struct rev_info *revs)\n {\n \tstruct commit_list *list = revs->commits;\n@@ -1070,6 +1077,10 @@ struct commit *get_revision(struct rev_i\n \t\tif (revs->no_merges &&\n \t\t    commit->parents && commit->parents->next)\n \t\t\tcontinue;\n+\t\tif (!commit_match(commit, \"author\", revs->author_pattern))\n+\t\t\tcontinue;\n+\t\tif (!commit_match(commit, \"committer\", revs->committer_pattern))\n+\t\t\tcontinue;\n \t\tif (revs->prune_fn && revs->dense) {\n \t\t\t/* Commit without changes? */\n \t\t\tif (!(commit->object.flags & TREECHANGE)) {\n"},{"id":"26167","messageId":"20060831225714.GD482@diku.dk","threadId":"5422","inReplyTo":"Pine.LNX.4.64.0608281147420.27779@g5.osdl.org","subject":"[PATCH] Support author and commiter based revision list limiting","fromName":"Jonas Fonseca","fromEmail":"fonseca@diku.dk","sentAt":"2006-08-31T22:57:14Z","receivedAt":"2006-08-31T22:57:14Z","isPatch":true,"sender":{"key":"fonseca@diku.dk","avatar":"https://gravatar.com/avatar/f82f3ad698717c51873b020c750a92438c820a24056dc39fe4d07baa10a92264?d=mp&s=160"},"body":"Adds the two options: --author=string and --committer=string, which can\nbe used to limit the set of interesting commits to the ones matching the\ngiven idents.\n\nSigned-off-by: Jonas Fonseca <fonseca@diku.dk>\n---\n\n[ On top of the git-rev-list(1) update posted earlier ... ]\n\nLinus Torvalds <torvalds@osdl.org> wrote Mon, Aug 28, 2006:\n> Th[e] trivial approach doesn't allow \"gitk\" to show the results sanely, \n> though (to do that, you'd need to make the commit matching be part of the \n> parent simplification instead - that would be extra bonus points for the \n> intrpid git hacker-wannabe)\n\nHereby serving one patch doing the trivial thing very stupid, since I\ndidn't have the imagination to go and hunt for the bonus points just\nyet.\n\n Documentation/git-rev-list.txt |    6 +++++\n builtin-rev-list.c             |    3 ++\n revision.c                     |   53 ++++++++++++++++++++++++++++++++++++++++\n revision.h                     |    2 ++\n 4 files changed, 63 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt\nindex d6c86db..4d5f5ab 100644\n--- a/Documentation/git-rev-list.txt\n+++ b/Documentation/git-rev-list.txt\n@@ -12,6 +12,8 @@ SYNOPSIS\n 'git-rev-list' [ \\--max-count=number ]\n \t     [ \\--max-age=timestamp ]\n \t     [ \\--min-age=timestamp ]\n+\t     [ \\--author=string ]\n+\t     [ \\--committer=string ]\n \t     [ \\--sparse ]\n \t     [ \\--no-merges ]\n \t     [ \\--remove-empty ]\n@@ -153,6 +155,10 @@ limiting may be applied.\n \n \tLimit the commits output to specified time range.\n \n+--author='string', --committer='string'::\n+\n+\tLimit the commits output to specified author and/or committer.\n+\n --remove-empty::\n \n \tStop when a given path disappears from the tree.\ndiff --git a/builtin-rev-list.c b/builtin-rev-list.c\nindex 402af8e..09e3d37 100644\n--- a/builtin-rev-list.c\n+++ b/builtin-rev-list.c\n@@ -352,7 +352,8 @@ int cmd_rev_list(int argc, const char **\n \t    revs.diff)\n \t\tusage(rev_list_usage);\n \n-\tsave_commit_buffer = revs.verbose_header;\n+\tif (!revs.author_pattern && !revs.committer_pattern)\n+\t\tsave_commit_buffer = revs.verbose_header;\n \ttrack_object_refs = 0;\n \tif (bisect_list)\n \t\trevs.limited = 1;\ndiff --git a/revision.c b/revision.c\nindex b588f74..31618fe 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -671,6 +671,14 @@ int setup_revisions(int argc, const char\n \t\t\t\trevs->min_age = approxidate(arg + 8);\n \t\t\t\tcontinue;\n \t\t\t}\n+\t\t\tif (!strncmp(arg, \"--author=\", 9)) {\n+\t\t\t\trevs->author_pattern = arg + 9;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tif (!strncmp(arg, \"--committer=\", 12)) {\n+\t\t\t\trevs->committer_pattern = arg + 12;\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (!strcmp(arg, \"--all\")) {\n \t\t\t\thandle_all(revs, flags);\n \t\t\t\tcontinue;\n@@ -1015,6 +1023,47 @@ static void mark_boundary_to_show(struct\n \t}\n }\n \n+static int commit_match_ident(struct commit *commit, const char *field, const char *pattern)\n+{\n+\tconst char *pos;\n+\tint field_len;\n+\tint pattern_len;\n+\n+\tif (!pattern)\n+\t\treturn 1;\n+\n+\tfield_len = strlen(field);\n+\tpattern_len = strlen(pattern);\n+\n+\tfor (pos = commit->buffer; *pos != '\\n'; pos++) {\n+\t\tconst char *line_end = strchr(pos, '\\n');\n+\n+\t\tif (!strncmp(pos, field, field_len) &&\n+\t\t    pos[field_len] == ' ') {\n+\t\t\tconst char *ident_end = line_end;\n+\n+\t\t\tpos += field_len;\n+\t\t\twhile (ident_end > pos && ident_end[-1] != '>')\n+\t\t\t\tident_end--;\n+\n+\t\t\t/* A slow \"strncasestr\" */\n+\t\t\twhile (pos + pattern_len <= ident_end) {\n+\t\t\t\tif (!strncasecmp(pos, pattern, pattern_len))\n+\t\t\t\t\treturn 1;\n+\t\t\t\tpos++;\n+\t\t\t}\n+\n+\t\t\t/* Assumes that fields that should be matched only\n+\t\t\t * appear once in the commit header. */\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\tpos = line_end;\n+\t}\n+\n+\treturn 0;\n+}\n+\n struct commit *get_revision(struct rev_info *revs)\n {\n \tstruct commit_list *list = revs->commits;\n@@ -1074,6 +1123,10 @@ struct commit *get_revision(struct rev_i\n \t\tif (revs->no_merges &&\n \t\t    commit->parents && commit->parents->next)\n \t\t\tcontinue;\n+\t\tif (!commit_match_ident(commit, \"author\", revs->author_pattern))\n+\t\t\tcontinue;\n+\t\tif (!commit_match_ident(commit, \"committer\", revs->committer_pattern))\n+\t\t\tcontinue;\n \t\tif (revs->prune_fn && revs->dense) {\n \t\t\t/* Commit without changes? */\n \t\t\tif (!(commit->object.flags & TREECHANGE)) {\ndiff --git a/revision.h b/revision.h\nindex d289781..7688e3a 100644\n--- a/revision.h\n+++ b/revision.h\n@@ -71,6 +71,8 @@ struct rev_info {\n \tint max_count;\n \tunsigned long max_age;\n \tunsigned long min_age;\n+\tconst char *author_pattern;\n+\tconst char *committer_pattern;\n \n \t/* diff info for patches and for paths limiting */\n \tstruct diff_options diffopt;\n-- \n1.4.2.g2ba6b-dirty\n\n-- \nJonas Fonseca\n"},{"id":"26175","messageId":"7vhczs78lu.fsf@assigned-by-dhcp.cox.net","threadId":"5422","inReplyTo":"20060831225714.GD482@diku.dk","subject":"Re: [PATCH] Support author and commiter based revision list limiting","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-09-01T00:07:09Z","receivedAt":"2006-09-01T00:07:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jonas Fonseca <fonseca@diku.dk> writes:\n\n> Adds the two options: --author=string and --committer=string, which can\n> be used to limit the set of interesting commits to the ones matching the\n> given idents.\n>\n> diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt\n> index d6c86db..4d5f5ab 100644\n> --- a/Documentation/git-rev-list.txt\n> +++ b/Documentation/git-rev-list.txt\n> @@ -12,6 +12,8 @@ SYNOPSIS\n>  'git-rev-list' [ \\--max-count=number ]\n>  \t     [ \\--max-age=timestamp ]\n>  \t     [ \\--min-age=timestamp ]\n> +\t     [ \\--author=string ]\n> +\t     [ \\--committer=string ]\n>  \t     [ \\--sparse ]\n>  \t     [ \\--no-merges ]\n>  \t     [ \\--remove-empty ]\n\nThese two separate options are Ok at the level of front-end,\nbut...\n\n> diff --git a/builtin-rev-list.c b/builtin-rev-list.c\n> index 402af8e..09e3d37 100644\n> --- a/builtin-rev-list.c\n> +++ b/builtin-rev-list.c\n> @@ -352,7 +352,8 @@ int cmd_rev_list(int argc, const char **\n>  \t    revs.diff)\n>  \t\tusage(rev_list_usage);\n>  \n> -\tsave_commit_buffer = revs.verbose_header;\n> +\tif (!revs.author_pattern && !revs.committer_pattern)\n> +\t\tsave_commit_buffer = revs.verbose_header;\n>  \ttrack_object_refs = 0;\n>  \tif (bisect_list)\n>  \t\trevs.limited = 1;\n\nI wonder if it is simpler and yet more powerful to internally\nuse a regex to match the contents of commit buffer, not just\nspecific its header fields.\n\nWhen --author or --committer is given, you internally synthesize\na regex \"^author Jonas Fonseca <fonseca@\" from the string.\n\nAnd then, instead of doing commit_match_ident() twice like this:\n\n> @@ -1074,6 +1123,10 @@ struct commit *get_revision(struct rev_i\n>  \t\tif (revs->no_merges &&\n>  \t\t    commit->parents && commit->parents->next)\n>  \t\t\tcontinue;\n> +\t\tif (!commit_match_ident(commit, \"author\", revs->author_pattern))\n> +\t\t\tcontinue;\n> +\t\tif (!commit_match_ident(commit, \"committer\", revs->committer_pattern))\n> +\t\t\tcontinue;\n\nyou would just do:\n\n\tif (revs->commit_filter_pattern &&\n            commit_search_message(commit, revs->commit_filter_pattern))\n\t\tcontinue;\n\ninstead.\n\nFor an extra bonus point, the matching logic might want to steal\nfrom builtin-grep to allow multiple regular expressions, case\ninsensitive match and other bells and whistles.  You probably\ncould lift the whole grep_buffer() -- add another option that\nbehaves similarly to opt->name_only (name it opt->status_only)\nbut make it not even print anything upon hit, so that you can\ntell from the return value if it found the pattern in the\nbuffer, like this:\n\ndiff --git a/builtin-grep.c b/builtin-grep.c\nindex 8213ce2..714ad50 100644\n--- a/builtin-grep.c\n+++ b/builtin-grep.c\n@@ -128,6 +128,7 @@ struct grep_opt {\n \tunsigned linenum:1;\n \tunsigned invert:1;\n \tunsigned name_only:1;\n+\tunsigned status_only:1;\n \tunsigned unmatch_name_only:1;\n \tunsigned count:1;\n \tunsigned word_regexp:1;\n@@ -492,6 +493,8 @@ static int grep_buffer(struct grep_opt *\n \t\t}\n \t\tif (hit) {\n \t\t\tcount++;\n+\t\t\tif (opt->status_only)\n+\t\t\t\treturn 1;\n \t\t\tif (binary_match_only) {\n \t\t\t\tprintf(\"Binary file %s matches\\n\", name);\n \t\t\t\treturn 1;\n\n\n\nHmm?\n"},{"id":"27098","messageId":"7vlkoiypk7.fsf@assigned-by-dhcp.cox.net","threadId":"5422","inReplyTo":"Pine.LNX.4.64.0608281147420.27779@g5.osdl.org","subject":"git log --author='Jeff King'","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-09-18T00:40:56Z","receivedAt":"2006-09-18T00:40:56Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"I have three patch series that makes a part of git-grep\navailable and use it for log filtering:\n\n [PATCH] builtin-grep: make pieces of it available as library.\n [PATCH] revision traversal: prepare for commit log match.\n [PATCH] revision traversal: --author, --committer, and --grep.\n\nI didn't implement the boolean combination of patterns like\ngit-grep does, but it should be pretty straightforward to do so\nin setup_revisions().  The syntax probably would be something\nlike:\n\n    git log --grep-( rev-list gitweb --and --not --author=Jakub --grep-)\n\nto find logs that:\n\n * talk about rev-list, or\n * talk about gitweb but not by Jakub\n"}]}