6 from optparse
import OptionParser
9 from git_stats
import parse
11 def belongsTo(commit
):
17 result
= git
.for_each_ref("refs/heads", format
="%(objectname)")
19 branches
= result
.split('\n')
21 if commit
in branches
:
22 print("Easy as pie, that's a branch head!")
28 for branch
in branches
:
29 result
= git
.rev_list(branch
)
30 commits
= result
.split('\n')
32 # No need to keep going if the commit is not part of this branch
33 if not commit
in commits
:
36 result
= git
.rev_list("--no-merges", branch
)
37 no_merges
= result
.split('\n')
39 # Make the ommits into a set
40 commits
= set(commits
)
41 no_merges
= set(no_merges
)
43 # Store all commits for later use
44 rev_lists
[branch
] = commits
46 # The merges are 'all_commits - no_merges'
47 merges
= commits
.difference(no_merges
)
51 # Check all the merges to see if they diluted this branch
53 result
= git
.cat_file("-p", merge
)
54 log
= result
.split('\n')
56 # We really only have to check the first parent
57 # If it's not in there, it is a dilution (for this branch at least)
59 if not line
.startswith("parent "):
65 result
= git
.rev_list(parent
)
66 children
= result
.split('\n')
68 # Diluted iff the commit is not a child of the primary parent
69 if not commit
in children
:
72 results
[branch
] = dilution
79 for branch
in results
.iteritems():
86 # Clear the old ones if we have a better set
91 champs
.append(branch
[0])
95 # Loop over all the champs and exclude any subsets
97 champlist
= rev_lists
[champ
]
98 for otherchamp
in champs
:
99 # Don't compare to self
100 if champ
== otherchamp
:
103 otherlist
= rev_lists
[otherchamp
]
104 if champlist
.issubset(otherlist
):
112 def branchcontains(branch
, commit
):
113 """returns whether the specified branch contains the specified commit.
120 whether the branch contains the commit.
124 arg
= branch
+ ".." + commit
125 result
= git
.rev_list(arg
)
128 # if there is a difference between these sets, the commit is not in the branch
131 # there is no difference between the two, thus the branch contains the commit
134 def branchList(commitFilter
, includeRemotes
=False):
146 args
.append("--contains")
147 args
.append(commitFilter
)
149 result
= git
.branch(*args
)
151 branches
= result
.split('\n')
155 for branch
in branches
:
156 result
.append(branch
[2:])
161 """Dispatches branch related commands
164 progname
= os
.path
.basename(sys
.argv
[0]) + " branch"
166 parser
= OptionParser(option_class
=parse
.GitOption
, prog
=progname
)
170 "-b", "--belongs-to",
173 help="find out which branch the specified commit belongs to")
178 help="show only branches that contain the specified commit")
183 help="include remotes in the listing")
185 (options
, args
) = parser
.parse_args(list(args
))
187 if options
.belongs_to
:
188 result
= belongsTo(options
.belongs_to
)
190 result
= branchList(commitFilter
=options
.contains
,
191 includeRemotes
=options
.remotes
)
193 print("Matching branches:")
195 for branch
in result
: