12
12
#include "tag.h"
13
13
#include "run-command.h"
14
14
#include "parse-options.h"
15
+ #include "diff.h"
16
+ #include "revision.h"
15
17
16
18
static const char * const git_tag_usage [] = {
17
19
"git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]" ,
@@ -40,6 +42,48 @@ static int match_pattern(const char **patterns, const char *ref)
40
42
return 0 ;
41
43
}
42
44
45
+ static int in_commit_list (const struct commit_list * want , struct commit * c )
46
+ {
47
+ for (; want ; want = want -> next )
48
+ if (!hashcmp (want -> item -> object .sha1 , c -> object .sha1 ))
49
+ return 1 ;
50
+ return 0 ;
51
+ }
52
+
53
+ static int contains_recurse (struct commit * candidate ,
54
+ const struct commit_list * want )
55
+ {
56
+ struct commit_list * p ;
57
+
58
+ /* was it previously marked as containing a want commit? */
59
+ if (candidate -> object .flags & TMP_MARK )
60
+ return 1 ;
61
+ /* or marked as not possibly containing a want commit? */
62
+ if (candidate -> object .flags & UNINTERESTING )
63
+ return 0 ;
64
+ /* or are we it? */
65
+ if (in_commit_list (want , candidate ))
66
+ return 1 ;
67
+
68
+ if (parse_commit (candidate ) < 0 )
69
+ return 0 ;
70
+
71
+ /* Otherwise recurse and mark ourselves for future traversals. */
72
+ for (p = candidate -> parents ; p ; p = p -> next ) {
73
+ if (contains_recurse (p -> item , want )) {
74
+ candidate -> object .flags |= TMP_MARK ;
75
+ return 1 ;
76
+ }
77
+ }
78
+ candidate -> object .flags |= UNINTERESTING ;
79
+ return 0 ;
80
+ }
81
+
82
+ static int contains (struct commit * candidate , const struct commit_list * want )
83
+ {
84
+ return contains_recurse (candidate , want );
85
+ }
86
+
43
87
static int show_reference (const char * refname , const unsigned char * sha1 ,
44
88
int flag , void * cb_data )
45
89
{
@@ -58,7 +102,7 @@ static int show_reference(const char *refname, const unsigned char *sha1,
58
102
commit = lookup_commit_reference_gently (sha1 , 1 );
59
103
if (!commit )
60
104
return 0 ;
61
- if (!is_descendant_of (commit , filter -> with_commit ))
105
+ if (!contains (commit , filter -> with_commit ))
62
106
return 0 ;
63
107
}
64
108
0 commit comments