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 )
@@ -105,6 +127,9 @@ static int show_reference(const char *refname, const unsigned char *sha1,
105
127
return 0 ;
106
128
}
107
129
130
+ if (points_at .nr && !match_points_at (refname , sha1 ))
131
+ return 0 ;
132
+
108
133
if (!filter -> lines ) {
109
134
printf ("%s\n" , refname );
110
135
return 0 ;
@@ -375,6 +400,23 @@ static int strbuf_check_tag_ref(struct strbuf *sb, const char *name)
375
400
return check_refname_format (sb -> buf , 0 );
376
401
}
377
402
403
+ int parse_opt_points_at (const struct option * opt __attribute__ ((unused )),
404
+ const char * arg , int unset )
405
+ {
406
+ unsigned char sha1 [20 ];
407
+
408
+ if (unset ) {
409
+ sha1_array_clear (& points_at );
410
+ return 0 ;
411
+ }
412
+ if (!arg )
413
+ return error (_ ("switch 'points-at' requires an object" ));
414
+ if (get_sha1 (arg , sha1 ))
415
+ return error (_ ("malformed object name '%s'" ), arg );
416
+ sha1_array_append (& points_at , sha1 );
417
+ return 0 ;
418
+ }
419
+
378
420
int cmd_tag (int argc , const char * * argv , const char * prefix )
379
421
{
380
422
struct strbuf buf = STRBUF_INIT ;
@@ -417,6 +459,10 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
417
459
PARSE_OPT_LASTARG_DEFAULT ,
418
460
parse_opt_with_commit , (intptr_t )"HEAD" ,
419
461
},
462
+ {
463
+ OPTION_CALLBACK , 0 , "points-at" , NULL , "object" ,
464
+ "print only tags of the object" , 0 , parse_opt_points_at
465
+ },
420
466
OPT_END ()
421
467
};
422
468
@@ -448,6 +494,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
448
494
die (_ ("-n option is only allowed with -l." ));
449
495
if (with_commit )
450
496
die (_ ("--contains option is only allowed with -l." ));
497
+ if (points_at .nr )
498
+ die (_ ("--points-at option is only allowed with -l." ));
451
499
if (delete )
452
500
return for_each_tag_name (argv , delete_tag );
453
501
if (verify )
0 commit comments