Fossil SCM

Add the --list option to the "tarball", "zip", and "sqlar" commands. Also rig those commands so that if the output filename is an empty string or "/dev/null" then they do not actually form the output archive.

drh 2021-01-21 23:33 trunk
Commit c88880fa8af0ed5664d984a5593d106509d0581c589823ed75e1403f056745bc
2 files changed +56 -24 +61 -24
+56 -24
--- src/tar.c
+++ src/tar.c
@@ -474,11 +474,12 @@
474474
void tarball_of_checkin(
475475
int rid, /* The RID of the checkin from which to form a tarball */
476476
Blob *pTar, /* Write the tarball into this blob */
477477
const char *zDir, /* Directory prefix for all file added to tarball */
478478
Glob *pInclude, /* Only add files matching this pattern */
479
- Glob *pExclude /* Exclude files matching this pattern */
479
+ Glob *pExclude, /* Exclude files matching this pattern */
480
+ int listFlag /* Show filenames on stdout */
480481
){
481482
Blob mfile, hash, file;
482483
Manifest *pManifest;
483484
ManifestFile *pFile;
484485
Blob filename;
@@ -501,11 +502,11 @@
501502
502503
pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
503504
if( pManifest ){
504505
int flg, eflg = 0;
505506
mTime = (pManifest->rDate - 2440587.5)*86400.0;
506
- tar_begin(mTime);
507
+ if( pTar ) tar_begin(mTime);
507508
flg = db_get_manifest_setting();
508509
if( flg ){
509510
/* eflg is the effective flags, taking include/exclude into account */
510511
if( (pInclude==0 || glob_match(pInclude, "manifest"))
511512
&& !glob_match(pExclude, "manifest")
@@ -525,62 +526,75 @@
525526
526527
if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
527528
if( eflg & MFESTFLG_RAW ){
528529
blob_append(&filename, "manifest", -1);
529530
zName = blob_str(&filename);
530
- }
531
- if( eflg & MFESTFLG_RAW ) {
532
- sterilize_manifest(&mfile, CFTYPE_MANIFEST);
533
- tar_add_file(zName, &mfile, 0, mTime);
531
+ if( listFlag ) fossil_print("%s\n", zName);
532
+ if( pTar ){
533
+ sterilize_manifest(&mfile, CFTYPE_MANIFEST);
534
+ tar_add_file(zName, &mfile, 0, mTime);
535
+ }
534536
}
535537
}
536538
blob_reset(&mfile);
537539
if( eflg & MFESTFLG_UUID ){
538
- blob_append(&hash, "\n", 1);
539540
blob_resize(&filename, nPrefix);
540541
blob_append(&filename, "manifest.uuid", -1);
541542
zName = blob_str(&filename);
542
- tar_add_file(zName, &hash, 0, mTime);
543
+ if( listFlag ) fossil_print("%s\n", zName);
544
+ if( pTar ){
545
+ blob_append(&hash, "\n", 1);
546
+ tar_add_file(zName, &hash, 0, mTime);
547
+ }
543548
}
544549
if( eflg & MFESTFLG_TAGS ){
545
- Blob tagslist;
546
- blob_zero(&tagslist);
547
- get_checkin_taglist(rid, &tagslist);
548550
blob_resize(&filename, nPrefix);
549551
blob_append(&filename, "manifest.tags", -1);
550552
zName = blob_str(&filename);
551
- tar_add_file(zName, &tagslist, 0, mTime);
552
- blob_reset(&tagslist);
553
+ if( listFlag ) fossil_print("%s\n", zName);
554
+ if( pTar ){
555
+ Blob tagslist;
556
+ blob_zero(&tagslist);
557
+ get_checkin_taglist(rid, &tagslist);
558
+ tar_add_file(zName, &tagslist, 0, mTime);
559
+ blob_reset(&tagslist);
560
+ }
553561
}
554562
}
555563
manifest_file_rewind(pManifest);
556564
while( (pFile = manifest_file_next(pManifest,0))!=0 ){
557565
int fid;
558566
if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
559567
if( glob_match(pExclude, pFile->zName) ) continue;
560568
fid = uuid_to_rid(pFile->zUuid, 0);
561569
if( fid ){
562
- content_get(fid, &file);
563570
blob_resize(&filename, nPrefix);
564571
blob_append(&filename, pFile->zName, -1);
565572
zName = blob_str(&filename);
566
- tar_add_file(zName, &file, manifest_file_mperm(pFile), mTime);
567
- blob_reset(&file);
573
+ if( listFlag ) fossil_print("%s\n", zName);
574
+ if( pTar ){
575
+ content_get(fid, &file);
576
+ tar_add_file(zName, &file, manifest_file_mperm(pFile), mTime);
577
+ blob_reset(&file);
578
+ }
568579
}
569580
}
570581
}else{
571582
blob_append(&filename, blob_str(&hash), 16);
572583
zName = blob_str(&filename);
573
- mTime = db_int64(0, "SELECT (julianday('now') - 2440587.5)*86400.0;");
574
- tar_begin(mTime);
575
- tar_add_file(zName, &mfile, 0, mTime);
584
+ if( listFlag ) fossil_print("%s\n", zName);
585
+ if( pTar ){
586
+ mTime = db_int64(0, "SELECT (julianday('now') - 2440587.5)*86400.0;");
587
+ tar_begin(mTime);
588
+ tar_add_file(zName, &mfile, 0, mTime);
589
+ }
576590
}
577591
manifest_destroy(pManifest);
578592
blob_reset(&mfile);
579593
blob_reset(&hash);
580594
blob_reset(&filename);
581
- tar_finish(pTar);
595
+ if( pTar ) tar_finish(pTar);
582596
}
583597
584598
/*
585599
** COMMAND: tarball*
586600
**
@@ -595,13 +609,20 @@
595609
** The GLOBLIST argument to --exclude and --include can be a comma-separated
596610
** list of glob patterns, where each glob pattern may optionally be enclosed
597611
** in "..." or '...' so that it may contain commas. If a file matches both
598612
** --include and --exclude then it is excluded.
599613
**
614
+** If OUTPUTFILE is an empty string or "/dev/null" then no tarball is
615
+** actually generated. This feature can be used in combination with
616
+** the --list option to get a list of the filename that would be in the
617
+** tarball had it actually been generated. Note that --list shows only
618
+** filenames. "tar tzf" shows both filesnames and subdirectory names.
619
+**
600620
** Options:
601621
** -X|--exclude GLOBLIST Comma-separated list of GLOBs of files to exclude
602622
** --include GLOBLIST Comma-separated list of GLOBs of files to include
623
+** -l|--list Show archive content on stdout
603624
** --name DIRECTORYNAME The name of the top-level directory in the archive
604625
** -R REPOSITORY Specify a Fossil repository
605626
*/
606627
void tarball_cmd(void){
607628
int rid;
@@ -609,16 +630,19 @@
609630
const char *zName;
610631
Glob *pInclude = 0;
611632
Glob *pExclude = 0;
612633
const char *zInclude;
613634
const char *zExclude;
635
+ int listFlag = 0;
636
+ const char *zOut;
614637
zName = find_option("name", 0, 1);
615638
zExclude = find_option("exclude", "X", 1);
616639
if( zExclude ) pExclude = glob_create(zExclude);
617640
zInclude = find_option("include", 0, 1);
618641
if( zInclude ) pInclude = glob_create(zInclude);
619642
db_find_and_open_repository(0, 0);
643
+ listFlag = find_option("list","l",0)!=0;
620644
621645
/* We should be done with options.. */
622646
verify_all_options();
623647
624648
if( g.argc!=4 ){
@@ -628,10 +652,14 @@
628652
rid = name_to_typed_rid(g.argv[2], "ci");
629653
if( rid==0 ){
630654
fossil_fatal("Check-in not found: %s", g.argv[2]);
631655
return;
632656
}
657
+ zOut = g.argv[3];
658
+ if( fossil_strcmp("/dev/null",zOut)==0 || fossil_strcmp("",zOut)==0 ){
659
+ zOut = 0;
660
+ }
633661
634662
if( zName==0 ){
635663
zName = db_text("default-name",
636664
"SELECT replace(%Q,' ','_') "
637665
" || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) "
@@ -640,15 +668,19 @@
640668
" WHERE event.objid=%d"
641669
" AND blob.rid=%d",
642670
db_get("project-name", "unnamed"), rid, rid
643671
);
644672
}
645
- tarball_of_checkin(rid, &tarball, zName, pInclude, pExclude);
673
+ tarball_of_checkin(rid, zOut ? &tarball : 0,
674
+ zName, pInclude, pExclude, listFlag);
646675
glob_free(pInclude);
647676
glob_free(pExclude);
648
- blob_write_to_file(&tarball, g.argv[3]);
649
- blob_reset(&tarball);
677
+ if( listFlag ) fflush(stdout);
678
+ if( zOut ){
679
+ blob_write_to_file(&tarball, zOut);
680
+ blob_reset(&tarball);
681
+ }
650682
}
651683
652684
/*
653685
** Check to see if the input string is of the form:
654686
**
@@ -801,11 +833,11 @@
801833
style_finish_page();
802834
return;
803835
}
804836
blob_zero(&tarball);
805837
if( cache_read(&tarball, zKey)==0 ){
806
- tarball_of_checkin(rid, &tarball, zName, pInclude, pExclude);
838
+ tarball_of_checkin(rid, &tarball, zName, pInclude, pExclude, 0);
807839
cache_write(&tarball, zKey);
808840
}
809841
glob_free(pInclude);
810842
glob_free(pExclude);
811843
fossil_free(zName);
812844
--- src/tar.c
+++ src/tar.c
@@ -474,11 +474,12 @@
474 void tarball_of_checkin(
475 int rid, /* The RID of the checkin from which to form a tarball */
476 Blob *pTar, /* Write the tarball into this blob */
477 const char *zDir, /* Directory prefix for all file added to tarball */
478 Glob *pInclude, /* Only add files matching this pattern */
479 Glob *pExclude /* Exclude files matching this pattern */
 
480 ){
481 Blob mfile, hash, file;
482 Manifest *pManifest;
483 ManifestFile *pFile;
484 Blob filename;
@@ -501,11 +502,11 @@
501
502 pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
503 if( pManifest ){
504 int flg, eflg = 0;
505 mTime = (pManifest->rDate - 2440587.5)*86400.0;
506 tar_begin(mTime);
507 flg = db_get_manifest_setting();
508 if( flg ){
509 /* eflg is the effective flags, taking include/exclude into account */
510 if( (pInclude==0 || glob_match(pInclude, "manifest"))
511 && !glob_match(pExclude, "manifest")
@@ -525,62 +526,75 @@
525
526 if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
527 if( eflg & MFESTFLG_RAW ){
528 blob_append(&filename, "manifest", -1);
529 zName = blob_str(&filename);
530 }
531 if( eflg & MFESTFLG_RAW ) {
532 sterilize_manifest(&mfile, CFTYPE_MANIFEST);
533 tar_add_file(zName, &mfile, 0, mTime);
 
534 }
535 }
536 blob_reset(&mfile);
537 if( eflg & MFESTFLG_UUID ){
538 blob_append(&hash, "\n", 1);
539 blob_resize(&filename, nPrefix);
540 blob_append(&filename, "manifest.uuid", -1);
541 zName = blob_str(&filename);
542 tar_add_file(zName, &hash, 0, mTime);
 
 
 
 
543 }
544 if( eflg & MFESTFLG_TAGS ){
545 Blob tagslist;
546 blob_zero(&tagslist);
547 get_checkin_taglist(rid, &tagslist);
548 blob_resize(&filename, nPrefix);
549 blob_append(&filename, "manifest.tags", -1);
550 zName = blob_str(&filename);
551 tar_add_file(zName, &tagslist, 0, mTime);
552 blob_reset(&tagslist);
 
 
 
 
 
 
553 }
554 }
555 manifest_file_rewind(pManifest);
556 while( (pFile = manifest_file_next(pManifest,0))!=0 ){
557 int fid;
558 if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
559 if( glob_match(pExclude, pFile->zName) ) continue;
560 fid = uuid_to_rid(pFile->zUuid, 0);
561 if( fid ){
562 content_get(fid, &file);
563 blob_resize(&filename, nPrefix);
564 blob_append(&filename, pFile->zName, -1);
565 zName = blob_str(&filename);
566 tar_add_file(zName, &file, manifest_file_mperm(pFile), mTime);
567 blob_reset(&file);
 
 
 
 
568 }
569 }
570 }else{
571 blob_append(&filename, blob_str(&hash), 16);
572 zName = blob_str(&filename);
573 mTime = db_int64(0, "SELECT (julianday('now') - 2440587.5)*86400.0;");
574 tar_begin(mTime);
575 tar_add_file(zName, &mfile, 0, mTime);
 
 
 
576 }
577 manifest_destroy(pManifest);
578 blob_reset(&mfile);
579 blob_reset(&hash);
580 blob_reset(&filename);
581 tar_finish(pTar);
582 }
583
584 /*
585 ** COMMAND: tarball*
586 **
@@ -595,13 +609,20 @@
595 ** The GLOBLIST argument to --exclude and --include can be a comma-separated
596 ** list of glob patterns, where each glob pattern may optionally be enclosed
597 ** in "..." or '...' so that it may contain commas. If a file matches both
598 ** --include and --exclude then it is excluded.
599 **
 
 
 
 
 
 
600 ** Options:
601 ** -X|--exclude GLOBLIST Comma-separated list of GLOBs of files to exclude
602 ** --include GLOBLIST Comma-separated list of GLOBs of files to include
 
603 ** --name DIRECTORYNAME The name of the top-level directory in the archive
604 ** -R REPOSITORY Specify a Fossil repository
605 */
606 void tarball_cmd(void){
607 int rid;
@@ -609,16 +630,19 @@
609 const char *zName;
610 Glob *pInclude = 0;
611 Glob *pExclude = 0;
612 const char *zInclude;
613 const char *zExclude;
 
 
614 zName = find_option("name", 0, 1);
615 zExclude = find_option("exclude", "X", 1);
616 if( zExclude ) pExclude = glob_create(zExclude);
617 zInclude = find_option("include", 0, 1);
618 if( zInclude ) pInclude = glob_create(zInclude);
619 db_find_and_open_repository(0, 0);
 
620
621 /* We should be done with options.. */
622 verify_all_options();
623
624 if( g.argc!=4 ){
@@ -628,10 +652,14 @@
628 rid = name_to_typed_rid(g.argv[2], "ci");
629 if( rid==0 ){
630 fossil_fatal("Check-in not found: %s", g.argv[2]);
631 return;
632 }
 
 
 
 
633
634 if( zName==0 ){
635 zName = db_text("default-name",
636 "SELECT replace(%Q,' ','_') "
637 " || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) "
@@ -640,15 +668,19 @@
640 " WHERE event.objid=%d"
641 " AND blob.rid=%d",
642 db_get("project-name", "unnamed"), rid, rid
643 );
644 }
645 tarball_of_checkin(rid, &tarball, zName, pInclude, pExclude);
 
646 glob_free(pInclude);
647 glob_free(pExclude);
648 blob_write_to_file(&tarball, g.argv[3]);
649 blob_reset(&tarball);
 
 
 
650 }
651
652 /*
653 ** Check to see if the input string is of the form:
654 **
@@ -801,11 +833,11 @@
801 style_finish_page();
802 return;
803 }
804 blob_zero(&tarball);
805 if( cache_read(&tarball, zKey)==0 ){
806 tarball_of_checkin(rid, &tarball, zName, pInclude, pExclude);
807 cache_write(&tarball, zKey);
808 }
809 glob_free(pInclude);
810 glob_free(pExclude);
811 fossil_free(zName);
812
--- src/tar.c
+++ src/tar.c
@@ -474,11 +474,12 @@
474 void tarball_of_checkin(
475 int rid, /* The RID of the checkin from which to form a tarball */
476 Blob *pTar, /* Write the tarball into this blob */
477 const char *zDir, /* Directory prefix for all file added to tarball */
478 Glob *pInclude, /* Only add files matching this pattern */
479 Glob *pExclude, /* Exclude files matching this pattern */
480 int listFlag /* Show filenames on stdout */
481 ){
482 Blob mfile, hash, file;
483 Manifest *pManifest;
484 ManifestFile *pFile;
485 Blob filename;
@@ -501,11 +502,11 @@
502
503 pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
504 if( pManifest ){
505 int flg, eflg = 0;
506 mTime = (pManifest->rDate - 2440587.5)*86400.0;
507 if( pTar ) tar_begin(mTime);
508 flg = db_get_manifest_setting();
509 if( flg ){
510 /* eflg is the effective flags, taking include/exclude into account */
511 if( (pInclude==0 || glob_match(pInclude, "manifest"))
512 && !glob_match(pExclude, "manifest")
@@ -525,62 +526,75 @@
526
527 if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
528 if( eflg & MFESTFLG_RAW ){
529 blob_append(&filename, "manifest", -1);
530 zName = blob_str(&filename);
531 if( listFlag ) fossil_print("%s\n", zName);
532 if( pTar ){
533 sterilize_manifest(&mfile, CFTYPE_MANIFEST);
534 tar_add_file(zName, &mfile, 0, mTime);
535 }
536 }
537 }
538 blob_reset(&mfile);
539 if( eflg & MFESTFLG_UUID ){
 
540 blob_resize(&filename, nPrefix);
541 blob_append(&filename, "manifest.uuid", -1);
542 zName = blob_str(&filename);
543 if( listFlag ) fossil_print("%s\n", zName);
544 if( pTar ){
545 blob_append(&hash, "\n", 1);
546 tar_add_file(zName, &hash, 0, mTime);
547 }
548 }
549 if( eflg & MFESTFLG_TAGS ){
 
 
 
550 blob_resize(&filename, nPrefix);
551 blob_append(&filename, "manifest.tags", -1);
552 zName = blob_str(&filename);
553 if( listFlag ) fossil_print("%s\n", zName);
554 if( pTar ){
555 Blob tagslist;
556 blob_zero(&tagslist);
557 get_checkin_taglist(rid, &tagslist);
558 tar_add_file(zName, &tagslist, 0, mTime);
559 blob_reset(&tagslist);
560 }
561 }
562 }
563 manifest_file_rewind(pManifest);
564 while( (pFile = manifest_file_next(pManifest,0))!=0 ){
565 int fid;
566 if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
567 if( glob_match(pExclude, pFile->zName) ) continue;
568 fid = uuid_to_rid(pFile->zUuid, 0);
569 if( fid ){
 
570 blob_resize(&filename, nPrefix);
571 blob_append(&filename, pFile->zName, -1);
572 zName = blob_str(&filename);
573 if( listFlag ) fossil_print("%s\n", zName);
574 if( pTar ){
575 content_get(fid, &file);
576 tar_add_file(zName, &file, manifest_file_mperm(pFile), mTime);
577 blob_reset(&file);
578 }
579 }
580 }
581 }else{
582 blob_append(&filename, blob_str(&hash), 16);
583 zName = blob_str(&filename);
584 if( listFlag ) fossil_print("%s\n", zName);
585 if( pTar ){
586 mTime = db_int64(0, "SELECT (julianday('now') - 2440587.5)*86400.0;");
587 tar_begin(mTime);
588 tar_add_file(zName, &mfile, 0, mTime);
589 }
590 }
591 manifest_destroy(pManifest);
592 blob_reset(&mfile);
593 blob_reset(&hash);
594 blob_reset(&filename);
595 if( pTar ) tar_finish(pTar);
596 }
597
598 /*
599 ** COMMAND: tarball*
600 **
@@ -595,13 +609,20 @@
609 ** The GLOBLIST argument to --exclude and --include can be a comma-separated
610 ** list of glob patterns, where each glob pattern may optionally be enclosed
611 ** in "..." or '...' so that it may contain commas. If a file matches both
612 ** --include and --exclude then it is excluded.
613 **
614 ** If OUTPUTFILE is an empty string or "/dev/null" then no tarball is
615 ** actually generated. This feature can be used in combination with
616 ** the --list option to get a list of the filename that would be in the
617 ** tarball had it actually been generated. Note that --list shows only
618 ** filenames. "tar tzf" shows both filesnames and subdirectory names.
619 **
620 ** Options:
621 ** -X|--exclude GLOBLIST Comma-separated list of GLOBs of files to exclude
622 ** --include GLOBLIST Comma-separated list of GLOBs of files to include
623 ** -l|--list Show archive content on stdout
624 ** --name DIRECTORYNAME The name of the top-level directory in the archive
625 ** -R REPOSITORY Specify a Fossil repository
626 */
627 void tarball_cmd(void){
628 int rid;
@@ -609,16 +630,19 @@
630 const char *zName;
631 Glob *pInclude = 0;
632 Glob *pExclude = 0;
633 const char *zInclude;
634 const char *zExclude;
635 int listFlag = 0;
636 const char *zOut;
637 zName = find_option("name", 0, 1);
638 zExclude = find_option("exclude", "X", 1);
639 if( zExclude ) pExclude = glob_create(zExclude);
640 zInclude = find_option("include", 0, 1);
641 if( zInclude ) pInclude = glob_create(zInclude);
642 db_find_and_open_repository(0, 0);
643 listFlag = find_option("list","l",0)!=0;
644
645 /* We should be done with options.. */
646 verify_all_options();
647
648 if( g.argc!=4 ){
@@ -628,10 +652,14 @@
652 rid = name_to_typed_rid(g.argv[2], "ci");
653 if( rid==0 ){
654 fossil_fatal("Check-in not found: %s", g.argv[2]);
655 return;
656 }
657 zOut = g.argv[3];
658 if( fossil_strcmp("/dev/null",zOut)==0 || fossil_strcmp("",zOut)==0 ){
659 zOut = 0;
660 }
661
662 if( zName==0 ){
663 zName = db_text("default-name",
664 "SELECT replace(%Q,' ','_') "
665 " || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) "
@@ -640,15 +668,19 @@
668 " WHERE event.objid=%d"
669 " AND blob.rid=%d",
670 db_get("project-name", "unnamed"), rid, rid
671 );
672 }
673 tarball_of_checkin(rid, zOut ? &tarball : 0,
674 zName, pInclude, pExclude, listFlag);
675 glob_free(pInclude);
676 glob_free(pExclude);
677 if( listFlag ) fflush(stdout);
678 if( zOut ){
679 blob_write_to_file(&tarball, zOut);
680 blob_reset(&tarball);
681 }
682 }
683
684 /*
685 ** Check to see if the input string is of the form:
686 **
@@ -801,11 +833,11 @@
833 style_finish_page();
834 return;
835 }
836 blob_zero(&tarball);
837 if( cache_read(&tarball, zKey)==0 ){
838 tarball_of_checkin(rid, &tarball, zName, pInclude, pExclude, 0);
839 cache_write(&tarball, zKey);
840 }
841 glob_free(pInclude);
842 glob_free(pExclude);
843 fossil_free(zName);
844
+61 -24
--- src/zip.c
+++ src/zip.c
@@ -623,11 +623,12 @@
623623
int eType, /* Type of archive (ZIP or SQLAR) */
624624
int rid, /* The RID of the checkin to build the archive from */
625625
Blob *pZip, /* Write the archive content into this blob */
626626
const char *zDir, /* Top-level directory of the archive */
627627
Glob *pInclude, /* Only include files that match this pattern */
628
- Glob *pExclude /* Exclude files that match this pattern */
628
+ Glob *pExclude, /* Exclude files that match this pattern */
629
+ int listFlag /* Print each file on stdout */
629630
){
630631
Blob mfile, hash, file;
631632
Manifest *pManifest;
632633
ManifestFile *pFile;
633634
Blob filename;
@@ -636,19 +637,19 @@
636637
Archive sArchive;
637638
memset(&sArchive, 0, sizeof(Archive));
638639
sArchive.eType = eType;
639640
sArchive.pBlob = pZip;
640641
blob_zero(&sArchive.tmp);
641
- blob_zero(pZip);
642
+ if( pZip ) blob_zero(pZip);
642643
643644
content_get(rid, &mfile);
644645
if( blob_size(&mfile)==0 ){
645646
return;
646647
}
647648
blob_set_dynamic(&hash, rid_to_uuid(rid));
648649
blob_zero(&filename);
649
- zip_open();
650
+ if( pZip ) zip_open();
650651
651652
if( zDir && zDir[0] ){
652653
blob_appendf(&filename, "%s/", zDir);
653654
}
654655
nPrefix = blob_size(&filename);
@@ -678,57 +679,71 @@
678679
}
679680
680681
if( eflg & MFESTFLG_RAW ){
681682
blob_append(&filename, "manifest", -1);
682683
zName = blob_str(&filename);
683
- zip_add_folders(&sArchive, zName);
684
- sterilize_manifest(&mfile, CFTYPE_MANIFEST);
685
- zip_add_file(&sArchive, zName, &mfile, 0);
684
+ if( listFlag ) fossil_print("%s\n", zName);
685
+ if( pZip ){
686
+ zip_add_folders(&sArchive, zName);
687
+ sterilize_manifest(&mfile, CFTYPE_MANIFEST);
688
+ zip_add_file(&sArchive, zName, &mfile, 0);
689
+ }
686690
}
687691
if( eflg & MFESTFLG_UUID ){
688692
blob_append(&hash, "\n", 1);
689693
blob_resize(&filename, nPrefix);
690694
blob_append(&filename, "manifest.uuid", -1);
691695
zName = blob_str(&filename);
692
- zip_add_folders(&sArchive, zName);
693
- zip_add_file(&sArchive, zName, &hash, 0);
696
+ if( listFlag ) fossil_print("%s\n", zName);
697
+ if( pZip ){
698
+ zip_add_folders(&sArchive, zName);
699
+ zip_add_file(&sArchive, zName, &hash, 0);
700
+ }
694701
}
695702
if( eflg & MFESTFLG_TAGS ){
696
- Blob tagslist;
697
- blob_zero(&tagslist);
698
- get_checkin_taglist(rid, &tagslist);
699703
blob_resize(&filename, nPrefix);
700704
blob_append(&filename, "manifest.tags", -1);
701705
zName = blob_str(&filename);
702
- zip_add_folders(&sArchive, zName);
703
- zip_add_file(&sArchive, zName, &tagslist, 0);
704
- blob_reset(&tagslist);
706
+ if( listFlag ) fossil_print("%s\n", zName);
707
+ if( pZip ){
708
+ Blob tagslist;
709
+ blob_zero(&tagslist);
710
+ get_checkin_taglist(rid, &tagslist);
711
+ zip_add_folders(&sArchive, zName);
712
+ zip_add_file(&sArchive, zName, &tagslist, 0);
713
+ blob_reset(&tagslist);
714
+ }
705715
}
706716
}
707717
manifest_file_rewind(pManifest);
708
- zip_add_file(&sArchive, "", 0, 0);
718
+ if( pZip ) zip_add_file(&sArchive, "", 0, 0);
709719
while( (pFile = manifest_file_next(pManifest,0))!=0 ){
710720
int fid;
711721
if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
712722
if( glob_match(pExclude, pFile->zName) ) continue;
713723
fid = uuid_to_rid(pFile->zUuid, 0);
714724
if( fid ){
715
- content_get(fid, &file);
716725
blob_resize(&filename, nPrefix);
717726
blob_append(&filename, pFile->zName, -1);
718727
zName = blob_str(&filename);
719
- zip_add_folders(&sArchive, zName);
720
- zip_add_file(&sArchive, zName, &file, manifest_file_mperm(pFile));
721
- blob_reset(&file);
728
+ if( listFlag ) fossil_print("%s\n", zName);
729
+ if( pZip ){
730
+ content_get(fid, &file);
731
+ zip_add_folders(&sArchive, zName);
732
+ zip_add_file(&sArchive, zName, &file, manifest_file_mperm(pFile));
733
+ blob_reset(&file);
734
+ }
722735
}
723736
}
724737
}
725738
blob_reset(&mfile);
726739
manifest_destroy(pManifest);
727740
blob_reset(&filename);
728741
blob_reset(&hash);
729
- zip_close(&sArchive);
742
+ if( pZip ){
743
+ zip_close(&sArchive);
744
+ }
730745
}
731746
732747
/*
733748
** Implementation of zip_cmd and sqlar_cmd.
734749
*/
@@ -738,16 +753,19 @@
738753
const char *zName;
739754
Glob *pInclude = 0;
740755
Glob *pExclude = 0;
741756
const char *zInclude;
742757
const char *zExclude;
758
+ int listFlag = 0;
759
+ const char *zOut;
743760
744761
zName = find_option("name", 0, 1);
745762
zExclude = find_option("exclude", "X", 1);
746763
if( zExclude ) pExclude = glob_create(zExclude);
747764
zInclude = find_option("include", 0, 1);
748765
if( zInclude ) pInclude = glob_create(zInclude);
766
+ listFlag = find_option("list","l",0)!=0;
749767
db_find_and_open_repository(0, 0);
750768
751769
/* We should be done with options.. */
752770
verify_all_options();
753771
@@ -758,10 +776,14 @@
758776
rid = name_to_typed_rid(g.argv[2], "ci");
759777
if( rid==0 ){
760778
fossil_fatal("Check-in not found: %s", g.argv[2]);
761779
return;
762780
}
781
+ zOut = g.argv[3];
782
+ if( fossil_strcmp(zOut,"")==0 || fossil_strcmp(zOut,"/dev/null")==0 ){
783
+ zOut = 0;
784
+ }
763785
764786
if( zName==0 ){
765787
zName = db_text("default-name",
766788
"SELECT replace(%Q,' ','_') "
767789
" || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) "
@@ -770,15 +792,18 @@
770792
" WHERE event.objid=%d"
771793
" AND blob.rid=%d",
772794
db_get("project-name", "unnamed"), rid, rid
773795
);
774796
}
775
- zip_of_checkin(eType, rid, &zip, zName, pInclude, pExclude);
797
+ zip_of_checkin(eType, rid, zOut ? &zip : 0,
798
+ zName, pInclude, pExclude, listFlag);
776799
glob_free(pInclude);
777800
glob_free(pExclude);
778
- blob_write_to_file(&zip, g.argv[3]);
779
- blob_reset(&zip);
801
+ if( zOut ){
802
+ blob_write_to_file(&zip, zOut);
803
+ blob_reset(&zip);
804
+ }
780805
}
781806
782807
/*
783808
** COMMAND: zip*
784809
**
@@ -793,13 +818,19 @@
793818
** The GLOBLIST argument to --exclude and --include can be a comma-separated
794819
** list of glob patterns, where each glob pattern may optionally be enclosed
795820
** in "..." or '...' so that it may contain commas. If a file matches both
796821
** --include and --exclude then it is excluded.
797822
**
823
+** If OUTPUTFILE is an empty string or "/dev/null" then no ZIP archive is
824
+** actually generated. This feature can be used in combination with
825
+** the --list option to get a list of the filename that would be in the
826
+** ZIP archive had it actually been generated.
827
+**
798828
** Options:
799829
** -X|--exclude GLOBLIST Comma-separated list of GLOBs of files to exclude
800830
** --include GLOBLIST Comma-separated list of GLOBs of files to include
831
+** -l|--list Show archive content on stdout
801832
** --name DIRECTORYNAME The name of the top-level directory in the archive
802833
** -R REPOSITORY Specify a Fossil repository
803834
*/
804835
void zip_cmd(void){
805836
archive_cmd(ARCHIVE_ZIP);
@@ -819,13 +850,19 @@
819850
** The GLOBLIST argument to --exclude and --include can be a comma-separated
820851
** list of glob patterns, where each glob pattern may optionally be enclosed
821852
** in "..." or '...' so that it may contain commas. If a file matches both
822853
** --include and --exclude then it is excluded.
823854
**
855
+** If OUTPUTFILE is an empty string or "/dev/null" then no SQLAR archive is
856
+** actually generated. This feature can be used in combination with
857
+** the --list option to get a list of the filename that would be in the
858
+** SQLAR archive had it actually been generated.
859
+**
824860
** Options:
825861
** -X|--exclude GLOBLIST Comma-separated list of GLOBs of files to exclude
826862
** --include GLOBLIST Comma-separated list of GLOBs of files to include
863
+** -l|--list Show archive content on stdout
827864
** --name DIRECTORYNAME The name of the top-level directory in the archive
828865
** -R REPOSITORY Specify a Fossil repository
829866
*/
830867
void sqlar_cmd(void){
831868
archive_cmd(ARCHIVE_SQLAR);
@@ -972,11 +1009,11 @@
9721009
style_finish_page();
9731010
return;
9741011
}
9751012
blob_zero(&zip);
9761013
if( cache_read(&zip, zKey)==0 ){
977
- zip_of_checkin(eType, rid, &zip, zName, pInclude, pExclude);
1014
+ zip_of_checkin(eType, rid, &zip, zName, pInclude, pExclude, 0);
9781015
cache_write(&zip, zKey);
9791016
}
9801017
glob_free(pInclude);
9811018
glob_free(pExclude);
9821019
fossil_free(zName);
9831020
--- src/zip.c
+++ src/zip.c
@@ -623,11 +623,12 @@
623 int eType, /* Type of archive (ZIP or SQLAR) */
624 int rid, /* The RID of the checkin to build the archive from */
625 Blob *pZip, /* Write the archive content into this blob */
626 const char *zDir, /* Top-level directory of the archive */
627 Glob *pInclude, /* Only include files that match this pattern */
628 Glob *pExclude /* Exclude files that match this pattern */
 
629 ){
630 Blob mfile, hash, file;
631 Manifest *pManifest;
632 ManifestFile *pFile;
633 Blob filename;
@@ -636,19 +637,19 @@
636 Archive sArchive;
637 memset(&sArchive, 0, sizeof(Archive));
638 sArchive.eType = eType;
639 sArchive.pBlob = pZip;
640 blob_zero(&sArchive.tmp);
641 blob_zero(pZip);
642
643 content_get(rid, &mfile);
644 if( blob_size(&mfile)==0 ){
645 return;
646 }
647 blob_set_dynamic(&hash, rid_to_uuid(rid));
648 blob_zero(&filename);
649 zip_open();
650
651 if( zDir && zDir[0] ){
652 blob_appendf(&filename, "%s/", zDir);
653 }
654 nPrefix = blob_size(&filename);
@@ -678,57 +679,71 @@
678 }
679
680 if( eflg & MFESTFLG_RAW ){
681 blob_append(&filename, "manifest", -1);
682 zName = blob_str(&filename);
683 zip_add_folders(&sArchive, zName);
684 sterilize_manifest(&mfile, CFTYPE_MANIFEST);
685 zip_add_file(&sArchive, zName, &mfile, 0);
 
 
 
686 }
687 if( eflg & MFESTFLG_UUID ){
688 blob_append(&hash, "\n", 1);
689 blob_resize(&filename, nPrefix);
690 blob_append(&filename, "manifest.uuid", -1);
691 zName = blob_str(&filename);
692 zip_add_folders(&sArchive, zName);
693 zip_add_file(&sArchive, zName, &hash, 0);
 
 
 
694 }
695 if( eflg & MFESTFLG_TAGS ){
696 Blob tagslist;
697 blob_zero(&tagslist);
698 get_checkin_taglist(rid, &tagslist);
699 blob_resize(&filename, nPrefix);
700 blob_append(&filename, "manifest.tags", -1);
701 zName = blob_str(&filename);
702 zip_add_folders(&sArchive, zName);
703 zip_add_file(&sArchive, zName, &tagslist, 0);
704 blob_reset(&tagslist);
 
 
 
 
 
 
705 }
706 }
707 manifest_file_rewind(pManifest);
708 zip_add_file(&sArchive, "", 0, 0);
709 while( (pFile = manifest_file_next(pManifest,0))!=0 ){
710 int fid;
711 if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
712 if( glob_match(pExclude, pFile->zName) ) continue;
713 fid = uuid_to_rid(pFile->zUuid, 0);
714 if( fid ){
715 content_get(fid, &file);
716 blob_resize(&filename, nPrefix);
717 blob_append(&filename, pFile->zName, -1);
718 zName = blob_str(&filename);
719 zip_add_folders(&sArchive, zName);
720 zip_add_file(&sArchive, zName, &file, manifest_file_mperm(pFile));
721 blob_reset(&file);
 
 
 
 
722 }
723 }
724 }
725 blob_reset(&mfile);
726 manifest_destroy(pManifest);
727 blob_reset(&filename);
728 blob_reset(&hash);
729 zip_close(&sArchive);
 
 
730 }
731
732 /*
733 ** Implementation of zip_cmd and sqlar_cmd.
734 */
@@ -738,16 +753,19 @@
738 const char *zName;
739 Glob *pInclude = 0;
740 Glob *pExclude = 0;
741 const char *zInclude;
742 const char *zExclude;
 
 
743
744 zName = find_option("name", 0, 1);
745 zExclude = find_option("exclude", "X", 1);
746 if( zExclude ) pExclude = glob_create(zExclude);
747 zInclude = find_option("include", 0, 1);
748 if( zInclude ) pInclude = glob_create(zInclude);
 
749 db_find_and_open_repository(0, 0);
750
751 /* We should be done with options.. */
752 verify_all_options();
753
@@ -758,10 +776,14 @@
758 rid = name_to_typed_rid(g.argv[2], "ci");
759 if( rid==0 ){
760 fossil_fatal("Check-in not found: %s", g.argv[2]);
761 return;
762 }
 
 
 
 
763
764 if( zName==0 ){
765 zName = db_text("default-name",
766 "SELECT replace(%Q,' ','_') "
767 " || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) "
@@ -770,15 +792,18 @@
770 " WHERE event.objid=%d"
771 " AND blob.rid=%d",
772 db_get("project-name", "unnamed"), rid, rid
773 );
774 }
775 zip_of_checkin(eType, rid, &zip, zName, pInclude, pExclude);
 
776 glob_free(pInclude);
777 glob_free(pExclude);
778 blob_write_to_file(&zip, g.argv[3]);
779 blob_reset(&zip);
 
 
780 }
781
782 /*
783 ** COMMAND: zip*
784 **
@@ -793,13 +818,19 @@
793 ** The GLOBLIST argument to --exclude and --include can be a comma-separated
794 ** list of glob patterns, where each glob pattern may optionally be enclosed
795 ** in "..." or '...' so that it may contain commas. If a file matches both
796 ** --include and --exclude then it is excluded.
797 **
 
 
 
 
 
798 ** Options:
799 ** -X|--exclude GLOBLIST Comma-separated list of GLOBs of files to exclude
800 ** --include GLOBLIST Comma-separated list of GLOBs of files to include
 
801 ** --name DIRECTORYNAME The name of the top-level directory in the archive
802 ** -R REPOSITORY Specify a Fossil repository
803 */
804 void zip_cmd(void){
805 archive_cmd(ARCHIVE_ZIP);
@@ -819,13 +850,19 @@
819 ** The GLOBLIST argument to --exclude and --include can be a comma-separated
820 ** list of glob patterns, where each glob pattern may optionally be enclosed
821 ** in "..." or '...' so that it may contain commas. If a file matches both
822 ** --include and --exclude then it is excluded.
823 **
 
 
 
 
 
824 ** Options:
825 ** -X|--exclude GLOBLIST Comma-separated list of GLOBs of files to exclude
826 ** --include GLOBLIST Comma-separated list of GLOBs of files to include
 
827 ** --name DIRECTORYNAME The name of the top-level directory in the archive
828 ** -R REPOSITORY Specify a Fossil repository
829 */
830 void sqlar_cmd(void){
831 archive_cmd(ARCHIVE_SQLAR);
@@ -972,11 +1009,11 @@
972 style_finish_page();
973 return;
974 }
975 blob_zero(&zip);
976 if( cache_read(&zip, zKey)==0 ){
977 zip_of_checkin(eType, rid, &zip, zName, pInclude, pExclude);
978 cache_write(&zip, zKey);
979 }
980 glob_free(pInclude);
981 glob_free(pExclude);
982 fossil_free(zName);
983
--- src/zip.c
+++ src/zip.c
@@ -623,11 +623,12 @@
623 int eType, /* Type of archive (ZIP or SQLAR) */
624 int rid, /* The RID of the checkin to build the archive from */
625 Blob *pZip, /* Write the archive content into this blob */
626 const char *zDir, /* Top-level directory of the archive */
627 Glob *pInclude, /* Only include files that match this pattern */
628 Glob *pExclude, /* Exclude files that match this pattern */
629 int listFlag /* Print each file on stdout */
630 ){
631 Blob mfile, hash, file;
632 Manifest *pManifest;
633 ManifestFile *pFile;
634 Blob filename;
@@ -636,19 +637,19 @@
637 Archive sArchive;
638 memset(&sArchive, 0, sizeof(Archive));
639 sArchive.eType = eType;
640 sArchive.pBlob = pZip;
641 blob_zero(&sArchive.tmp);
642 if( pZip ) blob_zero(pZip);
643
644 content_get(rid, &mfile);
645 if( blob_size(&mfile)==0 ){
646 return;
647 }
648 blob_set_dynamic(&hash, rid_to_uuid(rid));
649 blob_zero(&filename);
650 if( pZip ) zip_open();
651
652 if( zDir && zDir[0] ){
653 blob_appendf(&filename, "%s/", zDir);
654 }
655 nPrefix = blob_size(&filename);
@@ -678,57 +679,71 @@
679 }
680
681 if( eflg & MFESTFLG_RAW ){
682 blob_append(&filename, "manifest", -1);
683 zName = blob_str(&filename);
684 if( listFlag ) fossil_print("%s\n", zName);
685 if( pZip ){
686 zip_add_folders(&sArchive, zName);
687 sterilize_manifest(&mfile, CFTYPE_MANIFEST);
688 zip_add_file(&sArchive, zName, &mfile, 0);
689 }
690 }
691 if( eflg & MFESTFLG_UUID ){
692 blob_append(&hash, "\n", 1);
693 blob_resize(&filename, nPrefix);
694 blob_append(&filename, "manifest.uuid", -1);
695 zName = blob_str(&filename);
696 if( listFlag ) fossil_print("%s\n", zName);
697 if( pZip ){
698 zip_add_folders(&sArchive, zName);
699 zip_add_file(&sArchive, zName, &hash, 0);
700 }
701 }
702 if( eflg & MFESTFLG_TAGS ){
 
 
 
703 blob_resize(&filename, nPrefix);
704 blob_append(&filename, "manifest.tags", -1);
705 zName = blob_str(&filename);
706 if( listFlag ) fossil_print("%s\n", zName);
707 if( pZip ){
708 Blob tagslist;
709 blob_zero(&tagslist);
710 get_checkin_taglist(rid, &tagslist);
711 zip_add_folders(&sArchive, zName);
712 zip_add_file(&sArchive, zName, &tagslist, 0);
713 blob_reset(&tagslist);
714 }
715 }
716 }
717 manifest_file_rewind(pManifest);
718 if( pZip ) zip_add_file(&sArchive, "", 0, 0);
719 while( (pFile = manifest_file_next(pManifest,0))!=0 ){
720 int fid;
721 if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
722 if( glob_match(pExclude, pFile->zName) ) continue;
723 fid = uuid_to_rid(pFile->zUuid, 0);
724 if( fid ){
 
725 blob_resize(&filename, nPrefix);
726 blob_append(&filename, pFile->zName, -1);
727 zName = blob_str(&filename);
728 if( listFlag ) fossil_print("%s\n", zName);
729 if( pZip ){
730 content_get(fid, &file);
731 zip_add_folders(&sArchive, zName);
732 zip_add_file(&sArchive, zName, &file, manifest_file_mperm(pFile));
733 blob_reset(&file);
734 }
735 }
736 }
737 }
738 blob_reset(&mfile);
739 manifest_destroy(pManifest);
740 blob_reset(&filename);
741 blob_reset(&hash);
742 if( pZip ){
743 zip_close(&sArchive);
744 }
745 }
746
747 /*
748 ** Implementation of zip_cmd and sqlar_cmd.
749 */
@@ -738,16 +753,19 @@
753 const char *zName;
754 Glob *pInclude = 0;
755 Glob *pExclude = 0;
756 const char *zInclude;
757 const char *zExclude;
758 int listFlag = 0;
759 const char *zOut;
760
761 zName = find_option("name", 0, 1);
762 zExclude = find_option("exclude", "X", 1);
763 if( zExclude ) pExclude = glob_create(zExclude);
764 zInclude = find_option("include", 0, 1);
765 if( zInclude ) pInclude = glob_create(zInclude);
766 listFlag = find_option("list","l",0)!=0;
767 db_find_and_open_repository(0, 0);
768
769 /* We should be done with options.. */
770 verify_all_options();
771
@@ -758,10 +776,14 @@
776 rid = name_to_typed_rid(g.argv[2], "ci");
777 if( rid==0 ){
778 fossil_fatal("Check-in not found: %s", g.argv[2]);
779 return;
780 }
781 zOut = g.argv[3];
782 if( fossil_strcmp(zOut,"")==0 || fossil_strcmp(zOut,"/dev/null")==0 ){
783 zOut = 0;
784 }
785
786 if( zName==0 ){
787 zName = db_text("default-name",
788 "SELECT replace(%Q,' ','_') "
789 " || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) "
@@ -770,15 +792,18 @@
792 " WHERE event.objid=%d"
793 " AND blob.rid=%d",
794 db_get("project-name", "unnamed"), rid, rid
795 );
796 }
797 zip_of_checkin(eType, rid, zOut ? &zip : 0,
798 zName, pInclude, pExclude, listFlag);
799 glob_free(pInclude);
800 glob_free(pExclude);
801 if( zOut ){
802 blob_write_to_file(&zip, zOut);
803 blob_reset(&zip);
804 }
805 }
806
807 /*
808 ** COMMAND: zip*
809 **
@@ -793,13 +818,19 @@
818 ** The GLOBLIST argument to --exclude and --include can be a comma-separated
819 ** list of glob patterns, where each glob pattern may optionally be enclosed
820 ** in "..." or '...' so that it may contain commas. If a file matches both
821 ** --include and --exclude then it is excluded.
822 **
823 ** If OUTPUTFILE is an empty string or "/dev/null" then no ZIP archive is
824 ** actually generated. This feature can be used in combination with
825 ** the --list option to get a list of the filename that would be in the
826 ** ZIP archive had it actually been generated.
827 **
828 ** Options:
829 ** -X|--exclude GLOBLIST Comma-separated list of GLOBs of files to exclude
830 ** --include GLOBLIST Comma-separated list of GLOBs of files to include
831 ** -l|--list Show archive content on stdout
832 ** --name DIRECTORYNAME The name of the top-level directory in the archive
833 ** -R REPOSITORY Specify a Fossil repository
834 */
835 void zip_cmd(void){
836 archive_cmd(ARCHIVE_ZIP);
@@ -819,13 +850,19 @@
850 ** The GLOBLIST argument to --exclude and --include can be a comma-separated
851 ** list of glob patterns, where each glob pattern may optionally be enclosed
852 ** in "..." or '...' so that it may contain commas. If a file matches both
853 ** --include and --exclude then it is excluded.
854 **
855 ** If OUTPUTFILE is an empty string or "/dev/null" then no SQLAR archive is
856 ** actually generated. This feature can be used in combination with
857 ** the --list option to get a list of the filename that would be in the
858 ** SQLAR archive had it actually been generated.
859 **
860 ** Options:
861 ** -X|--exclude GLOBLIST Comma-separated list of GLOBs of files to exclude
862 ** --include GLOBLIST Comma-separated list of GLOBs of files to include
863 ** -l|--list Show archive content on stdout
864 ** --name DIRECTORYNAME The name of the top-level directory in the archive
865 ** -R REPOSITORY Specify a Fossil repository
866 */
867 void sqlar_cmd(void){
868 archive_cmd(ARCHIVE_SQLAR);
@@ -972,11 +1009,11 @@
1009 style_finish_page();
1010 return;
1011 }
1012 blob_zero(&zip);
1013 if( cache_read(&zip, zKey)==0 ){
1014 zip_of_checkin(eType, rid, &zip, zName, pInclude, pExclude, 0);
1015 cache_write(&zip, zKey);
1016 }
1017 glob_free(pInclude);
1018 glob_free(pExclude);
1019 fossil_free(zName);
1020

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button