Index: src/checkin.c
==================================================================
--- src/checkin.c
+++ src/checkin.c
@@ -351,19 +351,19 @@
   if( file_tree_name(g.zRepositoryName, &repo, 0) ){
     db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
   }
   while( db_step(&q)==SQLITE_ROW ){
     if( allFlag ){
-      unlink(db_column_text(&q, 0));
+      file_delete(db_column_text(&q, 0));
     }else{
       Blob ans;
       char *prompt = mprintf("remove unmanaged file \"%s\" (y/N)? ",
                               db_column_text(&q, 0));
       blob_zero(&ans);
       prompt_user(prompt, &ans);
       if( blob_str(&ans)[0]=='y' ){
-        unlink(db_column_text(&q, 0));
+        file_delete(db_column_text(&q, 0));
       }
     }
   }
   db_finalize(&q);
 }
@@ -458,11 +458,11 @@
       if( zIn[0]=='.' && (zIn[1]==0 || zIn[1]=='\r' || zIn[1]=='\n') ) break;
       blob_append(&text, zIn, -1);
     }
   }
   blob_remove_cr(&text);
-  unlink(zFile);
+  file_delete(zFile);
   free(zFile);
   blob_zero(pComment);
   while( blob_line(&text, &line) ){
     int i, n;
     char *z;

Index: src/checkout.c
==================================================================
--- src/checkout.c
+++ src/checkout.c
@@ -157,16 +157,16 @@
     free(zManFile);
     blob_reset(&hash);
   }else{
     if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){
       zManFile = mprintf("%smanifest", g.zLocalRoot);
-      unlink(zManFile);
+      file_delete(zManFile);
       free(zManFile);
     }
     if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){
       zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
-      unlink(zManFile);
+      file_delete(zManFile);
       free(zManFile);
     }
   }
     
 }
@@ -268,11 +268,11 @@
   int i;
   for(i=0; (zReserved = fossil_reserved_name(i))!=0; i++){
     if( manifestOnly==0 || zReserved[0]=='m' ){
       char *z;
       z = mprintf("%s%s", g.zLocalRoot, zReserved);
-      unlink(z);
+      file_delete(z);
       free(z);
     }
   }
 }
 

Index: src/clearsign.c
==================================================================
--- src/clearsign.c
+++ src/clearsign.c
@@ -52,11 +52,11 @@
   }else{
     if( pOut!=pIn ){
       blob_copy(pOut, pIn);
     }
   }
-  unlink(zOut);
-  unlink(zIn);
+  file_delete(zOut);
+  file_delete(zIn);
   free(zOut);
   free(zIn);
   return rc;
 }

Index: src/clone.c
==================================================================
--- src/clone.c
+++ src/clone.c
@@ -100,11 +100,11 @@
     g.xlinkClusterOnly = 0;
     verify_cancel();
     db_end_transaction(0);
     db_close(1);
     if( nErr ){
-      unlink(g.argv[3]);
+      file_delete(g.argv[3]);
       fossil_fatal("server returned an error - clone aborted");
     }
     db_open_repository(g.argv[3]);
   }
   db_begin_transaction();

Index: src/db.c
==================================================================
--- src/db.c
+++ src/db.c
@@ -151,11 +151,11 @@
   if( nBegin ){
     sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0);
     nBegin = 0;
     if( isNewRepo ){
       db_close(0);
-      unlink(g.zRepositoryName);
+      file_delete(g.zRepositoryName);
     }
   }
   busy = 0;
   db_close(0);
 }

Index: src/diffcmd.c
==================================================================
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -99,11 +99,11 @@
 
     /* Run the external diff command */
     fossil_system(blob_str(&cmd));
 
     /* Delete the temporary file and clean up memory used */
-    unlink(blob_str(&nameFile1));
+    file_delete(blob_str(&nameFile1));
     blob_reset(&nameFile1);
     blob_reset(&cmd);
   }
 }
 
@@ -153,12 +153,12 @@
 
     /* Run the external diff command */
     fossil_system(blob_str(&cmd));
 
     /* Delete the temporary file and clean up memory used */
-    unlink(zTemp1);
-    unlink(zTemp2);
+    file_delete(zTemp1);
+    file_delete(zTemp2);
     blob_reset(&cmd);
   }
 }
 
 /*

Index: src/file.c
==================================================================
--- src/file.c
+++ src/file.c
@@ -133,10 +133,17 @@
     if( z[0]=='/' ) zTail = &z[1];
     z++;
   }
   return zTail;
 }
+
+/*
+** Delete a file.
+*/
+void file_delete(const char *zFilename){
+  unlink(zFilename);
+}
 
 /*
 ** Copy the content of a file from one place to another.
 */
 void file_copy(const char *zFrom, const char *zTo){
@@ -151,10 +158,46 @@
     fwrite(zBuf, 1, got, out);
   }
   fclose(in);
   fclose(out);
 }
+
+/*
+** Rename a file.
+*/
+void file_move(const char *zFrom, const char *zTo){
+#if defined(_WIN32)
+  /* if( MoveFileW(zFrom, zTo) ) return; */
+#else
+  if( rename(zFrom, zTo)==0 ) return;
+#endif
+  file_copy(zFrom, zTo);
+  file_delete(zFrom);
+}
+
+/*
+** If the named file exists, move it out of the way so that it will not
+** be overwritten by subsequent operations.
+*/
+void file_dont_overwrite(const char *z){
+  char *zNow;
+  char *zNewName;
+  int cnt = 0;
+  if( file_mtime(z)<0 ) return;
+  if( !file_isfile(0) ){
+    fossil_fatal("cannot overwrite \"%s\"  - not an ordinary file");
+  }
+  zNow = db_text(0, "SELECT strftime('%%Y%%m%%d%%H%%M%%S', 'now')");
+  while(1){
+    zNewName = mprintf("%s-%s-%d", z, zNow, cnt++);
+    if( file_mtime(zNewName)<0 ) break;
+    fossil_free(zNewName);
+  }
+  fossil_free(zNow);
+  file_move(z, zNewName);
+  fossil_free(zNewName);
+}
 
 /*
 ** Set or clear the execute bit on a file.
 */
 void file_setexe(const char *zFilename, int onoff){
@@ -182,11 +225,11 @@
 */
 int file_mkdir(const char *zName, int forceFlag){
   int rc = file_isdir(zName);
   if( rc==2 ){
     if( !forceFlag ) return 1;
-    unlink(zName);
+    file_delete(zName);
   }
   if( rc!=1 ){
 #if defined(_WIN32)
     return mkdir(zName);
 #else

Index: src/http_transport.c
==================================================================
--- src/http_transport.c
+++ src/http_transport.c
@@ -242,12 +242,12 @@
     }else if( g.urlIsFile ){
       if( transport.pFile ){ 
         fclose(transport.pFile);
         transport.pFile = 0;
       }
-      unlink(transport.zInFile);
-      unlink(transport.zOutFile);
+      file_delete(transport.zInFile);
+      file_delete(transport.zOutFile);
       free(transport.zInFile);
       free(transport.zOutFile);
     }else{
       socket_close();
     }

Index: src/import.c
==================================================================
--- src/import.c
+++ src/import.c
@@ -643,11 +643,11 @@
     pIn = fopen(g.argv[3], "rb");
   }else{
     pIn = stdin;
     fossil_binary_mode(pIn);
   }
-  if( forceFlag ) unlink(g.argv[2]);
+  if( forceFlag ) file_delete(g.argv[2]);
   db_create_repository(g.argv[2]);
   db_open_repository(g.argv[2]);
   db_open_config(0);
   db_multi_exec(
      "CREATE TEMP TABLE xtag(tname TEXT UNIQUE, trid INT, tuuid TEXT);"

Index: src/merge.c
==================================================================
--- src/merge.c
+++ src/merge.c
@@ -410,11 +410,11 @@
     db_multi_exec(
       "UPDATE vfile SET deleted=1 WHERE id=%d", idv
     );
     if( !nochangeFlag ){
       char *zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
-      unlink(zFullPath);
+      file_delete(zFullPath);
       free(zFullPath);
     }
   }
   db_finalize(&q);
 
@@ -440,11 +440,11 @@
     );
     if( !nochangeFlag ){
       char *zFullOldPath = mprintf("%s%s", g.zLocalRoot, zOldName);
       char *zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName);
       file_copy(zFullOldPath, zFullNewPath);
-      unlink(zFullOldPath);
+      file_delete(zFullOldPath);
       free(zFullNewPath);
       free(zFullOldPath);
     }
   }
   db_finalize(&q);

Index: src/stash.c
==================================================================
--- src/stash.c
+++ src/stash.c
@@ -188,11 +188,11 @@
       db_ephemeral_blob(&q, 5, &delta);
       blob_write_to_file(&delta, zNPath);
       printf("ADD %s\n", zNew);
     }else if( isRemoved ){
       printf("DELETE %s\n", zOrig);
-      unlink(zOPath);
+      file_delete(zOPath);
     }else{
       Blob a, b, out, disk;
       db_ephemeral_blob(&q, 5, &delta);
       blob_read_from_file(&disk, zOPath);     
       content_get(rid, &a);
@@ -216,11 +216,11 @@
       blob_reset(&disk);
     }
     blob_reset(&delta);
     if( fossil_strcmp(zOrig,zNew)!=0 ){
       undo_save(zOrig);
-      unlink(zOPath);
+      file_delete(zOPath);
     }
   }
   db_finalize(&q);
   if( nConflict ){
     printf("WARNING: merge conflicts - see messages above for details.\n");

Index: src/undo.c
==================================================================
--- src/undo.c
+++ src/undo.c
@@ -59,11 +59,11 @@
         printf("NEW %s\n", zPathname);
       }
       blob_write_to_file(&new, zFullname);
     }else{
       printf("DELETE %s\n", zPathname);
-      unlink(zFullname);
+      file_delete(zFullname);
     }
     blob_reset(&new);
     free(zFullname);
     db_finalize(&q);
     db_prepare(&q, 

Index: src/update.c
==================================================================
--- src/update.c
+++ src/update.c
@@ -358,11 +358,11 @@
         printf("CONFLICT %s - edited locally but deleted by update\n", zName);
         nConflict++;
       }else{
         printf("REMOVE %s\n", zName);
         undo_save(zName);
-        if( !nochangeFlag ) unlink(zFullPath);
+        if( !nochangeFlag ) file_delete(zFullPath);
       }
     }else if( idt>0 && idv>0 && ridt!=ridv && chnged ){
       /* Merge the changes in the current tree into the target version */
       Blob e, r, t, v;
       int rc;
@@ -386,11 +386,11 @@
       }else{
         if( !nochangeFlag ) blob_write_to_file(&t, zFullNewPath);
         printf("***** Cannot merge binary file %s\n", zNewName);
         nConflict++;
       }
-      if( nameChng && !nochangeFlag ) unlink(zFullPath);
+      if( nameChng && !nochangeFlag ) file_delete(zFullPath);
       blob_reset(&v);
       blob_reset(&e);
       blob_reset(&t);
       blob_reset(&r);
     }else{

Index: src/vfile.c
==================================================================
--- src/vfile.c
+++ src/vfile.c
@@ -268,11 +268,11 @@
                  " WHERE vid=%d AND mrid>0", g.zLocalRoot, vid);
   while( db_step(&q)==SQLITE_ROW ){
     const char *zName;
 
     zName = db_column_text(&q, 0);
-    unlink(zName);
+    file_delete(zName);
   }
   db_finalize(&q);
   db_multi_exec("UPDATE vfile SET mtime=NULL WHERE vid=%d AND mrid>0", vid);
 }
 

Index: src/winhttp.c
==================================================================
--- src/winhttp.c
+++ src/winhttp.c
@@ -123,12 +123,12 @@
 
 end_request:
   if( out ) fclose(out);
   if( in ) fclose(in);
   closesocket(p->s);
-  unlink(zRequestFName);
-  unlink(zReplyFName);
+  file_delete(zRequestFName);
+  file_delete(zReplyFName);
   free(p);
 }
 
 /*
 ** Start a listening socket and process incoming HTTP requests on
@@ -146,11 +146,11 @@
   SOCKADDR_IN addr;
   int idCnt = 0;
   int iPort = mnPort;
   char *zNotFoundOption;
 
-  if( zStopper ) unlink(zStopper);
+  if( zStopper ) file_delete(zStopper);
   if( zNotFound ){
     zNotFoundOption = mprintf(" --notfound %s", zNotFound);
   }else{
     zNotFoundOption = "";
   }