tag.c: implement '--merged' and '--no-merged' options
authorKarthik Nayak <karthik.188@gmail.com>
Thu, 10 Sep 2015 16:22:49 +0000 (21:52 +0530)
committerJunio C Hamano <gitster@pobox.com>
Thu, 17 Sep 2015 17:02:50 +0000 (10:02 -0700)
Use 'ref-filter' APIs to implement the '--merged' and '--no-merged'
options into 'tag.c'. The '--merged' option lets the user to only list
tags merged into the named commit. The '--no-merged' option lets the
user to only list tags not merged into the named commit. If no object
is provided it assumes HEAD as the object.

Add documentation and tests for the same.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-tag.txt
builtin/tag.c
t/t7004-tag.sh
index 0c7f4e65663c8428f84f625c7d8a1a6d3ca0d2a8..3803bf7fb97eec9e1e3786f739dab43cc61ff1cd 100644 (file)
@@ -14,7 +14,7 @@ SYNOPSIS
 'git tag' -d <tagname>...
 'git tag' [-n[<num>]] -l [--contains <commit>] [--points-at <object>]
        [--column[=<options>] | --no-column] [--create-reflog] [--sort=<key>]
 'git tag' -d <tagname>...
 'git tag' [-n[<num>]] -l [--contains <commit>] [--points-at <object>]
        [--column[=<options>] | --no-column] [--create-reflog] [--sort=<key>]
-       [--format=<format>] [<pattern>...]
+       [--format=<format>] [--[no-]merged [<commit>]] [<pattern>...]
 'git tag' -v <tagname>...
 
 DESCRIPTION
 'git tag' -v <tagname>...
 
 DESCRIPTION
@@ -165,6 +165,11 @@ This option is only applicable when listing tags without annotation lines.
        that of linkgit:git-for-each-ref[1].  When unspecified,
        defaults to `%(refname:short)`.
 
        that of linkgit:git-for-each-ref[1].  When unspecified,
        defaults to `%(refname:short)`.
 
+--[no-]merged [<commit>]::
+       Only list tags whose tips are reachable, or not reachable
+       if '--no-merged' is used, from the specified commit ('HEAD'
+       if not specified).
+
 CONFIGURATION
 -------------
 By default, 'git tag' in sign-with-default mode (-s) will use your
 CONFIGURATION
 -------------
 By default, 'git tag' in sign-with-default mode (-s) will use your
index 74eaf25d5cec12d364ad7626b57edcc610d44ddc..b2e4ddca07ce7a812203259cfdfc32c187d4d2e4 100644 (file)
@@ -23,7 +23,7 @@ static const char * const git_tag_usage[] = {
        N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] <tagname> [<head>]"),
        N_("git tag -d <tagname>..."),
        N_("git tag -l [-n[<num>]] [--contains <commit>] [--points-at <object>]"
        N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] <tagname> [<head>]"),
        N_("git tag -d <tagname>..."),
        N_("git tag -l [-n[<num>]] [--contains <commit>] [--points-at <object>]"
-               "\n\t\t[--format=<format>] [<pattern>...]"),
+               "\n\t\t[--format=<format>] [--[no-]merged [<commit>]] [<pattern>...]"),
        N_("git tag -v <tagname>..."),
        NULL
 };
        N_("git tag -v <tagname>..."),
        NULL
 };
@@ -360,6 +360,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                OPT_COLUMN(0, "column", &colopts, N_("show tag list in columns")),
                OPT_CONTAINS(&filter.with_commit, N_("print only tags that contain the commit")),
                OPT_WITH(&filter.with_commit, N_("print only tags that contain the commit")),
                OPT_COLUMN(0, "column", &colopts, N_("show tag list in columns")),
                OPT_CONTAINS(&filter.with_commit, N_("print only tags that contain the commit")),
                OPT_WITH(&filter.with_commit, N_("print only tags that contain the commit")),
+               OPT_MERGED(&filter, N_("print only tags that are merged")),
+               OPT_NO_MERGED(&filter, N_("print only tags that are not merged")),
                OPT_CALLBACK(0 , "sort", sorting_tail, N_("key"),
                             N_("field name to sort on"), &parse_opt_ref_sorting),
                {
                OPT_CALLBACK(0 , "sort", sorting_tail, N_("key"),
                             N_("field name to sort on"), &parse_opt_ref_sorting),
                {
@@ -418,6 +420,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                die(_("--contains option is only allowed with -l."));
        if (filter.points_at.nr)
                die(_("--points-at option is only allowed with -l."));
                die(_("--contains option is only allowed with -l."));
        if (filter.points_at.nr)
                die(_("--points-at option is only allowed with -l."));
+       if (filter.merge_commit)
+               die(_("--merged and --no-merged option are only allowed with -l"));
        if (cmdmode == 'd')
                return for_each_tag_name(argv, delete_tag);
        if (cmdmode == 'v')
        if (cmdmode == 'd')
                return for_each_tag_name(argv, delete_tag);
        if (cmdmode == 'v')
index 8987fb160df36d4e9cc2f264258b62e8446feaa9..3dd2f51e49d7e6824382ac415cf64842fa3b757f 100755 (executable)
@@ -1531,4 +1531,31 @@ test_expect_success '--format should list tags as per format given' '
        test_cmp expect actual
 '
 
        test_cmp expect actual
 '
 
+test_expect_success 'setup --merged test tags' '
+       git tag mergetest-1 HEAD~2 &&
+       git tag mergetest-2 HEAD~1 &&
+       git tag mergetest-3 HEAD
+'
+
+test_expect_success '--merged cannot be used in non-list mode' '
+       test_must_fail git tag --merged=mergetest-2 foo
+'
+
+test_expect_success '--merged shows merged tags' '
+       cat >expect <<-\EOF &&
+       mergetest-1
+       mergetest-2
+       EOF
+       git tag -l --merged=mergetest-2 mergetest-* >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success '--no-merged show unmerged tags' '
+       cat >expect <<-\EOF &&
+       mergetest-3
+       EOF
+       git tag -l --no-merged=mergetest-2 mergetest-* >actual &&
+       test_cmp expect actual
+'
+
 test_done
 test_done