| | @@ -253,11 +253,12 @@ |
| 253 | 253 | ** Get the contents of a file within a given revision. |
| 254 | 254 | */ |
| 255 | 255 | int historical_version_of_file( |
| 256 | 256 | const char *revision, /* The baseline name containing the file */ |
| 257 | 257 | const char *file, /* Full treename of the file */ |
| 258 | | - Blob *content /* Put the content here */ |
| 258 | + Blob *content, /* Put the content here */ |
| 259 | + int errCode /* Error code if file not found. Panic if 0. */ |
| 259 | 260 | ){ |
| 260 | 261 | Blob mfile; |
| 261 | 262 | Manifest m; |
| 262 | 263 | int i, rid=0; |
| 263 | 264 | |
| | @@ -265,10 +266,11 @@ |
| 265 | 266 | rid = name_to_rid(revision); |
| 266 | 267 | }else{ |
| 267 | 268 | rid = db_lget_int("checkout", 0); |
| 268 | 269 | } |
| 269 | 270 | if( !is_a_version(rid) ){ |
| 271 | + if( errCode>0 ) return errCode; |
| 270 | 272 | fossil_fatal("no such check-out: %s", revision); |
| 271 | 273 | } |
| 272 | 274 | content_get(rid, &mfile); |
| 273 | 275 | |
| 274 | 276 | if( manifest_parse(&m, &mfile) ){ |
| | @@ -276,82 +278,76 @@ |
| 276 | 278 | if( strcmp(m.aFile[i].zName, file)==0 ){ |
| 277 | 279 | rid = uuid_to_rid(m.aFile[i].zUuid, 0); |
| 278 | 280 | return content_get(rid, content); |
| 279 | 281 | } |
| 280 | 282 | } |
| 281 | | - fossil_fatal("file %s does not exist in baseline: %s", file, revision); |
| 282 | | - }else{ |
| 283 | + if( errCode<=0 ){ |
| 284 | + fossil_fatal("file %s does not exist in baseline: %s", file, revision); |
| 285 | + } |
| 286 | + }else if( errCode<=0 ){ |
| 283 | 287 | fossil_panic("could not parse manifest for baseline: %s", revision); |
| 284 | 288 | } |
| 285 | | - return 0; |
| 289 | + return errCode; |
| 286 | 290 | } |
| 287 | 291 | |
| 288 | 292 | |
| 289 | 293 | /* |
| 290 | 294 | ** COMMAND: revert |
| 291 | 295 | ** |
| 292 | | -** Usage: %fossil revert ?--yes? ?-r REVISION? FILE ... |
| 296 | +** Usage: %fossil revert ?-r REVISION? FILE ... |
| 293 | 297 | ** |
| 294 | 298 | ** Revert to the current repository version of FILE, or to |
| 295 | 299 | ** the version associated with baseline REVISION if the -r flag |
| 296 | | -** appears. This command will confirm your operation unless the |
| 297 | | -** file is missing or the --yes option is used. |
| 298 | | -**/ |
| 300 | +** appears. |
| 301 | +** |
| 302 | +** If a file is reverted accidently, it can be restored using |
| 303 | +** the "fossil undo" command. |
| 304 | +*/ |
| 299 | 305 | void revert_cmd(void){ |
| 300 | 306 | char *zFile; |
| 301 | 307 | const char *zRevision; |
| 302 | 308 | Blob fname; |
| 303 | 309 | Blob record; |
| 304 | | - Blob ans; |
| 305 | 310 | int i; |
| 311 | + int errCode; |
| 306 | 312 | int rid = 0; |
| 307 | | - int yesFlag; |
| 308 | | - int yesRevert; |
| 309 | 313 | |
| 310 | | - yesFlag = find_option("yes", "y", 0)!=0; |
| 311 | 314 | zRevision = find_option("revision", "r", 1); |
| 312 | 315 | verify_all_options(); |
| 313 | 316 | |
| 314 | 317 | if( g.argc<3 ){ |
| 315 | | - usage("?OPTIONS FILE ..."); |
| 318 | + usage("?OPTIONS? FILE ..."); |
| 316 | 319 | } |
| 317 | 320 | db_must_be_within_tree(); |
| 321 | + db_begin_transaction(); |
| 322 | + undo_begin(); |
| 318 | 323 | |
| 319 | 324 | for(i=2; i<g.argc; i++){ |
| 320 | 325 | zFile = mprintf("%/", g.argv[i]); |
| 321 | 326 | file_tree_name(zFile, &fname, 1); |
| 322 | | - yesRevert = yesFlag; |
| 323 | | - if( !yesRevert && access(zFile, 0) ) yesRevert = 1; |
| 324 | | - if( yesRevert==0 ){ |
| 325 | | - char *prompt = mprintf("revert file %B? this will" |
| 326 | | - " destroy local changes (y/N)? ", |
| 327 | | - &fname); |
| 328 | | - blob_zero(&ans); |
| 329 | | - prompt_user(prompt, &ans); |
| 330 | | - free( prompt ); |
| 331 | | - if( blob_str(&ans)[0]=='y' ){ |
| 332 | | - yesRevert = 1; |
| 333 | | - } |
| 334 | | - blob_reset(&ans); |
| 335 | | - } |
| 336 | | - |
| 337 | | - if( yesRevert==1 && zRevision!=0 ){ |
| 338 | | - historical_version_of_file(zRevision, zFile, &record); |
| 339 | | - }else if( yesRevert==1 ){ |
| 340 | | - rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname); |
| 341 | | - if( rid==0 ){ |
| 342 | | - fossil_panic("no history for file: %b", &fname); |
| 343 | | - } |
| 344 | | - content_get(rid, &record); |
| 345 | | - } |
| 346 | | - |
| 347 | | - if( yesRevert==1 ){ |
| 348 | | - blob_write_to_file(&record, zFile); |
| 349 | | - printf("%s reverted\n", zFile); |
| 350 | | - blob_reset(&record); |
| 351 | | - blob_reset(&fname); |
| 352 | | - }else{ |
| 353 | | - printf("revert canceled\n"); |
| 354 | | - } |
| 355 | | - free(zFile); |
| 356 | | - } |
| 327 | + |
| 328 | + if( zRevision!=0 ){ |
| 329 | + errCode = historical_version_of_file(zRevision, blob_str(&fname), |
| 330 | + &record, 2); |
| 331 | + }else{ |
| 332 | + rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname); |
| 333 | + if( rid==0 ){ |
| 334 | + errCode = 2; |
| 335 | + }else{ |
| 336 | + content_get(rid, &record); |
| 337 | + errCode = 0; |
| 338 | + } |
| 339 | + } |
| 340 | + |
| 341 | + if( errCode==2 ){ |
| 342 | + fossil_warning("file not in repository: %s", zFile); |
| 343 | + }else{ |
| 344 | + undo_save(blob_str(&fname)); |
| 345 | + blob_write_to_file(&record, zFile); |
| 346 | + printf("%s reverted\n", zFile); |
| 347 | + } |
| 348 | + blob_reset(&record); |
| 349 | + blob_reset(&fname); |
| 350 | + free(zFile); |
| 351 | + } |
| 352 | + db_end_transaction(0); |
| 357 | 353 | } |
| 358 | 354 | |