Fossil SCM

When doing a "fossil update" if files are removed from a directory, then try to delete that directory (if it is empty) at the end of the update, if the directory is not on the empty-dirs list.

drh 2019-02-26 01:22 UTC trunk
Commit 43111aa93925ca10bae3503278387e07d7994b21354708ef9ce65d89989f86d5
+1 -1
--- src/checkout.c
+++ src/checkout.c
@@ -303,11 +303,11 @@
303303
if( !keepFlag ){
304304
vfile_to_disk(vid, 0, !g.fQuiet, promptFlag);
305305
}
306306
checkout_set_all_exe(vid);
307307
manifest_to_disk(vid);
308
- ensure_empty_dirs_created();
308
+ ensure_empty_dirs_created(0);
309309
db_set_checkout(vid);
310310
undo_reset();
311311
db_multi_exec("DELETE FROM vmerge");
312312
if( !keepFlag && db_get_boolean("repo-cksum",1) ){
313313
vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
314314
--- src/checkout.c
+++ src/checkout.c
@@ -303,11 +303,11 @@
303 if( !keepFlag ){
304 vfile_to_disk(vid, 0, !g.fQuiet, promptFlag);
305 }
306 checkout_set_all_exe(vid);
307 manifest_to_disk(vid);
308 ensure_empty_dirs_created();
309 db_set_checkout(vid);
310 undo_reset();
311 db_multi_exec("DELETE FROM vmerge");
312 if( !keepFlag && db_get_boolean("repo-cksum",1) ){
313 vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
314
--- src/checkout.c
+++ src/checkout.c
@@ -303,11 +303,11 @@
303 if( !keepFlag ){
304 vfile_to_disk(vid, 0, !g.fQuiet, promptFlag);
305 }
306 checkout_set_all_exe(vid);
307 manifest_to_disk(vid);
308 ensure_empty_dirs_created(0);
309 db_set_checkout(vid);
310 undo_reset();
311 db_multi_exec("DELETE FROM vmerge");
312 if( !keepFlag && db_get_boolean("repo-cksum",1) ){
313 vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
314
+20
--- src/file.c
+++ src/file.c
@@ -684,10 +684,30 @@
684684
fossil_path_free(zMbcs);
685685
return rc;
686686
}
687687
return 0;
688688
}
689
+
690
+/* SQL Function: rmdir(NAME)
691
+**
692
+** Try to remove the directory NAME. Return zero on success and non-zero
693
+** for failure.
694
+*/
695
+void file_rmdir_sql_function(
696
+ sqlite3_context *context,
697
+ int argc,
698
+ sqlite3_value **argv
699
+){
700
+ const char *zName = (const char*)sqlite3_value_text(argv[0]);
701
+ int rc;
702
+ if( zName==0 ){
703
+ rc = 1;
704
+ }else{
705
+ rc = file_rmdir(zName);
706
+ }
707
+ sqlite3_result_int(context, rc);
708
+}
689709
690710
/*
691711
** Return true if the filename given is a valid filename for
692712
** a file in a repository. Valid filenames follow all of the
693713
** following rules:
694714
--- src/file.c
+++ src/file.c
@@ -684,10 +684,30 @@
684 fossil_path_free(zMbcs);
685 return rc;
686 }
687 return 0;
688 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
689
690 /*
691 ** Return true if the filename given is a valid filename for
692 ** a file in a repository. Valid filenames follow all of the
693 ** following rules:
694
--- src/file.c
+++ src/file.c
@@ -684,10 +684,30 @@
684 fossil_path_free(zMbcs);
685 return rc;
686 }
687 return 0;
688 }
689
690 /* SQL Function: rmdir(NAME)
691 **
692 ** Try to remove the directory NAME. Return zero on success and non-zero
693 ** for failure.
694 */
695 void file_rmdir_sql_function(
696 sqlite3_context *context,
697 int argc,
698 sqlite3_value **argv
699 ){
700 const char *zName = (const char*)sqlite3_value_text(argv[0]);
701 int rc;
702 if( zName==0 ){
703 rc = 1;
704 }else{
705 rc = file_rmdir(zName);
706 }
707 sqlite3_result_int(context, rc);
708 }
709
710 /*
711 ** Return true if the filename given is a valid filename for
712 ** a file in a repository. Valid filenames follow all of the
713 ** following rules:
714
+31 -5
--- src/update.c
+++ src/update.c
@@ -160,11 +160,11 @@
160160
}
161161
}
162162
163163
/* Create any empty directories now, as well as after the update,
164164
** so changes in settings are reflected now */
165
- if( !dryRunFlag ) ensure_empty_dirs_created();
165
+ if( !dryRunFlag ) ensure_empty_dirs_created(0);
166166
167167
if( internalUpdate ){
168168
tid = internalUpdate;
169169
}else if( g.argc>=3 ){
170170
if( fossil_strcmp(g.argv[2], "current")==0 ){
@@ -227,10 +227,14 @@
227227
if( tid==0 ){
228228
return;
229229
}
230230
231231
db_begin_transaction();
232
+ db_multi_exec(
233
+ "CREATE TEMP TABLE dir_to_delete(name TEXT %s PRIMARY KEY)WITHOUT ROWID",
234
+ filename_collation()
235
+ );
232236
vfile_check_signature(vid, CKSIG_ENOTFILE);
233237
if( !dryRunFlag && !internalUpdate ) undo_begin();
234238
if( load_vfile_from_rid(tid) && !forceMissingFlag ){
235239
fossil_fatal("missing content, unable to update");
236240
};
@@ -455,11 +459,23 @@
455459
zName);
456460
nConflict++;
457461
}else{
458462
fossil_print("REMOVE %s\n", zName);
459463
if( !dryRunFlag && !internalUpdate ) undo_save(zName);
460
- if( !dryRunFlag ) file_delete(zFullPath);
464
+ if( !dryRunFlag ){
465
+ char *zDir;
466
+ file_delete(zFullPath);
467
+ zDir = file_dirname(zName);
468
+ while( zDir!=0 ){
469
+ char *zNext;
470
+ db_multi_exec("INSERT OR IGNORE INTO dir_to_delete(name)"
471
+ "VALUES(%Q)", zDir);
472
+ zNext = db_changes() ? file_dirname(zDir) : 0;
473
+ fossil_free(zDir);
474
+ zDir = zNext;
475
+ }
476
+ }
461477
}
462478
}else if( idt>0 && idv>0 && ridt!=ridv && chnged ){
463479
/* Merge the changes in the current tree into the target version */
464480
Blob r, t, v;
465481
int rc;
@@ -566,11 +582,16 @@
566582
** Clean up the mid and pid VFILE entries. Then commit the changes.
567583
*/
568584
if( dryRunFlag ){
569585
db_end_transaction(1); /* With --dry-run, rollback changes */
570586
}else{
571
- ensure_empty_dirs_created();
587
+ ensure_empty_dirs_created(1);
588
+ sqlite3_create_function(g.db, "rmdir", 1, SQLITE_UTF8, 0,
589
+ file_rmdir_sql_function, 0, 0);
590
+ db_multi_exec(
591
+ "SELECT rmdir(name) FROM dir_to_delete ORDER BY name DESC"
592
+ );
572593
if( g.argc<=3 ){
573594
/* All files updated. Shift the current checkout to the target. */
574595
db_multi_exec("DELETE FROM vfile WHERE vid!=%d", tid);
575596
checkout_set_all_exe(tid);
576597
manifest_to_disk(tid);
@@ -587,11 +608,11 @@
587608
}
588609
589610
/*
590611
** Create empty directories specified by the empty-dirs setting.
591612
*/
592
-void ensure_empty_dirs_created(void){
613
+void ensure_empty_dirs_created(int clearDirTable){
593614
char *zEmptyDirs = db_get("empty-dirs", 0);
594615
if( zEmptyDirs!=0 ){
595616
int i;
596617
Blob dirName;
597618
Blob dirsList;
@@ -613,11 +634,16 @@
613634
"required by empty-dirs setting", zDir);
614635
}
615636
break;
616637
}
617638
case 1: { /* exists, and is a directory */
618
- /* do nothing - required directory exists already */
639
+ /* make sure this directory is not on the delete list */
640
+ if( clearDirTable ){
641
+ db_multi_exec(
642
+ "DELETE FROM dir_to_delete WHERE name=%Q", zDir
643
+ );
644
+ }
619645
break;
620646
}
621647
case 2: { /* exists, but isn't a directory */
622648
fossil_warning("file %s found, but a directory is required "
623649
"by empty-dirs setting", zDir);
624650
--- src/update.c
+++ src/update.c
@@ -160,11 +160,11 @@
160 }
161 }
162
163 /* Create any empty directories now, as well as after the update,
164 ** so changes in settings are reflected now */
165 if( !dryRunFlag ) ensure_empty_dirs_created();
166
167 if( internalUpdate ){
168 tid = internalUpdate;
169 }else if( g.argc>=3 ){
170 if( fossil_strcmp(g.argv[2], "current")==0 ){
@@ -227,10 +227,14 @@
227 if( tid==0 ){
228 return;
229 }
230
231 db_begin_transaction();
 
 
 
 
232 vfile_check_signature(vid, CKSIG_ENOTFILE);
233 if( !dryRunFlag && !internalUpdate ) undo_begin();
234 if( load_vfile_from_rid(tid) && !forceMissingFlag ){
235 fossil_fatal("missing content, unable to update");
236 };
@@ -455,11 +459,23 @@
455 zName);
456 nConflict++;
457 }else{
458 fossil_print("REMOVE %s\n", zName);
459 if( !dryRunFlag && !internalUpdate ) undo_save(zName);
460 if( !dryRunFlag ) file_delete(zFullPath);
 
 
 
 
 
 
 
 
 
 
 
 
461 }
462 }else if( idt>0 && idv>0 && ridt!=ridv && chnged ){
463 /* Merge the changes in the current tree into the target version */
464 Blob r, t, v;
465 int rc;
@@ -566,11 +582,16 @@
566 ** Clean up the mid and pid VFILE entries. Then commit the changes.
567 */
568 if( dryRunFlag ){
569 db_end_transaction(1); /* With --dry-run, rollback changes */
570 }else{
571 ensure_empty_dirs_created();
 
 
 
 
 
572 if( g.argc<=3 ){
573 /* All files updated. Shift the current checkout to the target. */
574 db_multi_exec("DELETE FROM vfile WHERE vid!=%d", tid);
575 checkout_set_all_exe(tid);
576 manifest_to_disk(tid);
@@ -587,11 +608,11 @@
587 }
588
589 /*
590 ** Create empty directories specified by the empty-dirs setting.
591 */
592 void ensure_empty_dirs_created(void){
593 char *zEmptyDirs = db_get("empty-dirs", 0);
594 if( zEmptyDirs!=0 ){
595 int i;
596 Blob dirName;
597 Blob dirsList;
@@ -613,11 +634,16 @@
613 "required by empty-dirs setting", zDir);
614 }
615 break;
616 }
617 case 1: { /* exists, and is a directory */
618 /* do nothing - required directory exists already */
 
 
 
 
 
619 break;
620 }
621 case 2: { /* exists, but isn't a directory */
622 fossil_warning("file %s found, but a directory is required "
623 "by empty-dirs setting", zDir);
624
--- src/update.c
+++ src/update.c
@@ -160,11 +160,11 @@
160 }
161 }
162
163 /* Create any empty directories now, as well as after the update,
164 ** so changes in settings are reflected now */
165 if( !dryRunFlag ) ensure_empty_dirs_created(0);
166
167 if( internalUpdate ){
168 tid = internalUpdate;
169 }else if( g.argc>=3 ){
170 if( fossil_strcmp(g.argv[2], "current")==0 ){
@@ -227,10 +227,14 @@
227 if( tid==0 ){
228 return;
229 }
230
231 db_begin_transaction();
232 db_multi_exec(
233 "CREATE TEMP TABLE dir_to_delete(name TEXT %s PRIMARY KEY)WITHOUT ROWID",
234 filename_collation()
235 );
236 vfile_check_signature(vid, CKSIG_ENOTFILE);
237 if( !dryRunFlag && !internalUpdate ) undo_begin();
238 if( load_vfile_from_rid(tid) && !forceMissingFlag ){
239 fossil_fatal("missing content, unable to update");
240 };
@@ -455,11 +459,23 @@
459 zName);
460 nConflict++;
461 }else{
462 fossil_print("REMOVE %s\n", zName);
463 if( !dryRunFlag && !internalUpdate ) undo_save(zName);
464 if( !dryRunFlag ){
465 char *zDir;
466 file_delete(zFullPath);
467 zDir = file_dirname(zName);
468 while( zDir!=0 ){
469 char *zNext;
470 db_multi_exec("INSERT OR IGNORE INTO dir_to_delete(name)"
471 "VALUES(%Q)", zDir);
472 zNext = db_changes() ? file_dirname(zDir) : 0;
473 fossil_free(zDir);
474 zDir = zNext;
475 }
476 }
477 }
478 }else if( idt>0 && idv>0 && ridt!=ridv && chnged ){
479 /* Merge the changes in the current tree into the target version */
480 Blob r, t, v;
481 int rc;
@@ -566,11 +582,16 @@
582 ** Clean up the mid and pid VFILE entries. Then commit the changes.
583 */
584 if( dryRunFlag ){
585 db_end_transaction(1); /* With --dry-run, rollback changes */
586 }else{
587 ensure_empty_dirs_created(1);
588 sqlite3_create_function(g.db, "rmdir", 1, SQLITE_UTF8, 0,
589 file_rmdir_sql_function, 0, 0);
590 db_multi_exec(
591 "SELECT rmdir(name) FROM dir_to_delete ORDER BY name DESC"
592 );
593 if( g.argc<=3 ){
594 /* All files updated. Shift the current checkout to the target. */
595 db_multi_exec("DELETE FROM vfile WHERE vid!=%d", tid);
596 checkout_set_all_exe(tid);
597 manifest_to_disk(tid);
@@ -587,11 +608,11 @@
608 }
609
610 /*
611 ** Create empty directories specified by the empty-dirs setting.
612 */
613 void ensure_empty_dirs_created(int clearDirTable){
614 char *zEmptyDirs = db_get("empty-dirs", 0);
615 if( zEmptyDirs!=0 ){
616 int i;
617 Blob dirName;
618 Blob dirsList;
@@ -613,11 +634,16 @@
634 "required by empty-dirs setting", zDir);
635 }
636 break;
637 }
638 case 1: { /* exists, and is a directory */
639 /* make sure this directory is not on the delete list */
640 if( clearDirTable ){
641 db_multi_exec(
642 "DELETE FROM dir_to_delete WHERE name=%Q", zDir
643 );
644 }
645 break;
646 }
647 case 2: { /* exists, but isn't a directory */
648 fossil_warning("file %s found, but a directory is required "
649 "by empty-dirs setting", zDir);
650

Keyboard Shortcuts

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