Fossil SCM

merge from trunk

wolfgang 2010-10-03 20:34 wolfgangFormat2CSS_2 merge
Commit 287dd50e7b85aca157ee72aed11c1d8039881dc8
1 file changed +97 -44
+97 -44
--- src/rebuild.c
+++ src/rebuild.c
@@ -72,16 +72,20 @@
7272
@ content TEXT
7373
@ );
7474
;
7575
7676
/*
77
-** Variables used for progress information
77
+** Variables used to store state information about an on-going "rebuild"
78
+** or "deconstruct".
7879
*/
7980
static int totalSize; /* Total number of artifacts to process */
8081
static int processCnt; /* Number processed so far */
8182
static int ttyOutput; /* Do progress output */
8283
static Bag bagDone; /* Bag of records rebuilt */
84
+
85
+static char *zFNameFormat; /* Format string for filenames on deconstruct */
86
+static int prefixLength; /* Length of directory prefix for deconstruct */
8387
8488
/*
8589
** Called after each artifact is processed
8690
*/
8791
static void rebuild_step_done(rid){
@@ -98,10 +102,21 @@
98102
99103
/*
100104
** Rebuild cross-referencing information for the artifact
101105
** rid with content pBase and all of its descendants. This
102106
** routine clears the content buffer before returning.
107
+**
108
+** If the zFNameFormat variable is set, then this routine is
109
+** called to run "fossil deconstruct" instead of the usual
110
+** "fossil rebuild". In that case, instead of rebuilding the
111
+** cross-referencing information, write the file content out
112
+** to the approriate directory.
113
+**
114
+** In both cases, this routine automatically recurses to process
115
+** other artifacts that are deltas off of the current artifact.
116
+** This is the most efficient way to extract all of the original
117
+** artifact content from the Fossil repository.
103118
*/
104119
static void rebuild_step(int rid, int size, Blob *pBase){
105120
static Stmt q1;
106121
Bag children;
107122
Blob copy;
@@ -133,12 +148,23 @@
133148
pUse = pBase;
134149
}else{
135150
blob_copy(&copy, pBase);
136151
pUse = ©
137152
}
138
- manifest_crosslink(rid, pUse);
153
+ if( zFNameFormat==0 ){
154
+ /* We are doing "fossil rebuild" */
155
+ manifest_crosslink(rid, pUse);
156
+ }else{
157
+ /* We are doing "fossil deconstruct" */
158
+ char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
159
+ char *zFile = mprintf(zFNameFormat, zUuid, zUuid+prefixLength);
160
+ blob_write_to_file(pUse,zFile);
161
+ free(zFile);
162
+ free(zUuid);
163
+ }
139164
blob_reset(pUse);
165
+ rebuild_step_done(rid);
140166
141167
/* Call all children recursively */
142168
for(cid=bag_first(&children), i=1; cid; cid=bag_next(&children, cid), i++){
143169
Stmt q2;
144170
int sz;
@@ -161,11 +187,10 @@
161187
db_finalize(&q2);
162188
blob_reset(pUse);
163189
}
164190
}
165191
bag_clear(&children);
166
- rebuild_step_done(rid);
167192
}
168193
169194
/*
170195
** Check to see if the "sym-trunk" tag exists. If not, create it
171196
** and attach it to the very first check-in.
@@ -402,18 +427,19 @@
402427
rebuild_db(0, 1);
403428
db_end_transaction(0);
404429
}
405430
}
406431
407
-/*
408
-** help function for reconstruct for recursiv directory
409
-** reading.
432
+/*
433
+** Recursively read all files from the directory zPath and install
434
+** every file read as a new artifact in the repository.
410435
*/
411
-void recon_read_dir(char * zPath){
436
+void recon_read_dir(char *zPath){
412437
DIR *d;
413438
struct dirent *pEntry;
414439
Blob aContent; /* content of the just read artifact */
440
+ static int nFileRead = 0;
415441
416442
d = opendir(zPath);
417443
if( d ){
418444
while( (pEntry=readdir(d))!=0 ){
419445
Blob path;
@@ -434,10 +460,12 @@
434460
}
435461
content_put(&aContent, 0, 0);
436462
blob_reset(&path);
437463
blob_reset(&aContent);
438464
free(zSubpath);
465
+ printf("\r%d", ++nFileRead);
466
+ fflush(stdout);
439467
}
440468
}else {
441469
fossil_panic("encountered error %d while trying to open \"%s\".",
442470
errno, g.argv[3]);
443471
}
@@ -467,14 +495,22 @@
467495
db_open_repository(g.argv[2]);
468496
db_open_config(0);
469497
db_begin_transaction();
470498
db_initial_setup(0, 0, 1);
471499
500
+ printf("Reading files from directory \"%s\"...\n", g.argv[3]);
472501
recon_read_dir(g.argv[3]);
502
+ printf("\nBuilding the Fossil repository...\n");
473503
474504
rebuild_db(0, 1);
475505
506
+ /* Skip the verify_before_commit() step on a reconstruct. Most artifacts
507
+ ** will have been changed and verification therefore takes a really, really
508
+ ** long time.
509
+ */
510
+ verify_cancel();
511
+
476512
db_end_transaction(0);
477513
printf("project-id: %s\n", db_get("project-code", 0));
478514
printf("server-id: %s\n", db_get("server-code", 0));
479515
zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
480516
printf("admin-user: %s (initial password is \"%s\")\n", g.zLogin, zPassword);
@@ -493,13 +529,11 @@
493529
** prefix can be set to 0,1,..,9 characters.
494530
*/
495531
void deconstruct_cmd(void){
496532
const char *zDestDir;
497533
const char *zPrefixOpt;
498
- int prefixLength = 0;
499
- char *zAFileOutFormat;
500
- Stmt q;
534
+ Stmt s;
501535
502536
/* check number of arguments */
503537
if( (g.argc != 3) && (g.argc != 5) && (g.argc != 7)){
504538
usage ("?-R|--repository REPOSITORY? ?-L|--prefixlength N? DESTINATION");
505539
}
@@ -514,52 +548,71 @@
514548
prefixLength = 2;
515549
}else{
516550
if( zPrefixOpt[0]>='0' && zPrefixOpt[0]<='9' && !zPrefixOpt[1] ){
517551
prefixLength = (int)(*zPrefixOpt-'0');
518552
}else{
519
- fossil_panic("N(%s) is not a a valid prefix length!",zPrefixOpt);
553
+ fossil_fatal("N(%s) is not a a valid prefix length!",zPrefixOpt);
520554
}
521555
}
522
- if( prefixLength ){
523
- zAFileOutFormat = mprintf("%%s/%%.%ds/%%s",prefixLength);
524
- }else{
525
- zAFileOutFormat = mprintf("%%s/%%s");
526
- }
527556
#ifndef _WIN32
528557
if( access(zDestDir, W_OK) ){
529
- fossil_panic("DESTINATION(%s) is not writeable!",zDestDir);
558
+ fossil_fatal("DESTINATION(%s) is not writeable!",zDestDir);
530559
}
531560
#else
532561
/* write access on windows is not checked, errors will be
533562
** dected on blob_write_to_file
534563
*/
535564
#endif
565
+ if( prefixLength ){
566
+ zFNameFormat = mprintf("%s/%%.%ds/%%s",zDestDir,prefixLength);
567
+ }else{
568
+ zFNameFormat = mprintf("%s/%%s",zDestDir);
569
+ }
536570
/* open repository and open query for all artifacts */
537571
db_find_and_open_repository(1);
538
- db_prepare(&q, "SELECT rid,uuid FROM blob");
539
- /* loop over artifacts and write them to single files */
540
- while( db_step(&q)==SQLITE_ROW ){
541
- int aRid;
542
- const char *zAUuid;
543
- char *zAFName;
544
- Blob zACont;
545
-
546
- /* get data from query */
547
- aRid = db_column_int (&q, 0);
548
- zAUuid = db_column_text(&q, 1);
549
-
550
- /* construct output filename */
551
- zAFName = mprintf(zAFileOutFormat, zDestDir, zAUuid, zAUuid + prefixLength);
552
-
553
- /* read artifact contents from db and write to file */
554
- content_get(aRid,&zACont);
555
- blob_write_to_file(&zACont,zAFName);
556
- blob_reset(&zACont);
557
-
558
- /* free artifact filename string */
559
- free(zAFName);
560
- }
561
- /* close query statement */
562
- db_finalize(&q);
563
- /* free filename format string */
564
- free(zAFileOutFormat);
572
+ bag_init(&bagDone);
573
+ ttyOutput = 1;
574
+ processCnt = 0;
575
+ if (!g.fQuiet) {
576
+ printf("0 (0%%)...\r");
577
+ fflush(stdout);
578
+ }
579
+ totalSize = db_int(0, "SELECT count(*) FROM blob");
580
+ db_prepare(&s,
581
+ "SELECT rid, size FROM blob /*scan*/"
582
+ " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
583
+ " AND NOT EXISTS(SELECT 1 FROM delta WHERE rid=blob.rid)"
584
+ );
585
+ while( db_step(&s)==SQLITE_ROW ){
586
+ int rid = db_column_int(&s, 0);
587
+ int size = db_column_int(&s, 1);
588
+ if( size>=0 ){
589
+ Blob content;
590
+ content_get(rid, &content);
591
+ rebuild_step(rid, size, &content);
592
+ }
593
+ }
594
+ db_finalize(&s);
595
+ db_prepare(&s,
596
+ "SELECT rid, size FROM blob"
597
+ " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
598
+ );
599
+ while( db_step(&s)==SQLITE_ROW ){
600
+ int rid = db_column_int(&s, 0);
601
+ int size = db_column_int(&s, 1);
602
+ if( size>=0 ){
603
+ if( !bag_find(&bagDone, rid) ){
604
+ Blob content;
605
+ content_get(rid, &content);
606
+ rebuild_step(rid, size, &content);
607
+ }
608
+ }
609
+ }
610
+ db_finalize(&s);
611
+ if(!g.fQuiet && ttyOutput ){
612
+ printf("\n");
613
+ }
614
+
615
+ /* free filename format string */
616
+ free(zFNameFormat);
617
+ zFNameFormat = 0;
565618
}
566619
--- src/rebuild.c
+++ src/rebuild.c
@@ -72,16 +72,20 @@
72 @ content TEXT
73 @ );
74 ;
75
76 /*
77 ** Variables used for progress information
 
78 */
79 static int totalSize; /* Total number of artifacts to process */
80 static int processCnt; /* Number processed so far */
81 static int ttyOutput; /* Do progress output */
82 static Bag bagDone; /* Bag of records rebuilt */
 
 
 
83
84 /*
85 ** Called after each artifact is processed
86 */
87 static void rebuild_step_done(rid){
@@ -98,10 +102,21 @@
98
99 /*
100 ** Rebuild cross-referencing information for the artifact
101 ** rid with content pBase and all of its descendants. This
102 ** routine clears the content buffer before returning.
 
 
 
 
 
 
 
 
 
 
 
103 */
104 static void rebuild_step(int rid, int size, Blob *pBase){
105 static Stmt q1;
106 Bag children;
107 Blob copy;
@@ -133,12 +148,23 @@
133 pUse = pBase;
134 }else{
135 blob_copy(&copy, pBase);
136 pUse = &copy;
137 }
138 manifest_crosslink(rid, pUse);
 
 
 
 
 
 
 
 
 
 
139 blob_reset(pUse);
 
140
141 /* Call all children recursively */
142 for(cid=bag_first(&children), i=1; cid; cid=bag_next(&children, cid), i++){
143 Stmt q2;
144 int sz;
@@ -161,11 +187,10 @@
161 db_finalize(&q2);
162 blob_reset(pUse);
163 }
164 }
165 bag_clear(&children);
166 rebuild_step_done(rid);
167 }
168
169 /*
170 ** Check to see if the "sym-trunk" tag exists. If not, create it
171 ** and attach it to the very first check-in.
@@ -402,18 +427,19 @@
402 rebuild_db(0, 1);
403 db_end_transaction(0);
404 }
405 }
406
407 /*
408 ** help function for reconstruct for recursiv directory
409 ** reading.
410 */
411 void recon_read_dir(char * zPath){
412 DIR *d;
413 struct dirent *pEntry;
414 Blob aContent; /* content of the just read artifact */
 
415
416 d = opendir(zPath);
417 if( d ){
418 while( (pEntry=readdir(d))!=0 ){
419 Blob path;
@@ -434,10 +460,12 @@
434 }
435 content_put(&aContent, 0, 0);
436 blob_reset(&path);
437 blob_reset(&aContent);
438 free(zSubpath);
 
 
439 }
440 }else {
441 fossil_panic("encountered error %d while trying to open \"%s\".",
442 errno, g.argv[3]);
443 }
@@ -467,14 +495,22 @@
467 db_open_repository(g.argv[2]);
468 db_open_config(0);
469 db_begin_transaction();
470 db_initial_setup(0, 0, 1);
471
 
472 recon_read_dir(g.argv[3]);
 
473
474 rebuild_db(0, 1);
475
 
 
 
 
 
 
476 db_end_transaction(0);
477 printf("project-id: %s\n", db_get("project-code", 0));
478 printf("server-id: %s\n", db_get("server-code", 0));
479 zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
480 printf("admin-user: %s (initial password is \"%s\")\n", g.zLogin, zPassword);
@@ -493,13 +529,11 @@
493 ** prefix can be set to 0,1,..,9 characters.
494 */
495 void deconstruct_cmd(void){
496 const char *zDestDir;
497 const char *zPrefixOpt;
498 int prefixLength = 0;
499 char *zAFileOutFormat;
500 Stmt q;
501
502 /* check number of arguments */
503 if( (g.argc != 3) && (g.argc != 5) && (g.argc != 7)){
504 usage ("?-R|--repository REPOSITORY? ?-L|--prefixlength N? DESTINATION");
505 }
@@ -514,52 +548,71 @@
514 prefixLength = 2;
515 }else{
516 if( zPrefixOpt[0]>='0' && zPrefixOpt[0]<='9' && !zPrefixOpt[1] ){
517 prefixLength = (int)(*zPrefixOpt-'0');
518 }else{
519 fossil_panic("N(%s) is not a a valid prefix length!",zPrefixOpt);
520 }
521 }
522 if( prefixLength ){
523 zAFileOutFormat = mprintf("%%s/%%.%ds/%%s",prefixLength);
524 }else{
525 zAFileOutFormat = mprintf("%%s/%%s");
526 }
527 #ifndef _WIN32
528 if( access(zDestDir, W_OK) ){
529 fossil_panic("DESTINATION(%s) is not writeable!",zDestDir);
530 }
531 #else
532 /* write access on windows is not checked, errors will be
533 ** dected on blob_write_to_file
534 */
535 #endif
 
 
 
 
 
536 /* open repository and open query for all artifacts */
537 db_find_and_open_repository(1);
538 db_prepare(&q, "SELECT rid,uuid FROM blob");
539 /* loop over artifacts and write them to single files */
540 while( db_step(&q)==SQLITE_ROW ){
541 int aRid;
542 const char *zAUuid;
543 char *zAFName;
544 Blob zACont;
545
546 /* get data from query */
547 aRid = db_column_int (&q, 0);
548 zAUuid = db_column_text(&q, 1);
549
550 /* construct output filename */
551 zAFName = mprintf(zAFileOutFormat, zDestDir, zAUuid, zAUuid + prefixLength);
552
553 /* read artifact contents from db and write to file */
554 content_get(aRid,&zACont);
555 blob_write_to_file(&zACont,zAFName);
556 blob_reset(&zACont);
557
558 /* free artifact filename string */
559 free(zAFName);
560 }
561 /* close query statement */
562 db_finalize(&q);
563 /* free filename format string */
564 free(zAFileOutFormat);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
565 }
566
--- src/rebuild.c
+++ src/rebuild.c
@@ -72,16 +72,20 @@
72 @ content TEXT
73 @ );
74 ;
75
76 /*
77 ** Variables used to store state information about an on-going "rebuild"
78 ** or "deconstruct".
79 */
80 static int totalSize; /* Total number of artifacts to process */
81 static int processCnt; /* Number processed so far */
82 static int ttyOutput; /* Do progress output */
83 static Bag bagDone; /* Bag of records rebuilt */
84
85 static char *zFNameFormat; /* Format string for filenames on deconstruct */
86 static int prefixLength; /* Length of directory prefix for deconstruct */
87
88 /*
89 ** Called after each artifact is processed
90 */
91 static void rebuild_step_done(rid){
@@ -98,10 +102,21 @@
102
103 /*
104 ** Rebuild cross-referencing information for the artifact
105 ** rid with content pBase and all of its descendants. This
106 ** routine clears the content buffer before returning.
107 **
108 ** If the zFNameFormat variable is set, then this routine is
109 ** called to run "fossil deconstruct" instead of the usual
110 ** "fossil rebuild". In that case, instead of rebuilding the
111 ** cross-referencing information, write the file content out
112 ** to the approriate directory.
113 **
114 ** In both cases, this routine automatically recurses to process
115 ** other artifacts that are deltas off of the current artifact.
116 ** This is the most efficient way to extract all of the original
117 ** artifact content from the Fossil repository.
118 */
119 static void rebuild_step(int rid, int size, Blob *pBase){
120 static Stmt q1;
121 Bag children;
122 Blob copy;
@@ -133,12 +148,23 @@
148 pUse = pBase;
149 }else{
150 blob_copy(&copy, pBase);
151 pUse = &copy;
152 }
153 if( zFNameFormat==0 ){
154 /* We are doing "fossil rebuild" */
155 manifest_crosslink(rid, pUse);
156 }else{
157 /* We are doing "fossil deconstruct" */
158 char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
159 char *zFile = mprintf(zFNameFormat, zUuid, zUuid+prefixLength);
160 blob_write_to_file(pUse,zFile);
161 free(zFile);
162 free(zUuid);
163 }
164 blob_reset(pUse);
165 rebuild_step_done(rid);
166
167 /* Call all children recursively */
168 for(cid=bag_first(&children), i=1; cid; cid=bag_next(&children, cid), i++){
169 Stmt q2;
170 int sz;
@@ -161,11 +187,10 @@
187 db_finalize(&q2);
188 blob_reset(pUse);
189 }
190 }
191 bag_clear(&children);
 
192 }
193
194 /*
195 ** Check to see if the "sym-trunk" tag exists. If not, create it
196 ** and attach it to the very first check-in.
@@ -402,18 +427,19 @@
427 rebuild_db(0, 1);
428 db_end_transaction(0);
429 }
430 }
431
432 /*
433 ** Recursively read all files from the directory zPath and install
434 ** every file read as a new artifact in the repository.
435 */
436 void recon_read_dir(char *zPath){
437 DIR *d;
438 struct dirent *pEntry;
439 Blob aContent; /* content of the just read artifact */
440 static int nFileRead = 0;
441
442 d = opendir(zPath);
443 if( d ){
444 while( (pEntry=readdir(d))!=0 ){
445 Blob path;
@@ -434,10 +460,12 @@
460 }
461 content_put(&aContent, 0, 0);
462 blob_reset(&path);
463 blob_reset(&aContent);
464 free(zSubpath);
465 printf("\r%d", ++nFileRead);
466 fflush(stdout);
467 }
468 }else {
469 fossil_panic("encountered error %d while trying to open \"%s\".",
470 errno, g.argv[3]);
471 }
@@ -467,14 +495,22 @@
495 db_open_repository(g.argv[2]);
496 db_open_config(0);
497 db_begin_transaction();
498 db_initial_setup(0, 0, 1);
499
500 printf("Reading files from directory \"%s\"...\n", g.argv[3]);
501 recon_read_dir(g.argv[3]);
502 printf("\nBuilding the Fossil repository...\n");
503
504 rebuild_db(0, 1);
505
506 /* Skip the verify_before_commit() step on a reconstruct. Most artifacts
507 ** will have been changed and verification therefore takes a really, really
508 ** long time.
509 */
510 verify_cancel();
511
512 db_end_transaction(0);
513 printf("project-id: %s\n", db_get("project-code", 0));
514 printf("server-id: %s\n", db_get("server-code", 0));
515 zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
516 printf("admin-user: %s (initial password is \"%s\")\n", g.zLogin, zPassword);
@@ -493,13 +529,11 @@
529 ** prefix can be set to 0,1,..,9 characters.
530 */
531 void deconstruct_cmd(void){
532 const char *zDestDir;
533 const char *zPrefixOpt;
534 Stmt s;
 
 
535
536 /* check number of arguments */
537 if( (g.argc != 3) && (g.argc != 5) && (g.argc != 7)){
538 usage ("?-R|--repository REPOSITORY? ?-L|--prefixlength N? DESTINATION");
539 }
@@ -514,52 +548,71 @@
548 prefixLength = 2;
549 }else{
550 if( zPrefixOpt[0]>='0' && zPrefixOpt[0]<='9' && !zPrefixOpt[1] ){
551 prefixLength = (int)(*zPrefixOpt-'0');
552 }else{
553 fossil_fatal("N(%s) is not a a valid prefix length!",zPrefixOpt);
554 }
555 }
 
 
 
 
 
556 #ifndef _WIN32
557 if( access(zDestDir, W_OK) ){
558 fossil_fatal("DESTINATION(%s) is not writeable!",zDestDir);
559 }
560 #else
561 /* write access on windows is not checked, errors will be
562 ** dected on blob_write_to_file
563 */
564 #endif
565 if( prefixLength ){
566 zFNameFormat = mprintf("%s/%%.%ds/%%s",zDestDir,prefixLength);
567 }else{
568 zFNameFormat = mprintf("%s/%%s",zDestDir);
569 }
570 /* open repository and open query for all artifacts */
571 db_find_and_open_repository(1);
572 bag_init(&bagDone);
573 ttyOutput = 1;
574 processCnt = 0;
575 if (!g.fQuiet) {
576 printf("0 (0%%)...\r");
577 fflush(stdout);
578 }
579 totalSize = db_int(0, "SELECT count(*) FROM blob");
580 db_prepare(&s,
581 "SELECT rid, size FROM blob /*scan*/"
582 " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
583 " AND NOT EXISTS(SELECT 1 FROM delta WHERE rid=blob.rid)"
584 );
585 while( db_step(&s)==SQLITE_ROW ){
586 int rid = db_column_int(&s, 0);
587 int size = db_column_int(&s, 1);
588 if( size>=0 ){
589 Blob content;
590 content_get(rid, &content);
591 rebuild_step(rid, size, &content);
592 }
593 }
594 db_finalize(&s);
595 db_prepare(&s,
596 "SELECT rid, size FROM blob"
597 " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
598 );
599 while( db_step(&s)==SQLITE_ROW ){
600 int rid = db_column_int(&s, 0);
601 int size = db_column_int(&s, 1);
602 if( size>=0 ){
603 if( !bag_find(&bagDone, rid) ){
604 Blob content;
605 content_get(rid, &content);
606 rebuild_step(rid, size, &content);
607 }
608 }
609 }
610 db_finalize(&s);
611 if(!g.fQuiet && ttyOutput ){
612 printf("\n");
613 }
614
615 /* free filename format string */
616 free(zFNameFormat);
617 zFNameFormat = 0;
618 }
619

Keyboard Shortcuts

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