File History on Fossil SCM command line
I eval'ed a bunch of distributed version control systems, and settled on fossil (www.fossil-scm.org). It helped that it's the successor to cvstrac. I am impressed with how easy it makes distributed development. One of the things I miss sorely is the integration of fossil into emacs. I delved some into the fossil source code. Here's one of my first contributions (original at http://www.mail-archive.com/fossil-users@lists.fossil-scm.org/msg00665.html).
2009-Oct-27: added error checking and -l option for verbose listings
In src/info.c add this code just before finfo_page. Then fossil finfo filename gives you the change history for a file.
/*
** COMMAND: finfo
**
** Usage: %fossil finfo ?-l|--long? FILENAME
**
** Print the complete change history for a single file going backwards
** in time. If -l is specified the full comment is printed, otherwise
** one line is printed per revision.
**
*/
void finfo_cmd(void){
Stmt q;
int rid;
int verbose = 0; /* 1 means long listing */
Blob fname;
Blob line;
const char *zFilename;
db_must_be_within_tree();
if (g.argc<3) {
usage("FILENAME");
}
if (find_option("long","l",0))
verbose = 1;
file_tree_name(g.argv[2], &fname, 1);
zFilename = blob_str(&fname);
rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname);
if( rid==0 ){
fossil_fatal("no history for file: %b", &fname);
}
db_prepare(&q,
"SELECT substr(b.uuid,1,10), datetime(event.mtime,'localtime'),"
" coalesce(event.ecomment, event.comment),"
" coalesce(event.euser, event.user),"
" mlink.pid, mlink.fid, mlink.mid, mlink.fnid, ci.uuid"
" FROM mlink, blob b, event, blob ci"
" WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
" AND b.rid=mlink.fid"
" AND event.objid=mlink.mid"
" AND event.objid=ci.rid"
" ORDER BY event.mtime DESC",
zFilename
);
blob_zero(&line);
printf("History of %s\n", zFilename);
while( db_step(&q)==SQLITE_ROW ){
const char *zUuid = db_column_text(&q, 0);
const char *zDate = db_column_text(&q, 1);
const char *zCom = db_column_text(&q, 2);
const char *zUser = db_column_text(&q, 3);
blob_reset(&line);
if (verbose) {
blob_appendf(&line, "%.10s by %s ", zUuid, zUser);
blob_appendf(&line, "at %s\n", zDate);
blob_appendf(&line,"%s\n", zCom);
comment_print(blob_str(&line), 4, 79);
} else {
blob_appendf(&line, "%.10s ", zUuid);
blob_appendf(&line, "%.10s ", zDate);
blob_appendf(&line, "%8.8s ", zUser);
blob_appendf(&line,"%-40.40s\n", zCom );
comment_print(blob_str(&line), 0, 79);
}
}
db_finalize(&q);
blob_reset(&fname);
}