Fossil SCM

Allow a revert of current changes for the whole directory tree

ashepilko 2020-04-30 08:25 trunk
Commit 575fe0c8af6568e861f0a95ea28248003f257c4f6e016740ff9e6188731f9e50
2 files changed +54 -8 +164
+54 -8
--- src/update.c
+++ src/update.c
@@ -794,10 +794,12 @@
794794
const char *zFile; /* Filename relative to checkout root */
795795
const char *zRevision; /* Selected revert version, NULL if current */
796796
Blob record = BLOB_INITIALIZER; /* Contents of each reverted file */
797797
int i;
798798
Stmt q;
799
+ int revert_all = 0;
800
+ int fail_no_revsion_allowed = 0;
799801
800802
undo_capture_command_line();
801803
zRevision = find_option("revision", "r", 1);
802804
verify_all_options();
803805
@@ -821,21 +823,64 @@
821823
for(i=2; i<g.argc; i++){
822824
Blob fname;
823825
zFile = mprintf("%/", g.argv[i]);
824826
blob_zero(&fname);
825827
file_tree_name(zFile, &fname, 0, 1);
826
- db_multi_exec(
827
- "REPLACE INTO torevert VALUES(%B);"
828
- "INSERT OR IGNORE INTO torevert"
829
- " SELECT pathname"
830
- " FROM vfile"
831
- " WHERE origname=%B;",
832
- &fname, &fname
833
- );
828
+ if( blob_eq(&fname, ".") ){
829
+ if( zRevision ){
830
+ fail_no_revsion_allowed = 1;
831
+ break;
832
+ }
833
+ revert_all = 1;
834
+ break;
835
+ }else if( db_exists(
836
+ "SELECT pathname"
837
+ " FROM vfile"
838
+ " WHERE (substr(pathname,1,length('%q/'))='%q/'"
839
+ " OR substr(origname,1,length('%q/'))='%q/');",
840
+ blob_str(&fname), blob_str(&fname),
841
+ blob_str(&fname), blob_str(&fname)) ){
842
+ int vid;
843
+ vid = db_lget_int("checkout", 0);
844
+ vfile_check_signature(vid, 0);
845
+
846
+ if( zRevision ){
847
+ fail_no_revsion_allowed = 1;
848
+ break;
849
+ }
850
+ db_multi_exec(
851
+ "INSERT OR IGNORE INTO torevert"
852
+ " SELECT pathname"
853
+ " FROM vfile"
854
+ " WHERE (substr(pathname,1,length('%q/'))='%q/'"
855
+ " OR substr(origname,1,length('%q/'))='%q/')"
856
+ " AND (chnged OR deleted OR rid=0 OR pathname!=origname);",
857
+ blob_str(&fname), blob_str(&fname),
858
+ blob_str(&fname), blob_str(&fname)
859
+ );
860
+ }else{
861
+ db_multi_exec(
862
+ "REPLACE INTO torevert VALUES(%B);"
863
+ "INSERT OR IGNORE INTO torevert"
864
+ " SELECT pathname"
865
+ " FROM vfile"
866
+ " WHERE origname=%B;",
867
+ &fname, &fname
868
+ );
869
+ }
834870
blob_reset(&fname);
835871
}
836872
}else{
873
+ revert_all = 1;
874
+ }
875
+
876
+ if( fail_no_revsion_allowed ){
877
+ fossil_fatal("the --revision option does not work for the directories"
878
+ " or the entire tree");
879
+ }
880
+
881
+ if ( revert_all ){
837882
int vid;
838883
vid = db_lget_int("checkout", 0);
839884
vfile_check_signature(vid, 0);
840885
db_multi_exec(
841886
"DELETE FROM vmerge;"
@@ -843,10 +888,11 @@
843888
" SELECT pathname"
844889
" FROM vfile "
845890
" WHERE chnged OR deleted OR rid=0 OR pathname!=origname;"
846891
);
847892
}
893
+
848894
db_multi_exec(
849895
"INSERT OR IGNORE INTO torevert"
850896
" SELECT origname"
851897
" FROM vfile"
852898
" WHERE origname!=pathname AND pathname IN (SELECT name FROM torevert);"
853899
--- src/update.c
+++ src/update.c
@@ -794,10 +794,12 @@
794 const char *zFile; /* Filename relative to checkout root */
795 const char *zRevision; /* Selected revert version, NULL if current */
796 Blob record = BLOB_INITIALIZER; /* Contents of each reverted file */
797 int i;
798 Stmt q;
 
 
799
800 undo_capture_command_line();
801 zRevision = find_option("revision", "r", 1);
802 verify_all_options();
803
@@ -821,21 +823,64 @@
821 for(i=2; i<g.argc; i++){
822 Blob fname;
823 zFile = mprintf("%/", g.argv[i]);
824 blob_zero(&fname);
825 file_tree_name(zFile, &fname, 0, 1);
826 db_multi_exec(
827 "REPLACE INTO torevert VALUES(%B);"
828 "INSERT OR IGNORE INTO torevert"
829 " SELECT pathname"
830 " FROM vfile"
831 " WHERE origname=%B;",
832 &fname, &fname
833 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
834 blob_reset(&fname);
835 }
836 }else{
 
 
 
 
 
 
 
 
 
837 int vid;
838 vid = db_lget_int("checkout", 0);
839 vfile_check_signature(vid, 0);
840 db_multi_exec(
841 "DELETE FROM vmerge;"
@@ -843,10 +888,11 @@
843 " SELECT pathname"
844 " FROM vfile "
845 " WHERE chnged OR deleted OR rid=0 OR pathname!=origname;"
846 );
847 }
 
848 db_multi_exec(
849 "INSERT OR IGNORE INTO torevert"
850 " SELECT origname"
851 " FROM vfile"
852 " WHERE origname!=pathname AND pathname IN (SELECT name FROM torevert);"
853
--- src/update.c
+++ src/update.c
@@ -794,10 +794,12 @@
794 const char *zFile; /* Filename relative to checkout root */
795 const char *zRevision; /* Selected revert version, NULL if current */
796 Blob record = BLOB_INITIALIZER; /* Contents of each reverted file */
797 int i;
798 Stmt q;
799 int revert_all = 0;
800 int fail_no_revsion_allowed = 0;
801
802 undo_capture_command_line();
803 zRevision = find_option("revision", "r", 1);
804 verify_all_options();
805
@@ -821,21 +823,64 @@
823 for(i=2; i<g.argc; i++){
824 Blob fname;
825 zFile = mprintf("%/", g.argv[i]);
826 blob_zero(&fname);
827 file_tree_name(zFile, &fname, 0, 1);
828 if( blob_eq(&fname, ".") ){
829 if( zRevision ){
830 fail_no_revsion_allowed = 1;
831 break;
832 }
833 revert_all = 1;
834 break;
835 }else if( db_exists(
836 "SELECT pathname"
837 " FROM vfile"
838 " WHERE (substr(pathname,1,length('%q/'))='%q/'"
839 " OR substr(origname,1,length('%q/'))='%q/');",
840 blob_str(&fname), blob_str(&fname),
841 blob_str(&fname), blob_str(&fname)) ){
842 int vid;
843 vid = db_lget_int("checkout", 0);
844 vfile_check_signature(vid, 0);
845
846 if( zRevision ){
847 fail_no_revsion_allowed = 1;
848 break;
849 }
850 db_multi_exec(
851 "INSERT OR IGNORE INTO torevert"
852 " SELECT pathname"
853 " FROM vfile"
854 " WHERE (substr(pathname,1,length('%q/'))='%q/'"
855 " OR substr(origname,1,length('%q/'))='%q/')"
856 " AND (chnged OR deleted OR rid=0 OR pathname!=origname);",
857 blob_str(&fname), blob_str(&fname),
858 blob_str(&fname), blob_str(&fname)
859 );
860 }else{
861 db_multi_exec(
862 "REPLACE INTO torevert VALUES(%B);"
863 "INSERT OR IGNORE INTO torevert"
864 " SELECT pathname"
865 " FROM vfile"
866 " WHERE origname=%B;",
867 &fname, &fname
868 );
869 }
870 blob_reset(&fname);
871 }
872 }else{
873 revert_all = 1;
874 }
875
876 if( fail_no_revsion_allowed ){
877 fossil_fatal("the --revision option does not work for the directories"
878 " or the entire tree");
879 }
880
881 if ( revert_all ){
882 int vid;
883 vid = db_lget_int("checkout", 0);
884 vfile_check_signature(vid, 0);
885 db_multi_exec(
886 "DELETE FROM vmerge;"
@@ -843,10 +888,11 @@
888 " SELECT pathname"
889 " FROM vfile "
890 " WHERE chnged OR deleted OR rid=0 OR pathname!=origname;"
891 );
892 }
893
894 db_multi_exec(
895 "INSERT OR IGNORE INTO torevert"
896 " SELECT origname"
897 " FROM vfile"
898 " WHERE origname!=pathname AND pathname IN (SELECT name FROM torevert);"
899
--- test/revert.test
+++ test/revert.test
@@ -186,9 +186,173 @@
186186
test 3-mv-2 {![file exists f1new]}
187187
revert-test 3-1 {} {
188188
REVERT f1
189189
DELETE f1new
190190
} -exists {f1} -notexists {f1n}
191
+
192
+
193
+# Test reverting of files under a sub-directory
194
+test_setup
195
+file mkdir d
196
+write_file d/f1 "d/f1"
197
+write_file d/f2 "d/f2"
198
+write_file d/f3 "d/f3"
199
+write_file d/f4 "d/f4"
200
+
201
+fossil add d
202
+fossil delete d/f1
203
+fossil commit -m "d/f2 d/f3 d/f4"
204
+
205
+## Changes to revert
206
+fossil add d/f1
207
+write_file d/f2 "4-1:d/f2"
208
+fossil changes d/f2
209
+fossil delete --soft d/f3
210
+
211
+revert-test 4-1 {d/f1} {
212
+ UNMANAGE d/f1
213
+} -changes {
214
+ EDITED d/f2
215
+ DELETED d/f3
216
+} -addremove {
217
+ ADDED d/f1
218
+} -exists {d/f1 d/f2 d/f3}
219
+
220
+revert-test 4-2 {d/f2} {
221
+ REVERT d/f2
222
+} -changes {
223
+ ADDED d/f1
224
+ DELETED d/f3
225
+} -exists {d/f1 d/f2 d/f3}
226
+
227
+revert-test 4-3 {d/f3} {
228
+ REVERT d/f3
229
+} -changes {
230
+ ADDED d/f1
231
+ EDITED d/f2
232
+} -exists {d/f1 d/f2 d/f3}
233
+
234
+fossil mv --soft d/f4 d/f4new
235
+test 4-4-mv-1 {[file exists d/f4]}
236
+test 4-4-mv-2 {![file exists d/f4new]}
237
+revert-test 4-4 {d/f4} {
238
+ DELETE d/f4new
239
+ REVERT d/f4
240
+} -changes {
241
+ ADDED d/f1
242
+ EDITED d/f2
243
+ DELETED d/f3
244
+} -exists {d/f4} -notexists {d/f4new}
245
+
246
+## Commit changes before testing reverting of directory rename,
247
+## otherwise there're could be sequencing issues
248
+fossil redo
249
+fossil commit -m "4-5:setup"
250
+
251
+fossil mv --soft d dnew
252
+revert-test 4-5 {d/f1 d/f2 d/f3 d/f4} {
253
+ REVERT d/f1
254
+ REVERT d/f2
255
+ UNMANAGE d/f3
256
+ REVERT d/f4
257
+ DELETE dnew/f1
258
+ DELETE dnew/f2
259
+ DELETE dnew/f4
260
+} -addremove {
261
+ ADDED d/f3
262
+} -exists {d/f1 d/f2 d/f3 d/f4} -notexists {dnew}
263
+
264
+
265
+## Test reverting of changes in whole sub-directory tree
266
+test_setup
267
+file mkdir d
268
+write_file f0 "f0"
269
+write_file d/f1 "d/f1"
270
+write_file d/f2 "d/f2"
271
+write_file d/f3 "d/f3"
272
+write_file d/f4 "d/f4"
273
+
274
+fossil add f0 d
275
+fossil delete d/f1
276
+fossil commit -m "f0 d/f2 d/f3 d/f4"
277
+
278
+## Changes to revert
279
+fossil add d/f1
280
+write_file d/f2 "5-1:d/f2"
281
+fossil changes d/f2
282
+fossil delete --soft d/f3
283
+
284
+revert-test 5-1 {d} {
285
+ UNMANAGE d/f1
286
+ REVERT d/f2
287
+ REVERT d/f3
288
+} -addremove {
289
+ ADDED d/f1
290
+} -exists {f0 d/f1 d/f2 d/f3}
291
+
292
+write_file f0 "5-2:f0"
293
+fossil changes f0
294
+revert-test 5-2 {f0 d} {
295
+ UNMANAGE d/f1
296
+ REVERT d/f2
297
+ REVERT d/f3
298
+ REVERT f0
299
+} -addremove {
300
+ ADDED d/f1
301
+} -exists {f0 d/f1 d/f2 d/f3}
302
+
303
+## Commit changes before testing the revert of directory rename,
304
+## otherwise there're could be sequencing issues
305
+fossil commit -m "5-3:setup"
306
+
307
+fossil changes
308
+
309
+fossil mv --soft d dnew
310
+revert-test 5-3 {d} {
311
+ REVERT d/f1
312
+ REVERT d/f2
313
+ REVERT d/f4
314
+ DELETE dnew/f1
315
+ DELETE dnew/f2
316
+ DELETE dnew/f4
317
+} -addremove {
318
+ ADDED d/f3
319
+} -exists {f0 d/f1 d/f2 d/f3 d/f4} -notexists {dnew}
320
+
321
+## Reset/redo the undone results of revert to get to a clean checkout
322
+fossil redo
323
+
324
+file mkdir d/e
325
+file mkdir d/e/f
326
+write_file d/e/fe1 "d/e/fe1"
327
+write_file d/e/f/ff1 "d/e/f/ff1"
328
+
329
+file mkdir d1
330
+file mkdir d1/e
331
+write_file d1/e/fe1 "d1/e/fe1"
332
+write_file d1/e/fe2 "d1/e/fe2"
333
+
334
+fossil add d1/e/fe1
335
+fossil commit d1/e/fe1 -m "d1/e/fe1"
336
+
337
+write_file d1/e/fe1 "5-4:d1/e/fe1"
338
+fossil changes d1/e/fe1
339
+fossil add d d1
340
+
341
+revert-test 5-4 {d d1} {
342
+ UNMANAGE d/f3
343
+ UNMANAGE d/e/fe1
344
+ UNMANAGE d/e/f/ff1
345
+ REVERT d1/e/fe1
346
+ UNMANAGE d1/e/fe2
347
+} -addremove {
348
+ ADDED d/f3
349
+ ADDED d/e/fe1
350
+ ADDED d/e/f/ff1
351
+ ADDED d1/e/fe2
352
+} -exists {d/f1 d/f2 d/f3 d/f4 d/e/fe1 d/e/fe1 d/e/f/ff1
353
+ d1/e/fe1 d1/e/fe2}
354
+
191355
192356
###############################################################################
193357
194358
test_cleanup
195359
--- test/revert.test
+++ test/revert.test
@@ -186,9 +186,173 @@
186 test 3-mv-2 {![file exists f1new]}
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
@@ -186,9 +186,173 @@
186 test 3-mv-2 {![file exists f1new]}
187 revert-test 3-1 {} {
188 REVERT f1
189 DELETE f1new
190 } -exists {f1} -notexists {f1n}
191
192
193 # Test reverting of files under a sub-directory
194 test_setup
195 file mkdir d
196 write_file d/f1 "d/f1"
197 write_file d/f2 "d/f2"
198 write_file d/f3 "d/f3"
199 write_file d/f4 "d/f4"
200
201 fossil add d
202 fossil delete d/f1
203 fossil commit -m "d/f2 d/f3 d/f4"
204
205 ## Changes to revert
206 fossil add d/f1
207 write_file d/f2 "4-1:d/f2"
208 fossil changes d/f2
209 fossil delete --soft d/f3
210
211 revert-test 4-1 {d/f1} {
212 UNMANAGE d/f1
213 } -changes {
214 EDITED d/f2
215 DELETED d/f3
216 } -addremove {
217 ADDED d/f1
218 } -exists {d/f1 d/f2 d/f3}
219
220 revert-test 4-2 {d/f2} {
221 REVERT d/f2
222 } -changes {
223 ADDED d/f1
224 DELETED d/f3
225 } -exists {d/f1 d/f2 d/f3}
226
227 revert-test 4-3 {d/f3} {
228 REVERT d/f3
229 } -changes {
230 ADDED d/f1
231 EDITED d/f2
232 } -exists {d/f1 d/f2 d/f3}
233
234 fossil mv --soft d/f4 d/f4new
235 test 4-4-mv-1 {[file exists d/f4]}
236 test 4-4-mv-2 {![file exists d/f4new]}
237 revert-test 4-4 {d/f4} {
238 DELETE d/f4new
239 REVERT d/f4
240 } -changes {
241 ADDED d/f1
242 EDITED d/f2
243 DELETED d/f3
244 } -exists {d/f4} -notexists {d/f4new}
245
246 ## Commit changes before testing reverting of directory rename,
247 ## otherwise there're could be sequencing issues
248 fossil redo
249 fossil commit -m "4-5:setup"
250
251 fossil mv --soft d dnew
252 revert-test 4-5 {d/f1 d/f2 d/f3 d/f4} {
253 REVERT d/f1
254 REVERT d/f2
255 UNMANAGE d/f3
256 REVERT d/f4
257 DELETE dnew/f1
258 DELETE dnew/f2
259 DELETE dnew/f4
260 } -addremove {
261 ADDED d/f3
262 } -exists {d/f1 d/f2 d/f3 d/f4} -notexists {dnew}
263
264
265 ## Test reverting of changes in whole sub-directory tree
266 test_setup
267 file mkdir d
268 write_file f0 "f0"
269 write_file d/f1 "d/f1"
270 write_file d/f2 "d/f2"
271 write_file d/f3 "d/f3"
272 write_file d/f4 "d/f4"
273
274 fossil add f0 d
275 fossil delete d/f1
276 fossil commit -m "f0 d/f2 d/f3 d/f4"
277
278 ## Changes to revert
279 fossil add d/f1
280 write_file d/f2 "5-1:d/f2"
281 fossil changes d/f2
282 fossil delete --soft d/f3
283
284 revert-test 5-1 {d} {
285 UNMANAGE d/f1
286 REVERT d/f2
287 REVERT d/f3
288 } -addremove {
289 ADDED d/f1
290 } -exists {f0 d/f1 d/f2 d/f3}
291
292 write_file f0 "5-2:f0"
293 fossil changes f0
294 revert-test 5-2 {f0 d} {
295 UNMANAGE d/f1
296 REVERT d/f2
297 REVERT d/f3
298 REVERT f0
299 } -addremove {
300 ADDED d/f1
301 } -exists {f0 d/f1 d/f2 d/f3}
302
303 ## Commit changes before testing the revert of directory rename,
304 ## otherwise there're could be sequencing issues
305 fossil commit -m "5-3:setup"
306
307 fossil changes
308
309 fossil mv --soft d dnew
310 revert-test 5-3 {d} {
311 REVERT d/f1
312 REVERT d/f2
313 REVERT d/f4
314 DELETE dnew/f1
315 DELETE dnew/f2
316 DELETE dnew/f4
317 } -addremove {
318 ADDED d/f3
319 } -exists {f0 d/f1 d/f2 d/f3 d/f4} -notexists {dnew}
320
321 ## Reset/redo the undone results of revert to get to a clean checkout
322 fossil redo
323
324 file mkdir d/e
325 file mkdir d/e/f
326 write_file d/e/fe1 "d/e/fe1"
327 write_file d/e/f/ff1 "d/e/f/ff1"
328
329 file mkdir d1
330 file mkdir d1/e
331 write_file d1/e/fe1 "d1/e/fe1"
332 write_file d1/e/fe2 "d1/e/fe2"
333
334 fossil add d1/e/fe1
335 fossil commit d1/e/fe1 -m "d1/e/fe1"
336
337 write_file d1/e/fe1 "5-4:d1/e/fe1"
338 fossil changes d1/e/fe1
339 fossil add d d1
340
341 revert-test 5-4 {d d1} {
342 UNMANAGE d/f3
343 UNMANAGE d/e/fe1
344 UNMANAGE d/e/f/ff1
345 REVERT d1/e/fe1
346 UNMANAGE d1/e/fe2
347 } -addremove {
348 ADDED d/f3
349 ADDED d/e/fe1
350 ADDED d/e/f/ff1
351 ADDED d1/e/fe2
352 } -exists {d/f1 d/f2 d/f3 d/f4 d/e/fe1 d/e/fe1 d/e/f/ff1
353 d1/e/fe1 d1/e/fe2}
354
355
356 ###############################################################################
357
358 test_cleanup
359

Keyboard Shortcuts

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