259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
|
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
|
/*
** Save the current content of the file zPathname so that it
** will be undoable. The name is relative to the root of the
** tree.
*/
void undo_save(const char *zPathname){
if( undo_maybe_save(zPathname, -1)!=UNDO_SAVED_OK ){
fossil_panic("failed to save undo information for path: %s",
zPathname);
}
}
/*
** Possibly save the current content of the file zPathname so
** that it will be undoable. The name is relative to the root
** of the tree. The limit argument may be used to specify the
** maximum size for the file to be saved. If the size of the
** specified file exceeds this size limit (in bytes), it will
** not be saved and an appropriate code will be returned.
**
** WARNING: Please do NOT call this function with a limit
** value less than zero, call the undo_save()
** function instead.
**
** The return value of this function will always be one of the
** following codes:
**
** UNDO_SAVED_OK: The specified file was saved succesfully.
**
** UNDO_INACTIVE: The specified file was NOT saved, because the
** "undo subsystem" is not active. This error
** may indicate that a call to undo_begin() is
** missing.
**
** UNDO_TOOBIG: The specified file was NOT saved, because it
** exceeded the specified size limit. It is
** impossible for this value to be returned if
** the specified size limit is less than zero
** (i.e. unlimited).
*/
int undo_maybe_save(const char *zPathname, i64 limit){
char *zFullname;
Blob content;
int existsFlag;
int isLink;
i64 size;
int result;
Stmt q;
if( !undoActive ) return;
if( !undoActive ) return UNDO_INACTIVE;
zFullname = mprintf("%s%s", g.zLocalRoot, zPathname);
existsFlag = file_wd_size(zFullname)>=0;
isLink = file_wd_islink(zFullname);
db_prepare(&q,
"INSERT OR IGNORE INTO"
" undo(pathname,redoflag,existsflag,isExe,isLink,content)"
" VALUES(%Q,0,%d,%d,%d,:c)",
zPathname, existsFlag, file_wd_isexe(zFullname), isLink
);
if( existsFlag ){
if( isLink ){
blob_read_link(&content, zFullname);
}else{
blob_read_from_file(&content, zFullname);
}
db_bind_blob(&q, ":c", &content);
}
size = file_wd_size(zFullname);
if( limit<0 || size<=limit ){
int existsFlag = (size>=0);
int isLink = file_wd_islink(zFullname);
Stmt q;
Blob content;
db_prepare(&q,
"INSERT OR IGNORE INTO"
" undo(pathname,redoflag,existsflag,isExe,isLink,content)"
" VALUES(%Q,0,%d,%d,%d,:c)",
zPathname, existsFlag, file_wd_isexe(zFullname), isLink
);
if( existsFlag ){
if( isLink ){
blob_read_link(&content, zFullname);
}else{
blob_read_from_file(&content, zFullname);
}
db_bind_blob(&q, ":c", &content);
}
free(zFullname);
db_step(&q);
db_finalize(&q);
if( existsFlag ){
blob_reset(&content);
}
undoNeedRollback = 1;
db_step(&q);
db_finalize(&q);
if( existsFlag ){
blob_reset(&content);
}
undoNeedRollback = 1;
result = UNDO_SAVED_OK;
}else{
result = UNDO_TOOBIG;
}
free(zFullname);
return result;
}
/*
** Make the current state of stashid undoable.
*/
void undo_save_stash(int stashid){
const char *zDb = db_name("localdb");
|