Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Add primitive start-time and duration controols to the timeline. Additional checksums on check-in and check-out. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
394505791628e571d7020d6cdd85235e |
| User & Date: | drh 2007-08-01 21:03:03.000 |
Context
|
2007-08-01
| ||
| 21:59 | Add the ability to sign manifests using GPG during a check-in. Due to a bug in the manifest parser, older versions will not be able to check-out signed manifests. ... (check-in: e37451d9c2 user: drh tags: trunk) | |
| 21:03 | Add primitive start-time and duration controols to the timeline. Additional checksums on check-in and check-out. ... (check-in: 3945057916 user: drh tags: trunk) | |
| 20:05 | Documentation updates. Added Makefile. ... (check-in: 0e265b0184 user: drh tags: trunk) | |
Changes
Changes to src/checkin.c.
| ︙ | ︙ | |||
225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
Stmt q;
Stmt q2;
char *zUuid, *zDate;
char *zManifestFile; /* Name of the manifest file */
Blob manifest;
Blob mcksum; /* Self-checksum on the manifest */
Blob cksum1, cksum2; /* Before and after commit checksums */
db_must_be_within_tree();
user_select();
db_begin_transaction();
rc = unsaved_changes();
if( rc==0 ){
fossil_panic("nothing has changed");
| > | 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
Stmt q;
Stmt q2;
char *zUuid, *zDate;
char *zManifestFile; /* Name of the manifest file */
Blob manifest;
Blob mcksum; /* Self-checksum on the manifest */
Blob cksum1, cksum2; /* Before and after commit checksums */
Blob cksum1b; /* Checksum recorded in the manifest */
db_must_be_within_tree();
user_select();
db_begin_transaction();
rc = unsaved_changes();
if( rc==0 ){
fossil_panic("nothing has changed");
|
| ︙ | ︙ | |||
320 321 322 323 324 325 326 |
db_lset_int("checkout", nvid);
/* Verify that the tree checksum is unchanged */
vfile_aggregate_checksum_repository(nvid, &cksum2);
if( blob_compare(&cksum1, &cksum2) ){
fossil_panic("tree checksum does not match repository after commit");
}
| | > > > > | > | 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
db_lset_int("checkout", nvid);
/* Verify that the tree checksum is unchanged */
vfile_aggregate_checksum_repository(nvid, &cksum2);
if( blob_compare(&cksum1, &cksum2) ){
fossil_panic("tree checksum does not match repository after commit");
}
vfile_aggregate_checksum_manifest(nvid, &cksum2, &cksum1b);
if( blob_compare(&cksum1, &cksum1b) ){
fossil_panic("manifest checksum does not agree with manifest: "
"%b versus %b", &cksum1, &cksum1b);
}
if( blob_compare(&cksum1, &cksum2) ){
fossil_panic("tree checksum does not match manifest after commit: "
"%b versus %b", &cksum1, &cksum2);
}
vfile_aggregate_checksum_disk(nvid, &cksum2);
if( blob_compare(&cksum1, &cksum2) ){
fossil_panic("tree checksums before and after commit do not match");
}
/* Commit */
db_end_transaction(0);
}
|
Changes to src/checkout.c.
| ︙ | ︙ | |||
97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
**
** Check out a version specified on the command-line.
*/
void checkout_cmd(void){
int forceFlag;
int noWrite;
int vid, prior;
db_must_be_within_tree();
db_begin_transaction();
forceFlag = find_option("force","f",0)!=0;
noWrite = find_option("dontwrite",0,0)!=0;
if( g.argc!=3 ) usage("?--force? VERSION");
if( !forceFlag && unsaved_changes()==1 ){
| > | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
**
** Check out a version specified on the command-line.
*/
void checkout_cmd(void){
int forceFlag;
int noWrite;
int vid, prior;
Blob cksum1, cksum1b, cksum2;
db_must_be_within_tree();
db_begin_transaction();
forceFlag = find_option("force","f",0)!=0;
noWrite = find_option("dontwrite",0,0)!=0;
if( g.argc!=3 ) usage("?--force? VERSION");
if( !forceFlag && unsaved_changes()==1 ){
|
| ︙ | ︙ | |||
132 133 134 135 136 137 138 139 140 |
zManFile = mprintf("%smanifest", g.zLocalRoot);
content_get(vid, &manifest);
blob_write_to_file(&manifest, zManFile);
free(zManFile);
db_lset_int("checkout", vid);
}
db_multi_exec("DELETE FROM vmerge");
db_end_transaction(0);
}
| > > > > > > > > | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
zManFile = mprintf("%smanifest", g.zLocalRoot);
content_get(vid, &manifest);
blob_write_to_file(&manifest, zManFile);
free(zManFile);
db_lset_int("checkout", vid);
}
db_multi_exec("DELETE FROM vmerge");
vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
vfile_aggregate_checksum_disk(vid, &cksum2);
if( blob_compare(&cksum1, &cksum2) ){
printf("WARNING: manifest checksum does not agree with disk\n");
}
if( blob_compare(&cksum1, &cksum1b) ){
printf("WARNING: manifest checksum does not agree with manifest\n");
}
db_end_transaction(0);
}
|
Changes to src/descendents.c.
| ︙ | ︙ | |||
138 139 140 141 142 143 144 |
" event.comment, event.user"
" FROM blob, event"
" WHERE blob.rid IN"
" (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
" AND event.objid=blob.rid"
" ORDER BY event.mtime DESC"
);
| | | 138 139 140 141 142 143 144 145 146 147 148 |
" event.comment, event.user"
" FROM blob, event"
" WHERE blob.rid IN"
" (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
" AND event.objid=blob.rid"
" ORDER BY event.mtime DESC"
);
www_print_timeline(&q, 0);
db_finalize(&q);
style_footer();
}
|
Changes to src/timeline.c.
| ︙ | ︙ | |||
58 59 60 61 62 63 64 | ** should return 4 columns: ** ** 0. UUID ** 1. Date/Time ** 2. Comment string ** 3. User */ | | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
** should return 4 columns:
**
** 0. UUID
** 1. Date/Time
** 2. Comment string
** 3. User
*/
void www_print_timeline(Stmt *pQuery, char *zLastDate){
char zPrevDate[20];
zPrevDate[0] = 0;
@ <table cellspacing=0 border=0 cellpadding=0>
while( db_step(pQuery)==SQLITE_ROW ){
const char *zDate = db_column_text(pQuery, 1);
if( memcmp(zDate, zPrevDate, 10) ){
sprintf(zPrevDate, "%.10s", zDate);
|
| ︙ | ︙ | |||
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
@ </td></tr>
}
@ <tr><td valign="top">%s(&zDate[11])</td>
@ <td width="20"></td>
@ <td valign="top" align="left">
hyperlink_to_uuid(db_column_text(pQuery,0));
@ %h(db_column_text(pQuery,2)) (by %h(db_column_text(pQuery,3)))</td>
}
@ </table>
}
/*
** WEBPAGE: timeline
*/
void page_timeline(void){
Stmt q;
/* To view the timeline, must have permission to read project data.
*/
login_check_credentials();
if( !g.okRead ){ login_needed(); return; }
style_header("Timeline");
| > > > > > > > > > > > > > > | < > > > > > > > > > > | > > > > > > > > > > > > > > > > > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
@ </td></tr>
}
@ <tr><td valign="top">%s(&zDate[11])</td>
@ <td width="20"></td>
@ <td valign="top" align="left">
hyperlink_to_uuid(db_column_text(pQuery,0));
@ %h(db_column_text(pQuery,2)) (by %h(db_column_text(pQuery,3)))</td>
if( zLastDate ){
strcpy(zLastDate, zDate);
}
}
@ </table>
}
/*
** WEBPAGE: timeline
*/
void page_timeline(void){
Stmt q;
char *zSQL;
char zDate[100];
const char *zStart = P("d");
int nEntry = atoi(PD("n","25"));
/* To view the timeline, must have permission to read project data.
*/
login_check_credentials();
if( !g.okRead ){ login_needed(); return; }
style_header("Timeline");
if( !g.okHistory &&
db_exists("SELECT 1 FROM user"
" WHERE login='anonymous'"
" AND cap LIKE '%%h%%'") ){
@ <p><b>Note:</b> You will be able to see much more timeline
@ information if <a href="%s(g.zBaseURL)/login">login</a>.</p>
}
zSQL = mprintf(
"SELECT uuid, datetime(event.mtime,'localtime'), comment, user"
" FROM event, blob"
" WHERE event.type='ci' AND blob.rid=event.objid"
);
if( zStart ){
while( isspace(zStart[0]) ){ zStart++; }
if( zStart[0] ){
zSQL = mprintf("%z AND event.mtime<=julianday(%Q, 'localtime')",
zSQL, zStart);
}
}
zSQL = mprintf("%z ORDER BY event.mtime DESC LIMIT %d", zSQL, nEntry);
db_prepare(&q, zSQL);
free(zSQL);
www_print_timeline(&q, zDate);
db_finalize(&q);
if( zStart==0 ){
zStart = zDate;
}
@ <hr>
@ <form method="GET" action="%s(g.zBaseURL)/timeline">
@ Start Date:
@ <input type="text" size="30" value="%h(zStart)" name="d">
@ Number Of Entries:
@ <input type="text" size="4" value="%d(nEntry)" name="n">
@ <br><input type="submit" value="Submit">
@ </form>
@ <form method="GET" action="%s(g.zBaseURL)/timeline">
@ <input type="hidden" value="%h(zDate)" name="d">
@ <input type="hidden" value="%d(nEntry)" name="n">
@ <input type="submit" value="Next %d(nEntry) Rows">
@ </form>
style_footer();
}
/*
** The input query q selects various records. Print a human-readable
** summary of those records.
**
** Limit the number of entries printed to nLine.
*/
void print_timeline(Stmt *q, int mxLine){
|
| ︙ | ︙ |
Changes to src/vfile.c.
| ︙ | ︙ | |||
328 329 330 331 332 333 334 | /* ** Compute an aggregate MD5 checksum over the repository image of every ** file in manifest vid. The file names are part of the checksum. ** ** Return the resulting checksum in blob pOut. */ | | > > > > | | > | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 |
/*
** Compute an aggregate MD5 checksum over the repository image of every
** file in manifest vid. The file names are part of the checksum.
**
** Return the resulting checksum in blob pOut.
*/
void vfile_aggregate_checksum_manifest(int vid, Blob *pOut, Blob *pManOut){
int i, fid;
Blob file, mfile;
Manifest m;
char zBuf[100];
db_must_be_within_tree();
content_get(vid, &mfile);
if( manifest_parse(&m, &mfile)==0 ){
blob_zero(pOut);
return;
}
for(i=0; i<m.nFile; i++){
fid = uuid_to_rid(m.aFile[i].zUuid, 0);
md5sum_step_text(m.aFile[i].zName, -1);
content_get(fid, &file);
sprintf(zBuf, " %d\n", blob_size(&file));
md5sum_step_text(zBuf, -1);
md5sum_step_blob(&file);
blob_reset(&file);
}
if( pManOut ){
blob_zero(pManOut);
blob_append(pManOut, m.zRepoCksum, -1);
}
manifest_clear(&m);
md5sum_finish(pOut);
}
/*
** COMMAND: test-agg-cksum
*/
void test_agg_cksum_cmd(void){
int vid;
Blob hash, hash2;
db_must_be_within_tree();
vid = db_lget_int("checkout", 0);
vfile_aggregate_checksum_disk(vid, &hash);
printf("disk: %s\n", blob_str(&hash));
blob_reset(&hash);
vfile_aggregate_checksum_repository(vid, &hash);
printf("archive: %s\n", blob_str(&hash));
blob_reset(&hash);
vfile_aggregate_checksum_manifest(vid, &hash, &hash2);
printf("manifest: %s\n", blob_str(&hash));
printf("recorded: %s\n", blob_str(&hash2));
}
|