Fossil with Commonmark

Check-in [9e0ba1215d]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment: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.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | bad-winsymlink
Files: files | file ages | folders
SHA1: 9e0ba1215daee4b01519077878c7b515e6c6786b
User & Date: sdr 2014-09-20 18:11:06
Context
2014-09-20
18:32
Refactored symlink_create repeated block of code into a checked_symlink_create function. check-in: 2d3ff7bd23 user: sdr tags: bad-winsymlink
18:11
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. check-in: 9e0ba1215d user: sdr tags: bad-winsymlink
16:50
Fixed a problem with the high level symlink creation code to accommodate windows drive letters. Also modified windows symlink creation logic to better handle dir/file symlinks. check-in: 1f1f75066a user: sdr tags: bad-winsymlink
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/file.c.

518
519
520
521
522
523
524


















525
526
527
528
529
530
531
** Returns zero upon success.
*/
int file_delete(const char *zFilename){
  int rc;
#ifdef _WIN32
  wchar_t *z = fossil_utf8_to_filename(zFilename);
  rc = _wunlink(z);


















#else
  char *z = fossil_utf8_to_filename(zFilename);
  rc = unlink(zFilename);
#endif
  fossil_filename_free(z);
  return rc;
}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
** Returns zero upon success.
*/
int file_delete(const char *zFilename){
  int rc;
#ifdef _WIN32
  wchar_t *z = fossil_utf8_to_filename(zFilename);
  rc = _wunlink(z);
#else
  char *z = fossil_utf8_to_filename(zFilename);
  rc = unlink(zFilename);
#endif
  fossil_filename_free(z);
  return rc;
}

/*
** Delete a link.
**
** Returns zero upon success.
*/
int link_delete(const char *zFilename){
  int rc;
#ifdef _WIN32
  wchar_t *z = fossil_utf8_to_filename(zFilename);
  rc = win32_unlink_rmdir(z);
#else
  char *z = fossil_utf8_to_filename(zFilename);
  rc = unlink(zFilename);
#endif
  fossil_filename_free(z);
  return rc;
}

Changes to src/stash.c.

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
      }else{
        blob_read_from_file(&disk, zOPath);
      }
      content_get(rid, &a);
      blob_delta_apply(&a, &delta, &b);
      if( isLink == isNewLink && blob_compare(&disk, &a)==0 ){
        if( isLink || isNewLink ){
          file_delete(zNPath);
        }
        if( isLink ){
          symlink_create(blob_str(&b), zNPath);
        }else{
          blob_write_to_file(&b, zNPath);
        }
        file_wd_setexe(zNPath, isExec);







|







240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
      }else{
        blob_read_from_file(&disk, zOPath);
      }
      content_get(rid, &a);
      blob_delta_apply(&a, &delta, &b);
      if( isLink == isNewLink && blob_compare(&disk, &a)==0 ){
        if( isLink || isNewLink ){
          link_delete(zNPath);
        }
        if( isLink ){
          symlink_create(blob_str(&b), zNPath);
        }else{
          blob_write_to_file(&b, zNPath);
        }
        file_wd_setexe(zNPath, isExec);

Changes to src/undo.c.

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
    if( old_exists ){
      if( new_exists ){
        fossil_print("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname);
      }else{
        fossil_print("NEW %s\n", zPathname);
      }
      if( new_exists && (new_link || old_link) ){
        file_delete(zFullname);
      }
      if( old_link ){
        symlink_create(blob_str(&new), zFullname);
      }else{
        blob_write_to_file(&new, zFullname);
      }
      file_wd_setexe(zFullname, old_exe);







|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
    if( old_exists ){
      if( new_exists ){
        fossil_print("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname);
      }else{
        fossil_print("NEW %s\n", zPathname);
      }
      if( new_exists && (new_link || old_link) ){
        link_delete(zFullname);
      }
      if( old_link ){
        symlink_create(blob_str(&new), zFullname);
      }else{
        blob_write_to_file(&new, zFullname);
      }
      file_wd_setexe(zFullname, old_exe);

Changes to src/update.c.

764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
    vid = db_lget_int("checkout", 0);
    vfile_check_signature(vid, 0);
    db_multi_exec(
      "DELETE FROM vmerge;"
      "INSERT OR IGNORE INTO torevert "
      " SELECT pathname"
      "   FROM vfile "
      "  WHERE chnged OR deleted OR rid=0 OR pathname!=origname;"
    );
  }
  db_multi_exec(
    "INSERT OR IGNORE INTO torevert"
    " SELECT origname"
    "   FROM vfile"
    "  WHERE origname!=pathname AND pathname IN (SELECT name FROM torevert);"







|







764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
    vid = db_lget_int("checkout", 0);
    vfile_check_signature(vid, 0);
    db_multi_exec(
      "DELETE FROM vmerge;"
      "INSERT OR IGNORE INTO torevert "
      " SELECT pathname"
      "   FROM vfile "
      "  WHERE chnged OR deleted OR rid=0 OR pathname!=origname OR islink;"
    );
  }
  db_multi_exec(
    "INSERT OR IGNORE INTO torevert"
    " SELECT origname"
    "   FROM vfile"
    "  WHERE origname!=pathname AND pathname IN (SELECT name FROM torevert);"
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
        "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);







|







807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
        "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)) ){
        link_delete(zFull);
      }
      if( isLink ){
        symlink_create(blob_str(&record), zFull);
      }else{
        blob_write_to_file(&record, zFull);
      }
      file_wd_setexe(zFull, isExe);

Changes to src/vfile.c.

319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
    }
    if( verbose ) fossil_print("%s\n", &zName[nRepos]);
    if( file_wd_isdir(zName) == 1 ){
      /*TODO(dchest): remove directories? */
      fossil_fatal("%s is directory, cannot overwrite\n", zName);
    }
    if( file_wd_size(zName)>=0 && (isLink || file_wd_islink(zName)) ){
      file_delete(zName);
    }
    if( isLink ){
      symlink_create(blob_str(&content), zName);
    }else{
      blob_write_to_file(&content, zName);
    }
    file_wd_setexe(zName, isExe);







|







319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
    }
    if( verbose ) fossil_print("%s\n", &zName[nRepos]);
    if( file_wd_isdir(zName) == 1 ){
      /*TODO(dchest): remove directories? */
      fossil_fatal("%s is directory, cannot overwrite\n", zName);
    }
    if( file_wd_size(zName)>=0 && (isLink || file_wd_islink(zName)) ){
      link_delete(zName);
    }
    if( isLink ){
      symlink_create(blob_str(&content), zName);
    }else{
      blob_write_to_file(&content, zName);
    }
    file_wd_setexe(zName, isExe);

Changes to src/winfile.c.

173
174
175
176
177
178
179












180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
      /* all done, close the reparse point */
      CloseHandle(file);
    }
  }

  return rv;
}













int win32_symlink(const char *oldpath, const char *newpath){
  fossilStat stat;
  int created = 0;
  DWORD flags = 0;
  wchar_t *zMbcs;

  /* does oldpath exist? is it a dir or a file? */  
  zMbcs = fossil_utf8_to_filename(oldpath);
  if (win32_stat(zMbcs, &stat) == 0){
    if (stat.st_mode == S_IFDIR)
      flags = SYMBOLIC_LINK_FLAG_DIRECTORY;
  }
  fossil_filename_free(zMbcs);

  /* remove newpath before creating the symlink */
  zMbcs = fossil_utf8_to_filename(newpath);
  if (win32_stat(zMbcs, &stat) == 0){
    if (stat.st_mode == S_IFDIR)
      RemoveDirectory(newpath);
    else
      DeleteFile(newpath);
  }
  fossil_filename_free(zMbcs);

  if (CreateSymbolicLink(newpath, oldpath, flags))
    created = 1;

  /* if the symlink was not created, create a plain text file */
  if (!created){







>
>
>
>
>
>
>
>
>
>
>
>

















|
<
<
<
<
<







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209





210
211
212
213
214
215
216
      /* all done, close the reparse point */
      CloseHandle(file);
    }
  }

  return rv;
}

int win32_unlink_rmdir(const wchar_t *zFilename){
  int rc = -1;
  fossilStat stat;
  if (win32_stat(zFilename, &stat) == 0){
    if (stat.st_mode == S_IFDIR)
      rc = RemoveDirectoryW(zFilename) ? 0 : -1;
    else
      rc = DeleteFileW(zFilename) ? 0 : -1;
  }
  return rc;
}

int win32_symlink(const char *oldpath, const char *newpath){
  fossilStat stat;
  int created = 0;
  DWORD flags = 0;
  wchar_t *zMbcs;

  /* does oldpath exist? is it a dir or a file? */  
  zMbcs = fossil_utf8_to_filename(oldpath);
  if (win32_stat(zMbcs, &stat) == 0){
    if (stat.st_mode == S_IFDIR)
      flags = SYMBOLIC_LINK_FLAG_DIRECTORY;
  }
  fossil_filename_free(zMbcs);

  /* remove newpath before creating the symlink */
  zMbcs = fossil_utf8_to_filename(newpath);
  win32_unlink_rmdir(zMbcs);





  fossil_filename_free(zMbcs);

  if (CreateSymbolicLink(newpath, oldpath, flags))
    created = 1;

  /* if the symlink was not created, create a plain text file */
  if (!created){