Fossil SCM

Initial draft of new unaddremove command (will be renamed once a suitable name is found), as discussed at [https://fossil-scm.org/forum/forumpost/b9b20b04bd|forumpost/b9b20b04bd].

stephan 2020-04-22 23:45 trunk
Commit 369a14b33fb79ffca48f9de37ee95f183d76daba0970034dcf43d7d27bc88fee
1 file changed +79
+79
--- src/add.c
+++ src/add.c
@@ -711,10 +711,89 @@
711711
fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);
712712
713713
db_end_transaction(dryRunFlag);
714714
}
715715
716
+/*
717
+** COMMAND: unaddremove*
718
+**
719
+** Resets the ADD/REMOVE state of a checkout, such that all newly-added
720
+** (but not yet committed) files are no longer added and newly-removed
721
+** (but not yet committed) files are no longer removed.
722
+**
723
+** This command does not touch un-added files but restores any un-rm'd
724
+** files which are missing from the checkout.
725
+**
726
+** Options:
727
+**
728
+** -v|--verbose Output name of each un-added/un-removed file.
729
+**
730
+*/
731
+void unaddremove_cmd(void){
732
+ int nDeleted = 0; /* # of files which get un-rm'd */
733
+ int nAdded = 0; /* # of files which get un-added */
734
+ int fVerbose; /* true if --verbose */
735
+ Stmt stmt; /* vfile loop query */
736
+
737
+ db_must_be_within_tree();
738
+ fVerbose = find_option("verbose", "v", 0)!=0;
739
+ verify_all_options();
740
+
741
+ db_begin_transaction();
742
+ db_prepare(&stmt, "SELECT id, rid, deleted, pathname FROM vfile "
743
+ "ORDER BY deleted<>0, pathname");
744
+ while( db_step(&stmt)==SQLITE_ROW ){
745
+ /* This loop exists only so we can restore the contents of un-rm'd
746
+ ** files. All manipulation of vfile's contents happens after the
747
+ ** loop. */
748
+ int const rid = db_column_int(&stmt, 1);
749
+ int const deleted = db_column_int(&stmt, 2);
750
+ if(deleted!=0 || rid==0){
751
+ int const id = db_column_int(&stmt, 0);
752
+ char const * zPathname = db_column_text(&stmt, 3);
753
+ char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
754
+ Blob relName = empty_blob;
755
+ file_relative_name(zFullName, &relName, 0);
756
+ fossil_free(zFullName);
757
+ zFullName = 0;
758
+ if(deleted!=0){
759
+ /* Restore contents of missing un-rm'd files. We don't do this
760
+ ** unconditionally because we might cause data loss if a file
761
+ ** is modified, rm'd, then un-rm'd.
762
+ */
763
+ ++nDeleted;
764
+ if(!file_isfile_or_link(blob_str(&relName))){
765
+ vfile_to_disk(0, id, 0, 0);
766
+ }
767
+ /* *Potential* corner case: relName refers to a directory,
768
+ ** meaning the user rm'd the file and replaced it with a
769
+ ** directory. In that case, vfile_to_disk() will fail fatally,
770
+ ** which is arguably the best course of action.
771
+ */
772
+ if(fVerbose){
773
+ fossil_print("Un-removed: %b\n", &relName);
774
+ }
775
+ }else if(rid==0){
776
+ ++nAdded;
777
+ if(fVerbose){
778
+ fossil_print("Un-added: %b\n", &relName);
779
+ }
780
+ }
781
+ blob_reset(&relName);
782
+ }
783
+ }
784
+ db_finalize(&stmt);
785
+ if(nDeleted>0){
786
+ db_multi_exec("UPDATE vfile SET deleted=0 WHERE deleted<>0");
787
+ fossil_print("Un-removed %d file(s).\n", nDeleted);
788
+ }
789
+ if(nAdded>0){
790
+ db_multi_exec("DELETE FROM vfile WHERE rid=0");
791
+ fossil_print("Un-added %d file(s).\n", nAdded);
792
+ }
793
+ db_end_transaction(0);
794
+}
716795
717796
/*
718797
** Rename a single file.
719798
**
720799
** The original name of the file is zOrig. The new filename is zNew.
721800
--- src/add.c
+++ src/add.c
@@ -711,10 +711,89 @@
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
@@ -711,10 +711,89 @@
711 fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);
712
713 db_end_transaction(dryRunFlag);
714 }
715
716 /*
717 ** COMMAND: unaddremove*
718 **
719 ** Resets the ADD/REMOVE state of a checkout, such that all newly-added
720 ** (but not yet committed) files are no longer added and newly-removed
721 ** (but not yet committed) files are no longer removed.
722 **
723 ** This command does not touch un-added files but restores any un-rm'd
724 ** files which are missing from the checkout.
725 **
726 ** Options:
727 **
728 ** -v|--verbose Output name of each un-added/un-removed file.
729 **
730 */
731 void unaddremove_cmd(void){
732 int nDeleted = 0; /* # of files which get un-rm'd */
733 int nAdded = 0; /* # of files which get un-added */
734 int fVerbose; /* true if --verbose */
735 Stmt stmt; /* vfile loop query */
736
737 db_must_be_within_tree();
738 fVerbose = find_option("verbose", "v", 0)!=0;
739 verify_all_options();
740
741 db_begin_transaction();
742 db_prepare(&stmt, "SELECT id, rid, deleted, pathname FROM vfile "
743 "ORDER BY deleted<>0, pathname");
744 while( db_step(&stmt)==SQLITE_ROW ){
745 /* This loop exists only so we can restore the contents of un-rm'd
746 ** files. All manipulation of vfile's contents happens after the
747 ** loop. */
748 int const rid = db_column_int(&stmt, 1);
749 int const deleted = db_column_int(&stmt, 2);
750 if(deleted!=0 || rid==0){
751 int const id = db_column_int(&stmt, 0);
752 char const * zPathname = db_column_text(&stmt, 3);
753 char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
754 Blob relName = empty_blob;
755 file_relative_name(zFullName, &relName, 0);
756 fossil_free(zFullName);
757 zFullName = 0;
758 if(deleted!=0){
759 /* Restore contents of missing un-rm'd files. We don't do this
760 ** unconditionally because we might cause data loss if a file
761 ** is modified, rm'd, then un-rm'd.
762 */
763 ++nDeleted;
764 if(!file_isfile_or_link(blob_str(&relName))){
765 vfile_to_disk(0, id, 0, 0);
766 }
767 /* *Potential* corner case: relName refers to a directory,
768 ** meaning the user rm'd the file and replaced it with a
769 ** directory. In that case, vfile_to_disk() will fail fatally,
770 ** which is arguably the best course of action.
771 */
772 if(fVerbose){
773 fossil_print("Un-removed: %b\n", &relName);
774 }
775 }else if(rid==0){
776 ++nAdded;
777 if(fVerbose){
778 fossil_print("Un-added: %b\n", &relName);
779 }
780 }
781 blob_reset(&relName);
782 }
783 }
784 db_finalize(&stmt);
785 if(nDeleted>0){
786 db_multi_exec("UPDATE vfile SET deleted=0 WHERE deleted<>0");
787 fossil_print("Un-removed %d file(s).\n", nDeleted);
788 }
789 if(nAdded>0){
790 db_multi_exec("DELETE FROM vfile WHERE rid=0");
791 fossil_print("Un-added %d file(s).\n", nAdded);
792 }
793 db_end_transaction(0);
794 }
795
796 /*
797 ** Rename a single file.
798 **
799 ** The original name of the file is zOrig. The new filename is zNew.
800

Keyboard Shortcuts

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