| | @@ -449,10 +449,11 @@ |
| 449 | 449 | */ |
| 450 | 450 | int historical_version_of_file( |
| 451 | 451 | const char *revision, /* The checkin containing the file */ |
| 452 | 452 | const char *file, /* Full treename of the file */ |
| 453 | 453 | Blob *content, /* Put the content here */ |
| 454 | + int *pIsExe, /* Set to true if file is executable */ |
| 454 | 455 | int errCode /* Error code if file not found. Panic if 0. */ |
| 455 | 456 | ){ |
| 456 | 457 | Manifest *pManifest; |
| 457 | 458 | ManifestFile *pFile; |
| 458 | 459 | int rid=0; |
| | @@ -467,17 +468,16 @@ |
| 467 | 468 | fossil_fatal("no such checkin: %s", revision); |
| 468 | 469 | } |
| 469 | 470 | pManifest = manifest_get(rid, CFTYPE_MANIFEST); |
| 470 | 471 | |
| 471 | 472 | if( pManifest ){ |
| 472 | | - manifest_file_rewind(pManifest); |
| 473 | | - while( (pFile = manifest_file_next(pManifest,0))!=0 ){ |
| 474 | | - if( fossil_strcmp(pFile->zName, file)==0 ){ |
| 475 | | - rid = uuid_to_rid(pFile->zUuid, 0); |
| 476 | | - manifest_destroy(pManifest); |
| 477 | | - return content_get(rid, content); |
| 478 | | - } |
| 473 | + pFile = manifest_file_seek(pManifest, file); |
| 474 | + if( pFile ){ |
| 475 | + rid = uuid_to_rid(pFile->zUuid, 0); |
| 476 | + if( pIsExe ) *pIsExe = manifest_file_mperm(pFile); |
| 477 | + manifest_destroy(pManifest); |
| 478 | + return content_get(rid, content); |
| 479 | 479 | } |
| 480 | 480 | manifest_destroy(pManifest); |
| 481 | 481 | if( errCode<=0 ){ |
| 482 | 482 | fossil_fatal("file %s does not exist in checkin: %s", file, revision); |
| 483 | 483 | } |
| | @@ -509,11 +509,10 @@ |
| 509 | 509 | const char *zFile; |
| 510 | 510 | const char *zRevision; |
| 511 | 511 | Blob record; |
| 512 | 512 | int i; |
| 513 | 513 | int errCode; |
| 514 | | - int rid = 0; |
| 515 | 514 | Stmt q; |
| 516 | 515 | |
| 517 | 516 | undo_capture_command_line(); |
| 518 | 517 | zRevision = find_option("revision", "r", 1); |
| 519 | 518 | verify_all_options(); |
| | @@ -549,39 +548,34 @@ |
| 549 | 548 | " WHERE chnged OR deleted OR rid=0 OR pathname!=origname;" |
| 550 | 549 | ); |
| 551 | 550 | } |
| 552 | 551 | blob_zero(&record); |
| 553 | 552 | db_prepare(&q, "SELECT name FROM torevert"); |
| 553 | + if( zRevision==0 ){ |
| 554 | + int vid = db_lget_int("checkout", 0); |
| 555 | + zRevision = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid); |
| 556 | + } |
| 554 | 557 | while( db_step(&q)==SQLITE_ROW ){ |
| 558 | + int isExe = 0; |
| 555 | 559 | zFile = db_column_text(&q, 0); |
| 556 | | - if( zRevision!=0 ){ |
| 557 | | - errCode = historical_version_of_file(zRevision, zFile, &record, 2); |
| 558 | | - }else{ |
| 559 | | - rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFile); |
| 560 | | - if( rid==0 ){ |
| 561 | | - errCode = 2; |
| 562 | | - }else{ |
| 563 | | - content_get(rid, &record); |
| 564 | | - errCode = 0; |
| 565 | | - } |
| 566 | | - } |
| 567 | | - |
| 560 | + errCode = historical_version_of_file(zRevision, zFile, &record, &isExe,2); |
| 568 | 561 | if( errCode==2 ){ |
| 569 | 562 | fossil_warning("file not in repository: %s", zFile); |
| 570 | 563 | }else{ |
| 571 | 564 | char *zFull = mprintf("%/%/", g.zLocalRoot, zFile); |
| 572 | 565 | undo_save(zFile); |
| 573 | 566 | blob_write_to_file(&record, zFull); |
| 567 | + file_setexe(zFull, isExe); |
| 574 | 568 | printf("REVERTED: %s\n", zFile); |
| 575 | 569 | if( zRevision==0 ){ |
| 576 | 570 | sqlite3_int64 mtime = file_mtime(zFull); |
| 577 | 571 | db_multi_exec( |
| 578 | 572 | "UPDATE vfile" |
| 579 | | - " SET mtime=%lld, chnged=0, deleted=0," |
| 573 | + " SET mtime=%lld, chnged=0, deleted=0, isexe=%d," |
| 580 | 574 | " pathname=coalesce(origname,pathname), origname=NULL" |
| 581 | 575 | " WHERE pathname=%Q", |
| 582 | | - mtime, zFile |
| 576 | + mtime, isExe, zFile |
| 583 | 577 | ); |
| 584 | 578 | } |
| 585 | 579 | free(zFull); |
| 586 | 580 | } |
| 587 | 581 | blob_reset(&record); |
| 588 | 582 | |