Fossil SCM
Enhance the 'uv export' subcommand to make it easier to bulk export unversioned files.
Commit
9d310a5eb250593d19db05f9871a1e7f31d3c23199daf928fb7b6cb6b9850a2f
Parent
40c5397698246ca…
1 file changed
+76
-6
+76
-6
| --- src/unversioned.c | ||
| +++ src/unversioned.c | ||
| @@ -253,10 +253,21 @@ | ||
| 253 | 253 | ** Options: |
| 254 | 254 | ** --editor NAME Name of the text editor to use |
| 255 | 255 | ** |
| 256 | 256 | ** export FILE OUTPUT Write the content of FILE into OUTPUT on disk |
| 257 | 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 | +** | |
| 258 | 269 | ** list | ls Show all unversioned files held in the local |
| 259 | 270 | ** repository. |
| 260 | 271 | ** |
| 261 | 272 | ** Options: |
| 262 | 273 | ** --glob PATTERN Show only files that match |
| @@ -412,17 +423,76 @@ | ||
| 412 | 423 | unversioned_write(zUVFile, &content, mtime); |
| 413 | 424 | db_end_transaction(0); |
| 414 | 425 | blob_reset(&content); |
| 415 | 426 | }else if( strncmp(zCmd, "export", nCmd)==0 ){ |
| 416 | 427 | 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); | |
| 421 | 493 | } |
| 422 | - blob_write_to_file(&content, g.argv[4]); | |
| 423 | - blob_reset(&content); | |
| 424 | 494 | }else if( strncmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */ |
| 425 | 495 | /* Show the hash value used during uv sync */ |
| 426 | 496 | int debugFlag = find_option("debug",0,0)!=0; |
| 427 | 497 | fossil_print("%s\n", unversioned_content_hash(debugFlag)); |
| 428 | 498 | }else if( strncmp(zCmd, "list", nCmd)==0 || strncmp(zCmd, "ls", nCmd)==0 ){ |
| 429 | 499 |
| --- 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 |