Fossil SCM
Add an implementation for the "fossil bundle cat" command.
Commit
8f0ced670198928b4e2e1bc380ce52a7f9a48d84
Parent
454c727154772c6…
1 file changed
+77
-1
+77
-1
| --- src/bundle.c | ||
| +++ src/bundle.c | ||
| @@ -435,10 +435,86 @@ | ||
| 435 | 435 | } |
| 436 | 436 | db_finalize(&q); |
| 437 | 437 | if( iSrc>0 ) bag_remove(&busy, iSrc); |
| 438 | 438 | } |
| 439 | 439 | |
| 440 | +/* | |
| 441 | +** Extract an item from content from the bundle | |
| 442 | +*/ | |
| 443 | +static void bundle_extract_item( | |
| 444 | + int blobid, /* ID of the item to extract */ | |
| 445 | + Blob *pOut /* Write the content into this blob */ | |
| 446 | +){ | |
| 447 | + Stmt q; | |
| 448 | + Blob x, basis, h1, h2; | |
| 449 | + static Bag busy; | |
| 450 | + | |
| 451 | + db_prepare(&q, "SELECT uuid, delta, data FROM bblob" | |
| 452 | + " WHERE blobid=%d", blobid); | |
| 453 | + if( db_step(&q)!=SQLITE_ROW ){ | |
| 454 | + db_finalize(&q); | |
| 455 | + fossil_fatal("no such item: %d", blobid); | |
| 456 | + } | |
| 457 | + if( bag_find(&busy, blobid) ) fossil_fatal("delta loop"); | |
| 458 | + blob_zero(&x); | |
| 459 | + db_column_blob(&q, 2, &x); | |
| 460 | + blob_uncompress(&x, &x); | |
| 461 | + if( db_column_type(&q,1)==SQLITE_INTEGER ){ | |
| 462 | + bundle_extract_item(db_column_int(&q,1), &basis); | |
| 463 | + blob_delta_apply(&basis, &x, pOut); | |
| 464 | + blob_reset(&basis); | |
| 465 | + blob_reset(&x); | |
| 466 | + }else if( db_column_type(&q,1)==SQLITE_TEXT ){ | |
| 467 | + int rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", | |
| 468 | + db_column_text(&q,1)); | |
| 469 | + if( rid==0 ){ | |
| 470 | + fossil_fatal("cannot find delta basis %s", db_column_text(&q,1)); | |
| 471 | + } | |
| 472 | + content_get(rid, &basis); | |
| 473 | + db_column_blob(&q, 2, &x); | |
| 474 | + blob_delta_apply(&basis, &x, pOut); | |
| 475 | + blob_reset(&basis); | |
| 476 | + blob_reset(&x); | |
| 477 | + }else{ | |
| 478 | + *pOut = x; | |
| 479 | + } | |
| 480 | + blob_zero(&h1); | |
| 481 | + db_column_blob(&q, 0, &h1); | |
| 482 | + sha1sum_blob(pOut, &h2); | |
| 483 | + if( blob_compare(&h1, &h2)!=0 ){ | |
| 484 | + fossil_fatal("SHA1 hash mismatch - wanted %s, got %s", | |
| 485 | + blob_str(&h1), blob_str(&h2)); | |
| 486 | + } | |
| 487 | + blob_reset(&h1); | |
| 488 | + blob_reset(&h2); | |
| 489 | + bag_remove(&busy, blobid); | |
| 490 | + db_finalize(&q); | |
| 491 | +} | |
| 492 | + | |
| 493 | +/* fossil bundle cat BUNDLE UUID... | |
| 494 | +** | |
| 495 | +** Write elements of a bundle on standard output | |
| 496 | +*/ | |
| 497 | +static void bundle_cat_cmd(void){ | |
| 498 | + int i; | |
| 499 | + Blob x; | |
| 500 | + if( g.argc<5 ) usage("cat BUNDLE UUID..."); | |
| 501 | + verify_all_options(); | |
| 502 | + bundle_attach_file(g.argv[3], "b1", 1); | |
| 503 | + blob_zero(&x); | |
| 504 | + for(i=4; i<g.argc; i++){ | |
| 505 | + int blobid = db_int(0,"SELECT blobid FROM bblob WHERE uuid LIKE '%q%%'", | |
| 506 | + g.argv[i]); | |
| 507 | + if( blobid==0 ){ | |
| 508 | + fossil_fatal("no such artifact in bundle: %s", g.argv[i]); | |
| 509 | + } | |
| 510 | + bundle_extract_item(blobid, &x); | |
| 511 | + blob_write_to_file(&x, "-"); | |
| 512 | + blob_reset(&x); | |
| 513 | + } | |
| 514 | +} | |
| 515 | + | |
| 440 | 516 | |
| 441 | 517 | /* fossil bundle import BUNDLE ?OPTIONS? |
| 442 | 518 | ** |
| 443 | 519 | ** Attempt to import the changes contained in BUNDLE. Make the change |
| 444 | 520 | ** private so that they do not sync. |
| @@ -568,11 +644,11 @@ | ||
| 568 | 644 | db_find_and_open_repository(0,0); |
| 569 | 645 | n = (int)strlen(zSubcmd); |
| 570 | 646 | if( strncmp(zSubcmd, "append", n)==0 ){ |
| 571 | 647 | bundle_append_cmd(); |
| 572 | 648 | }else if( strncmp(zSubcmd, "cat", n)==0 ){ |
| 573 | - fossil_print("Not yet implemented...\n"); | |
| 649 | + bundle_cat_cmd(); | |
| 574 | 650 | }else if( strncmp(zSubcmd, "export", n)==0 ){ |
| 575 | 651 | bundle_export_cmd(); |
| 576 | 652 | }else if( strncmp(zSubcmd, "import", n)==0 ){ |
| 577 | 653 | bundle_import_cmd(); |
| 578 | 654 | }else if( strncmp(zSubcmd, "ls", n)==0 ){ |
| 579 | 655 |
| --- src/bundle.c | |
| +++ src/bundle.c | |
| @@ -435,10 +435,86 @@ | |
| 435 | } |
| 436 | db_finalize(&q); |
| 437 | if( iSrc>0 ) bag_remove(&busy, iSrc); |
| 438 | } |
| 439 | |
| 440 | |
| 441 | /* fossil bundle import BUNDLE ?OPTIONS? |
| 442 | ** |
| 443 | ** Attempt to import the changes contained in BUNDLE. Make the change |
| 444 | ** private so that they do not sync. |
| @@ -568,11 +644,11 @@ | |
| 568 | db_find_and_open_repository(0,0); |
| 569 | n = (int)strlen(zSubcmd); |
| 570 | if( strncmp(zSubcmd, "append", n)==0 ){ |
| 571 | bundle_append_cmd(); |
| 572 | }else if( strncmp(zSubcmd, "cat", n)==0 ){ |
| 573 | fossil_print("Not yet implemented...\n"); |
| 574 | }else if( strncmp(zSubcmd, "export", n)==0 ){ |
| 575 | bundle_export_cmd(); |
| 576 | }else if( strncmp(zSubcmd, "import", n)==0 ){ |
| 577 | bundle_import_cmd(); |
| 578 | }else if( strncmp(zSubcmd, "ls", n)==0 ){ |
| 579 |
| --- src/bundle.c | |
| +++ src/bundle.c | |
| @@ -435,10 +435,86 @@ | |
| 435 | } |
| 436 | db_finalize(&q); |
| 437 | if( iSrc>0 ) bag_remove(&busy, iSrc); |
| 438 | } |
| 439 | |
| 440 | /* |
| 441 | ** Extract an item from content from the bundle |
| 442 | */ |
| 443 | static void bundle_extract_item( |
| 444 | int blobid, /* ID of the item to extract */ |
| 445 | Blob *pOut /* Write the content into this blob */ |
| 446 | ){ |
| 447 | Stmt q; |
| 448 | Blob x, basis, h1, h2; |
| 449 | static Bag busy; |
| 450 | |
| 451 | db_prepare(&q, "SELECT uuid, delta, data FROM bblob" |
| 452 | " WHERE blobid=%d", blobid); |
| 453 | if( db_step(&q)!=SQLITE_ROW ){ |
| 454 | db_finalize(&q); |
| 455 | fossil_fatal("no such item: %d", blobid); |
| 456 | } |
| 457 | if( bag_find(&busy, blobid) ) fossil_fatal("delta loop"); |
| 458 | blob_zero(&x); |
| 459 | db_column_blob(&q, 2, &x); |
| 460 | blob_uncompress(&x, &x); |
| 461 | if( db_column_type(&q,1)==SQLITE_INTEGER ){ |
| 462 | bundle_extract_item(db_column_int(&q,1), &basis); |
| 463 | blob_delta_apply(&basis, &x, pOut); |
| 464 | blob_reset(&basis); |
| 465 | blob_reset(&x); |
| 466 | }else if( db_column_type(&q,1)==SQLITE_TEXT ){ |
| 467 | int rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", |
| 468 | db_column_text(&q,1)); |
| 469 | if( rid==0 ){ |
| 470 | fossil_fatal("cannot find delta basis %s", db_column_text(&q,1)); |
| 471 | } |
| 472 | content_get(rid, &basis); |
| 473 | db_column_blob(&q, 2, &x); |
| 474 | blob_delta_apply(&basis, &x, pOut); |
| 475 | blob_reset(&basis); |
| 476 | blob_reset(&x); |
| 477 | }else{ |
| 478 | *pOut = x; |
| 479 | } |
| 480 | blob_zero(&h1); |
| 481 | db_column_blob(&q, 0, &h1); |
| 482 | sha1sum_blob(pOut, &h2); |
| 483 | if( blob_compare(&h1, &h2)!=0 ){ |
| 484 | fossil_fatal("SHA1 hash mismatch - wanted %s, got %s", |
| 485 | blob_str(&h1), blob_str(&h2)); |
| 486 | } |
| 487 | blob_reset(&h1); |
| 488 | blob_reset(&h2); |
| 489 | bag_remove(&busy, blobid); |
| 490 | db_finalize(&q); |
| 491 | } |
| 492 | |
| 493 | /* fossil bundle cat BUNDLE UUID... |
| 494 | ** |
| 495 | ** Write elements of a bundle on standard output |
| 496 | */ |
| 497 | static void bundle_cat_cmd(void){ |
| 498 | int i; |
| 499 | Blob x; |
| 500 | if( g.argc<5 ) usage("cat BUNDLE UUID..."); |
| 501 | verify_all_options(); |
| 502 | bundle_attach_file(g.argv[3], "b1", 1); |
| 503 | blob_zero(&x); |
| 504 | for(i=4; i<g.argc; i++){ |
| 505 | int blobid = db_int(0,"SELECT blobid FROM bblob WHERE uuid LIKE '%q%%'", |
| 506 | g.argv[i]); |
| 507 | if( blobid==0 ){ |
| 508 | fossil_fatal("no such artifact in bundle: %s", g.argv[i]); |
| 509 | } |
| 510 | bundle_extract_item(blobid, &x); |
| 511 | blob_write_to_file(&x, "-"); |
| 512 | blob_reset(&x); |
| 513 | } |
| 514 | } |
| 515 | |
| 516 | |
| 517 | /* fossil bundle import BUNDLE ?OPTIONS? |
| 518 | ** |
| 519 | ** Attempt to import the changes contained in BUNDLE. Make the change |
| 520 | ** private so that they do not sync. |
| @@ -568,11 +644,11 @@ | |
| 644 | db_find_and_open_repository(0,0); |
| 645 | n = (int)strlen(zSubcmd); |
| 646 | if( strncmp(zSubcmd, "append", n)==0 ){ |
| 647 | bundle_append_cmd(); |
| 648 | }else if( strncmp(zSubcmd, "cat", n)==0 ){ |
| 649 | bundle_cat_cmd(); |
| 650 | }else if( strncmp(zSubcmd, "export", n)==0 ){ |
| 651 | bundle_export_cmd(); |
| 652 | }else if( strncmp(zSubcmd, "import", n)==0 ){ |
| 653 | bundle_import_cmd(); |
| 654 | }else if( strncmp(zSubcmd, "ls", n)==0 ){ |
| 655 |