Fossil SCM
Fix a problem in the commit logic that caused it to ignore merge changes. Add another test to the commit to detect future problems of a similar nature.
Commit
5c3e87171a336b076e87377b786fa9a1de711016
Parent
dd9633a03db92b9…
2 files changed
+5
-1
+37
-2
+5
-1
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -270,11 +270,11 @@ | ||
| 270 | 270 | blob_appendf(&manifest, "C %F\n", blob_str(&comment)); |
| 271 | 271 | zDate = db_text(0, "SELECT datetime('now')"); |
| 272 | 272 | zDate[10] = 'T'; |
| 273 | 273 | blob_appendf(&manifest, "D %s\n", zDate); |
| 274 | 274 | db_prepare(&q, |
| 275 | - "SELECT pathname, uuid FROM vfile JOIN blob USING (rid)" | |
| 275 | + "SELECT pathname, uuid FROM vfile JOIN blob ON vfile.mrid=blob.rid" | |
| 276 | 276 | " WHERE NOT deleted AND vfile.vid=%d" |
| 277 | 277 | " ORDER BY 1", vid); |
| 278 | 278 | while( db_step(&q)==SQLITE_ROW ){ |
| 279 | 279 | const char *zName = db_column_text(&q, 0); |
| 280 | 280 | const char *zUuid = db_column_text(&q, 1); |
| @@ -322,13 +322,17 @@ | ||
| 322 | 322 | /* Verify that the tree checksum is unchanged */ |
| 323 | 323 | vfile_aggregate_checksum_repository(nvid, &cksum2); |
| 324 | 324 | if( blob_compare(&cksum1, &cksum2) ){ |
| 325 | 325 | fossil_panic("tree checksum does not match repository after commit"); |
| 326 | 326 | } |
| 327 | + vfile_aggregate_checksum_manifest(nvid, &cksum2); | |
| 328 | + if( blob_compare(&cksum1, &cksum2) ){ | |
| 329 | + fossil_panic("tree checksum does not match manifest after commit"); | |
| 330 | + } | |
| 327 | 331 | vfile_aggregate_checksum_disk(nvid, &cksum2); |
| 328 | 332 | if( blob_compare(&cksum1, &cksum2) ){ |
| 329 | 333 | fossil_panic("tree checksums before and after commit do not match"); |
| 330 | 334 | } |
| 331 | 335 | |
| 332 | 336 | /* Commit */ |
| 333 | 337 | db_end_transaction(0); |
| 334 | 338 | } |
| 335 | 339 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -270,11 +270,11 @@ | |
| 270 | blob_appendf(&manifest, "C %F\n", blob_str(&comment)); |
| 271 | zDate = db_text(0, "SELECT datetime('now')"); |
| 272 | zDate[10] = 'T'; |
| 273 | blob_appendf(&manifest, "D %s\n", zDate); |
| 274 | db_prepare(&q, |
| 275 | "SELECT pathname, uuid FROM vfile JOIN blob USING (rid)" |
| 276 | " WHERE NOT deleted AND vfile.vid=%d" |
| 277 | " ORDER BY 1", vid); |
| 278 | while( db_step(&q)==SQLITE_ROW ){ |
| 279 | const char *zName = db_column_text(&q, 0); |
| 280 | const char *zUuid = db_column_text(&q, 1); |
| @@ -322,13 +322,17 @@ | |
| 322 | /* Verify that the tree checksum is unchanged */ |
| 323 | vfile_aggregate_checksum_repository(nvid, &cksum2); |
| 324 | if( blob_compare(&cksum1, &cksum2) ){ |
| 325 | fossil_panic("tree checksum does not match repository after commit"); |
| 326 | } |
| 327 | vfile_aggregate_checksum_disk(nvid, &cksum2); |
| 328 | if( blob_compare(&cksum1, &cksum2) ){ |
| 329 | fossil_panic("tree checksums before and after commit do not match"); |
| 330 | } |
| 331 | |
| 332 | /* Commit */ |
| 333 | db_end_transaction(0); |
| 334 | } |
| 335 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -270,11 +270,11 @@ | |
| 270 | blob_appendf(&manifest, "C %F\n", blob_str(&comment)); |
| 271 | zDate = db_text(0, "SELECT datetime('now')"); |
| 272 | zDate[10] = 'T'; |
| 273 | blob_appendf(&manifest, "D %s\n", zDate); |
| 274 | db_prepare(&q, |
| 275 | "SELECT pathname, uuid FROM vfile JOIN blob ON vfile.mrid=blob.rid" |
| 276 | " WHERE NOT deleted AND vfile.vid=%d" |
| 277 | " ORDER BY 1", vid); |
| 278 | while( db_step(&q)==SQLITE_ROW ){ |
| 279 | const char *zName = db_column_text(&q, 0); |
| 280 | const char *zUuid = db_column_text(&q, 1); |
| @@ -322,13 +322,17 @@ | |
| 322 | /* Verify that the tree checksum is unchanged */ |
| 323 | vfile_aggregate_checksum_repository(nvid, &cksum2); |
| 324 | if( blob_compare(&cksum1, &cksum2) ){ |
| 325 | fossil_panic("tree checksum does not match repository after commit"); |
| 326 | } |
| 327 | vfile_aggregate_checksum_manifest(nvid, &cksum2); |
| 328 | if( blob_compare(&cksum1, &cksum2) ){ |
| 329 | fossil_panic("tree checksum does not match manifest after commit"); |
| 330 | } |
| 331 | vfile_aggregate_checksum_disk(nvid, &cksum2); |
| 332 | if( blob_compare(&cksum1, &cksum2) ){ |
| 333 | fossil_panic("tree checksums before and after commit do not match"); |
| 334 | } |
| 335 | |
| 336 | /* Commit */ |
| 337 | db_end_transaction(0); |
| 338 | } |
| 339 |
+37
-2
| --- src/vfile.c | ||
| +++ src/vfile.c | ||
| @@ -303,10 +303,11 @@ | ||
| 303 | 303 | Blob file; |
| 304 | 304 | Stmt q; |
| 305 | 305 | char zBuf[100]; |
| 306 | 306 | |
| 307 | 307 | db_must_be_within_tree(); |
| 308 | + | |
| 308 | 309 | db_prepare(&q, "SELECT pathname, rid FROM vfile" |
| 309 | 310 | " WHERE NOT deleted AND rid>0 AND vid=%d" |
| 310 | 311 | " ORDER BY pathname", |
| 311 | 312 | vid); |
| 312 | 313 | blob_zero(&file); |
| @@ -322,10 +323,41 @@ | ||
| 322 | 323 | blob_reset(&file); |
| 323 | 324 | } |
| 324 | 325 | db_finalize(&q); |
| 325 | 326 | md5sum_finish(pOut); |
| 326 | 327 | } |
| 328 | + | |
| 329 | +/* | |
| 330 | +** Compute an aggregate MD5 checksum over the repository image of every | |
| 331 | +** file in manifest vid. The file names are part of the checksum. | |
| 332 | +** | |
| 333 | +** Return the resulting checksum in blob pOut. | |
| 334 | +*/ | |
| 335 | +void vfile_aggregate_checksum_manifest(int vid, Blob *pOut){ | |
| 336 | + int i, fid; | |
| 337 | + Blob file, mfile; | |
| 338 | + Manifest m; | |
| 339 | + char zBuf[100]; | |
| 340 | + | |
| 341 | + db_must_be_within_tree(); | |
| 342 | + content_get(vid, &mfile); | |
| 343 | + if( manifest_parse(&m, &mfile)==0 ){ | |
| 344 | + blob_zero(pOut); | |
| 345 | + return; | |
| 346 | + } | |
| 347 | + for(i=0; i<m.nFile; i++){ | |
| 348 | + fid = uuid_to_rid(m.aFile[i].zUuid, 0); | |
| 349 | + md5sum_step_text(m.aFile[i].zName, -1); | |
| 350 | + content_get(fid, &file); | |
| 351 | + sprintf(zBuf, " %d\n", blob_size(&file)); | |
| 352 | + md5sum_step_text(zBuf, -1); | |
| 353 | + md5sum_step_blob(&file); | |
| 354 | + blob_reset(&file); | |
| 355 | + } | |
| 356 | + manifest_clear(&m); | |
| 357 | + md5sum_finish(pOut); | |
| 358 | +} | |
| 327 | 359 | |
| 328 | 360 | /* |
| 329 | 361 | ** COMMAND: test-agg-cksum |
| 330 | 362 | */ |
| 331 | 363 | void test_agg_cksum_cmd(void){ |
| @@ -332,10 +364,13 @@ | ||
| 332 | 364 | int vid; |
| 333 | 365 | Blob hash; |
| 334 | 366 | db_must_be_within_tree(); |
| 335 | 367 | vid = db_lget_int("checkout", 0); |
| 336 | 368 | vfile_aggregate_checksum_disk(vid, &hash); |
| 337 | - printf("disk: %s\n", blob_str(&hash)); | |
| 369 | + printf("disk: %s\n", blob_str(&hash)); | |
| 338 | 370 | blob_reset(&hash); |
| 339 | 371 | vfile_aggregate_checksum_repository(vid, &hash); |
| 340 | - printf("archive: %s\n", blob_str(&hash)); | |
| 372 | + printf("archive: %s\n", blob_str(&hash)); | |
| 373 | + blob_reset(&hash); | |
| 374 | + vfile_aggregate_checksum_manifest(vid, &hash); | |
| 375 | + printf("manifest: %s\n", blob_str(&hash)); | |
| 341 | 376 | } |
| 342 | 377 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -303,10 +303,11 @@ | |
| 303 | Blob file; |
| 304 | Stmt q; |
| 305 | char zBuf[100]; |
| 306 | |
| 307 | db_must_be_within_tree(); |
| 308 | db_prepare(&q, "SELECT pathname, rid FROM vfile" |
| 309 | " WHERE NOT deleted AND rid>0 AND vid=%d" |
| 310 | " ORDER BY pathname", |
| 311 | vid); |
| 312 | blob_zero(&file); |
| @@ -322,10 +323,41 @@ | |
| 322 | blob_reset(&file); |
| 323 | } |
| 324 | db_finalize(&q); |
| 325 | md5sum_finish(pOut); |
| 326 | } |
| 327 | |
| 328 | /* |
| 329 | ** COMMAND: test-agg-cksum |
| 330 | */ |
| 331 | void test_agg_cksum_cmd(void){ |
| @@ -332,10 +364,13 @@ | |
| 332 | int vid; |
| 333 | Blob hash; |
| 334 | db_must_be_within_tree(); |
| 335 | vid = db_lget_int("checkout", 0); |
| 336 | vfile_aggregate_checksum_disk(vid, &hash); |
| 337 | printf("disk: %s\n", blob_str(&hash)); |
| 338 | blob_reset(&hash); |
| 339 | vfile_aggregate_checksum_repository(vid, &hash); |
| 340 | printf("archive: %s\n", blob_str(&hash)); |
| 341 | } |
| 342 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -303,10 +303,11 @@ | |
| 303 | Blob file; |
| 304 | Stmt q; |
| 305 | char zBuf[100]; |
| 306 | |
| 307 | db_must_be_within_tree(); |
| 308 | |
| 309 | db_prepare(&q, "SELECT pathname, rid FROM vfile" |
| 310 | " WHERE NOT deleted AND rid>0 AND vid=%d" |
| 311 | " ORDER BY pathname", |
| 312 | vid); |
| 313 | blob_zero(&file); |
| @@ -322,10 +323,41 @@ | |
| 323 | blob_reset(&file); |
| 324 | } |
| 325 | db_finalize(&q); |
| 326 | md5sum_finish(pOut); |
| 327 | } |
| 328 | |
| 329 | /* |
| 330 | ** Compute an aggregate MD5 checksum over the repository image of every |
| 331 | ** file in manifest vid. The file names are part of the checksum. |
| 332 | ** |
| 333 | ** Return the resulting checksum in blob pOut. |
| 334 | */ |
| 335 | void vfile_aggregate_checksum_manifest(int vid, Blob *pOut){ |
| 336 | int i, fid; |
| 337 | Blob file, mfile; |
| 338 | Manifest m; |
| 339 | char zBuf[100]; |
| 340 | |
| 341 | db_must_be_within_tree(); |
| 342 | content_get(vid, &mfile); |
| 343 | if( manifest_parse(&m, &mfile)==0 ){ |
| 344 | blob_zero(pOut); |
| 345 | return; |
| 346 | } |
| 347 | for(i=0; i<m.nFile; i++){ |
| 348 | fid = uuid_to_rid(m.aFile[i].zUuid, 0); |
| 349 | md5sum_step_text(m.aFile[i].zName, -1); |
| 350 | content_get(fid, &file); |
| 351 | sprintf(zBuf, " %d\n", blob_size(&file)); |
| 352 | md5sum_step_text(zBuf, -1); |
| 353 | md5sum_step_blob(&file); |
| 354 | blob_reset(&file); |
| 355 | } |
| 356 | manifest_clear(&m); |
| 357 | md5sum_finish(pOut); |
| 358 | } |
| 359 | |
| 360 | /* |
| 361 | ** COMMAND: test-agg-cksum |
| 362 | */ |
| 363 | void test_agg_cksum_cmd(void){ |
| @@ -332,10 +364,13 @@ | |
| 364 | int vid; |
| 365 | Blob hash; |
| 366 | db_must_be_within_tree(); |
| 367 | vid = db_lget_int("checkout", 0); |
| 368 | vfile_aggregate_checksum_disk(vid, &hash); |
| 369 | printf("disk: %s\n", blob_str(&hash)); |
| 370 | blob_reset(&hash); |
| 371 | vfile_aggregate_checksum_repository(vid, &hash); |
| 372 | printf("archive: %s\n", blob_str(&hash)); |
| 373 | blob_reset(&hash); |
| 374 | vfile_aggregate_checksum_manifest(vid, &hash); |
| 375 | printf("manifest: %s\n", blob_str(&hash)); |
| 376 | } |
| 377 |