Fossil SCM
Enhance the "fossil uv" command to make use of GLOB and LIKE patterns.
Commit
63837f423f2496fc0c011efbb28a1859daca4567ea6588be775f5fd7cd17be2b
Parent
a8967ca91c46f37…
1 file changed
+49
-10
+49
-10
| --- src/unversioned.c | ||
| +++ src/unversioned.c | ||
| @@ -237,11 +237,14 @@ | ||
| 237 | 237 | ** edit FILE Bring up FILE in a text editor for modification. |
| 238 | 238 | ** |
| 239 | 239 | ** export FILE OUTPUT Write the content of FILE into OUTPUT on disk |
| 240 | 240 | ** |
| 241 | 241 | ** list | ls Show all unversioned files held in the local |
| 242 | -** repository. | |
| 242 | +** repository. Options: | |
| 243 | +** | |
| 244 | +** --glob PATTERN Show only files that match | |
| 245 | +** --like PATTERN Show only files that match | |
| 243 | 246 | ** |
| 244 | 247 | ** revert ?URL? Restore the state of all unversioned files in the |
| 245 | 248 | ** local repository to match the remote repository |
| 246 | 249 | ** URL. |
| 247 | 250 | ** |
| @@ -250,11 +253,14 @@ | ||
| 250 | 253 | ** -n|--dryrun Show what would have happened |
| 251 | 254 | ** |
| 252 | 255 | ** remove|rm|delete FILE ... |
| 253 | 256 | ** Remove unversioned files from the local repository. |
| 254 | 257 | ** Changes are not pushed to other repositories until |
| 255 | -** the next sync. | |
| 258 | +** the next sync. Options: | |
| 259 | +** | |
| 260 | +** --glob PATTERN Remove files that match | |
| 261 | +** --like PATTERN Remove files that match | |
| 256 | 262 | ** |
| 257 | 263 | ** sync ?URL? Synchronize the state of all unversioned files with |
| 258 | 264 | ** the remote repository URL. The most recent version |
| 259 | 265 | ** of each file is propagated to all repositories and |
| 260 | 266 | ** all prior versions are permanently forgotten. |
| @@ -339,11 +345,13 @@ | ||
| 339 | 345 | |
| 340 | 346 | verify_all_options(); |
| 341 | 347 | if( g.argc!=4) usage("edit UVFILE"); |
| 342 | 348 | zUVFile = g.argv[3]; |
| 343 | 349 | zEditor = fossil_text_editor(); |
| 344 | - if( zEditor==0 ) fossil_fatal("no text editor - set the VISUAL env variable"); | |
| 350 | + if( zEditor==0 ){ | |
| 351 | + fossil_fatal("no text editor - set the VISUAL env variable"); | |
| 352 | + } | |
| 345 | 353 | zTFile = fossil_temp_filename(); |
| 346 | 354 | if( zTFile==0 ) fossil_fatal("cannot find a temporary filename"); |
| 347 | 355 | db_begin_transaction(); |
| 348 | 356 | content_rcvid_init("#!fossil unversioned edit"); |
| 349 | 357 | if( unversioned_content(zUVFile, &content) ){ |
| @@ -386,26 +394,40 @@ | ||
| 386 | 394 | fossil_print("%s\n", unversioned_content_hash(debugFlag)); |
| 387 | 395 | }else if( memcmp(zCmd, "list", nCmd)==0 || memcmp(zCmd, "ls", nCmd)==0 ){ |
| 388 | 396 | Stmt q; |
| 389 | 397 | int allFlag = find_option("all","a",0)!=0; |
| 390 | 398 | int longFlag = find_option("l",0,0)!=0 || (nCmd>1 && zCmd[1]=='i'); |
| 399 | + char *zPattern = sqlite3_mprintf("true"); | |
| 400 | + const char *zGlob; | |
| 401 | + zGlob = find_option("glob",0,1); | |
| 402 | + if( zGlob ){ | |
| 403 | + sqlite3_free(zPattern); | |
| 404 | + zPattern = sqlite3_mprintf("(name GLOB %Q)", zGlob); | |
| 405 | + } | |
| 406 | + zGlob = find_option("like",0,1); | |
| 407 | + if( zGlob ){ | |
| 408 | + sqlite3_free(zPattern); | |
| 409 | + zPattern = sqlite3_mprintf("(name LIKE %Q)", zGlob); | |
| 410 | + } | |
| 391 | 411 | verify_all_options(); |
| 392 | 412 | if( !longFlag ){ |
| 393 | 413 | if( allFlag ){ |
| 394 | - db_prepare(&q, "SELECT name FROM unversioned ORDER BY name"); | |
| 414 | + db_prepare(&q, "SELECT name FROM unversioned WHERE %s ORDER BY name", | |
| 415 | + zPattern/*safe-for-%s*/); | |
| 395 | 416 | }else{ |
| 396 | - db_prepare(&q, "SELECT name FROM unversioned WHERE hash IS NOT NULL" | |
| 397 | - " ORDER BY name"); | |
| 417 | + db_prepare(&q, "SELECT name FROM unversioned" | |
| 418 | + " WHERE %s AND hash IS NOT NULL" | |
| 419 | + " ORDER BY name", zPattern/*safe-for-%s*/); | |
| 398 | 420 | } |
| 399 | 421 | while( db_step(&q)==SQLITE_ROW ){ |
| 400 | 422 | fossil_print("%s\n", db_column_text(&q,0)); |
| 401 | 423 | } |
| 402 | 424 | }else{ |
| 403 | 425 | db_prepare(&q, |
| 404 | 426 | "SELECT hash, datetime(mtime,'unixepoch'), sz, length(content), name" |
| 405 | - " FROM unversioned" | |
| 406 | - " ORDER BY name;" | |
| 427 | + " FROM unversioned WHERE %s" | |
| 428 | + " ORDER BY name;", zPattern/*safe-for-%s*/ | |
| 407 | 429 | ); |
| 408 | 430 | while( db_step(&q)==SQLITE_ROW ){ |
| 409 | 431 | const char *zHash = db_column_text(&q, 0); |
| 410 | 432 | const char *zNoContent = ""; |
| 411 | 433 | if( zHash==0 ){ |
| @@ -423,20 +445,37 @@ | ||
| 423 | 445 | zNoContent |
| 424 | 446 | ); |
| 425 | 447 | } |
| 426 | 448 | } |
| 427 | 449 | db_finalize(&q); |
| 450 | + sqlite3_free(zPattern); | |
| 428 | 451 | }else if( memcmp(zCmd, "revert", nCmd)==0 ){ |
| 429 | - unsigned syncFlags = unversioned_sync_flags(SYNC_UNVERSIONED|SYNC_UV_REVERT); | |
| 452 | + unsigned syncFlags = | |
| 453 | + unversioned_sync_flags(SYNC_UNVERSIONED|SYNC_UV_REVERT); | |
| 430 | 454 | g.argv[1] = "sync"; |
| 431 | 455 | g.argv[2] = "--uv-noop"; |
| 432 | 456 | sync_unversioned(syncFlags); |
| 433 | 457 | }else if( memcmp(zCmd, "remove", nCmd)==0 || memcmp(zCmd, "rm", nCmd)==0 |
| 434 | 458 | || memcmp(zCmd, "delete", nCmd)==0 ){ |
| 435 | 459 | int i; |
| 436 | - verify_all_options(); | |
| 460 | + const char *zGlob; | |
| 437 | 461 | db_begin_transaction(); |
| 462 | + while( (zGlob = find_option("glob",0,1))!=0 ){ | |
| 463 | + db_multi_exec( | |
| 464 | + "UPDATE unversioned" | |
| 465 | + " SET hash=NULL, content=NULL, mtime=%lld, sz=0 WHERE name GLOB %Q", | |
| 466 | + mtime, zGlob | |
| 467 | + ); | |
| 468 | + } | |
| 469 | + while( (zGlob = find_option("like",0,1))!=0 ){ | |
| 470 | + db_multi_exec( | |
| 471 | + "UPDATE unversioned" | |
| 472 | + " SET hash=NULL, content=NULL, mtime=%lld, sz=0 WHERE name LIKE %Q", | |
| 473 | + mtime, zGlob | |
| 474 | + ); | |
| 475 | + } | |
| 476 | + verify_all_options(); | |
| 438 | 477 | for(i=3; i<g.argc; i++){ |
| 439 | 478 | db_multi_exec( |
| 440 | 479 | "UPDATE unversioned" |
| 441 | 480 | " SET hash=NULL, content=NULL, mtime=%lld, sz=0 WHERE name=%Q", |
| 442 | 481 | mtime, g.argv[i] |
| 443 | 482 |
| --- src/unversioned.c | |
| +++ src/unversioned.c | |
| @@ -237,11 +237,14 @@ | |
| 237 | ** edit FILE Bring up FILE in a text editor for modification. |
| 238 | ** |
| 239 | ** export FILE OUTPUT Write the content of FILE into OUTPUT on disk |
| 240 | ** |
| 241 | ** list | ls Show all unversioned files held in the local |
| 242 | ** repository. |
| 243 | ** |
| 244 | ** revert ?URL? Restore the state of all unversioned files in the |
| 245 | ** local repository to match the remote repository |
| 246 | ** URL. |
| 247 | ** |
| @@ -250,11 +253,14 @@ | |
| 250 | ** -n|--dryrun Show what would have happened |
| 251 | ** |
| 252 | ** remove|rm|delete FILE ... |
| 253 | ** Remove unversioned files from the local repository. |
| 254 | ** Changes are not pushed to other repositories until |
| 255 | ** the next sync. |
| 256 | ** |
| 257 | ** sync ?URL? Synchronize the state of all unversioned files with |
| 258 | ** the remote repository URL. The most recent version |
| 259 | ** of each file is propagated to all repositories and |
| 260 | ** all prior versions are permanently forgotten. |
| @@ -339,11 +345,13 @@ | |
| 339 | |
| 340 | verify_all_options(); |
| 341 | if( g.argc!=4) usage("edit UVFILE"); |
| 342 | zUVFile = g.argv[3]; |
| 343 | zEditor = fossil_text_editor(); |
| 344 | if( zEditor==0 ) fossil_fatal("no text editor - set the VISUAL env variable"); |
| 345 | zTFile = fossil_temp_filename(); |
| 346 | if( zTFile==0 ) fossil_fatal("cannot find a temporary filename"); |
| 347 | db_begin_transaction(); |
| 348 | content_rcvid_init("#!fossil unversioned edit"); |
| 349 | if( unversioned_content(zUVFile, &content) ){ |
| @@ -386,26 +394,40 @@ | |
| 386 | fossil_print("%s\n", unversioned_content_hash(debugFlag)); |
| 387 | }else if( memcmp(zCmd, "list", nCmd)==0 || memcmp(zCmd, "ls", nCmd)==0 ){ |
| 388 | Stmt q; |
| 389 | int allFlag = find_option("all","a",0)!=0; |
| 390 | int longFlag = find_option("l",0,0)!=0 || (nCmd>1 && zCmd[1]=='i'); |
| 391 | verify_all_options(); |
| 392 | if( !longFlag ){ |
| 393 | if( allFlag ){ |
| 394 | db_prepare(&q, "SELECT name FROM unversioned ORDER BY name"); |
| 395 | }else{ |
| 396 | db_prepare(&q, "SELECT name FROM unversioned WHERE hash IS NOT NULL" |
| 397 | " ORDER BY name"); |
| 398 | } |
| 399 | while( db_step(&q)==SQLITE_ROW ){ |
| 400 | fossil_print("%s\n", db_column_text(&q,0)); |
| 401 | } |
| 402 | }else{ |
| 403 | db_prepare(&q, |
| 404 | "SELECT hash, datetime(mtime,'unixepoch'), sz, length(content), name" |
| 405 | " FROM unversioned" |
| 406 | " ORDER BY name;" |
| 407 | ); |
| 408 | while( db_step(&q)==SQLITE_ROW ){ |
| 409 | const char *zHash = db_column_text(&q, 0); |
| 410 | const char *zNoContent = ""; |
| 411 | if( zHash==0 ){ |
| @@ -423,20 +445,37 @@ | |
| 423 | zNoContent |
| 424 | ); |
| 425 | } |
| 426 | } |
| 427 | db_finalize(&q); |
| 428 | }else if( memcmp(zCmd, "revert", nCmd)==0 ){ |
| 429 | unsigned syncFlags = unversioned_sync_flags(SYNC_UNVERSIONED|SYNC_UV_REVERT); |
| 430 | g.argv[1] = "sync"; |
| 431 | g.argv[2] = "--uv-noop"; |
| 432 | sync_unversioned(syncFlags); |
| 433 | }else if( memcmp(zCmd, "remove", nCmd)==0 || memcmp(zCmd, "rm", nCmd)==0 |
| 434 | || memcmp(zCmd, "delete", nCmd)==0 ){ |
| 435 | int i; |
| 436 | verify_all_options(); |
| 437 | db_begin_transaction(); |
| 438 | for(i=3; i<g.argc; i++){ |
| 439 | db_multi_exec( |
| 440 | "UPDATE unversioned" |
| 441 | " SET hash=NULL, content=NULL, mtime=%lld, sz=0 WHERE name=%Q", |
| 442 | mtime, g.argv[i] |
| 443 |
| --- src/unversioned.c | |
| +++ src/unversioned.c | |
| @@ -237,11 +237,14 @@ | |
| 237 | ** edit FILE Bring up FILE in a text editor for modification. |
| 238 | ** |
| 239 | ** export FILE OUTPUT Write the content of FILE into OUTPUT on disk |
| 240 | ** |
| 241 | ** list | ls Show all unversioned files held in the local |
| 242 | ** repository. Options: |
| 243 | ** |
| 244 | ** --glob PATTERN Show only files that match |
| 245 | ** --like PATTERN Show only files that match |
| 246 | ** |
| 247 | ** revert ?URL? Restore the state of all unversioned files in the |
| 248 | ** local repository to match the remote repository |
| 249 | ** URL. |
| 250 | ** |
| @@ -250,11 +253,14 @@ | |
| 253 | ** -n|--dryrun Show what would have happened |
| 254 | ** |
| 255 | ** remove|rm|delete FILE ... |
| 256 | ** Remove unversioned files from the local repository. |
| 257 | ** Changes are not pushed to other repositories until |
| 258 | ** the next sync. Options: |
| 259 | ** |
| 260 | ** --glob PATTERN Remove files that match |
| 261 | ** --like PATTERN Remove files that match |
| 262 | ** |
| 263 | ** sync ?URL? Synchronize the state of all unversioned files with |
| 264 | ** the remote repository URL. The most recent version |
| 265 | ** of each file is propagated to all repositories and |
| 266 | ** all prior versions are permanently forgotten. |
| @@ -339,11 +345,13 @@ | |
| 345 | |
| 346 | verify_all_options(); |
| 347 | if( g.argc!=4) usage("edit UVFILE"); |
| 348 | zUVFile = g.argv[3]; |
| 349 | zEditor = fossil_text_editor(); |
| 350 | if( zEditor==0 ){ |
| 351 | fossil_fatal("no text editor - set the VISUAL env variable"); |
| 352 | } |
| 353 | zTFile = fossil_temp_filename(); |
| 354 | if( zTFile==0 ) fossil_fatal("cannot find a temporary filename"); |
| 355 | db_begin_transaction(); |
| 356 | content_rcvid_init("#!fossil unversioned edit"); |
| 357 | if( unversioned_content(zUVFile, &content) ){ |
| @@ -386,26 +394,40 @@ | |
| 394 | fossil_print("%s\n", unversioned_content_hash(debugFlag)); |
| 395 | }else if( memcmp(zCmd, "list", nCmd)==0 || memcmp(zCmd, "ls", nCmd)==0 ){ |
| 396 | Stmt q; |
| 397 | int allFlag = find_option("all","a",0)!=0; |
| 398 | int longFlag = find_option("l",0,0)!=0 || (nCmd>1 && zCmd[1]=='i'); |
| 399 | char *zPattern = sqlite3_mprintf("true"); |
| 400 | const char *zGlob; |
| 401 | zGlob = find_option("glob",0,1); |
| 402 | if( zGlob ){ |
| 403 | sqlite3_free(zPattern); |
| 404 | zPattern = sqlite3_mprintf("(name GLOB %Q)", zGlob); |
| 405 | } |
| 406 | zGlob = find_option("like",0,1); |
| 407 | if( zGlob ){ |
| 408 | sqlite3_free(zPattern); |
| 409 | zPattern = sqlite3_mprintf("(name LIKE %Q)", zGlob); |
| 410 | } |
| 411 | verify_all_options(); |
| 412 | if( !longFlag ){ |
| 413 | if( allFlag ){ |
| 414 | db_prepare(&q, "SELECT name FROM unversioned WHERE %s ORDER BY name", |
| 415 | zPattern/*safe-for-%s*/); |
| 416 | }else{ |
| 417 | db_prepare(&q, "SELECT name FROM unversioned" |
| 418 | " WHERE %s AND hash IS NOT NULL" |
| 419 | " ORDER BY name", zPattern/*safe-for-%s*/); |
| 420 | } |
| 421 | while( db_step(&q)==SQLITE_ROW ){ |
| 422 | fossil_print("%s\n", db_column_text(&q,0)); |
| 423 | } |
| 424 | }else{ |
| 425 | db_prepare(&q, |
| 426 | "SELECT hash, datetime(mtime,'unixepoch'), sz, length(content), name" |
| 427 | " FROM unversioned WHERE %s" |
| 428 | " ORDER BY name;", zPattern/*safe-for-%s*/ |
| 429 | ); |
| 430 | while( db_step(&q)==SQLITE_ROW ){ |
| 431 | const char *zHash = db_column_text(&q, 0); |
| 432 | const char *zNoContent = ""; |
| 433 | if( zHash==0 ){ |
| @@ -423,20 +445,37 @@ | |
| 445 | zNoContent |
| 446 | ); |
| 447 | } |
| 448 | } |
| 449 | db_finalize(&q); |
| 450 | sqlite3_free(zPattern); |
| 451 | }else if( memcmp(zCmd, "revert", nCmd)==0 ){ |
| 452 | unsigned syncFlags = |
| 453 | unversioned_sync_flags(SYNC_UNVERSIONED|SYNC_UV_REVERT); |
| 454 | g.argv[1] = "sync"; |
| 455 | g.argv[2] = "--uv-noop"; |
| 456 | sync_unversioned(syncFlags); |
| 457 | }else if( memcmp(zCmd, "remove", nCmd)==0 || memcmp(zCmd, "rm", nCmd)==0 |
| 458 | || memcmp(zCmd, "delete", nCmd)==0 ){ |
| 459 | int i; |
| 460 | const char *zGlob; |
| 461 | db_begin_transaction(); |
| 462 | while( (zGlob = find_option("glob",0,1))!=0 ){ |
| 463 | db_multi_exec( |
| 464 | "UPDATE unversioned" |
| 465 | " SET hash=NULL, content=NULL, mtime=%lld, sz=0 WHERE name GLOB %Q", |
| 466 | mtime, zGlob |
| 467 | ); |
| 468 | } |
| 469 | while( (zGlob = find_option("like",0,1))!=0 ){ |
| 470 | db_multi_exec( |
| 471 | "UPDATE unversioned" |
| 472 | " SET hash=NULL, content=NULL, mtime=%lld, sz=0 WHERE name LIKE %Q", |
| 473 | mtime, zGlob |
| 474 | ); |
| 475 | } |
| 476 | verify_all_options(); |
| 477 | for(i=3; i<g.argc; i++){ |
| 478 | db_multi_exec( |
| 479 | "UPDATE unversioned" |
| 480 | " SET hash=NULL, content=NULL, mtime=%lld, sz=0 WHERE name=%Q", |
| 481 | mtime, g.argv[i] |
| 482 |