Skip to content

Instantly share code, notes, and snippets.

Created August 8, 2009 16:01
Show Gist options
  • Save anonymous/164441 to your computer and use it in GitHub Desktop.
Save anonymous/164441 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
REPOPATH="/home/andersg/xmms2-mergetest"
OUTPUTFILE="/var/www/git.xmms.se/merge/index.html"
#OUTPUTFILE="/tmp/merge.html"
BASEREMOTE="origin"
BASEBRANCH=BASEREMOTE + "/master"
import os
import sys
import sets
import time
import gitstuff
os.chdir(REPOPATH)
def repo(tree):
[r, branch] = tree.split("/")
return r
def branchid(tree):
return tree.replace("/", "_")
def treelink(tree):
[repo, branch] = tree.split("/")
return '<a href="http://git.xmms.se/?p=xmms2-%s.git;a=shortlog;h=refs/heads/%s">%s</a>' % (repo, branch, tree)
remotes = os.popen("git remote show").read().strip().split()
if BASEREMOTE not in remotes:
print "Need a remote named %s!" % BASEREMOTE
sys.exit(1)
remotes.remove(BASEREMOTE)
# update trees!
os.system("git remote update >/dev/null")
for r in remotes:
os.system("git remote prune %s >/dev/null" % r)
class Tree:
def __init__(self, name):
self.name = name
self.cherry = []
self.pollution = -1
self.pollutiond = []
self.clean = True
self.new = -1
self.lag = -1
self.changes = {}
self.authors = [x[2:].strip() for x in os.popen("git-cat-file blob %s:AUTHORS" % self.name) if x[:2]=='E:']
def update(self):
r = self.name
self.changes = gitstuff.changes(BASEBRANCH, r)
self.new=len(self.changes)
if self.new:
self.cherry = gitstuff.cherryharder(BASEBRANCH, r)
self.pollution = 100 * (self.new - len(self.cherry)) / self.new
self.pollutiond = list(sets.Set(self.changes.keys()).difference(sets.Set(self.cherry)))
for c in self.cherry:
d = self.changes[c]
if not (d.startswith("OTHER:") or
d.startswith("BUG(") or
d.startswith("FEATURE(")):
self.changes[c] = "<i>BAD PREFIX</i> - " + d
author = os.popen("git log -1 --pretty=format:%%ae %s" % c).read().strip()
if author not in self.authors:
self.changes[c] = "<i>UNKONWN AUTHOR</i> - " + self.changes[c]
patchid = os.popen("git diff-tree -p %s | git patch-id" % c).read().split()[0]
if os.access("/var/www/git.xmms.se/merge/notes/%s.txt" % patchid, os.R_OK):
self.changes[c] = ('<a href="/merge/notes/%s.txt"><blink>NOTES</blink></a> ' % patchid) + self.changes[c]
self.lag=int(os.popen("git rev-list %s..%s | wc -l" % (r, BASEBRANCH)).read())
if self.lag:
self.clean = gitstuff.mergetest(BASEBRANCH, r)
def sortorder(self):
if not self.new:
return 100000 + self.lag
o = 1000 - self.new
if self.lag:
o += 1000
if not self.clean:
o += 5000
return o
def displayhtml(self):
if self.lag:
if not self.new:
print '<div class="merge_lag">'
elif self.clean:
print '<div class="merge_clean">'
else:
print '<div class="merge_unclean">'
else:
if not self.new:
print '<div class="uptodate">'
else:
print '<div class="merged">'
print '<pre>'
if not self.lag + self.new:
print '[ ] %s' % treelink(self.name)
elif self.new:
print """<a id="d-%s-handle" href="javascript:toggle('d-%s')">[-]</a>""" % (branchid(self.name), branchid(self.name)),
print '%s has %d changes not in devel.' % (treelink(self.name), self.new),
if self.pollution:
print "%d of them are real, %d%% pollution." % (len(self.cherry), self.pollution),
else:
print "All are real!",
if self.lag:
if self.clean:
print "Lags %d changes, but merges cleanly" % self.lag,
else:
print "Lags %d changes and doesn't merge cleanly!" % self.lag,
print '<div id="d-%s-info">' % branchid(self.name)
if self.cherry:
print " The real changes are:"
for c in self.cherry:
print ' <a href="http://git.xmms.se/?p=xmms2-%s.git;a=commitdiff;h=%s">%s</a> %s' % (repo(self.name), c, c, self.changes[c])
if self.pollutiond:
print " The pollution:"
for c in self.pollutiond:
print " %s %s" % (c, self.changes[c])
print '</div>'
else:
print '[ ] %s is lagging %d changes' % (treelink(self.name), self.lag)
print '</pre>'
print "</div>"
trees=[]
for r in remotes:
for ref in os.popen('git-for-each-ref --format "%(refname)" refs/remotes/' + r):
t = ref.strip()[len("refs/remotes/"):]
B = t.split("/")[1]
if not (B == "master" or B.startswith("rfm-") or B.startswith("rfc-")):
continue
if not os.system("git merge-base %s %s >/dev/null" % (BASEBRANCH, t)):
trees.append(Tree(t))
for t in trees:
t.update()
trees.sort(key=lambda t: t.sortorder())
sys.stdout = file(OUTPUTFILE, "w")
print """
<html>
<head>
<title>Merge status</title>
<style type="text/css">
* { padding: 0px 0px; margin: 0px 0px; }
body { font-family: "Bitstream Vera Sans", "Trebuchet MS", Verdana, Tahoma, Arial, helvetica, sans-serif;
color: #333;
background-color: #eee;
}
h1 {
padding: 10px 10px;
text-transform: capitalize;
}
a:link, a:visited { color: #000; text-decoration: none; }
a:link:hover, a:visited:hover { color: #000; text-decoration: underline; }
div { margin: 10px 10px; padding: 2px 2px; }
div.merged { background-color: #cec; border: 1px solid #575; }
div.merge_clean { background-color: #cce; border: 1px solid #557; }
div.merge_unclean { background-color: #ecc; border: 1px solid #755; }
div.merge_lag { background-color: #aaa; border: 1px solid #575; }
div.uptodate { background-color: #aca; border: 1px solid #575; }
div#container { background-color: #ccc; border: 1px solid #aaa; padding: 0px 0px; }
</style>
<script type="text/javascript">
function toggle(arg) {
var handle = document.getElementById(arg + "-handle");
if (!handle) {
return
}
var block = document.getElementById(arg + "-info");
if (!block) {
return
}
var open = (handle.innerHTML == "[-]");
if (open) {
handle.innerHTML = "[+]";
block.style.display = "none";
} else {
handle.innerHTML = "[-]";
block.style.display = "block";
}
}
function close_all() {
"""
for t in trees:
print ' toggle("d-%s");' % branchid(t.name)
print """}
</script>
</head>
<body onload="close_all()">
<h1>Merge Status as of %s</h1>
<div id="container">
""" % time.strftime("%Y-%m-%d %H:%M")
for t in trees:
t.displayhtml()
print """</div>
</body>
</html>
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment