Fossil SCM
Enhance the 'undo' subsystem to prepare for an alternative implementation of being able to undo the clean command.
Commit
670da77e1abd65017bed451074a370040bc0b679
Parent
6ec714e519afb73…
1 file changed
+76
-27
+76
-27
| --- src/undo.c | ||
| +++ src/undo.c | ||
| @@ -18,11 +18,18 @@ | ||
| 18 | 18 | ** This file implements the undo/redo functionality. |
| 19 | 19 | */ |
| 20 | 20 | #include "config.h" |
| 21 | 21 | #include "undo.h" |
| 22 | 22 | |
| 23 | - | |
| 23 | +#if INTERFACE | |
| 24 | +/* | |
| 25 | +** Return values from the undo_maybe_save() routine. | |
| 26 | +*/ | |
| 27 | +#define UNDO_SAVED_OK (0) /* The specified file was saved succesfully. */ | |
| 28 | +#define UNDO_INACTIVE (1) /* File not saved, subsystem is not active. */ | |
| 29 | +#define UNDO_TOOBIG (2) /* File not saved, it exceeded a size limit. */ | |
| 30 | +#endif | |
| 24 | 31 | |
| 25 | 32 | /* |
| 26 | 33 | ** Undo the change to the file zPathname. zPathname is the pathname |
| 27 | 34 | ** of the file relative to the root of the repository. If redoFlag is |
| 28 | 35 | ** true the redo a change. If there is nothing to undo (or redo) then |
| @@ -261,41 +268,83 @@ | ||
| 261 | 268 | ** Save the current content of the file zPathname so that it |
| 262 | 269 | ** will be undoable. The name is relative to the root of the |
| 263 | 270 | ** tree. |
| 264 | 271 | */ |
| 265 | 272 | void undo_save(const char *zPathname){ |
| 273 | + if( undo_maybe_save(zPathname, -1)!=UNDO_SAVED_OK ){ | |
| 274 | + fossil_panic("failed to save undo information for path: %s", | |
| 275 | + zPathname); | |
| 276 | + } | |
| 277 | +} | |
| 278 | + | |
| 279 | +/* | |
| 280 | +** Possibly save the current content of the file zPathname so | |
| 281 | +** that it will be undoable. The name is relative to the root | |
| 282 | +** of the tree. The limit argument may be used to specify the | |
| 283 | +** maximum size for the file to be saved. If the size of the | |
| 284 | +** specified file exceeds this size limit (in bytes), it will | |
| 285 | +** not be saved and an appropriate code will be returned. | |
| 286 | +** | |
| 287 | +** WARNING: Please do NOT call this function with a limit | |
| 288 | +** value less than zero, call the undo_save() | |
| 289 | +** function instead. | |
| 290 | +** | |
| 291 | +** The return value of this function will always be one of the | |
| 292 | +** following codes: | |
| 293 | +** | |
| 294 | +** UNDO_SAVED_OK: The specified file was saved succesfully. | |
| 295 | +** | |
| 296 | +** UNDO_INACTIVE: The specified file was NOT saved, because the | |
| 297 | +** "undo subsystem" is not active. This error | |
| 298 | +** may indicate that a call to undo_begin() is | |
| 299 | +** missing. | |
| 300 | +** | |
| 301 | +** UNDO_TOOBIG: The specified file was NOT saved, because it | |
| 302 | +** exceeded the specified size limit. It is | |
| 303 | +** impossible for this value to be returned if | |
| 304 | +** the specified size limit is less than zero | |
| 305 | +** (i.e. unlimited). | |
| 306 | +*/ | |
| 307 | +int undo_maybe_save(const char *zPathname, i64 limit){ | |
| 266 | 308 | char *zFullname; |
| 267 | - Blob content; | |
| 268 | - int existsFlag; | |
| 269 | - int isLink; | |
| 270 | - Stmt q; | |
| 309 | + i64 size; | |
| 310 | + int result; | |
| 271 | 311 | |
| 272 | - if( !undoActive ) return; | |
| 312 | + if( !undoActive ) return UNDO_INACTIVE; | |
| 273 | 313 | zFullname = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 274 | - existsFlag = file_wd_size(zFullname)>=0; | |
| 275 | - isLink = file_wd_islink(zFullname); | |
| 276 | - db_prepare(&q, | |
| 277 | - "INSERT OR IGNORE INTO" | |
| 278 | - " undo(pathname,redoflag,existsflag,isExe,isLink,content)" | |
| 279 | - " VALUES(%Q,0,%d,%d,%d,:c)", | |
| 280 | - zPathname, existsFlag, file_wd_isexe(zFullname), isLink | |
| 281 | - ); | |
| 282 | - if( existsFlag ){ | |
| 283 | - if( isLink ){ | |
| 284 | - blob_read_link(&content, zFullname); | |
| 285 | - }else{ | |
| 286 | - blob_read_from_file(&content, zFullname); | |
| 287 | - } | |
| 288 | - db_bind_blob(&q, ":c", &content); | |
| 314 | + size = file_wd_size(zFullname); | |
| 315 | + if( limit<0 || size<=limit ){ | |
| 316 | + int existsFlag = (size>=0); | |
| 317 | + int isLink = file_wd_islink(zFullname); | |
| 318 | + Stmt q; | |
| 319 | + Blob content; | |
| 320 | + db_prepare(&q, | |
| 321 | + "INSERT OR IGNORE INTO" | |
| 322 | + " undo(pathname,redoflag,existsflag,isExe,isLink,content)" | |
| 323 | + " VALUES(%Q,0,%d,%d,%d,:c)", | |
| 324 | + zPathname, existsFlag, file_wd_isexe(zFullname), isLink | |
| 325 | + ); | |
| 326 | + if( existsFlag ){ | |
| 327 | + if( isLink ){ | |
| 328 | + blob_read_link(&content, zFullname); | |
| 329 | + }else{ | |
| 330 | + blob_read_from_file(&content, zFullname); | |
| 331 | + } | |
| 332 | + db_bind_blob(&q, ":c", &content); | |
| 333 | + } | |
| 334 | + db_step(&q); | |
| 335 | + db_finalize(&q); | |
| 336 | + if( existsFlag ){ | |
| 337 | + blob_reset(&content); | |
| 338 | + } | |
| 339 | + undoNeedRollback = 1; | |
| 340 | + result = UNDO_SAVED_OK; | |
| 341 | + }else{ | |
| 342 | + result = UNDO_TOOBIG; | |
| 289 | 343 | } |
| 290 | 344 | free(zFullname); |
| 291 | - db_step(&q); | |
| 292 | - db_finalize(&q); | |
| 293 | - if( existsFlag ){ | |
| 294 | - blob_reset(&content); | |
| 295 | - } | |
| 296 | - undoNeedRollback = 1; | |
| 345 | + return result; | |
| 297 | 346 | } |
| 298 | 347 | |
| 299 | 348 | /* |
| 300 | 349 | ** Make the current state of stashid undoable. |
| 301 | 350 | */ |
| 302 | 351 |
| --- src/undo.c | |
| +++ src/undo.c | |
| @@ -18,11 +18,18 @@ | |
| 18 | ** This file implements the undo/redo functionality. |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "undo.h" |
| 22 | |
| 23 | |
| 24 | |
| 25 | /* |
| 26 | ** Undo the change to the file zPathname. zPathname is the pathname |
| 27 | ** of the file relative to the root of the repository. If redoFlag is |
| 28 | ** true the redo a change. If there is nothing to undo (or redo) then |
| @@ -261,41 +268,83 @@ | |
| 261 | ** Save the current content of the file zPathname so that it |
| 262 | ** will be undoable. The name is relative to the root of the |
| 263 | ** tree. |
| 264 | */ |
| 265 | void undo_save(const char *zPathname){ |
| 266 | char *zFullname; |
| 267 | Blob content; |
| 268 | int existsFlag; |
| 269 | int isLink; |
| 270 | Stmt q; |
| 271 | |
| 272 | if( !undoActive ) return; |
| 273 | zFullname = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 274 | existsFlag = file_wd_size(zFullname)>=0; |
| 275 | isLink = file_wd_islink(zFullname); |
| 276 | db_prepare(&q, |
| 277 | "INSERT OR IGNORE INTO" |
| 278 | " undo(pathname,redoflag,existsflag,isExe,isLink,content)" |
| 279 | " VALUES(%Q,0,%d,%d,%d,:c)", |
| 280 | zPathname, existsFlag, file_wd_isexe(zFullname), isLink |
| 281 | ); |
| 282 | if( existsFlag ){ |
| 283 | if( isLink ){ |
| 284 | blob_read_link(&content, zFullname); |
| 285 | }else{ |
| 286 | blob_read_from_file(&content, zFullname); |
| 287 | } |
| 288 | db_bind_blob(&q, ":c", &content); |
| 289 | } |
| 290 | free(zFullname); |
| 291 | db_step(&q); |
| 292 | db_finalize(&q); |
| 293 | if( existsFlag ){ |
| 294 | blob_reset(&content); |
| 295 | } |
| 296 | undoNeedRollback = 1; |
| 297 | } |
| 298 | |
| 299 | /* |
| 300 | ** Make the current state of stashid undoable. |
| 301 | */ |
| 302 |
| --- src/undo.c | |
| +++ src/undo.c | |
| @@ -18,11 +18,18 @@ | |
| 18 | ** This file implements the undo/redo functionality. |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "undo.h" |
| 22 | |
| 23 | #if INTERFACE |
| 24 | /* |
| 25 | ** Return values from the undo_maybe_save() routine. |
| 26 | */ |
| 27 | #define UNDO_SAVED_OK (0) /* The specified file was saved succesfully. */ |
| 28 | #define UNDO_INACTIVE (1) /* File not saved, subsystem is not active. */ |
| 29 | #define UNDO_TOOBIG (2) /* File not saved, it exceeded a size limit. */ |
| 30 | #endif |
| 31 | |
| 32 | /* |
| 33 | ** Undo the change to the file zPathname. zPathname is the pathname |
| 34 | ** of the file relative to the root of the repository. If redoFlag is |
| 35 | ** true the redo a change. If there is nothing to undo (or redo) then |
| @@ -261,41 +268,83 @@ | |
| 268 | ** Save the current content of the file zPathname so that it |
| 269 | ** will be undoable. The name is relative to the root of the |
| 270 | ** tree. |
| 271 | */ |
| 272 | void undo_save(const char *zPathname){ |
| 273 | if( undo_maybe_save(zPathname, -1)!=UNDO_SAVED_OK ){ |
| 274 | fossil_panic("failed to save undo information for path: %s", |
| 275 | zPathname); |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | /* |
| 280 | ** Possibly save the current content of the file zPathname so |
| 281 | ** that it will be undoable. The name is relative to the root |
| 282 | ** of the tree. The limit argument may be used to specify the |
| 283 | ** maximum size for the file to be saved. If the size of the |
| 284 | ** specified file exceeds this size limit (in bytes), it will |
| 285 | ** not be saved and an appropriate code will be returned. |
| 286 | ** |
| 287 | ** WARNING: Please do NOT call this function with a limit |
| 288 | ** value less than zero, call the undo_save() |
| 289 | ** function instead. |
| 290 | ** |
| 291 | ** The return value of this function will always be one of the |
| 292 | ** following codes: |
| 293 | ** |
| 294 | ** UNDO_SAVED_OK: The specified file was saved succesfully. |
| 295 | ** |
| 296 | ** UNDO_INACTIVE: The specified file was NOT saved, because the |
| 297 | ** "undo subsystem" is not active. This error |
| 298 | ** may indicate that a call to undo_begin() is |
| 299 | ** missing. |
| 300 | ** |
| 301 | ** UNDO_TOOBIG: The specified file was NOT saved, because it |
| 302 | ** exceeded the specified size limit. It is |
| 303 | ** impossible for this value to be returned if |
| 304 | ** the specified size limit is less than zero |
| 305 | ** (i.e. unlimited). |
| 306 | */ |
| 307 | int undo_maybe_save(const char *zPathname, i64 limit){ |
| 308 | char *zFullname; |
| 309 | i64 size; |
| 310 | int result; |
| 311 | |
| 312 | if( !undoActive ) return UNDO_INACTIVE; |
| 313 | zFullname = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 314 | size = file_wd_size(zFullname); |
| 315 | if( limit<0 || size<=limit ){ |
| 316 | int existsFlag = (size>=0); |
| 317 | int isLink = file_wd_islink(zFullname); |
| 318 | Stmt q; |
| 319 | Blob content; |
| 320 | db_prepare(&q, |
| 321 | "INSERT OR IGNORE INTO" |
| 322 | " undo(pathname,redoflag,existsflag,isExe,isLink,content)" |
| 323 | " VALUES(%Q,0,%d,%d,%d,:c)", |
| 324 | zPathname, existsFlag, file_wd_isexe(zFullname), isLink |
| 325 | ); |
| 326 | if( existsFlag ){ |
| 327 | if( isLink ){ |
| 328 | blob_read_link(&content, zFullname); |
| 329 | }else{ |
| 330 | blob_read_from_file(&content, zFullname); |
| 331 | } |
| 332 | db_bind_blob(&q, ":c", &content); |
| 333 | } |
| 334 | db_step(&q); |
| 335 | db_finalize(&q); |
| 336 | if( existsFlag ){ |
| 337 | blob_reset(&content); |
| 338 | } |
| 339 | undoNeedRollback = 1; |
| 340 | result = UNDO_SAVED_OK; |
| 341 | }else{ |
| 342 | result = UNDO_TOOBIG; |
| 343 | } |
| 344 | free(zFullname); |
| 345 | return result; |
| 346 | } |
| 347 | |
| 348 | /* |
| 349 | ** Make the current state of stashid undoable. |
| 350 | */ |
| 351 |