satiromarra / vscode-sftp

Super fast sftp/ftp extension for VS Code
Other
23 stars 3 forks source link

Upload over newer file check on upload, not save #70

Closed andreysamode closed 1 year ago

andreysamode commented 1 year ago

Would it be possible to enable the override check on Right Click > Upload with uploadOnSave turned off? Currently, it appears that the date is only checked when saving, not plain uploading.

I imagine currently the timestamp is checked before saving, so the local pre-save mtime is checked against the server's mtime to determine which one's newer. If the local file was modified outside of VSCode, however, or if uploadOnSave was turned off for a time, it breaks the system.

I think a more reliable way of checking timestamps would be the last-upload mtime rather than the pre-current-save mtime.

One way to achieve this could be to index all the files and store their mtime, then on upload check against that mtime, and update it on a successful upload.

satiromarra commented 1 year ago

@mrandrey Any internal or external action can "corrupt" the integrity of the data.

In the moment before saving the file, the date that the local file has against the remote one is checked, but vscode always saves the file and this causes the mtime to be lost if the file is not uploaded, if at least vscode allowed to avoid saving it, the original mtime would be kept.

I also have that at the time of opening or closing a file I get the local data as mtime, atime, perms, etc.. and index them for other checks.

Any changes added to this can cause other problems.

As a suggestion, if you have doubts about whether a file is modified or not, select the "Diff with remote" in context menu option.

andreysamode commented 1 year ago

That's what I mean - because it's the local file's mtime that's being compared, when VSCode saves regardless of choice, we have problems. One way to avoid that would be to store mtime separately in globalState: https://stackoverflow.com/questions/51821924/how-to-persist-information-for-a-vscode-extension

On initial launch, the mtime of all the files is loaded into globalState. When file is created/uploaded/downloaded, the globalState entry is updated. When uploading, instead of checking local file's mtime, you can check the globalState entry's mtime against remote mtime. When you cancel, globalState doesn't get updated.

I think this would be much more stable, and would allow for saving and uploading to be treated as two separate actions.

Does this make sense? I'm not sure I'm explaining this too well.

satiromarra commented 1 year ago

Well, globalstate or workspacestate are used to save extensions settings.

If this is used to save the mtime of the files, on the one hand you would generate a greater memory consumption, on the other an increase in cache files since somehow you must save "path": "mtime" as a json.

And on the other hand, the problem would be added that the file is edited locally outside of vscode (textedit, nano, vi, ...) so you would have a different mtime.

It occurs to me that in the event that a file is saved and not uploaded, set the mtime I had before, but I do not know if that would work on all OS.

andreysamode commented 1 year ago

Here's an example. Let's say I'm working on a new client's website, so I have no files in my VSCode project.

I download index.html to make an update.

globalState['index.html'] = current time

I work on the file for a bit locally, save it.

globalState['index.html'] does't get updated.

I upload the file to the server

compare globalState['index.html'] with remote mtime = local is newer upload file globalState['index.html'] = current time

Someone else updates index.html on the server

remote mtime gets updated

I make some changes, save the file and upload it

compare globalState['index.html'] with remote mtime = remote is newer alert that file is newer with option to override or show diff

I look at diff, then decide to download the updated file

globalState['index.html'] = current time

When I update the file externally, it's still the globalState['index.html'] that gets compared, not the file's mtime.

If globalState['index.html'] is too much for json, it can be something like globalState['sftp' : [{'index.html', 'current time'}]]. I don't think filename and a timestamp is going to be that much of a memory hit even on a project with 1000 files.

Some numbers: "1688473103" + "index.html" = 21 characters. Let's round it to 25 and double it for super long filenames, so 50 characters per entry. If the site has 1000 files locally, that's 50,000 characters or 50KB. Given that my laptop has 16G, that's 0.0003125%. Even there are several CMSs kept locally, and we're tracking twenty times more files (20,000), it'll still only be a megabyte.