On a CIFS/SMB share every save asked "Someone else changed the file on
disk", because the size and modification time read straight after
saving can be the client's cached values, not the server's final ones,
and the next save demanded an exact match.
The size and time are still the quick check. When they differ, the file
now counts as changed only if its content differs from what this QET
last read or wrote (a SHA-1 kept at open and after each save). A real
change by someone else still asks; the same bytes with a new time do
not.
tst_changedondisk: sameContentNewTimeSaves fails before and passes
after; the two conflict cases now move a symbol so the content really
changes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A project opened from a .qet was saved as a .qetz beside it, with a
notice, and the .qet left as it was: a project kept in git did not stay
a .qet. Save now writes the format the project was opened in; only Save
As changes it (scorpio810, discussion #1512). A .qetz is saved as a
.qetz as before.
The save-beside path goes: the flag set on opening, the .qetz path made
from the .qet's, write()'s switch to it and back on failure, and the
notice and replace question in ProjectView::doSave().
tst_resaveunchanged::qetSavedAsQetzBeside becomes qetSavedAsQet: Save of
an opened .qet writes no .qetz and the .qet holds what a plain save of
it holds (it fails without the fix: a .qetz is written beside).
tst_changedondisk makes its .qetz with Save As, as Save no longer does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saving replaced the project file whatever had happened to it since it was
opened. If another user, another program or a second QET had saved the same
file in between (a shared drive, a copy synced from another PC), their work
was lost without a word.
QETProject now remembers the project file's size and modification time when
it reads it and after each save of its own. Before writing, write() compares
them with the file on disk and, if they differ, writes nothing and returns
"someone else changed the file on disk at <time> since it was opened".
- Interactive save (Ctrl+S, and the save on closing a project) asks:
"Someone else changed <file> on disk at <time> since you opened it" with
Save as a copy (opens Save As), Overwrite, or Cancel.
- Scripts (--run), the command line, MCP and the autosave timer have no one
to ask, so they keep the refusal (autosave logs it). Setting
QET_OVERWRITE_CHANGED=1 makes a script overwrite on purpose.
- A file that does not exist yet, and a Save As to another name, are not a
conflict; after Save As the remembered state is the new file's.
No change to what is written, so .qet and .qetz stay as they were.
Evidence: new tst_changedondisk (unchanged file saves twice; a file written
behind the open project is refused; the override overwrites; a Save As
target is no conflict) fails on the changed-file case without the source
change and passes with it. Full ctest 107/107. Physical check with
qet-gui-dialog.sh: file modified behind the open project, Ctrl+S shows the
three-button dialog.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MgPFANhWgD66V3v9KVKV58