Fossil SCM

Add --reset flag to add/rm/addremove commands.

stephan 2020-05-28 08:48 trunk merge
Commit e0fc98caa11249c790652758926a4bad024e8ba4914d6785d94e0412eede7701
+149 -6
--- src/add.c
+++ src/add.c
@@ -240,10 +240,101 @@
240240
}
241241
db_finalize(&loop);
242242
blob_reset(&repoName);
243243
return nAdd;
244244
}
245
+
246
+/*
247
+** Resets the ADDED/DELETED state of a checkout, such that all
248
+** newly-added (but not yet committed) files are no longer added and
249
+** newly-removed (but not yet committed) files are no longer
250
+** removed. If bIsAdd is true, it operates on the "add" state, else it
251
+** operates on the "rm" state.
252
+**
253
+** If bDryRun is true it outputs what it would have done, but does not
254
+** actually do it. In this case it rolls back the transaction it
255
+** starts (so don't start a transaction before calling this).
256
+**
257
+** If bVerbose is true it outputs the name of each reset entry.
258
+**
259
+** This is intended to be called only in the context of the
260
+** add/rm/addremove commands, after a call to verify_all_options().
261
+**
262
+** Un-added files are not modified but any un-rm'd files which are
263
+** missing from the checkout are restored from the repo. un-rm'd files
264
+** which exist in the checkout are left as-is, rather than restoring
265
+** them using vfile_to_disk(), to avoid overwriting any local changes
266
+** made to those files.
267
+*/
268
+static void addremove_reset(int bIsAdd, int bDryRun, int bVerbose){
269
+ int nReset = 0; /* # of entries which get reset */
270
+ Stmt stmt; /* vfile loop query */
271
+
272
+ db_begin_transaction();
273
+ db_prepare(&stmt, "SELECT id, pathname FROM vfile "
274
+ "WHERE %s ORDER BY pathname",
275
+ bIsAdd==0 ? "deleted<>0" : "rid=0"/*safe-for-%s*/);
276
+ while( db_step(&stmt)==SQLITE_ROW ){
277
+ /* This loop exists only so we can restore the contents of un-rm'd
278
+ ** files and support verbose mode. All manipulation of vfile's
279
+ ** contents happens after the loop. For the ADD case in non-verbose
280
+ ** mode we "could" skip this loop entirely.
281
+ */
282
+ int const id = db_column_int(&stmt, 0);
283
+ char const * zPathname = db_column_text(&stmt, 1);
284
+ Blob relName = empty_blob;
285
+ if(bIsAdd==0 || bVerbose!=0){
286
+ /* Make filename relative... */
287
+ char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
288
+ file_relative_name(zFullName, &relName, 0);
289
+ fossil_free(zFullName);
290
+ }
291
+ if(bIsAdd==0){
292
+ /* Restore contents of missing un-rm'd files. We don't do this
293
+ ** unconditionally because we might cause data loss if a file
294
+ ** is modified, rm'd, then un-rm'd.
295
+ */
296
+ ++nReset;
297
+ if(!file_isfile_or_link(blob_str(&relName))){
298
+ if(bDryRun==0){
299
+ vfile_to_disk(0, id, 0, 0);
300
+ if(bVerbose){
301
+ fossil_print("Restored missing file: %b\n", &relName);
302
+ }
303
+ }else{
304
+ fossil_print("Dry-run: not restoring missing file: %b\n", &relName);
305
+ }
306
+ }
307
+ if(bVerbose){
308
+ fossil_print("Un-removed: %b\n", &relName);
309
+ }
310
+ }else{
311
+ /* un-add... */
312
+ ++nReset;
313
+ if(bVerbose){
314
+ fossil_print("Un-added: %b\n", &relName);
315
+ }
316
+ }
317
+ blob_reset(&relName);
318
+ }
319
+ db_finalize(&stmt);
320
+ if(nReset>0){
321
+ if(bIsAdd==0){
322
+ if(bDryRun==0){
323
+ db_exec_sql("UPDATE vfile SET deleted=0 WHERE deleted<>0");
324
+ }
325
+ fossil_print("Un-removed %d file(s).\n", nReset);
326
+ }else{
327
+ if(bDryRun==0){
328
+ db_exec_sql("DELETE FROM vfile WHERE rid=0");
329
+ }
330
+ fossil_print("Un-added %d file(s).\n", nReset);
331
+ }
332
+ }
333
+ db_end_transaction(bDryRun ? 1 : 0);
334
+}
335
+
245336
246337
/*
247338
** COMMAND: add
248339
**
249340
** Usage: %fossil add ?OPTIONS? FILE1 ?FILE2 ...?
@@ -276,10 +367,19 @@
276367
** -f|--force Add files without prompting
277368
** --ignore <CSG> Ignore unmanaged files matching patterns from
278369
** the comma separated list of glob patterns.
279370
** --clean <CSG> Also ignore files matching patterns from
280371
** the comma separated list of glob patterns.
372
+** --reset Reset the ADDED state of a checkout, such
373
+** that all newly-added (but not yet committed)
374
+** files are no longer added. No flags other
375
+** than --verbose and --dry-run may be used
376
+** with --reset.
377
+**
378
+** The following options are only valid with --reset:
379
+** -v|--verbose Outputs information about each --reset file.
380
+** -n|--dry-run Display instead of run actions.
281381
**
282382
** See also: addremove, rm
283383
*/
284384
void add_cmd(void){
285385
int i; /* Loop counter */
@@ -288,10 +388,19 @@
288388
const char *zCleanFlag; /* The --clean option or clean-glob setting */
289389
const char *zIgnoreFlag; /* The --ignore option or ignore-glob setting */
290390
Glob *pIgnore, *pClean; /* Ignore everything matching the glob patterns */
291391
unsigned scanFlags = 0; /* Flags passed to vfile_scan() */
292392
int forceFlag;
393
+
394
+ if(0!=find_option("reset",0,0)){
395
+ int const verboseFlag = find_option("verbose","v",0)!=0;
396
+ int const dryRunFlag = find_option("dry-run","n",0)!=0;
397
+ db_must_be_within_tree();
398
+ verify_all_options();
399
+ addremove_reset(1, dryRunFlag, verboseFlag);
400
+ return;
401
+ }
293402
294403
zCleanFlag = find_option("clean",0,1);
295404
zIgnoreFlag = find_option("ignore",0,1);
296405
forceFlag = find_option("force","f",0)!=0;
297406
if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL;
@@ -442,22 +551,36 @@
442551
** --soft Skip removing files from the checkout.
443552
** This supersedes the --hard option.
444553
** --hard Remove files from the checkout.
445554
** --case-sensitive <BOOL> Override the case-sensitive setting.
446555
** -n|--dry-run If given, display instead of run actions.
556
+** --reset Reset the DELETED state of a checkout, such
557
+** that all newly-rm'd (but not yet committed)
558
+** files are no longer removed. No flags other
559
+** than --verbose or --dry-run may be used with
560
+** --reset.
561
+** --verbose|-v Outputs information about each --reset file.
562
+** Only usable with --reset.
447563
**
448564
** See also: addremove, add
449565
*/
450566
void delete_cmd(void){
451567
int i;
452568
int removeFiles;
453
- int dryRunFlag;
569
+ int dryRunFlag = find_option("dry-run","n",0)!=0;
454570
int softFlag;
455571
int hardFlag;
456572
Stmt loop;
457573
458
- dryRunFlag = find_option("dry-run","n",0)!=0;
574
+ if(0!=find_option("reset",0,0)){
575
+ int const verboseFlag = find_option("verbose","v",0)!=0;
576
+ db_must_be_within_tree();
577
+ verify_all_options();
578
+ addremove_reset(0, dryRunFlag, verboseFlag);
579
+ return;
580
+ }
581
+
459582
softFlag = find_option("soft",0,0)!=0;
460583
hardFlag = find_option("hard",0,0)!=0;
461584
462585
/* We should be done with options.. */
463586
verify_all_options();
@@ -623,18 +746,26 @@
623746
** --ignore <CSG> Ignore unmanaged files matching patterns from
624747
** the comma separated list of glob patterns.
625748
** --clean <CSG> Also ignore files matching patterns from
626749
** the comma separated list of glob patterns.
627750
** -n|--dry-run If given, display instead of run actions.
751
+** --reset Reset the ADDED/DELETED state of a checkout,
752
+** such that all newly-added (but not yet committed)
753
+** files are no longer added and all newly-removed
754
+** (but not yet committed) files are no longer
755
+** removed. No flags other than --verbose and
756
+** --dry-run may be used with --reset.
757
+** --verbose|-v Outputs information about each --reset file.
758
+** Only usable with --reset.
628759
**
629760
** See also: add, rm
630761
*/
631762
void addremove_cmd(void){
632763
Blob path;
633
- const char *zCleanFlag = find_option("clean",0,1);
634
- const char *zIgnoreFlag = find_option("ignore",0,1);
635
- unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
764
+ const char *zCleanFlag;
765
+ const char *zIgnoreFlag;
766
+ unsigned scanFlags;
636767
int dryRunFlag = find_option("dry-run","n",0)!=0;
637768
int n;
638769
Stmt q;
639770
int vid;
640771
int nAdd = 0;
@@ -643,10 +774,23 @@
643774
644775
if( !dryRunFlag ){
645776
dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
646777
}
647778
779
+ if(0!=find_option("reset",0,0)){
780
+ int const verboseFlag = find_option("verbose","v",0)!=0;
781
+ db_must_be_within_tree();
782
+ verify_all_options();
783
+ addremove_reset(0, dryRunFlag, verboseFlag);
784
+ addremove_reset(1, dryRunFlag, verboseFlag);
785
+ return;
786
+ }
787
+
788
+ zCleanFlag = find_option("clean",0,1);
789
+ zIgnoreFlag = find_option("ignore",0,1);
790
+ scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
791
+
648792
/* We should be done with options.. */
649793
verify_all_options();
650794
651795
/* Fail if unprocessed arguments are present, in case user expect the
652796
** addremove command to accept a list of file or directory.
@@ -710,11 +854,10 @@
710854
/* show command summary */
711855
fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);
712856
713857
db_end_transaction(dryRunFlag);
714858
}
715
-
716859
717860
/*
718861
** Rename a single file.
719862
**
720863
** The original name of the file is zOrig. The new filename is zNew.
721864
--- src/add.c
+++ src/add.c
@@ -240,10 +240,101 @@
240 }
241 db_finalize(&loop);
242 blob_reset(&repoName);
243 return nAdd;
244 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
246 /*
247 ** COMMAND: add
248 **
249 ** Usage: %fossil add ?OPTIONS? FILE1 ?FILE2 ...?
@@ -276,10 +367,19 @@
276 ** -f|--force Add files without prompting
277 ** --ignore <CSG> Ignore unmanaged files matching patterns from
278 ** the comma separated list of glob patterns.
279 ** --clean <CSG> Also ignore files matching patterns from
280 ** the comma separated list of glob patterns.
 
 
 
 
 
 
 
 
 
281 **
282 ** See also: addremove, rm
283 */
284 void add_cmd(void){
285 int i; /* Loop counter */
@@ -288,10 +388,19 @@
288 const char *zCleanFlag; /* The --clean option or clean-glob setting */
289 const char *zIgnoreFlag; /* The --ignore option or ignore-glob setting */
290 Glob *pIgnore, *pClean; /* Ignore everything matching the glob patterns */
291 unsigned scanFlags = 0; /* Flags passed to vfile_scan() */
292 int forceFlag;
 
 
 
 
 
 
 
 
 
293
294 zCleanFlag = find_option("clean",0,1);
295 zIgnoreFlag = find_option("ignore",0,1);
296 forceFlag = find_option("force","f",0)!=0;
297 if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL;
@@ -442,22 +551,36 @@
442 ** --soft Skip removing files from the checkout.
443 ** This supersedes the --hard option.
444 ** --hard Remove files from the checkout.
445 ** --case-sensitive <BOOL> Override the case-sensitive setting.
446 ** -n|--dry-run If given, display instead of run actions.
 
 
 
 
 
 
 
447 **
448 ** See also: addremove, add
449 */
450 void delete_cmd(void){
451 int i;
452 int removeFiles;
453 int dryRunFlag;
454 int softFlag;
455 int hardFlag;
456 Stmt loop;
457
458 dryRunFlag = find_option("dry-run","n",0)!=0;
 
 
 
 
 
 
 
459 softFlag = find_option("soft",0,0)!=0;
460 hardFlag = find_option("hard",0,0)!=0;
461
462 /* We should be done with options.. */
463 verify_all_options();
@@ -623,18 +746,26 @@
623 ** --ignore <CSG> Ignore unmanaged files matching patterns from
624 ** the comma separated list of glob patterns.
625 ** --clean <CSG> Also ignore files matching patterns from
626 ** the comma separated list of glob patterns.
627 ** -n|--dry-run If given, display instead of run actions.
 
 
 
 
 
 
 
 
628 **
629 ** See also: add, rm
630 */
631 void addremove_cmd(void){
632 Blob path;
633 const char *zCleanFlag = find_option("clean",0,1);
634 const char *zIgnoreFlag = find_option("ignore",0,1);
635 unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
636 int dryRunFlag = find_option("dry-run","n",0)!=0;
637 int n;
638 Stmt q;
639 int vid;
640 int nAdd = 0;
@@ -643,10 +774,23 @@
643
644 if( !dryRunFlag ){
645 dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
646 }
647
 
 
 
 
 
 
 
 
 
 
 
 
 
648 /* We should be done with options.. */
649 verify_all_options();
650
651 /* Fail if unprocessed arguments are present, in case user expect the
652 ** addremove command to accept a list of file or directory.
@@ -710,11 +854,10 @@
710 /* show command summary */
711 fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);
712
713 db_end_transaction(dryRunFlag);
714 }
715
716
717 /*
718 ** Rename a single file.
719 **
720 ** The original name of the file is zOrig. The new filename is zNew.
721
--- src/add.c
+++ src/add.c
@@ -240,10 +240,101 @@
240 }
241 db_finalize(&loop);
242 blob_reset(&repoName);
243 return nAdd;
244 }
245
246 /*
247 ** Resets the ADDED/DELETED state of a checkout, such that all
248 ** newly-added (but not yet committed) files are no longer added and
249 ** newly-removed (but not yet committed) files are no longer
250 ** removed. If bIsAdd is true, it operates on the "add" state, else it
251 ** operates on the "rm" state.
252 **
253 ** If bDryRun is true it outputs what it would have done, but does not
254 ** actually do it. In this case it rolls back the transaction it
255 ** starts (so don't start a transaction before calling this).
256 **
257 ** If bVerbose is true it outputs the name of each reset entry.
258 **
259 ** This is intended to be called only in the context of the
260 ** add/rm/addremove commands, after a call to verify_all_options().
261 **
262 ** Un-added files are not modified but any un-rm'd files which are
263 ** missing from the checkout are restored from the repo. un-rm'd files
264 ** which exist in the checkout are left as-is, rather than restoring
265 ** them using vfile_to_disk(), to avoid overwriting any local changes
266 ** made to those files.
267 */
268 static void addremove_reset(int bIsAdd, int bDryRun, int bVerbose){
269 int nReset = 0; /* # of entries which get reset */
270 Stmt stmt; /* vfile loop query */
271
272 db_begin_transaction();
273 db_prepare(&stmt, "SELECT id, pathname FROM vfile "
274 "WHERE %s ORDER BY pathname",
275 bIsAdd==0 ? "deleted<>0" : "rid=0"/*safe-for-%s*/);
276 while( db_step(&stmt)==SQLITE_ROW ){
277 /* This loop exists only so we can restore the contents of un-rm'd
278 ** files and support verbose mode. All manipulation of vfile's
279 ** contents happens after the loop. For the ADD case in non-verbose
280 ** mode we "could" skip this loop entirely.
281 */
282 int const id = db_column_int(&stmt, 0);
283 char const * zPathname = db_column_text(&stmt, 1);
284 Blob relName = empty_blob;
285 if(bIsAdd==0 || bVerbose!=0){
286 /* Make filename relative... */
287 char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
288 file_relative_name(zFullName, &relName, 0);
289 fossil_free(zFullName);
290 }
291 if(bIsAdd==0){
292 /* Restore contents of missing un-rm'd files. We don't do this
293 ** unconditionally because we might cause data loss if a file
294 ** is modified, rm'd, then un-rm'd.
295 */
296 ++nReset;
297 if(!file_isfile_or_link(blob_str(&relName))){
298 if(bDryRun==0){
299 vfile_to_disk(0, id, 0, 0);
300 if(bVerbose){
301 fossil_print("Restored missing file: %b\n", &relName);
302 }
303 }else{
304 fossil_print("Dry-run: not restoring missing file: %b\n", &relName);
305 }
306 }
307 if(bVerbose){
308 fossil_print("Un-removed: %b\n", &relName);
309 }
310 }else{
311 /* un-add... */
312 ++nReset;
313 if(bVerbose){
314 fossil_print("Un-added: %b\n", &relName);
315 }
316 }
317 blob_reset(&relName);
318 }
319 db_finalize(&stmt);
320 if(nReset>0){
321 if(bIsAdd==0){
322 if(bDryRun==0){
323 db_exec_sql("UPDATE vfile SET deleted=0 WHERE deleted<>0");
324 }
325 fossil_print("Un-removed %d file(s).\n", nReset);
326 }else{
327 if(bDryRun==0){
328 db_exec_sql("DELETE FROM vfile WHERE rid=0");
329 }
330 fossil_print("Un-added %d file(s).\n", nReset);
331 }
332 }
333 db_end_transaction(bDryRun ? 1 : 0);
334 }
335
336
337 /*
338 ** COMMAND: add
339 **
340 ** Usage: %fossil add ?OPTIONS? FILE1 ?FILE2 ...?
@@ -276,10 +367,19 @@
367 ** -f|--force Add files without prompting
368 ** --ignore <CSG> Ignore unmanaged files matching patterns from
369 ** the comma separated list of glob patterns.
370 ** --clean <CSG> Also ignore files matching patterns from
371 ** the comma separated list of glob patterns.
372 ** --reset Reset the ADDED state of a checkout, such
373 ** that all newly-added (but not yet committed)
374 ** files are no longer added. No flags other
375 ** than --verbose and --dry-run may be used
376 ** with --reset.
377 **
378 ** The following options are only valid with --reset:
379 ** -v|--verbose Outputs information about each --reset file.
380 ** -n|--dry-run Display instead of run actions.
381 **
382 ** See also: addremove, rm
383 */
384 void add_cmd(void){
385 int i; /* Loop counter */
@@ -288,10 +388,19 @@
388 const char *zCleanFlag; /* The --clean option or clean-glob setting */
389 const char *zIgnoreFlag; /* The --ignore option or ignore-glob setting */
390 Glob *pIgnore, *pClean; /* Ignore everything matching the glob patterns */
391 unsigned scanFlags = 0; /* Flags passed to vfile_scan() */
392 int forceFlag;
393
394 if(0!=find_option("reset",0,0)){
395 int const verboseFlag = find_option("verbose","v",0)!=0;
396 int const dryRunFlag = find_option("dry-run","n",0)!=0;
397 db_must_be_within_tree();
398 verify_all_options();
399 addremove_reset(1, dryRunFlag, verboseFlag);
400 return;
401 }
402
403 zCleanFlag = find_option("clean",0,1);
404 zIgnoreFlag = find_option("ignore",0,1);
405 forceFlag = find_option("force","f",0)!=0;
406 if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL;
@@ -442,22 +551,36 @@
551 ** --soft Skip removing files from the checkout.
552 ** This supersedes the --hard option.
553 ** --hard Remove files from the checkout.
554 ** --case-sensitive <BOOL> Override the case-sensitive setting.
555 ** -n|--dry-run If given, display instead of run actions.
556 ** --reset Reset the DELETED state of a checkout, such
557 ** that all newly-rm'd (but not yet committed)
558 ** files are no longer removed. No flags other
559 ** than --verbose or --dry-run may be used with
560 ** --reset.
561 ** --verbose|-v Outputs information about each --reset file.
562 ** Only usable with --reset.
563 **
564 ** See also: addremove, add
565 */
566 void delete_cmd(void){
567 int i;
568 int removeFiles;
569 int dryRunFlag = find_option("dry-run","n",0)!=0;
570 int softFlag;
571 int hardFlag;
572 Stmt loop;
573
574 if(0!=find_option("reset",0,0)){
575 int const verboseFlag = find_option("verbose","v",0)!=0;
576 db_must_be_within_tree();
577 verify_all_options();
578 addremove_reset(0, dryRunFlag, verboseFlag);
579 return;
580 }
581
582 softFlag = find_option("soft",0,0)!=0;
583 hardFlag = find_option("hard",0,0)!=0;
584
585 /* We should be done with options.. */
586 verify_all_options();
@@ -623,18 +746,26 @@
746 ** --ignore <CSG> Ignore unmanaged files matching patterns from
747 ** the comma separated list of glob patterns.
748 ** --clean <CSG> Also ignore files matching patterns from
749 ** the comma separated list of glob patterns.
750 ** -n|--dry-run If given, display instead of run actions.
751 ** --reset Reset the ADDED/DELETED state of a checkout,
752 ** such that all newly-added (but not yet committed)
753 ** files are no longer added and all newly-removed
754 ** (but not yet committed) files are no longer
755 ** removed. No flags other than --verbose and
756 ** --dry-run may be used with --reset.
757 ** --verbose|-v Outputs information about each --reset file.
758 ** Only usable with --reset.
759 **
760 ** See also: add, rm
761 */
762 void addremove_cmd(void){
763 Blob path;
764 const char *zCleanFlag;
765 const char *zIgnoreFlag;
766 unsigned scanFlags;
767 int dryRunFlag = find_option("dry-run","n",0)!=0;
768 int n;
769 Stmt q;
770 int vid;
771 int nAdd = 0;
@@ -643,10 +774,23 @@
774
775 if( !dryRunFlag ){
776 dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
777 }
778
779 if(0!=find_option("reset",0,0)){
780 int const verboseFlag = find_option("verbose","v",0)!=0;
781 db_must_be_within_tree();
782 verify_all_options();
783 addremove_reset(0, dryRunFlag, verboseFlag);
784 addremove_reset(1, dryRunFlag, verboseFlag);
785 return;
786 }
787
788 zCleanFlag = find_option("clean",0,1);
789 zIgnoreFlag = find_option("ignore",0,1);
790 scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
791
792 /* We should be done with options.. */
793 verify_all_options();
794
795 /* Fail if unprocessed arguments are present, in case user expect the
796 ** addremove command to accept a list of file or directory.
@@ -710,11 +854,10 @@
854 /* show command summary */
855 fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);
856
857 db_end_transaction(dryRunFlag);
858 }
 
859
860 /*
861 ** Rename a single file.
862 **
863 ** The original name of the file is zOrig. The new filename is zNew.
864
+149 -6
--- src/add.c
+++ src/add.c
@@ -240,10 +240,101 @@
240240
}
241241
db_finalize(&loop);
242242
blob_reset(&repoName);
243243
return nAdd;
244244
}
245
+
246
+/*
247
+** Resets the ADDED/DELETED state of a checkout, such that all
248
+** newly-added (but not yet committed) files are no longer added and
249
+** newly-removed (but not yet committed) files are no longer
250
+** removed. If bIsAdd is true, it operates on the "add" state, else it
251
+** operates on the "rm" state.
252
+**
253
+** If bDryRun is true it outputs what it would have done, but does not
254
+** actually do it. In this case it rolls back the transaction it
255
+** starts (so don't start a transaction before calling this).
256
+**
257
+** If bVerbose is true it outputs the name of each reset entry.
258
+**
259
+** This is intended to be called only in the context of the
260
+** add/rm/addremove commands, after a call to verify_all_options().
261
+**
262
+** Un-added files are not modified but any un-rm'd files which are
263
+** missing from the checkout are restored from the repo. un-rm'd files
264
+** which exist in the checkout are left as-is, rather than restoring
265
+** them using vfile_to_disk(), to avoid overwriting any local changes
266
+** made to those files.
267
+*/
268
+static void addremove_reset(int bIsAdd, int bDryRun, int bVerbose){
269
+ int nReset = 0; /* # of entries which get reset */
270
+ Stmt stmt; /* vfile loop query */
271
+
272
+ db_begin_transaction();
273
+ db_prepare(&stmt, "SELECT id, pathname FROM vfile "
274
+ "WHERE %s ORDER BY pathname",
275
+ bIsAdd==0 ? "deleted<>0" : "rid=0"/*safe-for-%s*/);
276
+ while( db_step(&stmt)==SQLITE_ROW ){
277
+ /* This loop exists only so we can restore the contents of un-rm'd
278
+ ** files and support verbose mode. All manipulation of vfile's
279
+ ** contents happens after the loop. For the ADD case in non-verbose
280
+ ** mode we "could" skip this loop entirely.
281
+ */
282
+ int const id = db_column_int(&stmt, 0);
283
+ char const * zPathname = db_column_text(&stmt, 1);
284
+ Blob relName = empty_blob;
285
+ if(bIsAdd==0 || bVerbose!=0){
286
+ /* Make filename relative... */
287
+ char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
288
+ file_relative_name(zFullName, &relName, 0);
289
+ fossil_free(zFullName);
290
+ }
291
+ if(bIsAdd==0){
292
+ /* Restore contents of missing un-rm'd files. We don't do this
293
+ ** unconditionally because we might cause data loss if a file
294
+ ** is modified, rm'd, then un-rm'd.
295
+ */
296
+ ++nReset;
297
+ if(!file_isfile_or_link(blob_str(&relName))){
298
+ if(bDryRun==0){
299
+ vfile_to_disk(0, id, 0, 0);
300
+ if(bVerbose){
301
+ fossil_print("Restored missing file: %b\n", &relName);
302
+ }
303
+ }else{
304
+ fossil_print("Dry-run: not restoring missing file: %b\n", &relName);
305
+ }
306
+ }
307
+ if(bVerbose){
308
+ fossil_print("Un-removed: %b\n", &relName);
309
+ }
310
+ }else{
311
+ /* un-add... */
312
+ ++nReset;
313
+ if(bVerbose){
314
+ fossil_print("Un-added: %b\n", &relName);
315
+ }
316
+ }
317
+ blob_reset(&relName);
318
+ }
319
+ db_finalize(&stmt);
320
+ if(nReset>0){
321
+ if(bIsAdd==0){
322
+ if(bDryRun==0){
323
+ db_exec_sql("UPDATE vfile SET deleted=0 WHERE deleted<>0");
324
+ }
325
+ fossil_print("Un-removed %d file(s).\n", nReset);
326
+ }else{
327
+ if(bDryRun==0){
328
+ db_exec_sql("DELETE FROM vfile WHERE rid=0");
329
+ }
330
+ fossil_print("Un-added %d file(s).\n", nReset);
331
+ }
332
+ }
333
+ db_end_transaction(bDryRun ? 1 : 0);
334
+}
335
+
245336
246337
/*
247338
** COMMAND: add
248339
**
249340
** Usage: %fossil add ?OPTIONS? FILE1 ?FILE2 ...?
@@ -276,10 +367,19 @@
276367
** -f|--force Add files without prompting
277368
** --ignore <CSG> Ignore unmanaged files matching patterns from
278369
** the comma separated list of glob patterns.
279370
** --clean <CSG> Also ignore files matching patterns from
280371
** the comma separated list of glob patterns.
372
+** --reset Reset the ADDED state of a checkout, such
373
+** that all newly-added (but not yet committed)
374
+** files are no longer added. No flags other
375
+** than --verbose and --dry-run may be used
376
+** with --reset.
377
+**
378
+** The following options are only valid with --reset:
379
+** -v|--verbose Outputs information about each --reset file.
380
+** -n|--dry-run Display instead of run actions.
281381
**
282382
** See also: addremove, rm
283383
*/
284384
void add_cmd(void){
285385
int i; /* Loop counter */
@@ -288,10 +388,19 @@
288388
const char *zCleanFlag; /* The --clean option or clean-glob setting */
289389
const char *zIgnoreFlag; /* The --ignore option or ignore-glob setting */
290390
Glob *pIgnore, *pClean; /* Ignore everything matching the glob patterns */
291391
unsigned scanFlags = 0; /* Flags passed to vfile_scan() */
292392
int forceFlag;
393
+
394
+ if(0!=find_option("reset",0,0)){
395
+ int const verboseFlag = find_option("verbose","v",0)!=0;
396
+ int const dryRunFlag = find_option("dry-run","n",0)!=0;
397
+ db_must_be_within_tree();
398
+ verify_all_options();
399
+ addremove_reset(1, dryRunFlag, verboseFlag);
400
+ return;
401
+ }
293402
294403
zCleanFlag = find_option("clean",0,1);
295404
zIgnoreFlag = find_option("ignore",0,1);
296405
forceFlag = find_option("force","f",0)!=0;
297406
if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL;
@@ -442,22 +551,36 @@
442551
** --soft Skip removing files from the checkout.
443552
** This supersedes the --hard option.
444553
** --hard Remove files from the checkout.
445554
** --case-sensitive <BOOL> Override the case-sensitive setting.
446555
** -n|--dry-run If given, display instead of run actions.
556
+** --reset Reset the DELETED state of a checkout, such
557
+** that all newly-rm'd (but not yet committed)
558
+** files are no longer removed. No flags other
559
+** than --verbose or --dry-run may be used with
560
+** --reset.
561
+** --verbose|-v Outputs information about each --reset file.
562
+** Only usable with --reset.
447563
**
448564
** See also: addremove, add
449565
*/
450566
void delete_cmd(void){
451567
int i;
452568
int removeFiles;
453
- int dryRunFlag;
569
+ int dryRunFlag = find_option("dry-run","n",0)!=0;
454570
int softFlag;
455571
int hardFlag;
456572
Stmt loop;
457573
458
- dryRunFlag = find_option("dry-run","n",0)!=0;
574
+ if(0!=find_option("reset",0,0)){
575
+ int const verboseFlag = find_option("verbose","v",0)!=0;
576
+ db_must_be_within_tree();
577
+ verify_all_options();
578
+ addremove_reset(0, dryRunFlag, verboseFlag);
579
+ return;
580
+ }
581
+
459582
softFlag = find_option("soft",0,0)!=0;
460583
hardFlag = find_option("hard",0,0)!=0;
461584
462585
/* We should be done with options.. */
463586
verify_all_options();
@@ -623,18 +746,26 @@
623746
** --ignore <CSG> Ignore unmanaged files matching patterns from
624747
** the comma separated list of glob patterns.
625748
** --clean <CSG> Also ignore files matching patterns from
626749
** the comma separated list of glob patterns.
627750
** -n|--dry-run If given, display instead of run actions.
751
+** --reset Reset the ADDED/DELETED state of a checkout,
752
+** such that all newly-added (but not yet committed)
753
+** files are no longer added and all newly-removed
754
+** (but not yet committed) files are no longer
755
+** removed. No flags other than --verbose and
756
+** --dry-run may be used with --reset.
757
+** --verbose|-v Outputs information about each --reset file.
758
+** Only usable with --reset.
628759
**
629760
** See also: add, rm
630761
*/
631762
void addremove_cmd(void){
632763
Blob path;
633
- const char *zCleanFlag = find_option("clean",0,1);
634
- const char *zIgnoreFlag = find_option("ignore",0,1);
635
- unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
764
+ const char *zCleanFlag;
765
+ const char *zIgnoreFlag;
766
+ unsigned scanFlags;
636767
int dryRunFlag = find_option("dry-run","n",0)!=0;
637768
int n;
638769
Stmt q;
639770
int vid;
640771
int nAdd = 0;
@@ -643,10 +774,23 @@
643774
644775
if( !dryRunFlag ){
645776
dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
646777
}
647778
779
+ if(0!=find_option("reset",0,0)){
780
+ int const verboseFlag = find_option("verbose","v",0)!=0;
781
+ db_must_be_within_tree();
782
+ verify_all_options();
783
+ addremove_reset(0, dryRunFlag, verboseFlag);
784
+ addremove_reset(1, dryRunFlag, verboseFlag);
785
+ return;
786
+ }
787
+
788
+ zCleanFlag = find_option("clean",0,1);
789
+ zIgnoreFlag = find_option("ignore",0,1);
790
+ scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
791
+
648792
/* We should be done with options.. */
649793
verify_all_options();
650794
651795
/* Fail if unprocessed arguments are present, in case user expect the
652796
** addremove command to accept a list of file or directory.
@@ -710,11 +854,10 @@
710854
/* show command summary */
711855
fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);
712856
713857
db_end_transaction(dryRunFlag);
714858
}
715
-
716859
717860
/*
718861
** Rename a single file.
719862
**
720863
** The original name of the file is zOrig. The new filename is zNew.
721864
--- src/add.c
+++ src/add.c
@@ -240,10 +240,101 @@
240 }
241 db_finalize(&loop);
242 blob_reset(&repoName);
243 return nAdd;
244 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
246 /*
247 ** COMMAND: add
248 **
249 ** Usage: %fossil add ?OPTIONS? FILE1 ?FILE2 ...?
@@ -276,10 +367,19 @@
276 ** -f|--force Add files without prompting
277 ** --ignore <CSG> Ignore unmanaged files matching patterns from
278 ** the comma separated list of glob patterns.
279 ** --clean <CSG> Also ignore files matching patterns from
280 ** the comma separated list of glob patterns.
 
 
 
 
 
 
 
 
 
281 **
282 ** See also: addremove, rm
283 */
284 void add_cmd(void){
285 int i; /* Loop counter */
@@ -288,10 +388,19 @@
288 const char *zCleanFlag; /* The --clean option or clean-glob setting */
289 const char *zIgnoreFlag; /* The --ignore option or ignore-glob setting */
290 Glob *pIgnore, *pClean; /* Ignore everything matching the glob patterns */
291 unsigned scanFlags = 0; /* Flags passed to vfile_scan() */
292 int forceFlag;
 
 
 
 
 
 
 
 
 
293
294 zCleanFlag = find_option("clean",0,1);
295 zIgnoreFlag = find_option("ignore",0,1);
296 forceFlag = find_option("force","f",0)!=0;
297 if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL;
@@ -442,22 +551,36 @@
442 ** --soft Skip removing files from the checkout.
443 ** This supersedes the --hard option.
444 ** --hard Remove files from the checkout.
445 ** --case-sensitive <BOOL> Override the case-sensitive setting.
446 ** -n|--dry-run If given, display instead of run actions.
 
 
 
 
 
 
 
447 **
448 ** See also: addremove, add
449 */
450 void delete_cmd(void){
451 int i;
452 int removeFiles;
453 int dryRunFlag;
454 int softFlag;
455 int hardFlag;
456 Stmt loop;
457
458 dryRunFlag = find_option("dry-run","n",0)!=0;
 
 
 
 
 
 
 
459 softFlag = find_option("soft",0,0)!=0;
460 hardFlag = find_option("hard",0,0)!=0;
461
462 /* We should be done with options.. */
463 verify_all_options();
@@ -623,18 +746,26 @@
623 ** --ignore <CSG> Ignore unmanaged files matching patterns from
624 ** the comma separated list of glob patterns.
625 ** --clean <CSG> Also ignore files matching patterns from
626 ** the comma separated list of glob patterns.
627 ** -n|--dry-run If given, display instead of run actions.
 
 
 
 
 
 
 
 
628 **
629 ** See also: add, rm
630 */
631 void addremove_cmd(void){
632 Blob path;
633 const char *zCleanFlag = find_option("clean",0,1);
634 const char *zIgnoreFlag = find_option("ignore",0,1);
635 unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
636 int dryRunFlag = find_option("dry-run","n",0)!=0;
637 int n;
638 Stmt q;
639 int vid;
640 int nAdd = 0;
@@ -643,10 +774,23 @@
643
644 if( !dryRunFlag ){
645 dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
646 }
647
 
 
 
 
 
 
 
 
 
 
 
 
 
648 /* We should be done with options.. */
649 verify_all_options();
650
651 /* Fail if unprocessed arguments are present, in case user expect the
652 ** addremove command to accept a list of file or directory.
@@ -710,11 +854,10 @@
710 /* show command summary */
711 fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);
712
713 db_end_transaction(dryRunFlag);
714 }
715
716
717 /*
718 ** Rename a single file.
719 **
720 ** The original name of the file is zOrig. The new filename is zNew.
721
--- src/add.c
+++ src/add.c
@@ -240,10 +240,101 @@
240 }
241 db_finalize(&loop);
242 blob_reset(&repoName);
243 return nAdd;
244 }
245
246 /*
247 ** Resets the ADDED/DELETED state of a checkout, such that all
248 ** newly-added (but not yet committed) files are no longer added and
249 ** newly-removed (but not yet committed) files are no longer
250 ** removed. If bIsAdd is true, it operates on the "add" state, else it
251 ** operates on the "rm" state.
252 **
253 ** If bDryRun is true it outputs what it would have done, but does not
254 ** actually do it. In this case it rolls back the transaction it
255 ** starts (so don't start a transaction before calling this).
256 **
257 ** If bVerbose is true it outputs the name of each reset entry.
258 **
259 ** This is intended to be called only in the context of the
260 ** add/rm/addremove commands, after a call to verify_all_options().
261 **
262 ** Un-added files are not modified but any un-rm'd files which are
263 ** missing from the checkout are restored from the repo. un-rm'd files
264 ** which exist in the checkout are left as-is, rather than restoring
265 ** them using vfile_to_disk(), to avoid overwriting any local changes
266 ** made to those files.
267 */
268 static void addremove_reset(int bIsAdd, int bDryRun, int bVerbose){
269 int nReset = 0; /* # of entries which get reset */
270 Stmt stmt; /* vfile loop query */
271
272 db_begin_transaction();
273 db_prepare(&stmt, "SELECT id, pathname FROM vfile "
274 "WHERE %s ORDER BY pathname",
275 bIsAdd==0 ? "deleted<>0" : "rid=0"/*safe-for-%s*/);
276 while( db_step(&stmt)==SQLITE_ROW ){
277 /* This loop exists only so we can restore the contents of un-rm'd
278 ** files and support verbose mode. All manipulation of vfile's
279 ** contents happens after the loop. For the ADD case in non-verbose
280 ** mode we "could" skip this loop entirely.
281 */
282 int const id = db_column_int(&stmt, 0);
283 char const * zPathname = db_column_text(&stmt, 1);
284 Blob relName = empty_blob;
285 if(bIsAdd==0 || bVerbose!=0){
286 /* Make filename relative... */
287 char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
288 file_relative_name(zFullName, &relName, 0);
289 fossil_free(zFullName);
290 }
291 if(bIsAdd==0){
292 /* Restore contents of missing un-rm'd files. We don't do this
293 ** unconditionally because we might cause data loss if a file
294 ** is modified, rm'd, then un-rm'd.
295 */
296 ++nReset;
297 if(!file_isfile_or_link(blob_str(&relName))){
298 if(bDryRun==0){
299 vfile_to_disk(0, id, 0, 0);
300 if(bVerbose){
301 fossil_print("Restored missing file: %b\n", &relName);
302 }
303 }else{
304 fossil_print("Dry-run: not restoring missing file: %b\n", &relName);
305 }
306 }
307 if(bVerbose){
308 fossil_print("Un-removed: %b\n", &relName);
309 }
310 }else{
311 /* un-add... */
312 ++nReset;
313 if(bVerbose){
314 fossil_print("Un-added: %b\n", &relName);
315 }
316 }
317 blob_reset(&relName);
318 }
319 db_finalize(&stmt);
320 if(nReset>0){
321 if(bIsAdd==0){
322 if(bDryRun==0){
323 db_exec_sql("UPDATE vfile SET deleted=0 WHERE deleted<>0");
324 }
325 fossil_print("Un-removed %d file(s).\n", nReset);
326 }else{
327 if(bDryRun==0){
328 db_exec_sql("DELETE FROM vfile WHERE rid=0");
329 }
330 fossil_print("Un-added %d file(s).\n", nReset);
331 }
332 }
333 db_end_transaction(bDryRun ? 1 : 0);
334 }
335
336
337 /*
338 ** COMMAND: add
339 **
340 ** Usage: %fossil add ?OPTIONS? FILE1 ?FILE2 ...?
@@ -276,10 +367,19 @@
367 ** -f|--force Add files without prompting
368 ** --ignore <CSG> Ignore unmanaged files matching patterns from
369 ** the comma separated list of glob patterns.
370 ** --clean <CSG> Also ignore files matching patterns from
371 ** the comma separated list of glob patterns.
372 ** --reset Reset the ADDED state of a checkout, such
373 ** that all newly-added (but not yet committed)
374 ** files are no longer added. No flags other
375 ** than --verbose and --dry-run may be used
376 ** with --reset.
377 **
378 ** The following options are only valid with --reset:
379 ** -v|--verbose Outputs information about each --reset file.
380 ** -n|--dry-run Display instead of run actions.
381 **
382 ** See also: addremove, rm
383 */
384 void add_cmd(void){
385 int i; /* Loop counter */
@@ -288,10 +388,19 @@
388 const char *zCleanFlag; /* The --clean option or clean-glob setting */
389 const char *zIgnoreFlag; /* The --ignore option or ignore-glob setting */
390 Glob *pIgnore, *pClean; /* Ignore everything matching the glob patterns */
391 unsigned scanFlags = 0; /* Flags passed to vfile_scan() */
392 int forceFlag;
393
394 if(0!=find_option("reset",0,0)){
395 int const verboseFlag = find_option("verbose","v",0)!=0;
396 int const dryRunFlag = find_option("dry-run","n",0)!=0;
397 db_must_be_within_tree();
398 verify_all_options();
399 addremove_reset(1, dryRunFlag, verboseFlag);
400 return;
401 }
402
403 zCleanFlag = find_option("clean",0,1);
404 zIgnoreFlag = find_option("ignore",0,1);
405 forceFlag = find_option("force","f",0)!=0;
406 if( find_option("dotfiles",0,0)!=0 ) scanFlags |= SCAN_ALL;
@@ -442,22 +551,36 @@
551 ** --soft Skip removing files from the checkout.
552 ** This supersedes the --hard option.
553 ** --hard Remove files from the checkout.
554 ** --case-sensitive <BOOL> Override the case-sensitive setting.
555 ** -n|--dry-run If given, display instead of run actions.
556 ** --reset Reset the DELETED state of a checkout, such
557 ** that all newly-rm'd (but not yet committed)
558 ** files are no longer removed. No flags other
559 ** than --verbose or --dry-run may be used with
560 ** --reset.
561 ** --verbose|-v Outputs information about each --reset file.
562 ** Only usable with --reset.
563 **
564 ** See also: addremove, add
565 */
566 void delete_cmd(void){
567 int i;
568 int removeFiles;
569 int dryRunFlag = find_option("dry-run","n",0)!=0;
570 int softFlag;
571 int hardFlag;
572 Stmt loop;
573
574 if(0!=find_option("reset",0,0)){
575 int const verboseFlag = find_option("verbose","v",0)!=0;
576 db_must_be_within_tree();
577 verify_all_options();
578 addremove_reset(0, dryRunFlag, verboseFlag);
579 return;
580 }
581
582 softFlag = find_option("soft",0,0)!=0;
583 hardFlag = find_option("hard",0,0)!=0;
584
585 /* We should be done with options.. */
586 verify_all_options();
@@ -623,18 +746,26 @@
746 ** --ignore <CSG> Ignore unmanaged files matching patterns from
747 ** the comma separated list of glob patterns.
748 ** --clean <CSG> Also ignore files matching patterns from
749 ** the comma separated list of glob patterns.
750 ** -n|--dry-run If given, display instead of run actions.
751 ** --reset Reset the ADDED/DELETED state of a checkout,
752 ** such that all newly-added (but not yet committed)
753 ** files are no longer added and all newly-removed
754 ** (but not yet committed) files are no longer
755 ** removed. No flags other than --verbose and
756 ** --dry-run may be used with --reset.
757 ** --verbose|-v Outputs information about each --reset file.
758 ** Only usable with --reset.
759 **
760 ** See also: add, rm
761 */
762 void addremove_cmd(void){
763 Blob path;
764 const char *zCleanFlag;
765 const char *zIgnoreFlag;
766 unsigned scanFlags;
767 int dryRunFlag = find_option("dry-run","n",0)!=0;
768 int n;
769 Stmt q;
770 int vid;
771 int nAdd = 0;
@@ -643,10 +774,23 @@
774
775 if( !dryRunFlag ){
776 dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
777 }
778
779 if(0!=find_option("reset",0,0)){
780 int const verboseFlag = find_option("verbose","v",0)!=0;
781 db_must_be_within_tree();
782 verify_all_options();
783 addremove_reset(0, dryRunFlag, verboseFlag);
784 addremove_reset(1, dryRunFlag, verboseFlag);
785 return;
786 }
787
788 zCleanFlag = find_option("clean",0,1);
789 zIgnoreFlag = find_option("ignore",0,1);
790 scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
791
792 /* We should be done with options.. */
793 verify_all_options();
794
795 /* Fail if unprocessed arguments are present, in case user expect the
796 ** addremove command to accept a list of file or directory.
@@ -710,11 +854,10 @@
854 /* show command summary */
855 fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);
856
857 db_end_transaction(dryRunFlag);
858 }
 
859
860 /*
861 ** Rename a single file.
862 **
863 ** The original name of the file is zOrig. The new filename is zNew.
864
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,11 +1,13 @@
11
<title>Change Log</title>
22
33
<a name='v2_12'></a>
44
<h2>Changes for Version 2.12 (pending)</h2>
55
6
- * <i>(no changes yet...)</i>
6
+ * Added <tt>--reset</tt> flag to the "[/help?cmd=add|fossil add]",
7
+ "[/help?cmd=rm|fossil rm]", and
8
+ "[/help?cmd=addremove|fossil addremove]" commands.
79
810
<a name='v2_11'></a>
911
<h2>Changes for Version 2.11 (2020-05-25)</h2>
1012
1113
* Support [/md_rules|Markdown] in the default ticket configuration.
1214
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,11 +1,13 @@
1 <title>Change Log</title>
2
3 <a name='v2_12'></a>
4 <h2>Changes for Version 2.12 (pending)</h2>
5
6 * <i>(no changes yet...)</i>
 
 
7
8 <a name='v2_11'></a>
9 <h2>Changes for Version 2.11 (2020-05-25)</h2>
10
11 * Support [/md_rules|Markdown] in the default ticket configuration.
12
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,11 +1,13 @@
1 <title>Change Log</title>
2
3 <a name='v2_12'></a>
4 <h2>Changes for Version 2.12 (pending)</h2>
5
6 * Added <tt>--reset</tt> flag to the "[/help?cmd=add|fossil add]",
7 "[/help?cmd=rm|fossil rm]", and
8 "[/help?cmd=addremove|fossil addremove]" commands.
9
10 <a name='v2_11'></a>
11 <h2>Changes for Version 2.11 (2020-05-25)</h2>
12
13 * Support [/md_rules|Markdown] in the default ticket configuration.
14
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,11 +1,13 @@
11
<title>Change Log</title>
22
33
<a name='v2_12'></a>
44
<h2>Changes for Version 2.12 (pending)</h2>
55
6
- * <i>(no changes yet...)</i>
6
+ * Added <tt>--reset</tt> flag to the "[/help?cmd=add|fossil add]",
7
+ "[/help?cmd=rm|fossil rm]", and
8
+ "[/help?cmd=addremove|fossil addremove]" commands.
79
810
<a name='v2_11'></a>
911
<h2>Changes for Version 2.11 (2020-05-25)</h2>
1012
1113
* Support [/md_rules|Markdown] in the default ticket configuration.
1214
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,11 +1,13 @@
1 <title>Change Log</title>
2
3 <a name='v2_12'></a>
4 <h2>Changes for Version 2.12 (pending)</h2>
5
6 * <i>(no changes yet...)</i>
 
 
7
8 <a name='v2_11'></a>
9 <h2>Changes for Version 2.11 (2020-05-25)</h2>
10
11 * Support [/md_rules|Markdown] in the default ticket configuration.
12
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,11 +1,13 @@
1 <title>Change Log</title>
2
3 <a name='v2_12'></a>
4 <h2>Changes for Version 2.12 (pending)</h2>
5
6 * Added <tt>--reset</tt> flag to the "[/help?cmd=add|fossil add]",
7 "[/help?cmd=rm|fossil rm]", and
8 "[/help?cmd=addremove|fossil addremove]" commands.
9
10 <a name='v2_11'></a>
11 <h2>Changes for Version 2.11 (2020-05-25)</h2>
12
13 * Support [/md_rules|Markdown] in the default ticket configuration.
14

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button