{"thread":{"id":"39620","subject":"[PATCH v2 00/11] add options to for-each-ref","startedAt":"2015-06-13T20:17:34Z","lastAt":"2015-06-15T20:49:09Z","messageCount":20,"participants":["karthik nayak","Karthik Nayak","Christian Couder","Matthieu Moy","Junio C Hamano"],"isPatch":true,"patchVersion":2,"patchTotal":11},"messages":[{"id":"263751","messageId":"CAOLa=ZRA7jVhs-NixjP+EFqfBNwLEfU-WgEMMQzb5NC+HZDYiw@mail.gmail.com","threadId":"39620","inReplyTo":null,"subject":"[PATCH v2 00/11] add options to for-each-ref","fromName":"karthik nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-13T20:17:34Z","receivedAt":"2015-06-13T20:17:34Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"This is continuation of the patch series 'Create ref-filter from for-each-ref'\nfound at : http://article.gmane.org/gmane.comp.version-control.git/271563\n\nThe previous version of this series can be found at :\nhttp://www.mail-archive.com/git%40vger.kernel.org/msg70929.html\n\nChanges made:\n* Added tests\n* Added comments to filter_refs()\n* Small structural changes\n* Various coding style fixes\n\nThanks to Junio C Hamano, Matthieu Moy, and Christian Couder for all\nthe suggestions.\n\n-- \nRegards,\nKarthik Nayak\n"},{"id":"263754","messageId":"1434226706-3764-1-git-send-email-karthik.188@gmail.com","threadId":"39620","inReplyTo":"CAOLa=ZRA7jVhs-NixjP+EFqfBNwLEfU-WgEMMQzb5NC+HZDYiw@mail.gmail.com","subject":"[PATCH v2 01/11] t6301: for-each-ref tests for ref-filter APIs","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-13T20:18:16Z","receivedAt":"2015-06-13T20:18:16Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Add tests for for-each-ref which utilizes the ref-filter APIs.\n\nBased-on-patch-by: Jeff King <peff@peff.net>\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>\nSigned-off-by: Karthik Nayak <karthik.188@gmail.com>\n---\n t/t6301-for-each-ref-filter.sh | 35 +++++++++++++++++++++++++++++++++++\n 1 file changed, 35 insertions(+)\n create mode 100644 t/t6301-for-each-ref-filter.sh\n\ndiff --git a/t/t6301-for-each-ref-filter.sh b/t/t6301-for-each-ref-filter.sh\nnew file mode 100644\nindex 0000000..5bd49b3\n--- /dev/null\n+++ b/t/t6301-for-each-ref-filter.sh\n@@ -0,0 +1,35 @@\n+#!/bin/sh\n+\n+test_description='test for-each-refs usage of ref-filter APIs'\n+\n+. ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-gpg.sh\n+\n+test_expect_success 'setup some history and refs' '\n+\ttest_commit one &&\n+\ttest_commit two &&\n+\ttest_commit three &&\n+\tgit checkout -b side &&\n+\ttest_commit four &&\n+\tgit checkout master &&\n+\tgit update-ref refs/odd/spot master\n+'\n+test_expect_success 'filtering by leading name' '\n+\tcat >expect <<-\\EOF &&\n+\trefs/heads/master\n+\trefs/heads/side\n+\tEOF\n+\tgit for-each-ref --format=\"%(refname)\" refs/heads >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'filtering with fnmatch' '\n+\tcat >expect <<-\\EOF &&\n+\trefs/tags/three\n+\trefs/tags/two\n+\tEOF\n+\tgit for-each-ref --format=\"%(refname)\" refs/tags/t* >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_done\n-- \n2.4.3.435.g2403634.dirty\n"},{"id":"263752","messageId":"1434226706-3764-2-git-send-email-karthik.188@gmail.com","threadId":"39620","inReplyTo":"1434226706-3764-1-git-send-email-karthik.188@gmail.com","subject":"[PATCH v2 02/11] tag: libify parse_opt_points_at()","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-13T20:18:17Z","receivedAt":"2015-06-13T20:18:17Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Rename 'parse_opt_points_at()' to 'parse_opt_object_name()' and\nmove it from 'tag.c' to 'parse-options'. This now acts as a common\nparse_opt function which accepts an objectname and stores it into\na sha1_array.\n\nBased-on-patch-by: Jeff King <peff@peff.net>\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>\nSigned-off-by: Karthik Nayak <karthik.188@gmail.com>\n---\n builtin/tag.c      | 21 ++-------------------\n parse-options-cb.c | 17 +++++++++++++++++\n parse-options.h    |  1 +\n 3 files changed, 20 insertions(+), 19 deletions(-)\n\ndiff --git a/builtin/tag.c b/builtin/tag.c\nindex 5f6cdc5..e36c43e 100644\n--- a/builtin/tag.c\n+++ b/builtin/tag.c\n@@ -546,23 +546,6 @@ static int strbuf_check_tag_ref(struct strbuf *sb, const char *name)\n \treturn check_refname_format(sb->buf, 0);\n }\n \n-static int parse_opt_points_at(const struct option *opt __attribute__((unused)),\n-\t\t\tconst char *arg, int unset)\n-{\n-\tunsigned char sha1[20];\n-\n-\tif (unset) {\n-\t\tsha1_array_clear(&points_at);\n-\t\treturn 0;\n-\t}\n-\tif (!arg)\n-\t\treturn error(_(\"switch 'points-at' requires an object\"));\n-\tif (get_sha1(arg, sha1))\n-\t\treturn error(_(\"malformed object name '%s'\"), arg);\n-\tsha1_array_append(&points_at, sha1);\n-\treturn 0;\n-}\n-\n static int parse_opt_sort(const struct option *opt, const char *arg, int unset)\n {\n \tint *sort = opt->value;\n@@ -625,8 +608,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \t\t\tparse_opt_with_commit, (intptr_t)\"HEAD\",\n \t\t},\n \t\t{\n-\t\t\tOPTION_CALLBACK, 0, \"points-at\", NULL, N_(\"object\"),\n-\t\t\tN_(\"print only tags of the object\"), 0, parse_opt_points_at\n+\t\t\tOPTION_CALLBACK, 0, \"points-at\", &points_at, N_(\"object\"),\n+\t\t\tN_(\"print only tags of the object\"), 0, parse_opt_object_name\n \t\t},\n \t\tOPT_END()\n \t};\ndiff --git a/parse-options-cb.c b/parse-options-cb.c\nindex be8c413..de75411 100644\n--- a/parse-options-cb.c\n+++ b/parse-options-cb.c\n@@ -4,6 +4,7 @@\n #include \"commit.h\"\n #include \"color.h\"\n #include \"string-list.h\"\n+#include \"sha1-array.h\"\n \n /*----- some often used options -----*/\n \n@@ -92,6 +93,22 @@ int parse_opt_with_commit(const struct option *opt, const char *arg, int unset)\n \treturn 0;\n }\n \n+int parse_opt_object_name(const struct option *opt, const char *arg, int unset)\n+{\n+\tunsigned char sha1[20];\n+\n+\tif (unset) {\n+\t\tsha1_array_clear(opt->value);\n+\t\treturn 0;\n+\t}\n+\tif (!arg)\n+\t\treturn -1;\n+\tif (get_sha1(arg, sha1))\n+\t\treturn error(_(\"malformed object name '%s'\"), arg);\n+\tsha1_array_append(opt->value, sha1);\n+\treturn 0;\n+}\n+\n int parse_opt_tertiary(const struct option *opt, const char *arg, int unset)\n {\n \tint *target = opt->value;\ndiff --git a/parse-options.h b/parse-options.h\nindex c71e9da..36c71fe 100644\n--- a/parse-options.h\n+++ b/parse-options.h\n@@ -220,6 +220,7 @@ extern int parse_opt_approxidate_cb(const struct option *, const char *, int);\n extern int parse_opt_expiry_date_cb(const struct option *, const char *, int);\n extern int parse_opt_color_flag_cb(const struct option *, const char *, int);\n extern int parse_opt_verbosity_cb(const struct option *, const char *, int);\n+extern int parse_opt_object_name(const struct option *, const char *, int);\n extern int parse_opt_with_commit(const struct option *, const char *, int);\n extern int parse_opt_tertiary(const struct option *, const char *, int);\n extern int parse_opt_string_list(const struct option *, const char *, int);\n-- \n2.4.3.435.g2403634.dirty\n"},{"id":"263753","messageId":"1434226706-3764-3-git-send-email-karthik.188@gmail.com","threadId":"39620","inReplyTo":"1434226706-3764-1-git-send-email-karthik.188@gmail.com","subject":"[PATCH v2 03/11] ref-filter: implement '--points-at' option","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-13T20:18:18Z","receivedAt":"2015-06-13T20:18:18Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"In 'tag -l' we have '--points-at' option which lets users\nlist only tags which point to a particular commit. Implement\nthis option in 'ref-filter.{c,h}' so that other commands can\nbenefit from this.\n\nThis is duplicated from tag.c, we will eventually remove that\nwhen we port tag.c to use ref-filter APIs.\n\nBased-on-patch-by: Jeff King <peff@peff.net>\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>\nSigned-off-by: Karthik Nayak <karthik.188@gmail.com>\n---\n builtin/tag.c |  4 ++++\n ref-filter.c  | 26 ++++++++++++++++++++++++++\n ref-filter.h  |  1 +\n 3 files changed, 31 insertions(+)\n\ndiff --git a/builtin/tag.c b/builtin/tag.c\nindex e36c43e..280981f 100644\n--- a/builtin/tag.c\n+++ b/builtin/tag.c\n@@ -56,6 +56,10 @@ static int match_pattern(const char **patterns, const char *ref)\n \treturn 0;\n }\n \n+/*\n+ * This is currently duplicated in ref-filter.c, and will eventually be\n+ * removed as we port tag.c to use the ref-filter APIs.\n+ */\n static const unsigned char *match_points_at(const char *refname,\n \t\t\t\t\t    const unsigned char *sha1)\n {\ndiff --git a/ref-filter.c b/ref-filter.c\nindex 43502a4..591e281 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -842,6 +842,29 @@ static int match_name_as_path(const char **pattern, const char *refname)\n \treturn 0;\n }\n \n+/*\n+ * Given a ref (sha1, refname) see if it points to a one of the sha1s\n+ * in a sha1_array.\n+ */\n+static int match_points_at(struct sha1_array *points_at, const unsigned char *sha1,\n+\t\t\t   const char *refname)\n+{\n+\tstruct object *obj;\n+\n+\tif (!points_at || !points_at->nr)\n+\t\treturn 1;\n+\n+\tif (sha1_array_lookup(points_at, sha1) >= 0)\n+\t\treturn 1;\n+\n+\tobj = parse_object_or_die(sha1, refname);\n+\tif (obj->type == OBJ_TAG &&\n+\t    sha1_array_lookup(points_at, ((struct tag *)obj)->tagged->sha1) >= 0)\n+\t\treturn 1;\n+\n+\treturn 0;\n+}\n+\n /* Allocate space for a new ref_array_item and copy the objectname and flag to it */\n static struct ref_array_item *new_ref_array_item(const char *refname,\n \t\t\t\t\t\t const unsigned char *objectname,\n@@ -875,6 +898,9 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid,\n \tif (*filter->name_patterns && !match_name_as_path(filter->name_patterns, refname))\n \t\treturn 0;\n \n+\tif (!match_points_at(&filter->points_at, oid->hash, refname))\n+\t\treturn 0;\n+\n \t/*\n \t * We do not open the object yet; sort may only need refname\n \t * to do its job and the resulting list may yet to be pruned\ndiff --git a/ref-filter.h b/ref-filter.h\nindex 6997984..c2856b8 100644\n--- a/ref-filter.h\n+++ b/ref-filter.h\n@@ -42,6 +42,7 @@ struct ref_array {\n \n struct ref_filter {\n \tconst char **name_patterns;\n+\tstruct sha1_array points_at;\n };\n \n struct ref_filter_cbdata {\n-- \n2.4.3.435.g2403634.dirty\n"},{"id":"263755","messageId":"1434226706-3764-4-git-send-email-karthik.188@gmail.com","threadId":"39620","inReplyTo":"1434226706-3764-1-git-send-email-karthik.188@gmail.com","subject":"[PATCH v2 04/11] for-each-ref: add '--points-at' option","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-13T20:18:19Z","receivedAt":"2015-06-13T20:18:19Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Add the '--points-at' option provided by 'ref-filter'. The\noption lets the user to pick only refs which point to a particular\ncommit.\n\nAdd documentation and tests for the same.\n\nBased-on-patch-by: Jeff King <peff@peff.net>\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>\nSigned-off-by: Karthik Nayak <karthik.188@gmail.com>\n---\n Documentation/git-for-each-ref.txt |  3 +++\n builtin/for-each-ref.c             |  9 +++++++--\n t/t6301-for-each-ref-filter.sh     | 10 ++++++++++\n 3 files changed, 20 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt\nindex 7f8d9a5..0524ac4 100644\n--- a/Documentation/git-for-each-ref.txt\n+++ b/Documentation/git-for-each-ref.txt\n@@ -10,6 +10,7 @@ SYNOPSIS\n [verse]\n 'git for-each-ref' [--count=<count>] [--shell|--perl|--python|--tcl]\n \t\t   [(--sort=<key>)...] [--format=<format>] [<pattern>...]\n+\t\t   [--points-at <object>]\n \n DESCRIPTION\n -----------\n@@ -62,6 +63,8 @@ OPTIONS\n \tthe specified host language.  This is meant to produce\n \ta scriptlet that can directly be `eval`ed.\n \n+--points-at <object>::\n+\tOnly list refs of the given object.\n \n FIELD NAMES\n -----------\ndiff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c\nindex 7919206..2dee149 100644\n--- a/builtin/for-each-ref.c\n+++ b/builtin/for-each-ref.c\n@@ -7,6 +7,7 @@\n \n static char const * const for_each_ref_usage[] = {\n \tN_(\"git for-each-ref [<options>] [<pattern>]\"),\n+\tN_(\"git for-each-ref [--points-at <object>]\"),\n \tNULL\n };\n \n@@ -34,9 +35,15 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)\n \t\tOPT_STRING(  0 , \"format\", &format, N_(\"format\"), N_(\"format to use for the output\")),\n \t\tOPT_CALLBACK(0 , \"sort\", sorting_tail, N_(\"key\"),\n \t\t\t    N_(\"field name to sort on\"), &parse_opt_ref_sorting),\n+\t\tOPT_CALLBACK(0, \"points-at\", &filter.points_at,\n+\t\t\t     N_(\"object\"), N_(\"print only refs of the object\"),\n+\t\t\t     parse_opt_object_name),\n \t\tOPT_END(),\n \t};\n \n+\tmemset(&array, 0, sizeof(array));\n+\tmemset(&filter, 0, sizeof(filter));\n+\n \tparse_options(argc, argv, prefix, opts, for_each_ref_usage, 0);\n \tif (maxcount < 0) {\n \t\terror(\"invalid --count argument: `%d'\", maxcount);\n@@ -55,8 +62,6 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)\n \t/* for warn_ambiguous_refs */\n \tgit_config(git_default_config, NULL);\n \n-\tmemset(&array, 0, sizeof(array));\n-\tmemset(&filter, 0, sizeof(filter));\n \tfilter.name_patterns = argv;\n \tfilter_refs(&array, &filter, FILTER_REFS_ALL | FILTER_REFS_INCLUDE_BROKEN);\n \tref_array_sort(sorting, &array);\ndiff --git a/t/t6301-for-each-ref-filter.sh b/t/t6301-for-each-ref-filter.sh\nindex 5bd49b3..3a1c3f6 100644\n--- a/t/t6301-for-each-ref-filter.sh\n+++ b/t/t6301-for-each-ref-filter.sh\n@@ -32,4 +32,14 @@ test_expect_success 'filtering with fnmatch' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'filtering with --points-at' '\n+\tcat >expect <<-\\EOF &&\n+\trefs/heads/master\n+\trefs/odd/spot\n+\trefs/tags/three\n+\tEOF\n+\tgit for-each-ref --format=\"%(refname)\" --points-at=master >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\n-- \n2.4.3.435.g2403634.dirty\n"},{"id":"263756","messageId":"1434226706-3764-5-git-send-email-karthik.188@gmail.com","threadId":"39620","inReplyTo":"1434226706-3764-1-git-send-email-karthik.188@gmail.com","subject":"[PATCH v2 05/11] ref-filter: add parse_opt_merge_filter()","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-13T20:18:20Z","receivedAt":"2015-06-13T20:18:20Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Add 'parse_opt_merge_filter()' to parse '--merged' and '--no-merged'\noptions and write MACROS for the same.\n\nThis is copied from 'builtin/branch.c' which will eventually be removed\nwhen we port 'branch.c' to use ref-filter APIs.\n\nBased-on-patch-by: Jeff King <peff@peff.net>\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>\nSigned-off-by: Karthik Nayak <karthik.188@gmail.com>\n---\n builtin/branch.c |  4 ++++\n ref-filter.c     | 21 +++++++++++++++++++++\n ref-filter.h     | 14 ++++++++++++++\n 3 files changed, 39 insertions(+)\n\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex b42e5b6..ddd90e6 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -745,6 +745,10 @@ static void rename_branch(const char *oldname, const char *newname, int force)\n \tstrbuf_release(&newsection);\n }\n \n+/*\n+ * This function is duplicated in ref-filter. It will eventually be removed\n+ * when we port branch.c to use ref-filter APIs.\n+ */\n static int opt_parse_merge_filter(const struct option *opt, const char *arg, int unset)\n {\n \tmerge_filter = ((opt->long_name[0] == 'n')\ndiff --git a/ref-filter.c b/ref-filter.c\nindex 591e281..6502179 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -1125,3 +1125,24 @@ int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset)\n \ts->atom = parse_ref_filter_atom(arg, arg+len);\n \treturn 0;\n }\n+\n+int parse_opt_merge_filter(const struct option *opt, const char *arg, int unset)\n+{\n+\tstruct ref_filter *rf = opt->value;\n+\tunsigned char sha1[20];\n+\n+\trf->merge = starts_with(opt->long_name, \"no\")\n+\t\t? REF_FILTER_MERGED_OMIT\n+\t\t: REF_FILTER_MERGED_INCLUDE;\n+\n+\tif (!arg)\n+\t\targ = \"HEAD\";\n+\tif (get_sha1(arg, sha1))\n+\t\tdie(_(\"malformed object name %s\"), arg);\n+\n+\trf->merge_commit = lookup_commit_reference_gently(sha1, 0);\n+\tif (!rf->merge_commit)\n+\t\treturn opterror(opt, \"must point to a commit\", 0);\n+\n+\treturn 0;\n+}\ndiff --git a/ref-filter.h b/ref-filter.h\nindex c2856b8..799e118 100644\n--- a/ref-filter.h\n+++ b/ref-filter.h\n@@ -50,6 +50,18 @@ struct ref_filter_cbdata {\n \tstruct ref_filter *filter;\n };\n \n+/*  Macros for checking --merged and --no-merged options */\n+#define OPT_NO_MERGED(filter, h) \\\n+\t{ OPTION_CALLBACK, 0, \"no-merged\", (filter), N_(\"commit\"), (h), \\\n+\t  PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG, \\\n+\t  parse_opt_merge_filter, (intptr_t) \"HEAD\" \\\n+\t}\n+#define OPT_MERGED(filter, h) \\\n+\t{ OPTION_CALLBACK, 0, \"merged\", (filter), N_(\"commit\"), (h), \\\n+\t  PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG, \\\n+\t  parse_opt_merge_filter, (intptr_t) \"HEAD\" \\\n+\t}\n+\n /*\n  * API for filtering a set of refs. Based on the type of refs the user\n  * has requested, we iterate through those refs and apply filters\n@@ -71,5 +83,7 @@ void show_ref_array_item(struct ref_array_item *info, const char *format, int qu\n int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset);\n /*  Default sort option based on refname */\n struct ref_sorting *ref_default_sorting(void);\n+/*  Function to parse --merged and --no-merged options */\n+int parse_opt_merge_filter(const struct option *opt, const char *arg, int unset);\n \n #endif /*  REF_FILTER_H  */\n-- \n2.4.3.435.g2403634.dirty\n"},{"id":"263757","messageId":"1434226706-3764-6-git-send-email-karthik.188@gmail.com","threadId":"39620","inReplyTo":"1434226706-3764-1-git-send-email-karthik.188@gmail.com","subject":"[PATCH v2 06/11] ref-filter: implement '--merged' and '--no-merged' options","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-13T20:18:21Z","receivedAt":"2015-06-13T20:18:21Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"In 'branch -l' we have '--merged' option which only lists refs (branches)\nmerged into the named commit and '--no-merged' option which only lists\nrefs (branches) not merged into the named commit. Implement these two\noptions in ref-filter.{c,h} so that other commands can benefit from this.\n\nBased-on-patch-by: Jeff King <peff@peff.net>\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>\nSigned-off-by: Karthik Nayak <karthik.188@gmail.com>\n---\n ref-filter.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----\n ref-filter.h |  8 +++++++\n 2 files changed, 72 insertions(+), 4 deletions(-)\n\ndiff --git a/ref-filter.c b/ref-filter.c\nindex 6502179..06328eb 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -9,6 +9,7 @@\n #include \"tag.h\"\n #include \"quote.h\"\n #include \"ref-filter.h\"\n+#include \"revision.h\"\n \n typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;\n \n@@ -889,6 +890,7 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid,\n \tstruct ref_filter_cbdata *ref_cbdata = cb_data;\n \tstruct ref_filter *filter = ref_cbdata->filter;\n \tstruct ref_array_item *ref;\n+\tstruct commit *commit = NULL;\n \n \tif (flag & REF_BAD_NAME) {\n \t\t  warning(\"ignoring ref with broken name %s\", refname);\n@@ -901,12 +903,19 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid,\n \tif (!match_points_at(&filter->points_at, oid->hash, refname))\n \t\treturn 0;\n \n+\tif (filter->merge_commit) {\n+\t\tcommit = lookup_commit_reference_gently(oid->hash, 1);\n+\t\tif (!commit)\n+\t\t\treturn 0;\n+\t}\n+\n \t/*\n \t * We do not open the object yet; sort may only need refname\n \t * to do its job and the resulting list may yet to be pruned\n \t * by maxcount logic.\n \t */\n \tref = new_ref_array_item(refname, oid->hash, flag);\n+\tref->commit = commit;\n \n \tREALLOC_ARRAY(ref_cbdata->array->items, ref_cbdata->array->nr + 1);\n \tref_cbdata->array->items[ref_cbdata->array->nr++] = ref;\n@@ -932,6 +941,50 @@ void ref_array_clear(struct ref_array *array)\n \tarray->nr = array->alloc = 0;\n }\n \n+static void do_merge_filter(struct ref_filter_cbdata *ref_cbdata)\n+{\n+\tstruct rev_info revs;\n+\tint i, old_nr;\n+\tstruct ref_filter *filter = ref_cbdata->filter;\n+\tstruct ref_array *array = ref_cbdata->array;\n+\tstruct commit_list *p, *to_clear = NULL;\n+\n+\tinit_revisions(&revs, NULL);\n+\n+\tfor (i = 0; i < array->nr; i++) {\n+\t\tstruct ref_array_item *item = array->items[i];\n+\t\tadd_pending_object(&revs, &item->commit->object, item->refname);\n+\t\tcommit_list_insert(item->commit, &to_clear);\n+\t}\n+\n+\tfilter->merge_commit->object.flags |= UNINTERESTING;\n+\tadd_pending_object(&revs, &filter->merge_commit->object, \"\");\n+\n+\trevs.limited = 1;\n+\tif (prepare_revision_walk(&revs))\n+\t\tdie(_(\"revision walk setup failed\"));\n+\n+\told_nr = array->nr;\n+\tarray->nr = 0;\n+\n+\tfor (i = 0; i < old_nr; i++) {\n+\t\tstruct ref_array_item *item = array->items[i];\n+\t\tstruct commit *commit = item->commit;\n+\n+\t\tint is_merged = !!(commit->object.flags & UNINTERESTING);\n+\n+\t\tif (is_merged == (filter->merge == REF_FILTER_MERGED_INCLUDE))\n+\t\t\tarray->items[array->nr++] = array->items[i];\n+\t\telse\n+\t\t\tfree_array_item(item);\n+\t}\n+\n+\tfor (p = to_clear; p; p = p->next)\n+\t\tclear_commit_marks(p->item, ALL_REV_FLAGS);\n+\tclear_commit_marks(filter->merge_commit, ALL_REV_FLAGS);\n+\tfree_commit_list(to_clear);\n+}\n+\n /*\n  * API for filtering a set of refs. Based on the type of refs the user\n  * has requested, we iterate through those refs and apply filters\n@@ -941,17 +994,24 @@ void ref_array_clear(struct ref_array *array)\n int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int type)\n {\n \tstruct ref_filter_cbdata ref_cbdata;\n+\tint ret = 0;\n \n \tref_cbdata.array = array;\n \tref_cbdata.filter = filter;\n \n+\t/*  Simple per-ref filtering */\n \tif (type & (FILTER_REFS_ALL | FILTER_REFS_INCLUDE_BROKEN))\n-\t\treturn for_each_rawref(ref_filter_handler, &ref_cbdata);\n+\t\tret = for_each_rawref(ref_filter_handler, &ref_cbdata);\n \telse if (type & FILTER_REFS_ALL)\n-\t\treturn for_each_ref(ref_filter_handler, &ref_cbdata);\n-\telse\n+\t\tret = for_each_ref(ref_filter_handler, &ref_cbdata);\n+\telse if (type)\n \t\tdie(\"filter_refs: invalid type\");\n-\treturn 0;\n+\n+\t/*  Filters that need revision walking */\n+\tif (filter->merge_commit)\n+\t\tdo_merge_filter(&ref_cbdata);\n+\n+\treturn ret;\n }\n \n static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, struct ref_array_item *b)\ndiff --git a/ref-filter.h b/ref-filter.h\nindex 799e118..39d66b0 100644\n--- a/ref-filter.h\n+++ b/ref-filter.h\n@@ -31,6 +31,7 @@ struct ref_array_item {\n \tunsigned char objectname[20];\n \tint flag;\n \tconst char *symref;\n+\tstruct commit *commit;\n \tstruct atom_value *value;\n \tchar refname[FLEX_ARRAY];\n };\n@@ -43,6 +44,13 @@ struct ref_array {\n struct ref_filter {\n \tconst char **name_patterns;\n \tstruct sha1_array points_at;\n+\n+\tenum {\n+\t\tREF_FILTER_MERGED_NONE = 0,\n+\t\tREF_FILTER_MERGED_INCLUDE,\n+\t\tREF_FILTER_MERGED_OMIT\n+\t} merge;\n+\tstruct commit *merge_commit;\n };\n \n struct ref_filter_cbdata {\n-- \n2.4.3.435.g2403634.dirty\n"},{"id":"263758","messageId":"1434226706-3764-7-git-send-email-karthik.188@gmail.com","threadId":"39620","inReplyTo":"1434226706-3764-1-git-send-email-karthik.188@gmail.com","subject":"[PATCH v2 07/11] for-each-ref: add '--merged' and '--no-merged' options","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-13T20:18:22Z","receivedAt":"2015-06-13T20:18:22Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Add the '--merged' and '--no-merged' options provided by 'ref-filter'.\nThe '--merged' option lets the user to only list refs merged into the\nnamed commit. The '--no-merged' option lets the user to only list refs\nnot merged into the named commit.\n\nAdd documentation and tests for the same.\n\nBased-on-patch-by: Jeff King <peff@peff.net>\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>\nSigned-off-by: Karthik Nayak <karthik.188@gmail.com>\n---\n Documentation/git-for-each-ref.txt | 10 +++++++++-\n builtin/for-each-ref.c             |  3 +++\n t/t6301-for-each-ref-filter.sh     | 21 +++++++++++++++++++++\n 3 files changed, 33 insertions(+), 1 deletion(-)\n\ndiff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt\nindex 0524ac4..d61a756 100644\n--- a/Documentation/git-for-each-ref.txt\n+++ b/Documentation/git-for-each-ref.txt\n@@ -10,7 +10,7 @@ SYNOPSIS\n [verse]\n 'git for-each-ref' [--count=<count>] [--shell|--perl|--python|--tcl]\n \t\t   [(--sort=<key>)...] [--format=<format>] [<pattern>...]\n-\t\t   [--points-at <object>]\n+\t\t   [--points-at <object>] [(--merged | --no-merged) <object>]\n \n DESCRIPTION\n -----------\n@@ -66,6 +66,14 @@ OPTIONS\n --points-at <object>::\n \tOnly list refs of the given object.\n \n+--merged [<commit>]::\n+\tOnly list refs whose tips are reachable from the\n+\tspecified commit (HEAD if not specified).\n+\n+--no-merged [<commit>]::\n+\tOnly list refs whose tips are not reachable from the\n+\tspecified commit (HEAD if not specified).\n+\n FIELD NAMES\n -----------\n \ndiff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c\nindex 2dee149..00913f4 100644\n--- a/builtin/for-each-ref.c\n+++ b/builtin/for-each-ref.c\n@@ -8,6 +8,7 @@\n static char const * const for_each_ref_usage[] = {\n \tN_(\"git for-each-ref [<options>] [<pattern>]\"),\n \tN_(\"git for-each-ref [--points-at <object>]\"),\n+\tN_(\"git for-each-ref [(--merged | --no-merged) <object>]\"),\n \tNULL\n };\n \n@@ -38,6 +39,8 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)\n \t\tOPT_CALLBACK(0, \"points-at\", &filter.points_at,\n \t\t\t     N_(\"object\"), N_(\"print only refs of the object\"),\n \t\t\t     parse_opt_object_name),\n+\t\tOPT_MERGED(&filter, N_(\"print only refs that are merged\")),\n+\t\tOPT_NO_MERGED(&filter, N_(\"print only refs that are not merged\")),\n \t\tOPT_END(),\n \t};\n \ndiff --git a/t/t6301-for-each-ref-filter.sh b/t/t6301-for-each-ref-filter.sh\nindex 3a1c3f6..3ed97bd 100644\n--- a/t/t6301-for-each-ref-filter.sh\n+++ b/t/t6301-for-each-ref-filter.sh\n@@ -42,4 +42,25 @@ test_expect_success 'filtering with --points-at' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'filtering with --merged' '\n+\tcat >expect <<-\\EOF &&\n+\trefs/heads/master\n+\trefs/odd/spot\n+\trefs/tags/one\n+\trefs/tags/three\n+\trefs/tags/two\n+\tEOF\n+\tgit for-each-ref --format=\"%(refname)\" --merged=master >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'filtering with --no-merged' '\n+\tcat >expect <<-\\EOF &&\n+\trefs/heads/side\n+\trefs/tags/four\n+\tEOF\n+\tgit for-each-ref --format=\"%(refname)\" --no-merged=master >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\n-- \n2.4.3.435.g2403634.dirty\n"},{"id":"263759","messageId":"1434226706-3764-8-git-send-email-karthik.188@gmail.com","threadId":"39620","inReplyTo":"1434226706-3764-1-git-send-email-karthik.188@gmail.com","subject":"[PATCH v2 08/11] parse-option: rename parse_opt_with_commit()","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-13T20:18:23Z","receivedAt":"2015-06-13T20:18:23Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Rename parse_opt_with_commit() to parse_opt_commit_object_name()\nto show that it can be used to obtain a list of commits and is\nnot constricted to usage of '--contains' option.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>\nSigned-off-by: Karthik Nayak <karthik.188@gmail.com>\n---\n builtin/branch.c   | 4 ++--\n builtin/tag.c      | 4 ++--\n parse-options-cb.c | 2 +-\n parse-options.h    | 2 +-\n 4 files changed, 6 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex ddd90e6..ddd728e 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -828,13 +828,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)\n \t\t\tOPTION_CALLBACK, 0, \"contains\", &with_commit, N_(\"commit\"),\n \t\t\tN_(\"print only branches that contain the commit\"),\n \t\t\tPARSE_OPT_LASTARG_DEFAULT,\n-\t\t\tparse_opt_with_commit, (intptr_t)\"HEAD\",\n+\t\t\tparse_opt_commit_object_name, (intptr_t)\"HEAD\",\n \t\t},\n \t\t{\n \t\t\tOPTION_CALLBACK, 0, \"with\", &with_commit, N_(\"commit\"),\n \t\t\tN_(\"print only branches that contain the commit\"),\n \t\t\tPARSE_OPT_HIDDEN | PARSE_OPT_LASTARG_DEFAULT,\n-\t\t\tparse_opt_with_commit, (intptr_t) \"HEAD\",\n+\t\t\tparse_opt_commit_object_name, (intptr_t) \"HEAD\",\n \t\t},\n \t\tOPT__ABBREV(&abbrev),\n \ndiff --git a/builtin/tag.c b/builtin/tag.c\nindex 280981f..2d6610a 100644\n--- a/builtin/tag.c\n+++ b/builtin/tag.c\n@@ -603,13 +603,13 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \t\t\tOPTION_CALLBACK, 0, \"contains\", &with_commit, N_(\"commit\"),\n \t\t\tN_(\"print only tags that contain the commit\"),\n \t\t\tPARSE_OPT_LASTARG_DEFAULT,\n-\t\t\tparse_opt_with_commit, (intptr_t)\"HEAD\",\n+\t\t\tparse_opt_commit_object_name, (intptr_t)\"HEAD\",\n \t\t},\n \t\t{\n \t\t\tOPTION_CALLBACK, 0, \"with\", &with_commit, N_(\"commit\"),\n \t\t\tN_(\"print only tags that contain the commit\"),\n \t\t\tPARSE_OPT_HIDDEN | PARSE_OPT_LASTARG_DEFAULT,\n-\t\t\tparse_opt_with_commit, (intptr_t)\"HEAD\",\n+\t\t\tparse_opt_commit_object_name, (intptr_t)\"HEAD\",\n \t\t},\n \t\t{\n \t\t\tOPTION_CALLBACK, 0, \"points-at\", &points_at, N_(\"object\"),\ndiff --git a/parse-options-cb.c b/parse-options-cb.c\nindex de75411..8bec5e4 100644\n--- a/parse-options-cb.c\n+++ b/parse-options-cb.c\n@@ -77,7 +77,7 @@ int parse_opt_verbosity_cb(const struct option *opt, const char *arg,\n \treturn 0;\n }\n \n-int parse_opt_with_commit(const struct option *opt, const char *arg, int unset)\n+int parse_opt_commit_object_name(const struct option *opt, const char *arg, int unset)\n {\n \tunsigned char sha1[20];\n \tstruct commit *commit;\ndiff --git a/parse-options.h b/parse-options.h\nindex 36c71fe..8542d9c 100644\n--- a/parse-options.h\n+++ b/parse-options.h\n@@ -221,7 +221,7 @@ extern int parse_opt_expiry_date_cb(const struct option *, const char *, int);\n extern int parse_opt_color_flag_cb(const struct option *, const char *, int);\n extern int parse_opt_verbosity_cb(const struct option *, const char *, int);\n extern int parse_opt_object_name(const struct option *, const char *, int);\n-extern int parse_opt_with_commit(const struct option *, const char *, int);\n+extern int parse_opt_commit_object_name(const struct option *, const char *, int);\n extern int parse_opt_tertiary(const struct option *, const char *, int);\n extern int parse_opt_string_list(const struct option *, const char *, int);\n extern int parse_opt_noop_cb(const struct option *, const char *, int);\n-- \n2.4.3.435.g2403634.dirty\n"},{"id":"263760","messageId":"1434226706-3764-9-git-send-email-karthik.188@gmail.com","threadId":"39620","inReplyTo":"1434226706-3764-1-git-send-email-karthik.188@gmail.com","subject":"[PATCH v2 09/11] parse-options.h: add macros for '--contains' option","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-13T20:18:24Z","receivedAt":"2015-06-13T20:18:24Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Add a macro for using the '--contains' option in parse-options.h\nalso include an optional '--with' option macro which performs the\nsame action as '--contains'.\n\nMake tag.c use this new macro\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>\nSigned-off-by: Karthik Nayak <karthik.188@gmail.com>\n---\n builtin/tag.c   | 14 ++------------\n parse-options.h |  7 +++++++\n 2 files changed, 9 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/tag.c b/builtin/tag.c\nindex 2d6610a..767162e 100644\n--- a/builtin/tag.c\n+++ b/builtin/tag.c\n@@ -595,23 +595,13 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \n \t\tOPT_GROUP(N_(\"Tag listing options\")),\n \t\tOPT_COLUMN(0, \"column\", &colopts, N_(\"show tag list in columns\")),\n+\t\tOPT_CONTAINS(&with_commit, N_(\"print only tags that contain the commit\")),\n+\t\tOPT_WITH(&with_commit, N_(\"print only tags that contain the commit\")),\n \t\t{\n \t\t\tOPTION_CALLBACK, 0, \"sort\", &tag_sort, N_(\"type\"), N_(\"sort tags\"),\n \t\t\tPARSE_OPT_NONEG, parse_opt_sort\n \t\t},\n \t\t{\n-\t\t\tOPTION_CALLBACK, 0, \"contains\", &with_commit, N_(\"commit\"),\n-\t\t\tN_(\"print only tags that contain the commit\"),\n-\t\t\tPARSE_OPT_LASTARG_DEFAULT,\n-\t\t\tparse_opt_commit_object_name, (intptr_t)\"HEAD\",\n-\t\t},\n-\t\t{\n-\t\t\tOPTION_CALLBACK, 0, \"with\", &with_commit, N_(\"commit\"),\n-\t\t\tN_(\"print only tags that contain the commit\"),\n-\t\t\tPARSE_OPT_HIDDEN | PARSE_OPT_LASTARG_DEFAULT,\n-\t\t\tparse_opt_commit_object_name, (intptr_t)\"HEAD\",\n-\t\t},\n-\t\t{\n \t\t\tOPTION_CALLBACK, 0, \"points-at\", &points_at, N_(\"object\"),\n \t\t\tN_(\"print only tags of the object\"), 0, parse_opt_object_name\n \t\t},\ndiff --git a/parse-options.h b/parse-options.h\nindex 8542d9c..d76e907 100644\n--- a/parse-options.h\n+++ b/parse-options.h\n@@ -243,5 +243,12 @@ extern int parse_opt_noop_cb(const struct option *, const char *, int);\n \tOPT_COLOR_FLAG(0, \"color\", (var), (h))\n #define OPT_COLUMN(s, l, v, h) \\\n \t{ OPTION_CALLBACK, (s), (l), (v), N_(\"style\"), (h), PARSE_OPT_OPTARG, parseopt_column_callback }\n+#define _OPT_CONTAINS_OR_WITH(name, variable, help) \\\n+\t{ OPTION_CALLBACK, 0, name, (variable), N_(\"commit\"), (help), \\\n+\t  PARSE_OPT_LASTARG_DEFAULT, \\\n+\t  parse_opt_commit_object_name, (intptr_t) \"HEAD\" \\\n+\t}\n+#define OPT_CONTAINS(v, h) _OPT_CONTAINS_OR_WITH(\"contains\", v, h)\n+#define OPT_WITH(v, h) _OPT_CONTAINS_OR_WITH(\"contains\", v, h)\n \n #endif\n-- \n2.4.3.435.g2403634.dirty\n"},{"id":"263761","messageId":"1434226706-3764-10-git-send-email-karthik.188@gmail.com","threadId":"39620","inReplyTo":"1434226706-3764-1-git-send-email-karthik.188@gmail.com","subject":"[PATCH v2 10/11] ref-filter: implement '--contains' option","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-13T20:18:25Z","receivedAt":"2015-06-13T20:18:25Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"'tag -l' and 'branch -l' have two different ways of finding\nout if a certain ref contains a commit. Implement both these\nmethods in ref-filter and give the caller of ref-filter API\nthe option to pick which implementation to be used.\n\n'branch -l' uses 'is_descendant_of()' from commit.c which is\nleft as the default implementation to be used.\n\n'tag -l' uses a more specific algorithm since ffc4b80. This\nimplementation is used whenever the 'with_commit_tag_algo' bit\nis set in 'struct ref_filter'.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>\nSigned-off-by: Karthik Nayak <karthik.188@gmail.com>\n---\n ref-filter.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n ref-filter.h |   3 ++\n 2 files changed, 114 insertions(+), 1 deletion(-)\n\ndiff --git a/ref-filter.c b/ref-filter.c\nindex 06328eb..40eb90e 100644\n--- a/ref-filter.c\n+++ b/ref-filter.c\n@@ -818,6 +818,113 @@ static void get_ref_atom_value(struct ref_array_item *ref, int atom, struct atom\n \t*v = &ref->value[atom];\n }\n \n+enum contains_result {\n+\tCONTAINS_UNKNOWN = -1,\n+\tCONTAINS_NO = 0,\n+\tCONTAINS_YES = 1\n+};\n+\n+/*\n+ * Mimicking the real stack, this stack lives on the heap, avoiding stack\n+ * overflows.\n+ *\n+ * At each recursion step, the stack items points to the commits whose\n+ * ancestors are to be inspected.\n+ */\n+struct contains_stack {\n+\tint nr, alloc;\n+\tstruct contains_stack_entry {\n+\t\tstruct commit *commit;\n+\t\tstruct commit_list *parents;\n+\t} *contains_stack;\n+};\n+\n+static int in_commit_list(const struct commit_list *want, struct commit *c)\n+{\n+\tfor (; want; want = want->next)\n+\t\tif (!hashcmp(want->item->object.sha1, c->object.sha1))\n+\t\t\treturn 1;\n+\treturn 0;\n+}\n+\n+/*\n+ * Test whether the candidate or one of its parents is contained in the list.\n+ * Do not recurse to find out, though, but return -1 if inconclusive.\n+ */\n+static enum contains_result contains_test(struct commit *candidate,\n+\t\t\t    const struct commit_list *want)\n+{\n+\t/* was it previously marked as containing a want commit? */\n+\tif (candidate->object.flags & TMP_MARK)\n+\t\treturn 1;\n+\t/* or marked as not possibly containing a want commit? */\n+\tif (candidate->object.flags & UNINTERESTING)\n+\t\treturn 0;\n+\t/* or are we it? */\n+\tif (in_commit_list(want, candidate)) {\n+\t\tcandidate->object.flags |= TMP_MARK;\n+\t\treturn 1;\n+\t}\n+\n+\tif (parse_commit(candidate) < 0)\n+\t\treturn 0;\n+\n+\treturn -1;\n+}\n+\n+static void push_to_contains_stack(struct commit *candidate, struct contains_stack *contains_stack)\n+{\n+\tALLOC_GROW(contains_stack->contains_stack, contains_stack->nr + 1, contains_stack->alloc);\n+\tcontains_stack->contains_stack[contains_stack->nr].commit = candidate;\n+\tcontains_stack->contains_stack[contains_stack->nr++].parents = candidate->parents;\n+}\n+\n+static enum contains_result contains_tag_algo(struct commit *candidate,\n+\t\tconst struct commit_list *want)\n+{\n+\tstruct contains_stack contains_stack = { 0, 0, NULL };\n+\tint result = contains_test(candidate, want);\n+\n+\tif (result != CONTAINS_UNKNOWN)\n+\t\treturn result;\n+\n+\tpush_to_contains_stack(candidate, &contains_stack);\n+\twhile (contains_stack.nr) {\n+\t\tstruct contains_stack_entry *entry = &contains_stack.contains_stack[contains_stack.nr - 1];\n+\t\tstruct commit *commit = entry->commit;\n+\t\tstruct commit_list *parents = entry->parents;\n+\n+\t\tif (!parents) {\n+\t\t\tcommit->object.flags |= UNINTERESTING;\n+\t\t\tcontains_stack.nr--;\n+\t\t}\n+\t\t/*\n+\t\t * If we just popped the stack, parents->item has been marked,\n+\t\t * therefore contains_test will return a meaningful 0 or 1.\n+\t\t */\n+\t\telse switch (contains_test(parents->item, want)) {\n+\t\tcase CONTAINS_YES:\n+\t\t\tcommit->object.flags |= TMP_MARK;\n+\t\t\tcontains_stack.nr--;\n+\t\t\tbreak;\n+\t\tcase CONTAINS_NO:\n+\t\t\tentry->parents = parents->next;\n+\t\t\tbreak;\n+\t\tcase CONTAINS_UNKNOWN:\n+\t\t\tpush_to_contains_stack(parents->item, &contains_stack);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\tfree(contains_stack.contains_stack);\n+\treturn contains_test(candidate, want);\n+}\n+\n+static int commit_contains(struct ref_filter *filter, struct commit *commit)\n+{\n+\tif (filter->with_commit_tag_algo)\n+\t\treturn contains_tag_algo(commit, filter->with_commit);\n+\treturn is_descendant_of(commit, filter->with_commit);\n+}\n /*\n  * Return 1 if the refname matches one of the patterns, otherwise 0.\n  * A pattern can be path prefix (e.g. a refname \"refs/heads/master\"\n@@ -903,10 +1010,13 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid,\n \tif (!match_points_at(&filter->points_at, oid->hash, refname))\n \t\treturn 0;\n \n-\tif (filter->merge_commit) {\n+\tif (filter->merge_commit || filter->with_commit) {\n \t\tcommit = lookup_commit_reference_gently(oid->hash, 1);\n \t\tif (!commit)\n \t\t\treturn 0;\n+\t\tif (filter->with_commit &&\n+\t\t    !commit_contains(filter, commit))\n+\t\t\treturn 0;\n \t}\n \n \t/*\ndiff --git a/ref-filter.h b/ref-filter.h\nindex 39d66b0..e614713 100644\n--- a/ref-filter.h\n+++ b/ref-filter.h\n@@ -44,6 +44,7 @@ struct ref_array {\n struct ref_filter {\n \tconst char **name_patterns;\n \tstruct sha1_array points_at;\n+\tstruct commit_list *with_commit;\n \n \tenum {\n \t\tREF_FILTER_MERGED_NONE = 0,\n@@ -51,6 +52,8 @@ struct ref_filter {\n \t\tREF_FILTER_MERGED_OMIT\n \t} merge;\n \tstruct commit *merge_commit;\n+\n+\tunsigned int with_commit_tag_algo: 1;\n };\n \n struct ref_filter_cbdata {\n-- \n2.4.3.435.g2403634.dirty\n"},{"id":"263762","messageId":"1434226706-3764-11-git-send-email-karthik.188@gmail.com","threadId":"39620","inReplyTo":"1434226706-3764-1-git-send-email-karthik.188@gmail.com","subject":"[PATCH v2 11/11] for-each-ref: add '--contains' option","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-13T20:18:26Z","receivedAt":"2015-06-13T20:18:26Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Add the '--contains' option provided by 'ref-filter'. The '--contains'\noption lists only refs which are contain the mentioned commit (HEAD if\nno commit is explicitly given).\n\nAdd documentation and tests for the same.\n\nMentored-by: Christian Couder <christian.couder@gmail.com>\nMentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>\nSigned-off-by: Karthik Nayak <karthik.188@gmail.com>\n---\n Documentation/git-for-each-ref.txt |  5 +++++\n builtin/for-each-ref.c             |  2 ++\n t/t6301-for-each-ref-filter.sh     | 13 +++++++++++++\n 3 files changed, 20 insertions(+)\n\ndiff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt\nindex d61a756..7a949f3 100644\n--- a/Documentation/git-for-each-ref.txt\n+++ b/Documentation/git-for-each-ref.txt\n@@ -11,6 +11,7 @@ SYNOPSIS\n 'git for-each-ref' [--count=<count>] [--shell|--perl|--python|--tcl]\n \t\t   [(--sort=<key>)...] [--format=<format>] [<pattern>...]\n \t\t   [--points-at <object>] [(--merged | --no-merged) <object>]\n+\t\t   [--contains <object>]\n \n DESCRIPTION\n -----------\n@@ -74,6 +75,10 @@ OPTIONS\n \tOnly list refs whose tips are not reachable from the\n \tspecified commit (HEAD if not specified).\n \n+--contains [<commit>]::\n+\tOnly list tags which contain the specified commit (HEAD if not\n+\tspecified).\n+\n FIELD NAMES\n -----------\n \ndiff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c\nindex 00913f4..8ccbb1c 100644\n--- a/builtin/for-each-ref.c\n+++ b/builtin/for-each-ref.c\n@@ -9,6 +9,7 @@ static char const * const for_each_ref_usage[] = {\n \tN_(\"git for-each-ref [<options>] [<pattern>]\"),\n \tN_(\"git for-each-ref [--points-at <object>]\"),\n \tN_(\"git for-each-ref [(--merged | --no-merged) <object>]\"),\n+\tN_(\"git for-each-ref [--contains <object>]\"),\n \tNULL\n };\n \n@@ -41,6 +42,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)\n \t\t\t     parse_opt_object_name),\n \t\tOPT_MERGED(&filter, N_(\"print only refs that are merged\")),\n \t\tOPT_NO_MERGED(&filter, N_(\"print only refs that are not merged\")),\n+\t\tOPT_CONTAINS(&filter.with_commit, N_(\"print only refs which contain the commit\")),\n \t\tOPT_END(),\n \t};\n \ndiff --git a/t/t6301-for-each-ref-filter.sh b/t/t6301-for-each-ref-filter.sh\nindex 3ed97bd..17cf7b0 100644\n--- a/t/t6301-for-each-ref-filter.sh\n+++ b/t/t6301-for-each-ref-filter.sh\n@@ -63,4 +63,17 @@ test_expect_success 'filtering with --no-merged' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'filtering with --contains' '\n+\tcat >expect <<-\\EOF &&\n+\trefs/heads/master\n+\trefs/heads/side\n+\trefs/odd/spot\n+\trefs/tags/four\n+\trefs/tags/three\n+\trefs/tags/two\n+\tEOF\n+\tgit for-each-ref --format=\"%(refname)\" --contains=two >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\n-- \n2.4.3.435.g2403634.dirty\n"},{"id":"263780","messageId":"CAP8UFD1Qw+ctvz_CbBoE-jb5_bC3jogAsTgp-mgkVBFG1y7SiQ@mail.gmail.com","threadId":"39620","inReplyTo":"1434226706-3764-5-git-send-email-karthik.188@gmail.com","subject":"Re: [PATCH v2 05/11] ref-filter: add parse_opt_merge_filter()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-06-14T05:49:40Z","receivedAt":"2015-06-14T05:49:40Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Sat, Jun 13, 2015 at 10:18 PM, Karthik Nayak <karthik.188@gmail.com> wrote:\n>\n> diff --git a/ref-filter.h b/ref-filter.h\n> index c2856b8..799e118 100644\n> --- a/ref-filter.h\n> +++ b/ref-filter.h\n> @@ -50,6 +50,18 @@ struct ref_filter_cbdata {\n>         struct ref_filter *filter;\n>  };\n>\n> +/*  Macros for checking --merged and --no-merged options */\n> +#define OPT_NO_MERGED(filter, h) \\\n> +       { OPTION_CALLBACK, 0, \"no-merged\", (filter), N_(\"commit\"), (h), \\\n> +         PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG, \\\n> +         parse_opt_merge_filter, (intptr_t) \"HEAD\" \\\n> +       }\n> +#define OPT_MERGED(filter, h) \\\n> +       { OPTION_CALLBACK, 0, \"merged\", (filter), N_(\"commit\"), (h), \\\n> +         PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG, \\\n> +         parse_opt_merge_filter, (intptr_t) \"HEAD\" \\\n> +       }\n\nCould you reduce the redundancy in these 2 macros?\n"},{"id":"263781","messageId":"CAP8UFD02qxKJYJ=hg7ZWsvUZfJe85CY-v2V-64swdxnibF=mmg@mail.gmail.com","threadId":"39620","inReplyTo":"1434226706-3764-9-git-send-email-karthik.188@gmail.com","subject":"Re: [PATCH v2 09/11] parse-options.h: add macros for '--contains' option","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-06-14T06:13:07Z","receivedAt":"2015-06-14T06:13:07Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Sat, Jun 13, 2015 at 10:18 PM, Karthik Nayak <karthik.188@gmail.com> wrote:\n> Add a macro for using the '--contains' option in parse-options.h\n> also include an optional '--with' option macro which performs the\n> same action as '--contains'.\n>\n> Make tag.c use this new macro\n>\n> Mentored-by: Christian Couder <christian.couder@gmail.com>\n> Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>\n> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>\n> ---\n>  builtin/tag.c   | 14 ++------------\n>  parse-options.h |  7 +++++++\n>  2 files changed, 9 insertions(+), 12 deletions(-)\n>\n> diff --git a/builtin/tag.c b/builtin/tag.c\n> index 2d6610a..767162e 100644\n> --- a/builtin/tag.c\n> +++ b/builtin/tag.c\n> @@ -595,23 +595,13 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n>\n>                 OPT_GROUP(N_(\"Tag listing options\")),\n>                 OPT_COLUMN(0, \"column\", &colopts, N_(\"show tag list in columns\")),\n> +               OPT_CONTAINS(&with_commit, N_(\"print only tags that contain the commit\")),\n> +               OPT_WITH(&with_commit, N_(\"print only tags that contain the commit\")),\n>                 {\n>                         OPTION_CALLBACK, 0, \"sort\", &tag_sort, N_(\"type\"), N_(\"sort tags\"),\n>                         PARSE_OPT_NONEG, parse_opt_sort\n>                 },\n>                 {\n> -                       OPTION_CALLBACK, 0, \"contains\", &with_commit, N_(\"commit\"),\n> -                       N_(\"print only tags that contain the commit\"),\n> -                       PARSE_OPT_LASTARG_DEFAULT,\n> -                       parse_opt_commit_object_name, (intptr_t)\"HEAD\",\n> -               },\n> -               {\n> -                       OPTION_CALLBACK, 0, \"with\", &with_commit, N_(\"commit\"),\n> -                       N_(\"print only tags that contain the commit\"),\n> -                       PARSE_OPT_HIDDEN | PARSE_OPT_LASTARG_DEFAULT,\n\nThe PARSE_OPT_HIDDEN flag is removed below. This means that \"--with\"\nwill appear in the \"git tag -h\" output, which means that \"--with\"\nshould appear in the documentation...\nThe commit message may also want to tell that with is not hidden any more.\n\n> -                       parse_opt_commit_object_name, (intptr_t)\"HEAD\",\n> -               },\n> -               {\n>                         OPTION_CALLBACK, 0, \"points-at\", &points_at, N_(\"object\"),\n>                         N_(\"print only tags of the object\"), 0, parse_opt_object_name\n>                 },\n> diff --git a/parse-options.h b/parse-options.h\n> index 8542d9c..d76e907 100644\n> --- a/parse-options.h\n> +++ b/parse-options.h\n> @@ -243,5 +243,12 @@ extern int parse_opt_noop_cb(const struct option *, const char *, int);\n>         OPT_COLOR_FLAG(0, \"color\", (var), (h))\n>  #define OPT_COLUMN(s, l, v, h) \\\n>         { OPTION_CALLBACK, (s), (l), (v), N_(\"style\"), (h), PARSE_OPT_OPTARG, parseopt_column_callback }\n> +#define _OPT_CONTAINS_OR_WITH(name, variable, help) \\\n> +       { OPTION_CALLBACK, 0, name, (variable), N_(\"commit\"), (help), \\\n> +         PARSE_OPT_LASTARG_DEFAULT, \\\n> +         parse_opt_commit_object_name, (intptr_t) \"HEAD\" \\\n> +       }\n> +#define OPT_CONTAINS(v, h) _OPT_CONTAINS_OR_WITH(\"contains\", v, h)\n> +#define OPT_WITH(v, h) _OPT_CONTAINS_OR_WITH(\"contains\", v, h)\n\nShouldn't it be \"with\" instead of \"contains\"?\n"},{"id":"263782","messageId":"CAOLa=ZRJeajtHOMjvtVjdK1cCh8w4c8PJTxgGFEXbs1V0NKkTw@mail.gmail.com","threadId":"39620","inReplyTo":"CAP8UFD1Qw+ctvz_CbBoE-jb5_bC3jogAsTgp-mgkVBFG1y7SiQ@mail.gmail.com","subject":"Re: [PATCH v2 05/11] ref-filter: add parse_opt_merge_filter()","fromName":"karthik nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-14T06:49:38Z","receivedAt":"2015-06-14T06:49:38Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"On Sun, Jun 14, 2015 at 11:19 AM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> On Sat, Jun 13, 2015 at 10:18 PM, Karthik Nayak <karthik.188@gmail.com> wrote:\n>>\n>> diff --git a/ref-filter.h b/ref-filter.h\n>> index c2856b8..799e118 100644\n>> --- a/ref-filter.h\n>> +++ b/ref-filter.h\n>> @@ -50,6 +50,18 @@ struct ref_filter_cbdata {\n>>         struct ref_filter *filter;\n>>  };\n>>\n>> +/*  Macros for checking --merged and --no-merged options */\n>> +#define OPT_NO_MERGED(filter, h) \\\n>> +       { OPTION_CALLBACK, 0, \"no-merged\", (filter), N_(\"commit\"), (h), \\\n>> +         PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG, \\\n>> +         parse_opt_merge_filter, (intptr_t) \"HEAD\" \\\n>> +       }\n>> +#define OPT_MERGED(filter, h) \\\n>> +       { OPTION_CALLBACK, 0, \"merged\", (filter), N_(\"commit\"), (h), \\\n>> +         PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG, \\\n>> +         parse_opt_merge_filter, (intptr_t) \"HEAD\" \\\n>> +       }\n>\n> Could you reduce the redundancy in these 2 macros?\n\nYes, will do!\n\n-- \nRegards,\nKarthik Nayak\n"},{"id":"263783","messageId":"CAOLa=ZRu14cJ22_0pbEi5hhZU3XaSeb+_BYEFTfi8fH3PgbxZw@mail.gmail.com","threadId":"39620","inReplyTo":"CAP8UFD02qxKJYJ=hg7ZWsvUZfJe85CY-v2V-64swdxnibF=mmg@mail.gmail.com","subject":"Re: [PATCH v2 09/11] parse-options.h: add macros for '--contains' option","fromName":"karthik nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-14T06:58:52Z","receivedAt":"2015-06-14T06:58:52Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"On Sun, Jun 14, 2015 at 11:43 AM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> On Sat, Jun 13, 2015 at 10:18 PM, Karthik Nayak <karthik.188@gmail.com> wrote:\n>> Add a macro for using the '--contains' option in parse-options.h\n>> also include an optional '--with' option macro which performs the\n>> same action as '--contains'.\n>>\n>> Make tag.c use this new macro\n>>\n>> Mentored-by: Christian Couder <christian.couder@gmail.com>\n>> Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>\n>> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>\n>> ---\n>>  builtin/tag.c   | 14 ++------------\n>>  parse-options.h |  7 +++++++\n>>  2 files changed, 9 insertions(+), 12 deletions(-)\n>>\n>> diff --git a/builtin/tag.c b/builtin/tag.c\n>> index 2d6610a..767162e 100644\n>> --- a/builtin/tag.c\n>> +++ b/builtin/tag.c\n>> @@ -595,23 +595,13 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n>>\n>>                 OPT_GROUP(N_(\"Tag listing options\")),\n>>                 OPT_COLUMN(0, \"column\", &colopts, N_(\"show tag list in columns\")),\n>> +               OPT_CONTAINS(&with_commit, N_(\"print only tags that contain the commit\")),\n>> +               OPT_WITH(&with_commit, N_(\"print only tags that contain the commit\")),\n>>                 {\n>>                         OPTION_CALLBACK, 0, \"sort\", &tag_sort, N_(\"type\"), N_(\"sort tags\"),\n>>                         PARSE_OPT_NONEG, parse_opt_sort\n>>                 },\n>>                 {\n>> -                       OPTION_CALLBACK, 0, \"contains\", &with_commit, N_(\"commit\"),\n>> -                       N_(\"print only tags that contain the commit\"),\n>> -                       PARSE_OPT_LASTARG_DEFAULT,\n>> -                       parse_opt_commit_object_name, (intptr_t)\"HEAD\",\n>> -               },\n>> -               {\n>> -                       OPTION_CALLBACK, 0, \"with\", &with_commit, N_(\"commit\"),\n>> -                       N_(\"print only tags that contain the commit\"),\n>> -                       PARSE_OPT_HIDDEN | PARSE_OPT_LASTARG_DEFAULT,\n>\n> The PARSE_OPT_HIDDEN flag is removed below. This means that \"--with\"\n> will appear in the \"git tag -h\" output, which means that \"--with\"\n> should appear in the documentation...\n> The commit message may also want to tell that with is not hidden any more.\n>\n\nYes! I will add that.\n\n>> -                       parse_opt_commit_object_name, (intptr_t)\"HEAD\",\n>> -               },\n>> -               {\n>>                         OPTION_CALLBACK, 0, \"points-at\", &points_at, N_(\"object\"),\n>>                         N_(\"print only tags of the object\"), 0, parse_opt_object_name\n>>                 },\n>> diff --git a/parse-options.h b/parse-options.h\n>> index 8542d9c..d76e907 100644\n>> --- a/parse-options.h\n>> +++ b/parse-options.h\n>> @@ -243,5 +243,12 @@ extern int parse_opt_noop_cb(const struct option *, const char *, int);\n>>         OPT_COLOR_FLAG(0, \"color\", (var), (h))\n>>  #define OPT_COLUMN(s, l, v, h) \\\n>>         { OPTION_CALLBACK, (s), (l), (v), N_(\"style\"), (h), PARSE_OPT_OPTARG, parseopt_column_callback }\n>> +#define _OPT_CONTAINS_OR_WITH(name, variable, help) \\\n>> +       { OPTION_CALLBACK, 0, name, (variable), N_(\"commit\"), (help), \\\n>> +         PARSE_OPT_LASTARG_DEFAULT, \\\n>> +         parse_opt_commit_object_name, (intptr_t) \"HEAD\" \\\n>> +       }\n>> +#define OPT_CONTAINS(v, h) _OPT_CONTAINS_OR_WITH(\"contains\", v, h)\n>> +#define OPT_WITH(v, h) _OPT_CONTAINS_OR_WITH(\"contains\", v, h)\n>\n> Shouldn't it be \"with\" instead of \"contains\"?\n\nActually it wouldn't matter, but since I've removed the PARSE_OPT_HIDDEN flag\nit would show 'contains' twice. Will change it to 'with'.\n\nThanks for the review.\n\n-- \nRegards,\nKarthik Nayak\n"},{"id":"263786","messageId":"vpqvbeqd7y5.fsf@anie.imag.fr","threadId":"39620","inReplyTo":"1434226706-3764-1-git-send-email-karthik.188@gmail.com","subject":"Re: [PATCH v2 01/11] t6301: for-each-ref tests for ref-filter APIs","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-06-14T08:12:50Z","receivedAt":"2015-06-14T08:12:50Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Karthik Nayak <karthik.188@gmail.com> writes:\n\n> +test_expect_success 'setup some history and refs' '\n> +\ttest_commit one &&\n> +\ttest_commit two &&\n> +\ttest_commit three &&\n> +\tgit checkout -b side &&\n> +\ttest_commit four &&\n> +\tgit checkout master &&\n> +\tgit update-ref refs/odd/spot master\n\nI think you want more corner-cases here. For example,\nrefs/headsfoo/master should not match refs/heads, and it's easy to write\nan incorrect implementation for this => test.\n\n> +'\n> +test_expect_success 'filtering by leading name' '\n\nBlank line between tests please.\n\n> +\tcat >expect <<-\\EOF &&\n> +\trefs/heads/master\n> +\trefs/heads/side\n> +\tEOF\n> +\tgit for-each-ref --format=\"%(refname)\" refs/heads >actual &&\n> +\ttest_cmp expect actual\n> +'\n\nIsn't this test redundant with the content of t6300-for-each-ref.sh?\n\nAt this point, you've done only internal refactoring, so you shouldn't\nneed new tests (except to fix coverage holes in existing tests).\n\nI guess you're adding this to build more tests on top, but the commit\nmessage should clarify this.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"263789","messageId":"CAOLa=ZRC+mZmXKJnrDFdM9oy4+WrWC0rg7kj_bpNCf=iRSVG2g@mail.gmail.com","threadId":"39620","inReplyTo":"vpqvbeqd7y5.fsf@anie.imag.fr","subject":"Re: [PATCH v2 01/11] t6301: for-each-ref tests for ref-filter APIs","fromName":"karthik nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-14T08:32:54Z","receivedAt":"2015-06-14T08:32:54Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"On Sun, Jun 14, 2015 at 1:42 PM, Matthieu Moy\n<Matthieu.Moy@grenoble-inp.fr> wrote:\n> Karthik Nayak <karthik.188@gmail.com> writes:\n>\n>> +test_expect_success 'setup some history and refs' '\n>> +     test_commit one &&\n>> +     test_commit two &&\n>> +     test_commit three &&\n>> +     git checkout -b side &&\n>> +     test_commit four &&\n>> +     git checkout master &&\n>> +     git update-ref refs/odd/spot master\n>\n> I think you want more corner-cases here. For example,\n> refs/headsfoo/master should not match refs/heads, and it's easy to write\n> an incorrect implementation for this => test.\n\nLike you mentioned below, currently it's redundant with t6300 and its\npurpose is to add tests for new functionality we provide to for-each-ref\nvia ref-filter. This is done in the next few patches in this series.\n\n>\n>> +'\n>> +test_expect_success 'filtering by leading name' '\n>\n> Blank line between tests please.\n\nNoted. Thanks.\n\n>\n>> +     cat >expect <<-\\EOF &&\n>> +     refs/heads/master\n>> +     refs/heads/side\n>> +     EOF\n>> +     git for-each-ref --format=\"%(refname)\" refs/heads >actual &&\n>> +     test_cmp expect actual\n>> +'\n>\n> Isn't this test redundant with the content of t6300-for-each-ref.sh?\n>\n> At this point, you've done only internal refactoring, so you shouldn't\n> need new tests (except to fix coverage holes in existing tests).\n>\n> I guess you're adding this to build more tests on top, but the commit\n> message should clarify this.\n>\n\nI'll add a note to the commit message about how this test file is so\nthat we can integrate\nmore tests in the future for functionality given to for-each-ref via\nref-filter APIs.\n\n-- \nRegards,\nKarthik Nayak\n"},{"id":"263885","messageId":"xmqqbngg93hj.fsf@gitster.dls.corp.google.com","threadId":"39620","inReplyTo":"CAP8UFD02qxKJYJ=hg7ZWsvUZfJe85CY-v2V-64swdxnibF=mmg@mail.gmail.com","subject":"Re: [PATCH v2 09/11] parse-options.h: add macros for '--contains' option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-15T19:27:20Z","receivedAt":"2015-06-15T19:27:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Christian Couder <christian.couder@gmail.com> writes:\n\n> The PARSE_OPT_HIDDEN flag is removed below. This means that \"--with\"\n> will appear in the \"git tag -h\" output, which means that \"--with\"\n> should appear in the documentation...\n> The commit message may also want to tell that with is not hidden any more.\n\nOr why is it a good idea to stop hiding.\n\nI would prefer to keep it hidden to avoid \"what's the difference\nbetween the two\" confusion.\n"},{"id":"263902","messageId":"CAOLa=ZROvzZD2Qz6gMLeciipJRyAGR5q3isR9zOih9v=GP17EA@mail.gmail.com","threadId":"39620","inReplyTo":"xmqqbngg93hj.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v2 09/11] parse-options.h: add macros for '--contains' option","fromName":"karthik nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2015-06-15T20:49:09Z","receivedAt":"2015-06-15T20:49:09Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"On Tue, Jun 16, 2015 at 12:57 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Christian Couder <christian.couder@gmail.com> writes:\n>\n>> The PARSE_OPT_HIDDEN flag is removed below. This means that \"--with\"\n>> will appear in the \"git tag -h\" output, which means that \"--with\"\n>> should appear in the documentation...\n>> The commit message may also want to tell that with is not hidden any more.\n>\n> Or why is it a good idea to stop hiding.\n>\n> I would prefer to keep it hidden to avoid \"what's the difference\n> between the two\" confusion.\n\nOk than, will do that.\n\n-- \nRegards,\nKarthik Nayak\n"}]}