Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Fix 'fossil revert' to fully revert renames |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
eef34741a998489ca6c1e6e36a00cf58 |
| User & Date: | joel 2013-01-25 23:49:11.216 |
| Original User & Date: | Joel 2013-01-25 23:49:11.216 |
Context
|
2013-01-26
| ||
| 08:26 | Fix revert tests 5 and 6 so they aren't carbon copies. Minor comment cleanup check-in: 1a5ac30583 user: joel tags: trunk | |
|
2013-01-25
| ||
| 23:49 | Fix 'fossil revert' to fully revert renames check-in: eef34741a9 user: joel tags: trunk | |
| 08:53 | Replaced a ..\ with $B\. check-in: 461a4d11d1 user: stephan tags: trunk | |
Changes
Changes to src/update.c.
| ︙ | ︙ | |||
665 666 667 668 669 670 671 672 673 674 675 676 677 678 | ** COMMAND: revert ** ** Usage: %fossil revert ?-r REVISION? ?FILE ...? ** ** Revert to the current repository version of FILE, or to ** the version associated with baseline REVISION if the -r flag ** appears. ** ** Revert all files if no file name is provided. ** ** If a file is reverted accidently, it can be restored using ** the "fossil undo" command. ** ** Options: | > > > | 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 | ** COMMAND: revert ** ** Usage: %fossil revert ?-r REVISION? ?FILE ...? ** ** Revert to the current repository version of FILE, or to ** the version associated with baseline REVISION if the -r flag ** appears. ** ** If FILE was part of a rename operation, both the original file ** and the renamed file are reverted. ** ** Revert all files if no file name is provided. ** ** If a file is reverted accidently, it can be restored using ** the "fossil undo" command. ** ** Options: |
| ︙ | ︙ | |||
704 705 706 707 708 709 710 |
db_multi_exec("CREATE TEMP TABLE torevert(name UNIQUE);");
if( g.argc>2 ){
for(i=2; i<g.argc; i++){
Blob fname;
zFile = mprintf("%/", g.argv[i]);
file_tree_name(zFile, &fname, 1);
| > | > > > > > > > > > > | 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 |
db_multi_exec("CREATE TEMP TABLE torevert(name UNIQUE);");
if( g.argc>2 ){
for(i=2; i<g.argc; i++){
Blob fname;
zFile = mprintf("%/", g.argv[i]);
file_tree_name(zFile, &fname, 1);
db_multi_exec(
"REPLACE INTO torevert VALUES(%B);"
"INSERT OR IGNORE INTO torevert"
" SELECT pathname"
" FROM vfile"
" WHERE origname IN(%B)"
" UNION ALL"
" SELECT origname"
" FROM vfile"
" WHERE pathname IN(%B) AND origname IS NOT NULL;",
&fname, &fname, &fname
);
blob_reset(&fname);
}
}else{
int vid;
vid = db_lget_int("checkout", 0);
vfile_check_signature(vid, 0);
db_multi_exec(
|
| ︙ | ︙ | |||
746 747 748 749 750 751 752 |
zFile, zFile)==0 ){
fossil_print("UNMANAGE: %s\n", zFile);
}else{
undo_save(zFile);
file_delete(zFull);
fossil_print("DELETE: %s\n", zFile);
}
| > > > > | > > | < | | | 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 |
zFile, zFile)==0 ){
fossil_print("UNMANAGE: %s\n", zFile);
}else{
undo_save(zFile);
file_delete(zFull);
fossil_print("DELETE: %s\n", zFile);
}
db_multi_exec(
"UPDATE vfile"
" SET pathname=origname, origname=NULL"
" WHERE pathname=%Q AND origname!=pathname AND origname IS NOT NULL;"
"DELETE FROM vfile WHERE pathname=%Q",
zFile, zFile
);
}else{
sqlite3_int64 mtime;
undo_save(zFile);
if( file_wd_size(zFull)>=0 && (isLink || file_wd_islink(zFull)) ){
file_delete(zFull);
}
if( isLink ){
symlink_create(blob_str(&record), zFull);
}else{
blob_write_to_file(&record, zFull);
}
file_wd_setexe(zFull, isExe);
fossil_print("REVERTED: %s\n", zFile);
mtime = file_wd_mtime(zFull);
db_multi_exec(
"UPDATE vfile"
" SET mtime=%lld, chnged=0, deleted=0, isexe=%d, islink=%d,mrid=rid"
" WHERE pathname=%Q OR origname=%Q",
mtime, isExe, isLink, zFile, zFile
);
}
blob_reset(&record);
free(zFull);
}
db_finalize(&q);
undo_finish();
db_end_transaction(0);
}
|
Added test/revert.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
#
# Tests for 'fossil revert'
#
#
catch {exec $::fossilexe info} res
puts res=$res
if {![regexp {use --repository} $res]} {
puts stderr "Cannot run this test within an open checkout"
return
}
#
# Fossil will write data on $HOME, running 'fossil new' here.
# We need not to clutter the $HOME of the test caller.
set env(HOME) [pwd]
# Normalize file status lists (like those returned by 'fossil changes')
# so they can be compared using simple string comparison
#
proc normalize-status-list {list} {
set normalized [list]
set matches [regexp -all -inline -line {^\s*([A-Z]+)\s+(.*)$} $list]
foreach {_ status file} $matches {
lappend normalized [list $status [string trim $file]]
}
set normalized [lsort -index 1 $normalized]
return $normalized
}
# Test 'fossil revert' against expected results from 'fossil changes' and
# 'fossil addremove --test', as well as by verifying the existence of files
# on the file system. 'fossil undo' is called after each test
#
proc revert-test {testid args} {
global RESULT
set passed 1
if {[llength $args] % 2} {
set revertArgs [lindex $args 0]
set args [lrange $args 1 end]
} else {
set revertArgs {}
}
set args [dict merge {
-changes {} -addremove {} -exists {} -notexists {}
} $args]
fossil revert {*}$revertArgs
set statusListTests [list -changes changes -addremove {addremove --test}]
foreach {key fossilArgs} $statusListTests {
set expected [normalize-status-list [dict get $args $key]]
set result [normalize-status-list [fossil {*}$fossilArgs]]
if {$result ne $expected} {
set passed 0
protOut " Expected:\n [join $expected "\n "]"
protOut " Got:\n [join $result "\n "]"
}
}
set fileExistsTests [list -exists 1 does -notexists 0 should]
foreach {key expected verb} $fileExistsTests {
foreach path [dict get $args $key] {
if {[file exists $path] != $expected} {
set passed 0
protOut " Failure: File $verb not exist: $path"
}
}
}
fossil undo
test revert-$testid $passed
}
# Create the repo
#
fossil new rep.fossil
fossil open rep.fossil
# Prepare first commit
#
write_file f1 "f1"
write_file f2 "f2"
write_file f3 "f3"
fossil add f1 f2 f3
fossil commit -m "c1"
# Make changes to be reverted
#
# Add f0
write_file f0 "f0"
fossil add f0
# Remove f1
exec rm f1
fossil rm f1
# Edit f2
write_file f2 "f2.1"
# Rename f3 to f3n
exec mv f3 f3n
fossil mv f3 f3n
# Test 'fossil revert' with no arguments
#
revert-test 1 -addremove {
ADDED f0
} -exists {f0 f1 f2 f3} -notexists f3n
# Test with a single filename argument
#
revert-test 2 f0 -changes {
DELETED f1
EDITED f2
RENAMED f3n
} -addremove {
ADDED f0
} -exists {f0 f2 f3n} -notexists f3
#
revert-test 3 f1 -changes {
ADDED f0
EDITED f2
RENAMED f3n
} -exists {f0 f1 f2 f3n} -notexists f3
revert-test 4 f2 -changes {
ADDED f0
DELETED f1
RENAMED f3n
} -exists {f0 f2 f3n} -notexists {f1 f3}
# Both files involved in a rename are reverted regardless of which filename
# is used as an argument to 'fossil revert'
revert-test 5 f3 -changes {
ADDED f0
DELETED f1
EDITED f2
} -exists {f0 f2 f3} -notexists {f1 f3n}
revert-test 6 f3 -changes {
ADDED f0
DELETED f1
EDITED f2
} -exists {f0 f2 f3} -notexists {f1 f3n}
# Test with multiple filename arguments
#
revert-test 7 {f0 f2 f3n} -changes {
DELETED f1
} -addremove {
ADDED f0
} -exists {f0 f2 f3} -notexists {f1 f3n}
|