1212#include "tag.h"
1313#include "run-command.h"
1414#include "parse-options.h"
15+ #include "diff.h"
16+ #include "revision.h"
1517
1618static const char * const git_tag_usage [] = {
1719 "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)
4042 return 0 ;
4143}
4244
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+
4387static int show_reference (const char * refname , const unsigned char * sha1 ,
4488 int flag , void * cb_data )
4589{
@@ -58,7 +102,7 @@ static int show_reference(const char *refname, const unsigned char *sha1,
58102 commit = lookup_commit_reference_gently (sha1 , 1 );
59103 if (!commit )
60104 return 0 ;
61- if (!is_descendant_of (commit , filter -> with_commit ))
105+ if (!contains (commit , filter -> with_commit ))
62106 return 0 ;
63107 }
64108
0 commit comments