Fossil SCM

Enhance the 'uv export' subcommand to make it easier to bulk export unversioned files.

danield 2026-10-10 09:04 UTC trunk
Commit 9d310a5eb250593d19db05f9871a1e7f31d3c23199daf928fb7b6cb6b9850a2f
1 file changed +76 -6
--- src/unversioned.c
+++ src/unversioned.c
@@ -253,10 +253,21 @@
253253
** Options:
254254
** --editor NAME Name of the text editor to use
255255
**
256256
** export FILE OUTPUT Write the content of FILE into OUTPUT on disk
257257
**
258
+** Options:
259
+** -a|--auto [FILE ...]
260
+** Write the content of given
261
+** (or all) unversioned files to
262
+** current directory on disk
263
+** using their saved file names
264
+** -f|--force With --auto, overwrite existing
265
+** files
266
+** --glob PATTERN Write only files that match
267
+** --like PATTERN Write only files that match
268
+**
258269
** list | ls Show all unversioned files held in the local
259270
** repository.
260271
**
261272
** Options:
262273
** --glob PATTERN Show only files that match
@@ -412,17 +423,76 @@
412423
unversioned_write(zUVFile, &content, mtime);
413424
db_end_transaction(0);
414425
blob_reset(&content);
415426
}else if( strncmp(zCmd, "export", nCmd)==0 ){
416427
Blob content;
417
- verify_all_options();
418
- if( g.argc!=5 ) usage("export UVFILE OUTPUT");
419
- if( unversioned_content(g.argv[3], &content)==0 ){
420
- fossil_fatal("no such uv-file: %Q", g.argv[3]);
428
+ int autoFlag = find_option("auto","a",0)!=0;
429
+ if( autoFlag ){
430
+ int forceFlag = find_option("force","f",0)!=0;
431
+ char *zPattern = sqlite3_mprintf("true");
432
+ const char *zGlob;
433
+ zGlob = find_option("glob",0,1);
434
+ if( zGlob ){
435
+ sqlite3_free(zPattern);
436
+ zPattern = sqlite3_mprintf("(name GLOB %Q)", zGlob);
437
+ }
438
+ zGlob = find_option("like",0,1);
439
+ if( zGlob ){
440
+ sqlite3_free(zPattern);
441
+ zPattern = sqlite3_mprintf("(name LIKE %Q)", zGlob);
442
+ }
443
+
444
+ verify_all_options();
445
+ if( zPattern && g.argc > 3 ){
446
+ fossil_fatal("cannot combine specific files with --like/--glob");
447
+ }
448
+ if( g.argc > 3 ){
449
+ /* Specific unversioned file names given */
450
+ int i;
451
+ for( i=3; i<g.argc; ++i ){
452
+ if( unversioned_content(g.argv[i], &content)==0 ){
453
+ fossil_print("no such uv-file: %Q\n", g.argv[i]);
454
+ continue;
455
+ }
456
+ if( file_isdir(g.argv[i], ExtFILE)>0 && !forceFlag ){
457
+ fossil_print("\"%s\" already exists, add -f to overwrite\n",
458
+ g.argv[i]);
459
+ }else{
460
+ blob_write_to_file(&content, g.argv[i]);
461
+ blob_reset(&content);
462
+ }
463
+ }
464
+ }else{
465
+ /* All unversioned files */
466
+ Stmt q;
467
+ db_prepare(&q, "SELECT name FROM unversioned WHERE %s "
468
+ "AND hash IS NOT NULL "
469
+ "ORDER BY name", zPattern/*safe-for-%s*/);
470
+ while( db_step(&q)==SQLITE_ROW ){
471
+ if( unversioned_content(db_column_text(&q,0), &content)==0 ){
472
+ fossil_print("no such uv-file: %Q\n", db_column_text(&q,0));
473
+ continue;
474
+ }
475
+ if( file_isdir(db_column_text(&q,0), ExtFILE)>0 && !forceFlag ){
476
+ fossil_print("\"%s\" already exists, add -f to overwrite\n",
477
+ db_column_text(&q,0));
478
+ }else{
479
+ blob_write_to_file(&content, db_column_text(&q,0));
480
+ blob_reset(&content);
481
+ }
482
+ }
483
+ db_finalize(&q);
484
+ }
485
+ }else{
486
+ verify_all_options();
487
+ if( g.argc!=5 ) usage("export UVFILE OUTPUT");
488
+ if( unversioned_content(g.argv[3], &content)==0 ){
489
+ fossil_fatal("no such uv-file: %Q", g.argv[3]);
490
+ }
491
+ blob_write_to_file(&content, g.argv[4]);
492
+ blob_reset(&content);
421493
}
422
- blob_write_to_file(&content, g.argv[4]);
423
- blob_reset(&content);
424494
}else if( strncmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
425495
/* Show the hash value used during uv sync */
426496
int debugFlag = find_option("debug",0,0)!=0;
427497
fossil_print("%s\n", unversioned_content_hash(debugFlag));
428498
}else if( strncmp(zCmd, "list", nCmd)==0 || strncmp(zCmd, "ls", nCmd)==0 ){
429499
--- src/unversioned.c
+++ src/unversioned.c
@@ -253,10 +253,21 @@
253 ** Options:
254 ** --editor NAME Name of the text editor to use
255 **
256 ** export FILE OUTPUT Write the content of FILE into OUTPUT on disk
257 **
 
 
 
 
 
 
 
 
 
 
 
258 ** list | ls Show all unversioned files held in the local
259 ** repository.
260 **
261 ** Options:
262 ** --glob PATTERN Show only files that match
@@ -412,17 +423,76 @@
412 unversioned_write(zUVFile, &content, mtime);
413 db_end_transaction(0);
414 blob_reset(&content);
415 }else if( strncmp(zCmd, "export", nCmd)==0 ){
416 Blob content;
417 verify_all_options();
418 if( g.argc!=5 ) usage("export UVFILE OUTPUT");
419 if( unversioned_content(g.argv[3], &content)==0 ){
420 fossil_fatal("no such uv-file: %Q", g.argv[3]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
421 }
422 blob_write_to_file(&content, g.argv[4]);
423 blob_reset(&content);
424 }else if( strncmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
425 /* Show the hash value used during uv sync */
426 int debugFlag = find_option("debug",0,0)!=0;
427 fossil_print("%s\n", unversioned_content_hash(debugFlag));
428 }else if( strncmp(zCmd, "list", nCmd)==0 || strncmp(zCmd, "ls", nCmd)==0 ){
429
--- src/unversioned.c
+++ src/unversioned.c
@@ -253,10 +253,21 @@
253 ** Options:
254 ** --editor NAME Name of the text editor to use
255 **
256 ** export FILE OUTPUT Write the content of FILE into OUTPUT on disk
257 **
258 ** Options:
259 ** -a|--auto [FILE ...]
260 ** Write the content of given
261 ** (or all) unversioned files to
262 ** current directory on disk
263 ** using their saved file names
264 ** -f|--force With --auto, overwrite existing
265 ** files
266 ** --glob PATTERN Write only files that match
267 ** --like PATTERN Write only files that match
268 **
269 ** list | ls Show all unversioned files held in the local
270 ** repository.
271 **
272 ** Options:
273 ** --glob PATTERN Show only files that match
@@ -412,17 +423,76 @@
423 unversioned_write(zUVFile, &content, mtime);
424 db_end_transaction(0);
425 blob_reset(&content);
426 }else if( strncmp(zCmd, "export", nCmd)==0 ){
427 Blob content;
428 int autoFlag = find_option("auto","a",0)!=0;
429 if( autoFlag ){
430 int forceFlag = find_option("force","f",0)!=0;
431 char *zPattern = sqlite3_mprintf("true");
432 const char *zGlob;
433 zGlob = find_option("glob",0,1);
434 if( zGlob ){
435 sqlite3_free(zPattern);
436 zPattern = sqlite3_mprintf("(name GLOB %Q)", zGlob);
437 }
438 zGlob = find_option("like",0,1);
439 if( zGlob ){
440 sqlite3_free(zPattern);
441 zPattern = sqlite3_mprintf("(name LIKE %Q)", zGlob);
442 }
443
444 verify_all_options();
445 if( zPattern && g.argc > 3 ){
446 fossil_fatal("cannot combine specific files with --like/--glob");
447 }
448 if( g.argc > 3 ){
449 /* Specific unversioned file names given */
450 int i;
451 for( i=3; i<g.argc; ++i ){
452 if( unversioned_content(g.argv[i], &content)==0 ){
453 fossil_print("no such uv-file: %Q\n", g.argv[i]);
454 continue;
455 }
456 if( file_isdir(g.argv[i], ExtFILE)>0 && !forceFlag ){
457 fossil_print("\"%s\" already exists, add -f to overwrite\n",
458 g.argv[i]);
459 }else{
460 blob_write_to_file(&content, g.argv[i]);
461 blob_reset(&content);
462 }
463 }
464 }else{
465 /* All unversioned files */
466 Stmt q;
467 db_prepare(&q, "SELECT name FROM unversioned WHERE %s "
468 "AND hash IS NOT NULL "
469 "ORDER BY name", zPattern/*safe-for-%s*/);
470 while( db_step(&q)==SQLITE_ROW ){
471 if( unversioned_content(db_column_text(&q,0), &content)==0 ){
472 fossil_print("no such uv-file: %Q\n", db_column_text(&q,0));
473 continue;
474 }
475 if( file_isdir(db_column_text(&q,0), ExtFILE)>0 && !forceFlag ){
476 fossil_print("\"%s\" already exists, add -f to overwrite\n",
477 db_column_text(&q,0));
478 }else{
479 blob_write_to_file(&content, db_column_text(&q,0));
480 blob_reset(&content);
481 }
482 }
483 db_finalize(&q);
484 }
485 }else{
486 verify_all_options();
487 if( g.argc!=5 ) usage("export UVFILE OUTPUT");
488 if( unversioned_content(g.argv[3], &content)==0 ){
489 fossil_fatal("no such uv-file: %Q", g.argv[3]);
490 }
491 blob_write_to_file(&content, g.argv[4]);
492 blob_reset(&content);
493 }
 
 
494 }else if( strncmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
495 /* Show the hash value used during uv sync */
496 int debugFlag = find_option("debug",0,0)!=0;
497 fossil_print("%s\n", unversioned_content_hash(debugFlag));
498 }else if( strncmp(zCmd, "list", nCmd)==0 || strncmp(zCmd, "ls", nCmd)==0 ){
499

Keyboard Shortcuts

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