I have done a first series of 6 patches, which improves blobdiff and adds treediff. [PATCH] gitweb: show no difference message This patch shows an "no difference" message instead of nothing for equal objects. [PATCH] gitweb: Support comparing blobs with different names This patch adds support for comparing objects with different file names using hb/hbp. [PATCH] gitweb: link base commit (hpb) to blobdiff output Add link the parent commit, as there is currently no such link. [PATCH] gitweb: support filename prefix in git_patchset_body [PATCH] gitweb: support filename prefix in git_difftree_body [PATCH] gitweb: Add treediff These 3 patches add the treediff method. Its a complete reworked verion. As git-diff-tree outputs relativ patches (discards part of the compared tree objects), the first two patches are necessary to produce correct links in the treediff output. I do not see many possibilties for code sharing with git_commitdiff: The only large portion of common code is calling git-diff-tree. I don't think that this would justify the more complex code. To test these patches, I still use a JavaScript implementation (see below). I'm working on the server side implementation. The next patch, I'm currently working on, will introduce a wrapper for all calls to $cgi->a({-href => href([Parameter])}, [Title]) mfg Martin Kögler diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 71d0933..db58319 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1837,6 +1837,7 @@ sub git_footer_html { close $fd; } + print '<script type="text/javascript" src="gitweb.js"></script>'; print "</body>\n" . "</html>"; } gitweb.js: ---------- function getCookie(name) { var name=name+"="; var c=document.cookie; var p=c.indexOf(name); if(p==-1) return null; c=c.substr(p+name.length,c.length); p=c.indexOf(";"); if(p==-1) return c; else return c.substr(0, p); } function insertAfter(elem, node) { if(node.nextSibling) node.parentNode.insertBefore(elem, node.nextSibling); else node.parentNode.appendChild(elem); } function createLink(href, linktext) { var l=document.createElement("a"); l.appendChild(document.createTextNode(linktext)); l.href=href; return l; } function createLinkGroup(href1, basetxt, href2, difftxt) { var l=document.createElement("span"); l.appendChild(document.createTextNode(" (")); l.appendChild(createLink(href1, basetxt)); l.appendChild(document.createTextNode(" | ")); l.appendChild(createLink(href2, difftxt)); l.appendChild(document.createTextNode(") ")); return l; } function GitRef() { this.t=null; this.h=null; this.hb=null; this.f=null; this.ToRef=ToRef; } function ToRef() { var parts=new Array(); if(this.f) parts.push("f="+this.f); if(this.h) parts.push("h="+this.h); if(this.hb) parts.push("hb="+this.hb); if(this.t) parts.push("t="+this.t); return parts.join("@"); } function splitGitRef(ref) { var parts=ref.split("@"); var res=new GitRef(); var i; for(i=0;i<parts.length;i++) { var p=parts[i].split("="); res[p[0]]=p[1]; } return res; } function GitURL(base) { this.base=base; this.p=null; this.a=null; this.f=null; this.fp=null; this.h=null; this.hp=null; this.hb=null; this.hpb=null; this.pg=null; this.o=null; this.s=null; this.st=null; this.ToURL=ToURL; this.ToRef=UrlToRef; this.ToDUrl=ToDUrl; } function ToURL() { var parts=new Array(); if(this.p) parts.push("p="+this.p); if(this.a) parts.push("a="+this.a); if(this.f) parts.push("f="+this.f); if(this.fp) parts.push("fp="+this.fp); if(this.h) parts.push("h="+this.h); if(this.hp) parts.push("hp="+this.hp); if(this.hb) parts.push("hb="+this.hb); if(this.hpb) parts.push("hpb="+this.hpb); if(this.o) parts.push("o="+this.o); if(this.s) parts.push("s="+this.s); if(this.st) parts.push("st="+this.st); return this.base+"?"+parts.join(";"); } function UrlToRef(type) { var res=new GitRef; res.f=this.f; res.h=this.h; res.hb=this.hb; res.t=type; return res.ToRef(); } function ToDUrl(type) { var res=new GitURL(this.base); res.f=this.f; res.h=this.h; res.hb=this.hb; res.p=this.p; res.a=type; return res.ToURL(); } function splitGitURL(url) { var Urls=url.split("?"); var res=new GitURL(Urls[0]); if(Urls.length>1) { var parts=Urls[1].split(";"); var i; for(i=0;i<parts.length;i++) { var p=parts[i].split("="); res[p[0]]=p[1]; } } return res; } function GitAddLinks() { var links=document.getElementsByTagName("a"); var i; for(i=0;i<links.length;i++) { var link=links[i]; if(link.innerHTML=='commit'||link.innerHTML=='tag') { var url=splitGitURL(link.href); if(!url.h) continue; var l=createLinkGroup("javascript:base('"+url.ToRef('commit')+"')","base", "javascript:diff('"+url.ToDUrl('commit')+"')","diff"); insertAfter(l, link); } if(link.innerHTML=='blob') { var url=splitGitURL(link.href); if(!url.h&&!(url.hb&&url.f)) continue; var l=createLinkGroup("javascript:base('"+url.ToRef('blob')+"')","base", "javascript:diff('"+url.ToDUrl('blob')+"')","diff"); insertAfter(l, link); } if(link.innerHTML=='tree') { var url=splitGitURL(link.href); if(!url.h&&!(url.hb&&url.f)) continue; var l=createLinkGroup("javascript:base('"+url.ToRef('tree')+"')","base", "javascript:diff('"+url.ToDUrl('tree')+"')","diff"); insertAfter(l, link); } } } function base(ref) { document.cookie="basename="+ref; } function diff(url) { var c=getCookie("basename"); if (!c) { alert("no diff base selected"); return; } c=splitGitRef(c); url=splitGitURL(url); if(c.t=='commit'&&url.a=='commit') { url.a='commitdiff'; if(!c.h||!url.h) { alert("commit diff not possible"); return; } url.hb=null; url.f=null; url.hp=c.h; document.location.href=url.ToURL(); return; } if(c.t=='blob'&&url.a=='blob') { url.a='blobdiff'; url.h=c.h; url.hpb=c.hb; url.fp=c.f; document.location.href=url.ToURL(); return; } if(c.t=='tree'&&url.a=='tree') { url.a='treediff'; url.hpb=c.hb; url.hp=c.h; url.fp=c.f; document.location.href=url.ToURL(); return; } if(c.t=='commit'&&url.a=='tree') { url.a='treediff'; url.hpb=c.h; url.hp=null; url.fp=null; document.location.href=url.ToURL(); return; } if(c.t=='tree'&&url.a=='commit') { url.a='treediff'; url.hpb=c.hb; url.hp=c.h; url.fp=c.f; url.hb=url.h; url.h=null; document.location.href=url.ToURL(); return; } alert("diff not possible"); } GitAddLinks(); - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html