Fossil SCM
Modified revert to always process symbolic links. Also added link_delete to complement file_delete, as windows needs special delete handling for symbolic links as they might be directory symlinks.
Commit
9e0ba1215daee4b01519077878c7b515e6c6786b
Parent
1f1f75066a2e4a3…
6 files changed
+18
+1
-1
+1
-1
+2
-2
+1
-1
+13
-6
+18
| --- src/file.c | ||
| +++ src/file.c | ||
| @@ -520,10 +520,28 @@ | ||
| 520 | 520 | int file_delete(const char *zFilename){ |
| 521 | 521 | int rc; |
| 522 | 522 | #ifdef _WIN32 |
| 523 | 523 | wchar_t *z = fossil_utf8_to_filename(zFilename); |
| 524 | 524 | rc = _wunlink(z); |
| 525 | +#else | |
| 526 | + char *z = fossil_utf8_to_filename(zFilename); | |
| 527 | + rc = unlink(zFilename); | |
| 528 | +#endif | |
| 529 | + fossil_filename_free(z); | |
| 530 | + return rc; | |
| 531 | +} | |
| 532 | + | |
| 533 | +/* | |
| 534 | +** Delete a link. | |
| 535 | +** | |
| 536 | +** Returns zero upon success. | |
| 537 | +*/ | |
| 538 | +int link_delete(const char *zFilename){ | |
| 539 | + int rc; | |
| 540 | +#ifdef _WIN32 | |
| 541 | + wchar_t *z = fossil_utf8_to_filename(zFilename); | |
| 542 | + rc = win32_unlink_rmdir(z); | |
| 525 | 543 | #else |
| 526 | 544 | char *z = fossil_utf8_to_filename(zFilename); |
| 527 | 545 | rc = unlink(zFilename); |
| 528 | 546 | #endif |
| 529 | 547 | fossil_filename_free(z); |
| 530 | 548 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -520,10 +520,28 @@ | |
| 520 | int file_delete(const char *zFilename){ |
| 521 | int rc; |
| 522 | #ifdef _WIN32 |
| 523 | wchar_t *z = fossil_utf8_to_filename(zFilename); |
| 524 | rc = _wunlink(z); |
| 525 | #else |
| 526 | char *z = fossil_utf8_to_filename(zFilename); |
| 527 | rc = unlink(zFilename); |
| 528 | #endif |
| 529 | fossil_filename_free(z); |
| 530 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -520,10 +520,28 @@ | |
| 520 | int file_delete(const char *zFilename){ |
| 521 | int rc; |
| 522 | #ifdef _WIN32 |
| 523 | wchar_t *z = fossil_utf8_to_filename(zFilename); |
| 524 | rc = _wunlink(z); |
| 525 | #else |
| 526 | char *z = fossil_utf8_to_filename(zFilename); |
| 527 | rc = unlink(zFilename); |
| 528 | #endif |
| 529 | fossil_filename_free(z); |
| 530 | return rc; |
| 531 | } |
| 532 | |
| 533 | /* |
| 534 | ** Delete a link. |
| 535 | ** |
| 536 | ** Returns zero upon success. |
| 537 | */ |
| 538 | int link_delete(const char *zFilename){ |
| 539 | int rc; |
| 540 | #ifdef _WIN32 |
| 541 | wchar_t *z = fossil_utf8_to_filename(zFilename); |
| 542 | rc = win32_unlink_rmdir(z); |
| 543 | #else |
| 544 | char *z = fossil_utf8_to_filename(zFilename); |
| 545 | rc = unlink(zFilename); |
| 546 | #endif |
| 547 | fossil_filename_free(z); |
| 548 |
+1
-1
| --- src/stash.c | ||
| +++ src/stash.c | ||
| @@ -242,11 +242,11 @@ | ||
| 242 | 242 | } |
| 243 | 243 | content_get(rid, &a); |
| 244 | 244 | blob_delta_apply(&a, &delta, &b); |
| 245 | 245 | if( isLink == isNewLink && blob_compare(&disk, &a)==0 ){ |
| 246 | 246 | if( isLink || isNewLink ){ |
| 247 | - file_delete(zNPath); | |
| 247 | + link_delete(zNPath); | |
| 248 | 248 | } |
| 249 | 249 | if( isLink ){ |
| 250 | 250 | symlink_create(blob_str(&b), zNPath); |
| 251 | 251 | }else{ |
| 252 | 252 | blob_write_to_file(&b, zNPath); |
| 253 | 253 |
| --- src/stash.c | |
| +++ src/stash.c | |
| @@ -242,11 +242,11 @@ | |
| 242 | } |
| 243 | content_get(rid, &a); |
| 244 | blob_delta_apply(&a, &delta, &b); |
| 245 | if( isLink == isNewLink && blob_compare(&disk, &a)==0 ){ |
| 246 | if( isLink || isNewLink ){ |
| 247 | file_delete(zNPath); |
| 248 | } |
| 249 | if( isLink ){ |
| 250 | symlink_create(blob_str(&b), zNPath); |
| 251 | }else{ |
| 252 | blob_write_to_file(&b, zNPath); |
| 253 |
| --- src/stash.c | |
| +++ src/stash.c | |
| @@ -242,11 +242,11 @@ | |
| 242 | } |
| 243 | content_get(rid, &a); |
| 244 | blob_delta_apply(&a, &delta, &b); |
| 245 | if( isLink == isNewLink && blob_compare(&disk, &a)==0 ){ |
| 246 | if( isLink || isNewLink ){ |
| 247 | link_delete(zNPath); |
| 248 | } |
| 249 | if( isLink ){ |
| 250 | symlink_create(blob_str(&b), zNPath); |
| 251 | }else{ |
| 252 | blob_write_to_file(&b, zNPath); |
| 253 |
+1
-1
| --- src/undo.c | ||
| +++ src/undo.c | ||
| @@ -71,11 +71,11 @@ | ||
| 71 | 71 | fossil_print("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname); |
| 72 | 72 | }else{ |
| 73 | 73 | fossil_print("NEW %s\n", zPathname); |
| 74 | 74 | } |
| 75 | 75 | if( new_exists && (new_link || old_link) ){ |
| 76 | - file_delete(zFullname); | |
| 76 | + link_delete(zFullname); | |
| 77 | 77 | } |
| 78 | 78 | if( old_link ){ |
| 79 | 79 | symlink_create(blob_str(&new), zFullname); |
| 80 | 80 | }else{ |
| 81 | 81 | blob_write_to_file(&new, zFullname); |
| 82 | 82 |
| --- src/undo.c | |
| +++ src/undo.c | |
| @@ -71,11 +71,11 @@ | |
| 71 | fossil_print("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname); |
| 72 | }else{ |
| 73 | fossil_print("NEW %s\n", zPathname); |
| 74 | } |
| 75 | if( new_exists && (new_link || old_link) ){ |
| 76 | file_delete(zFullname); |
| 77 | } |
| 78 | if( old_link ){ |
| 79 | symlink_create(blob_str(&new), zFullname); |
| 80 | }else{ |
| 81 | blob_write_to_file(&new, zFullname); |
| 82 |
| --- src/undo.c | |
| +++ src/undo.c | |
| @@ -71,11 +71,11 @@ | |
| 71 | fossil_print("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname); |
| 72 | }else{ |
| 73 | fossil_print("NEW %s\n", zPathname); |
| 74 | } |
| 75 | if( new_exists && (new_link || old_link) ){ |
| 76 | link_delete(zFullname); |
| 77 | } |
| 78 | if( old_link ){ |
| 79 | symlink_create(blob_str(&new), zFullname); |
| 80 | }else{ |
| 81 | blob_write_to_file(&new, zFullname); |
| 82 |
+2
-2
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -766,11 +766,11 @@ | ||
| 766 | 766 | db_multi_exec( |
| 767 | 767 | "DELETE FROM vmerge;" |
| 768 | 768 | "INSERT OR IGNORE INTO torevert " |
| 769 | 769 | " SELECT pathname" |
| 770 | 770 | " FROM vfile " |
| 771 | - " WHERE chnged OR deleted OR rid=0 OR pathname!=origname;" | |
| 771 | + " WHERE chnged OR deleted OR rid=0 OR pathname!=origname OR islink;" | |
| 772 | 772 | ); |
| 773 | 773 | } |
| 774 | 774 | db_multi_exec( |
| 775 | 775 | "INSERT OR IGNORE INTO torevert" |
| 776 | 776 | " SELECT origname" |
| @@ -809,11 +809,11 @@ | ||
| 809 | 809 | ); |
| 810 | 810 | }else{ |
| 811 | 811 | sqlite3_int64 mtime; |
| 812 | 812 | undo_save(zFile); |
| 813 | 813 | if( file_wd_size(zFull)>=0 && (isLink || file_wd_islink(zFull)) ){ |
| 814 | - file_delete(zFull); | |
| 814 | + link_delete(zFull); | |
| 815 | 815 | } |
| 816 | 816 | if( isLink ){ |
| 817 | 817 | symlink_create(blob_str(&record), zFull); |
| 818 | 818 | }else{ |
| 819 | 819 | blob_write_to_file(&record, zFull); |
| 820 | 820 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -766,11 +766,11 @@ | |
| 766 | db_multi_exec( |
| 767 | "DELETE FROM vmerge;" |
| 768 | "INSERT OR IGNORE INTO torevert " |
| 769 | " SELECT pathname" |
| 770 | " FROM vfile " |
| 771 | " WHERE chnged OR deleted OR rid=0 OR pathname!=origname;" |
| 772 | ); |
| 773 | } |
| 774 | db_multi_exec( |
| 775 | "INSERT OR IGNORE INTO torevert" |
| 776 | " SELECT origname" |
| @@ -809,11 +809,11 @@ | |
| 809 | ); |
| 810 | }else{ |
| 811 | sqlite3_int64 mtime; |
| 812 | undo_save(zFile); |
| 813 | if( file_wd_size(zFull)>=0 && (isLink || file_wd_islink(zFull)) ){ |
| 814 | file_delete(zFull); |
| 815 | } |
| 816 | if( isLink ){ |
| 817 | symlink_create(blob_str(&record), zFull); |
| 818 | }else{ |
| 819 | blob_write_to_file(&record, zFull); |
| 820 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -766,11 +766,11 @@ | |
| 766 | db_multi_exec( |
| 767 | "DELETE FROM vmerge;" |
| 768 | "INSERT OR IGNORE INTO torevert " |
| 769 | " SELECT pathname" |
| 770 | " FROM vfile " |
| 771 | " WHERE chnged OR deleted OR rid=0 OR pathname!=origname OR islink;" |
| 772 | ); |
| 773 | } |
| 774 | db_multi_exec( |
| 775 | "INSERT OR IGNORE INTO torevert" |
| 776 | " SELECT origname" |
| @@ -809,11 +809,11 @@ | |
| 809 | ); |
| 810 | }else{ |
| 811 | sqlite3_int64 mtime; |
| 812 | undo_save(zFile); |
| 813 | if( file_wd_size(zFull)>=0 && (isLink || file_wd_islink(zFull)) ){ |
| 814 | link_delete(zFull); |
| 815 | } |
| 816 | if( isLink ){ |
| 817 | symlink_create(blob_str(&record), zFull); |
| 818 | }else{ |
| 819 | blob_write_to_file(&record, zFull); |
| 820 |
+1
-1
| --- src/vfile.c | ||
| +++ src/vfile.c | ||
| @@ -321,11 +321,11 @@ | ||
| 321 | 321 | if( file_wd_isdir(zName) == 1 ){ |
| 322 | 322 | /*TODO(dchest): remove directories? */ |
| 323 | 323 | fossil_fatal("%s is directory, cannot overwrite\n", zName); |
| 324 | 324 | } |
| 325 | 325 | if( file_wd_size(zName)>=0 && (isLink || file_wd_islink(zName)) ){ |
| 326 | - file_delete(zName); | |
| 326 | + link_delete(zName); | |
| 327 | 327 | } |
| 328 | 328 | if( isLink ){ |
| 329 | 329 | symlink_create(blob_str(&content), zName); |
| 330 | 330 | }else{ |
| 331 | 331 | blob_write_to_file(&content, zName); |
| 332 | 332 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -321,11 +321,11 @@ | |
| 321 | if( file_wd_isdir(zName) == 1 ){ |
| 322 | /*TODO(dchest): remove directories? */ |
| 323 | fossil_fatal("%s is directory, cannot overwrite\n", zName); |
| 324 | } |
| 325 | if( file_wd_size(zName)>=0 && (isLink || file_wd_islink(zName)) ){ |
| 326 | file_delete(zName); |
| 327 | } |
| 328 | if( isLink ){ |
| 329 | symlink_create(blob_str(&content), zName); |
| 330 | }else{ |
| 331 | blob_write_to_file(&content, zName); |
| 332 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -321,11 +321,11 @@ | |
| 321 | if( file_wd_isdir(zName) == 1 ){ |
| 322 | /*TODO(dchest): remove directories? */ |
| 323 | fossil_fatal("%s is directory, cannot overwrite\n", zName); |
| 324 | } |
| 325 | if( file_wd_size(zName)>=0 && (isLink || file_wd_islink(zName)) ){ |
| 326 | link_delete(zName); |
| 327 | } |
| 328 | if( isLink ){ |
| 329 | symlink_create(blob_str(&content), zName); |
| 330 | }else{ |
| 331 | blob_write_to_file(&content, zName); |
| 332 |
+13
-6
| --- src/winfile.c | ||
| +++ src/winfile.c | ||
| @@ -175,10 +175,22 @@ | ||
| 175 | 175 | } |
| 176 | 176 | } |
| 177 | 177 | |
| 178 | 178 | return rv; |
| 179 | 179 | } |
| 180 | + | |
| 181 | +int win32_unlink_rmdir(const wchar_t *zFilename){ | |
| 182 | + int rc = -1; | |
| 183 | + fossilStat stat; | |
| 184 | + if (win32_stat(zFilename, &stat) == 0){ | |
| 185 | + if (stat.st_mode == S_IFDIR) | |
| 186 | + rc = RemoveDirectoryW(zFilename) ? 0 : -1; | |
| 187 | + else | |
| 188 | + rc = DeleteFileW(zFilename) ? 0 : -1; | |
| 189 | + } | |
| 190 | + return rc; | |
| 191 | +} | |
| 180 | 192 | |
| 181 | 193 | int win32_symlink(const char *oldpath, const char *newpath){ |
| 182 | 194 | fossilStat stat; |
| 183 | 195 | int created = 0; |
| 184 | 196 | DWORD flags = 0; |
| @@ -192,16 +204,11 @@ | ||
| 192 | 204 | } |
| 193 | 205 | fossil_filename_free(zMbcs); |
| 194 | 206 | |
| 195 | 207 | /* remove newpath before creating the symlink */ |
| 196 | 208 | zMbcs = fossil_utf8_to_filename(newpath); |
| 197 | - if (win32_stat(zMbcs, &stat) == 0){ | |
| 198 | - if (stat.st_mode == S_IFDIR) | |
| 199 | - RemoveDirectory(newpath); | |
| 200 | - else | |
| 201 | - DeleteFile(newpath); | |
| 202 | - } | |
| 209 | + win32_unlink_rmdir(zMbcs); | |
| 203 | 210 | fossil_filename_free(zMbcs); |
| 204 | 211 | |
| 205 | 212 | if (CreateSymbolicLink(newpath, oldpath, flags)) |
| 206 | 213 | created = 1; |
| 207 | 214 | |
| 208 | 215 |
| --- src/winfile.c | |
| +++ src/winfile.c | |
| @@ -175,10 +175,22 @@ | |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | return rv; |
| 179 | } |
| 180 | |
| 181 | int win32_symlink(const char *oldpath, const char *newpath){ |
| 182 | fossilStat stat; |
| 183 | int created = 0; |
| 184 | DWORD flags = 0; |
| @@ -192,16 +204,11 @@ | |
| 192 | } |
| 193 | fossil_filename_free(zMbcs); |
| 194 | |
| 195 | /* remove newpath before creating the symlink */ |
| 196 | zMbcs = fossil_utf8_to_filename(newpath); |
| 197 | if (win32_stat(zMbcs, &stat) == 0){ |
| 198 | if (stat.st_mode == S_IFDIR) |
| 199 | RemoveDirectory(newpath); |
| 200 | else |
| 201 | DeleteFile(newpath); |
| 202 | } |
| 203 | fossil_filename_free(zMbcs); |
| 204 | |
| 205 | if (CreateSymbolicLink(newpath, oldpath, flags)) |
| 206 | created = 1; |
| 207 | |
| 208 |
| --- src/winfile.c | |
| +++ src/winfile.c | |
| @@ -175,10 +175,22 @@ | |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | return rv; |
| 179 | } |
| 180 | |
| 181 | int win32_unlink_rmdir(const wchar_t *zFilename){ |
| 182 | int rc = -1; |
| 183 | fossilStat stat; |
| 184 | if (win32_stat(zFilename, &stat) == 0){ |
| 185 | if (stat.st_mode == S_IFDIR) |
| 186 | rc = RemoveDirectoryW(zFilename) ? 0 : -1; |
| 187 | else |
| 188 | rc = DeleteFileW(zFilename) ? 0 : -1; |
| 189 | } |
| 190 | return rc; |
| 191 | } |
| 192 | |
| 193 | int win32_symlink(const char *oldpath, const char *newpath){ |
| 194 | fossilStat stat; |
| 195 | int created = 0; |
| 196 | DWORD flags = 0; |
| @@ -192,16 +204,11 @@ | |
| 204 | } |
| 205 | fossil_filename_free(zMbcs); |
| 206 | |
| 207 | /* remove newpath before creating the symlink */ |
| 208 | zMbcs = fossil_utf8_to_filename(newpath); |
| 209 | win32_unlink_rmdir(zMbcs); |
| 210 | fossil_filename_free(zMbcs); |
| 211 | |
| 212 | if (CreateSymbolicLink(newpath, oldpath, flags)) |
| 213 | created = 1; |
| 214 | |
| 215 |