Fossil SCM

The revert command no longer resets the undo state if nothing is actually reverted. Additional tests and bug fixes as well.

joel 2016-04-01 04:04 trunk
Commit 418dd7ac51ba4e1547fb9b0ca55c29856a4c33c2
3 files changed +70 -19 +8 -8 +105 -14
+70 -19
--- src/update.c
+++ src/update.c
@@ -1,5 +1,6 @@
1
+
12
/*
23
** Copyright (c) 2007 D. Richard Hipp
34
**
45
** This program is free software; you can redistribute it and/or
56
** modify it under the terms of the Simplified BSD License (also
@@ -718,10 +719,12 @@
718719
const char *zRevision;
719720
Blob record;
720721
int i;
721722
int errCode;
722723
Stmt q;
724
+ int vid;
725
+ int mergeReverted = 0;
723726
724727
undo_capture_command_line();
725728
zRevision = find_option("revision", "r", 1);
726729
verify_all_options();
727730
@@ -733,47 +736,99 @@
733736
}
734737
db_must_be_within_tree();
735738
db_begin_transaction();
736739
undo_begin();
737740
db_multi_exec("CREATE TEMP TABLE torevert(name UNIQUE);");
741
+ vid = db_lget_int("checkout", 0);
742
+ vfile_check_signature(vid, 0);
738743
739744
if( g.argc>2 ){
745
+ int rid = 0;
746
+ if( zRevision ){
747
+ rid = name_to_typed_rid(zRevision, "ci");
748
+ load_vfile_from_rid(rid);
749
+ }
740750
for(i=2; i<g.argc; i++){
741751
Blob fname;
742752
zFile = mprintf("%/", g.argv[i]);
743753
blob_zero(&fname);
744754
file_tree_name(zFile, &fname, 0, 1);
745755
db_multi_exec(
746
- "REPLACE INTO torevert VALUES(%B);"
747756
"INSERT OR IGNORE INTO torevert"
748757
" SELECT pathname"
758
+ " FROM vfile v"
759
+ " WHERE vid=%d AND (pathname %s=%B OR origname %s=%B)"
760
+ " AND (chnged OR deleted OR rid=0 OR pathname!=origname OR rid!=("
761
+ " SELECT rid FROM vfile WHERE vid=%d AND pathname=v.pathname));"
762
+ "INSERT OR IGNORE INTO torevert"
763
+ " SELECT origname"
749764
" FROM vfile"
750
- " WHERE origname=%B;",
751
- &fname, &fname
765
+ " WHERE vid=%d AND origname %s=%B"
766
+ " AND pathname IN (SELECT name FROM torevert);",
767
+ vid, filename_collation(), &fname, filename_collation(), &fname, rid,
768
+ vid, filename_collation(), &fname
752769
);
770
+ free(zFile);
753771
blob_reset(&fname);
754772
}
773
+ if( rid ) db_multi_exec("DELETE FROM vfile WHERE vid=%d", rid);
774
+ /* Refuse to revert a renamed file if another file exists in its
775
+ ** original location that wasn't specified when calling revert.
776
+ */
777
+ db_prepare(&q,
778
+ " SELECT origname, pathname"
779
+ " FROM vfile"
780
+ " WHERE pathname IN (SELECT name FROM torevert)"
781
+ " AND origname NOT IN (SELECT name FROM torevert)"
782
+ " AND origname IN (SELECT pathname FROM vfile)"
783
+ );
784
+ if( db_step(&q)==SQLITE_ROW ){
785
+ const char *zOrig = db_column_text(&q, 0);
786
+ zFile = db_column_text(&q, 1);
787
+ fossil_fatal("cannot revert '%s' without '%s'", zFile, zOrig);
788
+ }
789
+ db_finalize(&q);
755790
}else{
756
- int vid;
757
- vid = db_lget_int("checkout", 0);
758
- vfile_check_signature(vid, 0);
791
+ mergeReverted = db_exists("SELECT 1 FROM vmerge");
759792
db_multi_exec(
760793
"DELETE FROM vmerge;"
761794
"INSERT OR IGNORE INTO torevert "
762795
" SELECT pathname"
763796
" FROM vfile "
764797
" WHERE chnged OR deleted OR rid=0 OR pathname!=origname;"
765798
);
766799
}
800
+
801
+ /* If there's nothing to revert, rollback and exit so the previous undo
802
+ ** state isn't unnecessarily discarded.
803
+ */
804
+ if( !mergeReverted && !db_exists("SELECT 1 FROM torevert") ){
805
+ db_end_transaction(1);
806
+ return;
807
+ }
808
+
767809
db_multi_exec(
768810
"INSERT OR IGNORE INTO torevert"
769811
" SELECT origname"
770812
" FROM vfile"
771813
" WHERE origname!=pathname AND pathname IN (SELECT name FROM torevert);"
772814
);
815
+
816
+ /* Revert pathnames. Added files (rid==0) that are to be reverted will
817
+ ** have a NULL pathname until their VFILE entries are deleted.
818
+ */
819
+ db_multi_exec(
820
+ "UPDATE vfile"
821
+ " SET pathname=NULL, origname=coalesce(origname,pathname)"
822
+ " WHERE pathname IN (SELECT name FROM torevert);"
823
+ "UPDATE vfile"
824
+ " SET pathname=origname, origname=NULL"
825
+ " WHERE pathname IS NULL AND rid>0;"
826
+ );
827
+
773828
blob_zero(&record);
774
- db_prepare(&q, "SELECT name FROM torevert");
829
+ db_prepare(&q, "SELECT name FROM torevert ORDER BY name");
775830
if( zRevision==0 ){
776831
int vid = db_lget_int("checkout", 0);
777832
zRevision = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
778833
}
779834
while( db_step(&q)==SQLITE_ROW ){
@@ -782,26 +837,21 @@
782837
char *zFull;
783838
zFile = db_column_text(&q, 0);
784839
zFull = mprintf("%/%/", g.zLocalRoot, zFile);
785840
errCode = historical_version_of_file(zRevision, zFile, &record,
786841
&isLink, &isExe, 0, 2);
787
- if( errCode==2 ){
788
- if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q OR origname=%Q",
789
- zFile, zFile)==0 ){
842
+ if( errCode==2
843
+ || !db_exists("SELECT 1 FROM vfile WHERE pathname=%Q", zFile) ){
844
+ if( db_exists("SELECT 1 FROM vfile"
845
+ " WHERE pathname IS NULL AND origname=%Q",
846
+ zFile) ){
790847
fossil_print("UNMANAGE %s\n", zFile);
791848
}else{
792849
undo_save(zFile);
793850
file_delete(zFull);
794851
fossil_print("DELETE %s\n", zFile);
795852
}
796
- db_multi_exec(
797
- "UPDATE OR REPLACE vfile"
798
- " SET pathname=origname, origname=NULL"
799
- " WHERE pathname=%Q AND origname!=pathname;"
800
- "DELETE FROM vfile WHERE pathname=%Q",
801
- zFile, zFile
802
- );
803853
}else{
804854
sqlite3_int64 mtime;
805855
undo_save(zFile);
806856
if( file_wd_size(zFull)>=0 && (isLink || file_wd_islink(0)) ){
807857
file_delete(zFull);
@@ -815,16 +865,17 @@
815865
fossil_print("REVERT %s\n", zFile);
816866
mtime = file_wd_mtime(zFull);
817867
db_multi_exec(
818868
"UPDATE vfile"
819869
" SET mtime=%lld, chnged=0, deleted=0, isexe=%d, islink=%d,mrid=rid"
820
- " WHERE pathname=%Q OR origname=%Q",
821
- mtime, isExe, isLink, zFile, zFile
870
+ " WHERE pathname=%Q",
871
+ mtime, isExe, isLink, zFile
822872
);
823873
}
824874
blob_reset(&record);
825875
free(zFull);
826876
}
827877
db_finalize(&q);
878
+ db_multi_exec("DELETE FROM vfile WHERE pathname IS NULL");
828879
undo_finish();
829880
db_end_transaction(0);
830881
}
831882
--- src/update.c
+++ src/update.c
@@ -1,5 +1,6 @@
 
1 /*
2 ** Copyright (c) 2007 D. Richard Hipp
3 **
4 ** This program is free software; you can redistribute it and/or
5 ** modify it under the terms of the Simplified BSD License (also
@@ -718,10 +719,12 @@
718 const char *zRevision;
719 Blob record;
720 int i;
721 int errCode;
722 Stmt q;
 
 
723
724 undo_capture_command_line();
725 zRevision = find_option("revision", "r", 1);
726 verify_all_options();
727
@@ -733,47 +736,99 @@
733 }
734 db_must_be_within_tree();
735 db_begin_transaction();
736 undo_begin();
737 db_multi_exec("CREATE TEMP TABLE torevert(name UNIQUE);");
 
 
738
739 if( g.argc>2 ){
 
 
 
 
 
740 for(i=2; i<g.argc; i++){
741 Blob fname;
742 zFile = mprintf("%/", g.argv[i]);
743 blob_zero(&fname);
744 file_tree_name(zFile, &fname, 0, 1);
745 db_multi_exec(
746 "REPLACE INTO torevert VALUES(%B);"
747 "INSERT OR IGNORE INTO torevert"
748 " SELECT pathname"
 
 
 
 
 
 
749 " FROM vfile"
750 " WHERE origname=%B;",
751 &fname, &fname
 
 
752 );
 
753 blob_reset(&fname);
754 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
755 }else{
756 int vid;
757 vid = db_lget_int("checkout", 0);
758 vfile_check_signature(vid, 0);
759 db_multi_exec(
760 "DELETE FROM vmerge;"
761 "INSERT OR IGNORE INTO torevert "
762 " SELECT pathname"
763 " FROM vfile "
764 " WHERE chnged OR deleted OR rid=0 OR pathname!=origname;"
765 );
766 }
 
 
 
 
 
 
 
 
 
767 db_multi_exec(
768 "INSERT OR IGNORE INTO torevert"
769 " SELECT origname"
770 " FROM vfile"
771 " WHERE origname!=pathname AND pathname IN (SELECT name FROM torevert);"
772 );
 
 
 
 
 
 
 
 
 
 
 
 
 
773 blob_zero(&record);
774 db_prepare(&q, "SELECT name FROM torevert");
775 if( zRevision==0 ){
776 int vid = db_lget_int("checkout", 0);
777 zRevision = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
778 }
779 while( db_step(&q)==SQLITE_ROW ){
@@ -782,26 +837,21 @@
782 char *zFull;
783 zFile = db_column_text(&q, 0);
784 zFull = mprintf("%/%/", g.zLocalRoot, zFile);
785 errCode = historical_version_of_file(zRevision, zFile, &record,
786 &isLink, &isExe, 0, 2);
787 if( errCode==2 ){
788 if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q OR origname=%Q",
789 zFile, zFile)==0 ){
 
 
790 fossil_print("UNMANAGE %s\n", zFile);
791 }else{
792 undo_save(zFile);
793 file_delete(zFull);
794 fossil_print("DELETE %s\n", zFile);
795 }
796 db_multi_exec(
797 "UPDATE OR REPLACE vfile"
798 " SET pathname=origname, origname=NULL"
799 " WHERE pathname=%Q AND origname!=pathname;"
800 "DELETE FROM vfile WHERE pathname=%Q",
801 zFile, zFile
802 );
803 }else{
804 sqlite3_int64 mtime;
805 undo_save(zFile);
806 if( file_wd_size(zFull)>=0 && (isLink || file_wd_islink(0)) ){
807 file_delete(zFull);
@@ -815,16 +865,17 @@
815 fossil_print("REVERT %s\n", zFile);
816 mtime = file_wd_mtime(zFull);
817 db_multi_exec(
818 "UPDATE vfile"
819 " SET mtime=%lld, chnged=0, deleted=0, isexe=%d, islink=%d,mrid=rid"
820 " WHERE pathname=%Q OR origname=%Q",
821 mtime, isExe, isLink, zFile, zFile
822 );
823 }
824 blob_reset(&record);
825 free(zFull);
826 }
827 db_finalize(&q);
 
828 undo_finish();
829 db_end_transaction(0);
830 }
831
--- src/update.c
+++ src/update.c
@@ -1,5 +1,6 @@
1
2 /*
3 ** Copyright (c) 2007 D. Richard Hipp
4 **
5 ** This program is free software; you can redistribute it and/or
6 ** modify it under the terms of the Simplified BSD License (also
@@ -718,10 +719,12 @@
719 const char *zRevision;
720 Blob record;
721 int i;
722 int errCode;
723 Stmt q;
724 int vid;
725 int mergeReverted = 0;
726
727 undo_capture_command_line();
728 zRevision = find_option("revision", "r", 1);
729 verify_all_options();
730
@@ -733,47 +736,99 @@
736 }
737 db_must_be_within_tree();
738 db_begin_transaction();
739 undo_begin();
740 db_multi_exec("CREATE TEMP TABLE torevert(name UNIQUE);");
741 vid = db_lget_int("checkout", 0);
742 vfile_check_signature(vid, 0);
743
744 if( g.argc>2 ){
745 int rid = 0;
746 if( zRevision ){
747 rid = name_to_typed_rid(zRevision, "ci");
748 load_vfile_from_rid(rid);
749 }
750 for(i=2; i<g.argc; i++){
751 Blob fname;
752 zFile = mprintf("%/", g.argv[i]);
753 blob_zero(&fname);
754 file_tree_name(zFile, &fname, 0, 1);
755 db_multi_exec(
 
756 "INSERT OR IGNORE INTO torevert"
757 " SELECT pathname"
758 " FROM vfile v"
759 " WHERE vid=%d AND (pathname %s=%B OR origname %s=%B)"
760 " AND (chnged OR deleted OR rid=0 OR pathname!=origname OR rid!=("
761 " SELECT rid FROM vfile WHERE vid=%d AND pathname=v.pathname));"
762 "INSERT OR IGNORE INTO torevert"
763 " SELECT origname"
764 " FROM vfile"
765 " WHERE vid=%d AND origname %s=%B"
766 " AND pathname IN (SELECT name FROM torevert);",
767 vid, filename_collation(), &fname, filename_collation(), &fname, rid,
768 vid, filename_collation(), &fname
769 );
770 free(zFile);
771 blob_reset(&fname);
772 }
773 if( rid ) db_multi_exec("DELETE FROM vfile WHERE vid=%d", rid);
774 /* Refuse to revert a renamed file if another file exists in its
775 ** original location that wasn't specified when calling revert.
776 */
777 db_prepare(&q,
778 " SELECT origname, pathname"
779 " FROM vfile"
780 " WHERE pathname IN (SELECT name FROM torevert)"
781 " AND origname NOT IN (SELECT name FROM torevert)"
782 " AND origname IN (SELECT pathname FROM vfile)"
783 );
784 if( db_step(&q)==SQLITE_ROW ){
785 const char *zOrig = db_column_text(&q, 0);
786 zFile = db_column_text(&q, 1);
787 fossil_fatal("cannot revert '%s' without '%s'", zFile, zOrig);
788 }
789 db_finalize(&q);
790 }else{
791 mergeReverted = db_exists("SELECT 1 FROM vmerge");
 
 
792 db_multi_exec(
793 "DELETE FROM vmerge;"
794 "INSERT OR IGNORE INTO torevert "
795 " SELECT pathname"
796 " FROM vfile "
797 " WHERE chnged OR deleted OR rid=0 OR pathname!=origname;"
798 );
799 }
800
801 /* If there's nothing to revert, rollback and exit so the previous undo
802 ** state isn't unnecessarily discarded.
803 */
804 if( !mergeReverted && !db_exists("SELECT 1 FROM torevert") ){
805 db_end_transaction(1);
806 return;
807 }
808
809 db_multi_exec(
810 "INSERT OR IGNORE INTO torevert"
811 " SELECT origname"
812 " FROM vfile"
813 " WHERE origname!=pathname AND pathname IN (SELECT name FROM torevert);"
814 );
815
816 /* Revert pathnames. Added files (rid==0) that are to be reverted will
817 ** have a NULL pathname until their VFILE entries are deleted.
818 */
819 db_multi_exec(
820 "UPDATE vfile"
821 " SET pathname=NULL, origname=coalesce(origname,pathname)"
822 " WHERE pathname IN (SELECT name FROM torevert);"
823 "UPDATE vfile"
824 " SET pathname=origname, origname=NULL"
825 " WHERE pathname IS NULL AND rid>0;"
826 );
827
828 blob_zero(&record);
829 db_prepare(&q, "SELECT name FROM torevert ORDER BY name");
830 if( zRevision==0 ){
831 int vid = db_lget_int("checkout", 0);
832 zRevision = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
833 }
834 while( db_step(&q)==SQLITE_ROW ){
@@ -782,26 +837,21 @@
837 char *zFull;
838 zFile = db_column_text(&q, 0);
839 zFull = mprintf("%/%/", g.zLocalRoot, zFile);
840 errCode = historical_version_of_file(zRevision, zFile, &record,
841 &isLink, &isExe, 0, 2);
842 if( errCode==2
843 || !db_exists("SELECT 1 FROM vfile WHERE pathname=%Q", zFile) ){
844 if( db_exists("SELECT 1 FROM vfile"
845 " WHERE pathname IS NULL AND origname=%Q",
846 zFile) ){
847 fossil_print("UNMANAGE %s\n", zFile);
848 }else{
849 undo_save(zFile);
850 file_delete(zFull);
851 fossil_print("DELETE %s\n", zFile);
852 }
 
 
 
 
 
 
 
853 }else{
854 sqlite3_int64 mtime;
855 undo_save(zFile);
856 if( file_wd_size(zFull)>=0 && (isLink || file_wd_islink(0)) ){
857 file_delete(zFull);
@@ -815,16 +865,17 @@
865 fossil_print("REVERT %s\n", zFile);
866 mtime = file_wd_mtime(zFull);
867 db_multi_exec(
868 "UPDATE vfile"
869 " SET mtime=%lld, chnged=0, deleted=0, isexe=%d, islink=%d,mrid=rid"
870 " WHERE pathname=%Q",
871 mtime, isExe, isLink, zFile
872 );
873 }
874 blob_reset(&record);
875 free(zFull);
876 }
877 db_finalize(&q);
878 db_multi_exec("DELETE FROM vfile WHERE pathname IS NULL");
879 undo_finish();
880 db_end_transaction(0);
881 }
882
+8 -8
--- test/mv-rm.test
+++ test/mv-rm.test
@@ -63,11 +63,11 @@
6363
fossil mv ../f1 .
6464
test mv-soft-relative-1 {$RESULT eq "RENAME f1 subdir1/f1"}
6565
6666
fossil revert
6767
test mv-soft-relative-2 {
68
- [normalize_result] eq "DELETE subdir1/f1\nREVERT f1${undoMsg}"
68
+ [normalize_result] eq "REVERT f1\nDELETE subdir1/f1${undoMsg}"
6969
}
7070
7171
cd $rootDir
7272
7373
###################################
@@ -80,11 +80,11 @@
8080
fossil mv ../f2 ./f2
8181
test mv-soft-relative-3 {$RESULT eq "RENAME f2 subdir2/f2"}
8282
8383
fossil revert
8484
test mv-soft-relative-4 {
85
- [normalize_result] eq "DELETE subdir2/f2\nREVERT f2${undoMsg}"
85
+ [normalize_result] eq "REVERT f2\nDELETE subdir2/f2${undoMsg}"
8686
}
8787
8888
cd $rootDir
8989
9090
########################################
@@ -99,11 +99,11 @@
9999
[normalize_result] eq "RENAME f3 subdir3/f3\nMOVED_FILE ${rootDir}/f3"
100100
}
101101
102102
fossil revert
103103
test mv-hard-relative-2 {
104
- [normalize_result] eq "DELETE subdir3/f3\nREVERT f3${undoMsg}"
104
+ [normalize_result] eq "REVERT f3\nDELETE subdir3/f3${undoMsg}"
105105
}
106106
107107
cd $rootDir
108108
109109
###################################
@@ -118,11 +118,11 @@
118118
[normalize_result] eq "RENAME f4 subdir4/f4\nMOVED_FILE ${rootDir}/f4"
119119
}
120120
121121
fossil revert
122122
test mv-hard-relative-4 {
123
- [normalize_result] eq "DELETE subdir4/f4\nREVERT f4${undoMsg}"
123
+ [normalize_result] eq "REVERT f4\nDELETE subdir4/f4${undoMsg}"
124124
}
125125
126126
cd $rootDir
127127
128128
########################################
@@ -135,11 +135,11 @@
135135
fossil mv [file join $rootDir f5] [file join $rootDir subdir5]
136136
test mv-soft-absolute-1 {$RESULT eq "RENAME f5 subdir5/f5"}
137137
138138
fossil revert
139139
test mv-soft-absolute-2 {
140
- [normalize_result] eq "DELETE subdir5/f5\nREVERT f5${undoMsg}"
140
+ [normalize_result] eq "REVERT f5\nDELETE subdir5/f5${undoMsg}"
141141
}
142142
143143
cd $rootDir
144144
145145
###################################
@@ -152,11 +152,11 @@
152152
fossil mv [file join $rootDir f6] [file join $rootDir subdir6 f6]
153153
test mv-soft-absolute-3 {$RESULT eq "RENAME f6 subdir6/f6"}
154154
155155
fossil revert
156156
test mv-soft-absolute-4 {
157
- [normalize_result] eq "DELETE subdir6/f6\nREVERT f6${undoMsg}"
157
+ [normalize_result] eq "REVERT f6\nDELETE subdir6/f6${undoMsg}"
158158
}
159159
160160
cd $rootDir
161161
162162
########################################
@@ -171,11 +171,11 @@
171171
[normalize_result] eq "RENAME f7 subdir7/f7\nMOVED_FILE ${rootDir}/f7"
172172
}
173173
174174
fossil revert
175175
test mv-hard-absolute-2 {
176
- [normalize_result] eq "DELETE subdir7/f7\nREVERT f7${undoMsg}"
176
+ [normalize_result] eq "REVERT f7\nDELETE subdir7/f7${undoMsg}"
177177
}
178178
179179
cd $rootDir
180180
181181
###################################
@@ -190,11 +190,11 @@
190190
[normalize_result] eq "RENAME f8 subdir8/f8\nMOVED_FILE ${rootDir}/f8"
191191
}
192192
193193
fossil revert
194194
test mv-hard-absolute-4 {
195
- [normalize_result] eq "DELETE subdir8/f8\nREVERT f8${undoMsg}"
195
+ [normalize_result] eq "REVERT f8\nDELETE subdir8/f8${undoMsg}"
196196
}
197197
198198
cd $rootDir
199199
200200
##########################################
201201
--- test/mv-rm.test
+++ test/mv-rm.test
@@ -63,11 +63,11 @@
63 fossil mv ../f1 .
64 test mv-soft-relative-1 {$RESULT eq "RENAME f1 subdir1/f1"}
65
66 fossil revert
67 test mv-soft-relative-2 {
68 [normalize_result] eq "DELETE subdir1/f1\nREVERT f1${undoMsg}"
69 }
70
71 cd $rootDir
72
73 ###################################
@@ -80,11 +80,11 @@
80 fossil mv ../f2 ./f2
81 test mv-soft-relative-3 {$RESULT eq "RENAME f2 subdir2/f2"}
82
83 fossil revert
84 test mv-soft-relative-4 {
85 [normalize_result] eq "DELETE subdir2/f2\nREVERT f2${undoMsg}"
86 }
87
88 cd $rootDir
89
90 ########################################
@@ -99,11 +99,11 @@
99 [normalize_result] eq "RENAME f3 subdir3/f3\nMOVED_FILE ${rootDir}/f3"
100 }
101
102 fossil revert
103 test mv-hard-relative-2 {
104 [normalize_result] eq "DELETE subdir3/f3\nREVERT f3${undoMsg}"
105 }
106
107 cd $rootDir
108
109 ###################################
@@ -118,11 +118,11 @@
118 [normalize_result] eq "RENAME f4 subdir4/f4\nMOVED_FILE ${rootDir}/f4"
119 }
120
121 fossil revert
122 test mv-hard-relative-4 {
123 [normalize_result] eq "DELETE subdir4/f4\nREVERT f4${undoMsg}"
124 }
125
126 cd $rootDir
127
128 ########################################
@@ -135,11 +135,11 @@
135 fossil mv [file join $rootDir f5] [file join $rootDir subdir5]
136 test mv-soft-absolute-1 {$RESULT eq "RENAME f5 subdir5/f5"}
137
138 fossil revert
139 test mv-soft-absolute-2 {
140 [normalize_result] eq "DELETE subdir5/f5\nREVERT f5${undoMsg}"
141 }
142
143 cd $rootDir
144
145 ###################################
@@ -152,11 +152,11 @@
152 fossil mv [file join $rootDir f6] [file join $rootDir subdir6 f6]
153 test mv-soft-absolute-3 {$RESULT eq "RENAME f6 subdir6/f6"}
154
155 fossil revert
156 test mv-soft-absolute-4 {
157 [normalize_result] eq "DELETE subdir6/f6\nREVERT f6${undoMsg}"
158 }
159
160 cd $rootDir
161
162 ########################################
@@ -171,11 +171,11 @@
171 [normalize_result] eq "RENAME f7 subdir7/f7\nMOVED_FILE ${rootDir}/f7"
172 }
173
174 fossil revert
175 test mv-hard-absolute-2 {
176 [normalize_result] eq "DELETE subdir7/f7\nREVERT f7${undoMsg}"
177 }
178
179 cd $rootDir
180
181 ###################################
@@ -190,11 +190,11 @@
190 [normalize_result] eq "RENAME f8 subdir8/f8\nMOVED_FILE ${rootDir}/f8"
191 }
192
193 fossil revert
194 test mv-hard-absolute-4 {
195 [normalize_result] eq "DELETE subdir8/f8\nREVERT f8${undoMsg}"
196 }
197
198 cd $rootDir
199
200 ##########################################
201
--- test/mv-rm.test
+++ test/mv-rm.test
@@ -63,11 +63,11 @@
63 fossil mv ../f1 .
64 test mv-soft-relative-1 {$RESULT eq "RENAME f1 subdir1/f1"}
65
66 fossil revert
67 test mv-soft-relative-2 {
68 [normalize_result] eq "REVERT f1\nDELETE subdir1/f1${undoMsg}"
69 }
70
71 cd $rootDir
72
73 ###################################
@@ -80,11 +80,11 @@
80 fossil mv ../f2 ./f2
81 test mv-soft-relative-3 {$RESULT eq "RENAME f2 subdir2/f2"}
82
83 fossil revert
84 test mv-soft-relative-4 {
85 [normalize_result] eq "REVERT f2\nDELETE subdir2/f2${undoMsg}"
86 }
87
88 cd $rootDir
89
90 ########################################
@@ -99,11 +99,11 @@
99 [normalize_result] eq "RENAME f3 subdir3/f3\nMOVED_FILE ${rootDir}/f3"
100 }
101
102 fossil revert
103 test mv-hard-relative-2 {
104 [normalize_result] eq "REVERT f3\nDELETE subdir3/f3${undoMsg}"
105 }
106
107 cd $rootDir
108
109 ###################################
@@ -118,11 +118,11 @@
118 [normalize_result] eq "RENAME f4 subdir4/f4\nMOVED_FILE ${rootDir}/f4"
119 }
120
121 fossil revert
122 test mv-hard-relative-4 {
123 [normalize_result] eq "REVERT f4\nDELETE subdir4/f4${undoMsg}"
124 }
125
126 cd $rootDir
127
128 ########################################
@@ -135,11 +135,11 @@
135 fossil mv [file join $rootDir f5] [file join $rootDir subdir5]
136 test mv-soft-absolute-1 {$RESULT eq "RENAME f5 subdir5/f5"}
137
138 fossil revert
139 test mv-soft-absolute-2 {
140 [normalize_result] eq "REVERT f5\nDELETE subdir5/f5${undoMsg}"
141 }
142
143 cd $rootDir
144
145 ###################################
@@ -152,11 +152,11 @@
152 fossil mv [file join $rootDir f6] [file join $rootDir subdir6 f6]
153 test mv-soft-absolute-3 {$RESULT eq "RENAME f6 subdir6/f6"}
154
155 fossil revert
156 test mv-soft-absolute-4 {
157 [normalize_result] eq "REVERT f6\nDELETE subdir6/f6${undoMsg}"
158 }
159
160 cd $rootDir
161
162 ########################################
@@ -171,11 +171,11 @@
171 [normalize_result] eq "RENAME f7 subdir7/f7\nMOVED_FILE ${rootDir}/f7"
172 }
173
174 fossil revert
175 test mv-hard-absolute-2 {
176 [normalize_result] eq "REVERT f7\nDELETE subdir7/f7${undoMsg}"
177 }
178
179 cd $rootDir
180
181 ###################################
@@ -190,11 +190,11 @@
190 [normalize_result] eq "RENAME f8 subdir8/f8\nMOVED_FILE ${rootDir}/f8"
191 }
192
193 fossil revert
194 test mv-hard-absolute-4 {
195 [normalize_result] eq "REVERT f8\nDELETE subdir8/f8${undoMsg}"
196 }
197
198 cd $rootDir
199
200 ##########################################
201
+105 -14
--- test/revert.test
+++ test/revert.test
@@ -23,11 +23,10 @@
2323
# Test 'fossil revert' against expected results from 'fossil changes' and
2424
# 'fossil addremove -n', as well as by verifying the existence of files
2525
# on the file system. 'fossil undo' is called after each test
2626
#
2727
proc revert-test {testid revertArgs expectedRevertOutput args} {
28
- global RESULT
2928
set passed 1
3029
3130
set args [dict merge {
3231
-changes {} -addremove {} -exists {} -notexists {}
3332
} $args]
@@ -42,10 +41,11 @@
4241
test_status_list revert-$testid$key $result $expected
4342
}
4443
4544
set fileExistsTests [list -exists 1 does -notexists 0 should]
4645
foreach {key expected verb} $fileExistsTests {
46
+ set passed 1
4747
foreach path [dict get $args $key] {
4848
if {[file exists $path] != $expected} {
4949
set passed 0
5050
protOut " Failure: File $verb not exist: $path"
5151
}
@@ -53,21 +53,34 @@
5353
test revert-$testid$key $passed
5454
}
5555
5656
fossil undo
5757
}
58
+
59
+# Test that a 'fossil revert' call is a no-op.
60
+proc noop-revert-test {testid revertArgs} {
61
+ set changes [fossil changes]
62
+ set undo [fossil undo -n]
63
+ test revert-$testid {[fossil revert {*}$revertArgs] eq ""}
64
+ test revert-$testid-changes {[fossil changes] eq $changes}
65
+ test revert-$testid-undo {[fossil undo -n] eq $undo}
66
+}
5867
5968
require_no_open_checkout
6069
test_setup
6170
6271
# Prepare first commit
6372
#
6473
write_file f1 "f1"
6574
write_file f2 "f2"
6675
write_file f3 "f3"
67
-fossil add f1 f2 f3
68
-fossil commit -m "c1"
76
+write_file f4 "f4"
77
+fossil add f1 f2 f3 f4
78
+fossil commit -m "c1" --tag c1
79
+
80
+write_file f4 "f4.1"
81
+fossil commit -m "c2" --tag c2
6982
7083
# Make changes to be reverted
7184
#
7285
# Add f0
7386
write_file f0 "f0"
@@ -89,11 +102,11 @@
89102
REVERT f2
90103
REVERT f3
91104
DELETE f3n
92105
} -addremove {
93106
ADDED f0
94
-} -exists {f0 f1 f2 f3} -notexists f3n
107
+} -exists {f0 f1 f2 f3 f4} -notexists f3n
95108
96109
# Test with a single filename argument
97110
#
98111
revert-test 1-2 f0 {
99112
UNMANAGE f0
@@ -101,27 +114,27 @@
101114
DELETED f1
102115
EDITED f2
103116
RENAMED f3n
104117
} -addremove {
105118
ADDED f0
106
-} -exists {f0 f2 f3n} -notexists f3
119
+} -exists {f0 f2 f3n f4} -notexists {f1 f3}
107120
108121
revert-test 1-3 f1 {
109122
REVERT f1
110123
} -changes {
111124
ADDED f0
112125
EDITED f2
113126
RENAMED f3n
114
-} -exists {f0 f1 f2 f3n} -notexists f3
127
+} -exists {f0 f1 f2 f3n f4} -notexists f3
115128
116129
revert-test 1-4 f2 {
117130
REVERT f2
118131
} -changes {
119132
ADDED f0
120133
DELETED f1
121134
RENAMED f3n
122
-} -exists {f0 f2 f3n} -notexists {f1 f3}
135
+} -exists {f0 f2 f3n f4} -notexists {f1 f3}
123136
124137
# Both files involved in a rename are reverted regardless of which filename
125138
# is used as an argument to 'fossil revert'
126139
#
127140
revert-test 1-5 f3 {
@@ -129,20 +142,20 @@
129142
DELETE f3n
130143
} -changes {
131144
ADDED f0
132145
DELETED f1
133146
EDITED f2
134
-} -exists {f0 f2 f3} -notexists {f1 f3n}
147
+} -exists {f0 f2 f3 f4} -notexists {f1 f3n}
135148
136149
revert-test 1-6 f3n {
137150
REVERT f3
138151
DELETE f3n
139152
} -changes {
140153
ADDED f0
141154
DELETED f1
142155
EDITED f2
143
-} -exists {f0 f2 f3} -notexists {f1 f3n}
156
+} -exists {f0 f2 f3 f4} -notexists {f1 f3n}
144157
145158
# Test with multiple filename arguments
146159
#
147160
revert-test 1-7 {f0 f2 f3n} {
148161
UNMANAGE f0
@@ -151,11 +164,59 @@
151164
DELETE f3n
152165
} -changes {
153166
DELETED f1
154167
} -addremove {
155168
ADDED f0
156
-} -exists {f0 f2 f3} -notexists {f1 f3n}
169
+} -exists {f0 f2 f3 f4} -notexists {f1 f3n}
170
+
171
+# Test with a revision specified
172
+#
173
+revert-test 1-8 {-r c1 f4} {
174
+ REVERT f4
175
+} -changes {
176
+ ADDED f0
177
+ DELETED f1
178
+ EDITED f2
179
+ RENAMED f3n
180
+ EDITED f4
181
+} -exists {f0 f2 f3n f4} -notexists {f1 f3}
182
+
183
+# Revision specified, no-op revert
184
+#
185
+noop-revert-test 1-9 {-r c2 f4 z1}
186
+
187
+# Invalid revision
188
+#
189
+fossil revert -r turnk f4
190
+test revert-1-10 {$RESULT eq "not found: turnk"}
191
+
192
+# Test case-sensitivity
193
+#
194
+fossil set case-sensitive 0
195
+revert-test 1-11 F3 {
196
+ REVERT f3
197
+ DELETE f3n
198
+} -changes {
199
+ ADDED f0
200
+ DELETED f1
201
+ EDITED f2
202
+} -exists {f0 f2 f3 f4} -notexists {f1 f3n}
203
+
204
+fossil set case-sensitive 1
205
+noop-revert-test 1-12 {F1 f4}
206
+fossil unset case-sensitive
207
+
208
+# No-op revert, no files or revision specified
209
+#
210
+fossil revert
211
+fossil clean -f
212
+noop-revert-test 1-13 {}
213
+
214
+# Reverting a no-op merge is not a no-op revert
215
+#
216
+fossil merge -f c1
217
+revert-test 1-14 {} {}
157218
158219
159220
# Test reverting the combination of a renamed file and an added file that
160221
# uses the renamed file's original filename.
161222
#
@@ -167,14 +228,19 @@
167228
write_file f1n "f1n"
168229
fossil mv f1 f1n
169230
write_file f1 "f1b"
170231
fossil add f1
171232
172
-revert-test 2-1 {} {
173
- REVERT f1
174
- DELETE f1n
175
-} -exists {f1} -notexists {f1n}
233
+foreach {testnum args} {1 {} 2 f1 3 {f1 f1n}} {
234
+ revert-test 2-$testnum $args {
235
+ REVERT f1
236
+ DELETE f1n
237
+ } -exists {f1} -notexists {f1n}
238
+}
239
+
240
+fossil revert f1n
241
+test revert-2-2 {$RESULT eq "cannot revert 'f1n' without 'f1'"}
176242
177243
178244
# Test reverting a rename in the repo but not completed in the file
179245
# system
180246
test_setup
@@ -187,8 +253,33 @@
187253
revert-test 3-1 {} {
188254
REVERT f1
189255
DELETE f1new
190256
} -exists {f1} -notexists {f1n}
191257
258
+
259
+# Test chained renames
260
+#
261
+test_setup
262
+write_file f1 "f1"
263
+write_file f2 "f2"
264
+write_file f3 "f3"
265
+fossil add f1 f2 f3
266
+fossil commit -m "add files"
267
+
268
+fossil mv --hard f1 f0
269
+fossil mv --hard f2 f1
270
+fossil mv --hard f3 f2
271
+
272
+revert-test 4-1 f2 {
273
+ DELETE f1
274
+ REVERT f2
275
+ REVERT f3
276
+} -changes {
277
+ RENAMED f0
278
+} -exists {f0 f2 f3} -notexists {f1}
279
+
280
+fossil revert f1
281
+test revert-4-2 {$RESULT eq "cannot revert 'f1' without 'f2'"}
282
+
192283
###############################################################################
193284
194285
test_cleanup
195286
--- test/revert.test
+++ test/revert.test
@@ -23,11 +23,10 @@
23 # Test 'fossil revert' against expected results from 'fossil changes' and
24 # 'fossil addremove -n', as well as by verifying the existence of files
25 # on the file system. 'fossil undo' is called after each test
26 #
27 proc revert-test {testid revertArgs expectedRevertOutput args} {
28 global RESULT
29 set passed 1
30
31 set args [dict merge {
32 -changes {} -addremove {} -exists {} -notexists {}
33 } $args]
@@ -42,10 +41,11 @@
42 test_status_list revert-$testid$key $result $expected
43 }
44
45 set fileExistsTests [list -exists 1 does -notexists 0 should]
46 foreach {key expected verb} $fileExistsTests {
 
47 foreach path [dict get $args $key] {
48 if {[file exists $path] != $expected} {
49 set passed 0
50 protOut " Failure: File $verb not exist: $path"
51 }
@@ -53,21 +53,34 @@
53 test revert-$testid$key $passed
54 }
55
56 fossil undo
57 }
 
 
 
 
 
 
 
 
 
58
59 require_no_open_checkout
60 test_setup
61
62 # Prepare first commit
63 #
64 write_file f1 "f1"
65 write_file f2 "f2"
66 write_file f3 "f3"
67 fossil add f1 f2 f3
68 fossil commit -m "c1"
 
 
 
 
69
70 # Make changes to be reverted
71 #
72 # Add f0
73 write_file f0 "f0"
@@ -89,11 +102,11 @@
89 REVERT f2
90 REVERT f3
91 DELETE f3n
92 } -addremove {
93 ADDED f0
94 } -exists {f0 f1 f2 f3} -notexists f3n
95
96 # Test with a single filename argument
97 #
98 revert-test 1-2 f0 {
99 UNMANAGE f0
@@ -101,27 +114,27 @@
101 DELETED f1
102 EDITED f2
103 RENAMED f3n
104 } -addremove {
105 ADDED f0
106 } -exists {f0 f2 f3n} -notexists f3
107
108 revert-test 1-3 f1 {
109 REVERT f1
110 } -changes {
111 ADDED f0
112 EDITED f2
113 RENAMED f3n
114 } -exists {f0 f1 f2 f3n} -notexists f3
115
116 revert-test 1-4 f2 {
117 REVERT f2
118 } -changes {
119 ADDED f0
120 DELETED f1
121 RENAMED f3n
122 } -exists {f0 f2 f3n} -notexists {f1 f3}
123
124 # Both files involved in a rename are reverted regardless of which filename
125 # is used as an argument to 'fossil revert'
126 #
127 revert-test 1-5 f3 {
@@ -129,20 +142,20 @@
129 DELETE f3n
130 } -changes {
131 ADDED f0
132 DELETED f1
133 EDITED f2
134 } -exists {f0 f2 f3} -notexists {f1 f3n}
135
136 revert-test 1-6 f3n {
137 REVERT f3
138 DELETE f3n
139 } -changes {
140 ADDED f0
141 DELETED f1
142 EDITED f2
143 } -exists {f0 f2 f3} -notexists {f1 f3n}
144
145 # Test with multiple filename arguments
146 #
147 revert-test 1-7 {f0 f2 f3n} {
148 UNMANAGE f0
@@ -151,11 +164,59 @@
151 DELETE f3n
152 } -changes {
153 DELETED f1
154 } -addremove {
155 ADDED f0
156 } -exists {f0 f2 f3} -notexists {f1 f3n}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
158
159 # Test reverting the combination of a renamed file and an added file that
160 # uses the renamed file's original filename.
161 #
@@ -167,14 +228,19 @@
167 write_file f1n "f1n"
168 fossil mv f1 f1n
169 write_file f1 "f1b"
170 fossil add f1
171
172 revert-test 2-1 {} {
173 REVERT f1
174 DELETE f1n
175 } -exists {f1} -notexists {f1n}
 
 
 
 
 
176
177
178 # Test reverting a rename in the repo but not completed in the file
179 # system
180 test_setup
@@ -187,8 +253,33 @@
187 revert-test 3-1 {} {
188 REVERT f1
189 DELETE f1new
190 } -exists {f1} -notexists {f1n}
191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192 ###############################################################################
193
194 test_cleanup
195
--- test/revert.test
+++ test/revert.test
@@ -23,11 +23,10 @@
23 # Test 'fossil revert' against expected results from 'fossil changes' and
24 # 'fossil addremove -n', as well as by verifying the existence of files
25 # on the file system. 'fossil undo' is called after each test
26 #
27 proc revert-test {testid revertArgs expectedRevertOutput args} {
 
28 set passed 1
29
30 set args [dict merge {
31 -changes {} -addremove {} -exists {} -notexists {}
32 } $args]
@@ -42,10 +41,11 @@
41 test_status_list revert-$testid$key $result $expected
42 }
43
44 set fileExistsTests [list -exists 1 does -notexists 0 should]
45 foreach {key expected verb} $fileExistsTests {
46 set passed 1
47 foreach path [dict get $args $key] {
48 if {[file exists $path] != $expected} {
49 set passed 0
50 protOut " Failure: File $verb not exist: $path"
51 }
@@ -53,21 +53,34 @@
53 test revert-$testid$key $passed
54 }
55
56 fossil undo
57 }
58
59 # Test that a 'fossil revert' call is a no-op.
60 proc noop-revert-test {testid revertArgs} {
61 set changes [fossil changes]
62 set undo [fossil undo -n]
63 test revert-$testid {[fossil revert {*}$revertArgs] eq ""}
64 test revert-$testid-changes {[fossil changes] eq $changes}
65 test revert-$testid-undo {[fossil undo -n] eq $undo}
66 }
67
68 require_no_open_checkout
69 test_setup
70
71 # Prepare first commit
72 #
73 write_file f1 "f1"
74 write_file f2 "f2"
75 write_file f3 "f3"
76 write_file f4 "f4"
77 fossil add f1 f2 f3 f4
78 fossil commit -m "c1" --tag c1
79
80 write_file f4 "f4.1"
81 fossil commit -m "c2" --tag c2
82
83 # Make changes to be reverted
84 #
85 # Add f0
86 write_file f0 "f0"
@@ -89,11 +102,11 @@
102 REVERT f2
103 REVERT f3
104 DELETE f3n
105 } -addremove {
106 ADDED f0
107 } -exists {f0 f1 f2 f3 f4} -notexists f3n
108
109 # Test with a single filename argument
110 #
111 revert-test 1-2 f0 {
112 UNMANAGE f0
@@ -101,27 +114,27 @@
114 DELETED f1
115 EDITED f2
116 RENAMED f3n
117 } -addremove {
118 ADDED f0
119 } -exists {f0 f2 f3n f4} -notexists {f1 f3}
120
121 revert-test 1-3 f1 {
122 REVERT f1
123 } -changes {
124 ADDED f0
125 EDITED f2
126 RENAMED f3n
127 } -exists {f0 f1 f2 f3n f4} -notexists f3
128
129 revert-test 1-4 f2 {
130 REVERT f2
131 } -changes {
132 ADDED f0
133 DELETED f1
134 RENAMED f3n
135 } -exists {f0 f2 f3n f4} -notexists {f1 f3}
136
137 # Both files involved in a rename are reverted regardless of which filename
138 # is used as an argument to 'fossil revert'
139 #
140 revert-test 1-5 f3 {
@@ -129,20 +142,20 @@
142 DELETE f3n
143 } -changes {
144 ADDED f0
145 DELETED f1
146 EDITED f2
147 } -exists {f0 f2 f3 f4} -notexists {f1 f3n}
148
149 revert-test 1-6 f3n {
150 REVERT f3
151 DELETE f3n
152 } -changes {
153 ADDED f0
154 DELETED f1
155 EDITED f2
156 } -exists {f0 f2 f3 f4} -notexists {f1 f3n}
157
158 # Test with multiple filename arguments
159 #
160 revert-test 1-7 {f0 f2 f3n} {
161 UNMANAGE f0
@@ -151,11 +164,59 @@
164 DELETE f3n
165 } -changes {
166 DELETED f1
167 } -addremove {
168 ADDED f0
169 } -exists {f0 f2 f3 f4} -notexists {f1 f3n}
170
171 # Test with a revision specified
172 #
173 revert-test 1-8 {-r c1 f4} {
174 REVERT f4
175 } -changes {
176 ADDED f0
177 DELETED f1
178 EDITED f2
179 RENAMED f3n
180 EDITED f4
181 } -exists {f0 f2 f3n f4} -notexists {f1 f3}
182
183 # Revision specified, no-op revert
184 #
185 noop-revert-test 1-9 {-r c2 f4 z1}
186
187 # Invalid revision
188 #
189 fossil revert -r turnk f4
190 test revert-1-10 {$RESULT eq "not found: turnk"}
191
192 # Test case-sensitivity
193 #
194 fossil set case-sensitive 0
195 revert-test 1-11 F3 {
196 REVERT f3
197 DELETE f3n
198 } -changes {
199 ADDED f0
200 DELETED f1
201 EDITED f2
202 } -exists {f0 f2 f3 f4} -notexists {f1 f3n}
203
204 fossil set case-sensitive 1
205 noop-revert-test 1-12 {F1 f4}
206 fossil unset case-sensitive
207
208 # No-op revert, no files or revision specified
209 #
210 fossil revert
211 fossil clean -f
212 noop-revert-test 1-13 {}
213
214 # Reverting a no-op merge is not a no-op revert
215 #
216 fossil merge -f c1
217 revert-test 1-14 {} {}
218
219
220 # Test reverting the combination of a renamed file and an added file that
221 # uses the renamed file's original filename.
222 #
@@ -167,14 +228,19 @@
228 write_file f1n "f1n"
229 fossil mv f1 f1n
230 write_file f1 "f1b"
231 fossil add f1
232
233 foreach {testnum args} {1 {} 2 f1 3 {f1 f1n}} {
234 revert-test 2-$testnum $args {
235 REVERT f1
236 DELETE f1n
237 } -exists {f1} -notexists {f1n}
238 }
239
240 fossil revert f1n
241 test revert-2-2 {$RESULT eq "cannot revert 'f1n' without 'f1'"}
242
243
244 # Test reverting a rename in the repo but not completed in the file
245 # system
246 test_setup
@@ -187,8 +253,33 @@
253 revert-test 3-1 {} {
254 REVERT f1
255 DELETE f1new
256 } -exists {f1} -notexists {f1n}
257
258
259 # Test chained renames
260 #
261 test_setup
262 write_file f1 "f1"
263 write_file f2 "f2"
264 write_file f3 "f3"
265 fossil add f1 f2 f3
266 fossil commit -m "add files"
267
268 fossil mv --hard f1 f0
269 fossil mv --hard f2 f1
270 fossil mv --hard f3 f2
271
272 revert-test 4-1 f2 {
273 DELETE f1
274 REVERT f2
275 REVERT f3
276 } -changes {
277 RENAMED f0
278 } -exists {f0 f2 f3} -notexists {f1}
279
280 fossil revert f1
281 test revert-4-2 {$RESULT eq "cannot revert 'f1' without 'f2'"}
282
283 ###############################################################################
284
285 test_cleanup
286

Keyboard Shortcuts

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