15
15
#include "diff.h"
16
16
#include "revision.h"
17
17
#include "gpg-interface.h"
18
+ #include "sha1-array.h"
18
19
19
20
static const char * const git_tag_usage [] = {
20
21
"git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]" ,
21
22
"git tag -d <tagname>..." ,
22
- "git tag -l [-n[<num>]] [<pattern>...]" ,
23
+ "git tag -l [-n[<num>]] [--contains <commit>] [--points-at <object>] "
24
+ "\n\t\t[<pattern>...]" ,
23
25
"git tag -v <tagname>..." ,
24
26
NULL
25
27
};
@@ -30,6 +32,8 @@ struct tag_filter {
30
32
struct commit_list * with_commit ;
31
33
};
32
34
35
+ static struct sha1_array points_at ;
36
+
33
37
static int match_pattern (const char * * patterns , const char * ref )
34
38
{
35
39
/* no pattern means match everything */
@@ -41,6 +45,24 @@ static int match_pattern(const char **patterns, const char *ref)
41
45
return 0 ;
42
46
}
43
47
48
+ static const unsigned char * match_points_at (const char * refname ,
49
+ const unsigned char * sha1 )
50
+ {
51
+ const unsigned char * tagged_sha1 = NULL ;
52
+ struct object * obj ;
53
+
54
+ if (sha1_array_lookup (& points_at , sha1 ) >= 0 )
55
+ return sha1 ;
56
+ obj = parse_object (sha1 );
57
+ if (!obj )
58
+ die (_ ("malformed object at '%s'" ), refname );
59
+ if (obj -> type == OBJ_TAG )
60
+ tagged_sha1 = ((struct tag * )obj )-> tagged -> sha1 ;
61
+ if (tagged_sha1 && sha1_array_lookup (& points_at , tagged_sha1 ) >= 0 )
62
+ return tagged_sha1 ;
63
+ return NULL ;
64
+ }
65
+
44
66
static int in_commit_list (const struct commit_list * want , struct commit * c )
45
67
{
46
68
for (; want ; want = want -> next )
@@ -138,6 +160,9 @@ static int show_reference(const char *refname, const unsigned char *sha1,
138
160
return 0 ;
139
161
}
140
162
163
+ if (points_at .nr && !match_points_at (refname , sha1 ))
164
+ return 0 ;
165
+
141
166
if (!filter -> lines ) {
142
167
printf ("%s\n" , refname );
143
168
return 0 ;
@@ -383,6 +408,23 @@ static int strbuf_check_tag_ref(struct strbuf *sb, const char *name)
383
408
return check_refname_format (sb -> buf , 0 );
384
409
}
385
410
411
+ static int parse_opt_points_at (const struct option * opt __attribute__((unused )),
412
+ const char * arg , int unset )
413
+ {
414
+ unsigned char sha1 [20 ];
415
+
416
+ if (unset ) {
417
+ sha1_array_clear (& points_at );
418
+ return 0 ;
419
+ }
420
+ if (!arg )
421
+ return error (_ ("switch 'points-at' requires an object" ));
422
+ if (get_sha1 (arg , sha1 ))
423
+ return error (_ ("malformed object name '%s'" ), arg );
424
+ sha1_array_append (& points_at , sha1 );
425
+ return 0 ;
426
+ }
427
+
386
428
int cmd_tag (int argc , const char * * argv , const char * prefix )
387
429
{
388
430
struct strbuf buf = STRBUF_INIT ;
@@ -425,6 +467,10 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
425
467
PARSE_OPT_LASTARG_DEFAULT ,
426
468
parse_opt_with_commit , (intptr_t )"HEAD" ,
427
469
},
470
+ {
471
+ OPTION_CALLBACK , 0 , "points-at" , NULL , "object" ,
472
+ "print only tags of the object" , 0 , parse_opt_points_at
473
+ },
428
474
OPT_END ()
429
475
};
430
476
@@ -456,6 +502,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
456
502
die (_ ("-n option is only allowed with -l." ));
457
503
if (with_commit )
458
504
die (_ ("--contains option is only allowed with -l." ));
505
+ if (points_at .nr )
506
+ die (_ ("--points-at option is only allowed with -l." ));
459
507
if (delete )
460
508
return for_each_tag_name (argv , delete_tag );
461
509
if (verify )
0 commit comments