Fossil SCM
Whan a commit fails because the repository checksum does match the working directory, in addition to printing the names of the files that disagree, also output the repository version of the files to separate temporary files to facilitate error analysis.
Commit
edc0c9464d3b3166da7689586e44f5e22faa4b28
Parent
bbcc8fe351784c9…
1 file changed
+24
+24
| --- src/vfile.c | ||
| +++ src/vfile.c | ||
| @@ -534,19 +534,35 @@ | ||
| 534 | 534 | } |
| 535 | 535 | } |
| 536 | 536 | db_finalize(&q); |
| 537 | 537 | md5sum_finish(pOut); |
| 538 | 538 | } |
| 539 | + | |
| 540 | +/* | |
| 541 | +** Write a BLOB into a random filename. Return the name of the file. | |
| 542 | +*/ | |
| 543 | +static char *write_blob_to_temp_file(Blob *pBlob){ | |
| 544 | + sqlite3_uint64 r; | |
| 545 | + char *zOut = 0; | |
| 546 | + do{ | |
| 547 | + sqlite3_free(zOut); | |
| 548 | + sqlite3_randomness(8, &r); | |
| 549 | + zOut = sqlite3_mprintf("file-%08llx", r); | |
| 550 | + }while( file_size(zOut)>=0 ); | |
| 551 | + blob_write_to_file(pBlob, zOut); | |
| 552 | + return zOut; | |
| 553 | +} | |
| 539 | 554 | |
| 540 | 555 | /* |
| 541 | 556 | ** Do a file-by-file comparison of the content of the repository and |
| 542 | 557 | ** the working check-out on disk. Report any errors. |
| 543 | 558 | */ |
| 544 | 559 | void vfile_compare_repository_to_disk(int vid){ |
| 545 | 560 | int rc; |
| 546 | 561 | Stmt q; |
| 547 | 562 | Blob disk, repo; |
| 563 | + char *zOut; | |
| 548 | 564 | |
| 549 | 565 | db_must_be_within_tree(); |
| 550 | 566 | db_prepare(&q, |
| 551 | 567 | "SELECT %Q || pathname, pathname, rid FROM vfile" |
| 552 | 568 | " WHERE NOT deleted AND vid=%d AND file_is_selected(id)", |
| @@ -572,18 +588,26 @@ | ||
| 572 | 588 | blob_zero(&repo); |
| 573 | 589 | content_get(rid, &repo); |
| 574 | 590 | if( blob_size(&repo)!=blob_size(&disk) ){ |
| 575 | 591 | fossil_print("ERROR: [%s] is %d bytes on disk but %d in the repository\n", |
| 576 | 592 | zName, blob_size(&disk), blob_size(&repo)); |
| 593 | + zOut = write_blob_to_temp_file(&repo); | |
| 594 | + fossil_print("NOTICE: Repository version of [%s] stored in [%s]\n", | |
| 595 | + zName, zOut); | |
| 596 | + sqlite3_free(zOut); | |
| 577 | 597 | blob_reset(&disk); |
| 578 | 598 | blob_reset(&repo); |
| 579 | 599 | continue; |
| 580 | 600 | } |
| 581 | 601 | if( blob_compare(&repo, &disk) ){ |
| 582 | 602 | fossil_print( |
| 583 | 603 | "ERROR: [%s] is different on disk compared to the repository\n", |
| 584 | 604 | zName); |
| 605 | + zOut = write_blob_to_temp_file(&repo); | |
| 606 | + fossil_print("NOTICE: Repository version of [%s] stored in [%s]\n", | |
| 607 | + zName, zOut); | |
| 608 | + sqlite3_free(zOut); | |
| 585 | 609 | } |
| 586 | 610 | blob_reset(&disk); |
| 587 | 611 | blob_reset(&repo); |
| 588 | 612 | } |
| 589 | 613 | db_finalize(&q); |
| 590 | 614 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -534,19 +534,35 @@ | |
| 534 | } |
| 535 | } |
| 536 | db_finalize(&q); |
| 537 | md5sum_finish(pOut); |
| 538 | } |
| 539 | |
| 540 | /* |
| 541 | ** Do a file-by-file comparison of the content of the repository and |
| 542 | ** the working check-out on disk. Report any errors. |
| 543 | */ |
| 544 | void vfile_compare_repository_to_disk(int vid){ |
| 545 | int rc; |
| 546 | Stmt q; |
| 547 | Blob disk, repo; |
| 548 | |
| 549 | db_must_be_within_tree(); |
| 550 | db_prepare(&q, |
| 551 | "SELECT %Q || pathname, pathname, rid FROM vfile" |
| 552 | " WHERE NOT deleted AND vid=%d AND file_is_selected(id)", |
| @@ -572,18 +588,26 @@ | |
| 572 | blob_zero(&repo); |
| 573 | content_get(rid, &repo); |
| 574 | if( blob_size(&repo)!=blob_size(&disk) ){ |
| 575 | fossil_print("ERROR: [%s] is %d bytes on disk but %d in the repository\n", |
| 576 | zName, blob_size(&disk), blob_size(&repo)); |
| 577 | blob_reset(&disk); |
| 578 | blob_reset(&repo); |
| 579 | continue; |
| 580 | } |
| 581 | if( blob_compare(&repo, &disk) ){ |
| 582 | fossil_print( |
| 583 | "ERROR: [%s] is different on disk compared to the repository\n", |
| 584 | zName); |
| 585 | } |
| 586 | blob_reset(&disk); |
| 587 | blob_reset(&repo); |
| 588 | } |
| 589 | db_finalize(&q); |
| 590 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -534,19 +534,35 @@ | |
| 534 | } |
| 535 | } |
| 536 | db_finalize(&q); |
| 537 | md5sum_finish(pOut); |
| 538 | } |
| 539 | |
| 540 | /* |
| 541 | ** Write a BLOB into a random filename. Return the name of the file. |
| 542 | */ |
| 543 | static char *write_blob_to_temp_file(Blob *pBlob){ |
| 544 | sqlite3_uint64 r; |
| 545 | char *zOut = 0; |
| 546 | do{ |
| 547 | sqlite3_free(zOut); |
| 548 | sqlite3_randomness(8, &r); |
| 549 | zOut = sqlite3_mprintf("file-%08llx", r); |
| 550 | }while( file_size(zOut)>=0 ); |
| 551 | blob_write_to_file(pBlob, zOut); |
| 552 | return zOut; |
| 553 | } |
| 554 | |
| 555 | /* |
| 556 | ** Do a file-by-file comparison of the content of the repository and |
| 557 | ** the working check-out on disk. Report any errors. |
| 558 | */ |
| 559 | void vfile_compare_repository_to_disk(int vid){ |
| 560 | int rc; |
| 561 | Stmt q; |
| 562 | Blob disk, repo; |
| 563 | char *zOut; |
| 564 | |
| 565 | db_must_be_within_tree(); |
| 566 | db_prepare(&q, |
| 567 | "SELECT %Q || pathname, pathname, rid FROM vfile" |
| 568 | " WHERE NOT deleted AND vid=%d AND file_is_selected(id)", |
| @@ -572,18 +588,26 @@ | |
| 588 | blob_zero(&repo); |
| 589 | content_get(rid, &repo); |
| 590 | if( blob_size(&repo)!=blob_size(&disk) ){ |
| 591 | fossil_print("ERROR: [%s] is %d bytes on disk but %d in the repository\n", |
| 592 | zName, blob_size(&disk), blob_size(&repo)); |
| 593 | zOut = write_blob_to_temp_file(&repo); |
| 594 | fossil_print("NOTICE: Repository version of [%s] stored in [%s]\n", |
| 595 | zName, zOut); |
| 596 | sqlite3_free(zOut); |
| 597 | blob_reset(&disk); |
| 598 | blob_reset(&repo); |
| 599 | continue; |
| 600 | } |
| 601 | if( blob_compare(&repo, &disk) ){ |
| 602 | fossil_print( |
| 603 | "ERROR: [%s] is different on disk compared to the repository\n", |
| 604 | zName); |
| 605 | zOut = write_blob_to_temp_file(&repo); |
| 606 | fossil_print("NOTICE: Repository version of [%s] stored in [%s]\n", |
| 607 | zName, zOut); |
| 608 | sqlite3_free(zOut); |
| 609 | } |
| 610 | blob_reset(&disk); |
| 611 | blob_reset(&repo); |
| 612 | } |
| 613 | db_finalize(&q); |
| 614 |