From: mkoegler@auto.tuwien.ac.at (Martin Koegler)
To: git@vger.kernel.org
Subject: [RFC] More diff possibilities in gitweb
Date: Sat, 17 Mar 2007 16:17:31 +0100 [thread overview]
Message-ID: <20070317151731.GA32571@auto.tuwien.ac.at> (raw)
Compared to eg. viewcvs, gitweb offers fewer possibilies to do a diff.
With viewcvs, you can compare arbitrary version of a file; gitweb only
offers diff to previous (or sometimes current) version.
As git offers an infinite number of possible (and maybe useful) diffs,
I added to each each compareable object two links:
* "base": Select this object as parent
* "diff": Diff against the last select parent
The selected parent object is stored as a cookie, so it is possible to
do a diff between objects shown on different pages.
The whole is implemented in JavaScript on the client side (tested with
IE 6 and Mozilla). On the server side, only the JavaScript file is
included in the output (see below). The link generation is done
completely in the browser.
The patch offers the following possibilies:
* Compare any commit with an other commit
Passes the hashes of the two commits as h and hp to commitdiff
function. The output includes the message of one commit, which can
be confusing.
* Compare any blob with an other blob
This feature is based on the blobdiff function. There are two types
of blob:
- blobs in the tree view can be compared with any blob in the tree view.
- blobs in the history view can only be compared with any blob with
the same file name in the history view.
* Compare trees
gitweb currently has no function for comparing trees. I currently
misused blobdiff for this. The content of the diff is OK, only the
filenames are wrong/destroyed. Additionally gitweb issus some "Use
of uninitialized value" message to the error log.
A proper implementation would need new function in gitweb.cgi,
basically git_commitdiff removing the requirement, that the hashes
must be a commit.
Is there an interest these function?
mfg Martin Kögler
Patch for gitweb.cgi (in function git_footer_html):
---------------------------------------------------
+ print '<script type="text/javascript" src="gitweb.js"></script>';
print "</body>\n" .
"</html>";
File 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')
{
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)
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';
if(c.h&&url.h)
{
url.hb=null;
url.hp=c.h;
url.fp=c.f;
}
else if (c.hb&&url.hb&&url.f&&c.f)
{
if (url.f!=c.f)
{
alert("file name do not match");
return;
}
url.h=null;
url.hpb=c.hb;
url.fp=c.f;
}
else
{
alert("blob diff not possible");
return;
}
document.location.href=url.ToURL();
return;
}
if(c.t=='tree'&&url.a=='tree')
{
url.a='blobdiff';
if(c.h&&url.h)
{
url.hb=null;
url.hp=c.h;
url.fp=c.f;
document.location.href=url.ToURL();
return;
}
}
alert("diff not possible");
}
GitAddLinks();
next reply other threads:[~2007-03-17 15:17 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-03-17 15:17 Martin Koegler [this message]
2007-03-17 18:04 ` [RFC] More diff possibilities in gitweb Johannes Schindelin
2007-03-18 14:14 ` Martin Koegler
2007-03-18 23:20 ` Jakub Narebski
2007-03-19 22:03 ` Martin Koegler
2007-03-20 1:41 ` Jakub Narebski
2007-03-17 21:51 ` Jakub Narebski
2007-03-18 15:02 ` Martin Koegler
2007-03-18 21:55 ` Jakub Narebski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070317151731.GA32571@auto.tuwien.ac.at \
--to=mkoegler@auto.tuwien.ac.at \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).