mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
FIX: sync compare — treat equivalent symlink targets as equal
When syncing with symlink follow mode set to skip, links may be recreated with different textual targets (e.g. short relative vs longer rebased relative) while still resolving to the same final destination. Sync compare previously used mtime + size; for symlinks on Linux size is just the link text length, so semantically equivalent links were flagged as different after sync. Fix: in TFileSyncRec.UpdateState, when both sides are links, compare resolved absolute targets and treat them as equal if they match.
This commit is contained in:
parent
a4c174d5ba
commit
bb1ad21df0
1 changed files with 26 additions and 1 deletions
|
|
@ -543,6 +543,30 @@ end;
|
|||
procedure TFileSyncRec.UpdateState(ignoreDate: Boolean);
|
||||
var
|
||||
FileTimeDiff: Integer;
|
||||
|
||||
function AreEquivalentLinks: Boolean;
|
||||
var
|
||||
LeftTarget, RightTarget: String;
|
||||
LeftResolved, RightResolved: String;
|
||||
begin
|
||||
Result := False;
|
||||
|
||||
if not (FFileL.IsLink and FFileR.IsLink) then Exit;
|
||||
|
||||
LeftTarget := FFileL.LinkProperty.LinkTo;
|
||||
RightTarget := FFileR.LinkProperty.LinkTo;
|
||||
|
||||
// Fast path: identical link text means semantically identical link.
|
||||
if LeftTarget = RightTarget then Exit(True);
|
||||
|
||||
if (LeftTarget = EmptyStr) or (RightTarget = EmptyStr) then Exit;
|
||||
|
||||
// Also accept different textual forms that resolve to the same target.
|
||||
LeftResolved := GetAbsoluteFileName(FFileL.Path, LeftTarget);
|
||||
RightResolved := GetAbsoluteFileName(FFileR.Path, RightTarget);
|
||||
|
||||
Result := mbCompareFileNames(LeftResolved, RightResolved);
|
||||
end;
|
||||
begin
|
||||
FState := srsNotEq;
|
||||
if Assigned(FFileR) and not Assigned(FFileL) then
|
||||
|
|
@ -552,7 +576,8 @@ begin
|
|||
FState := srsCopyRight
|
||||
else begin
|
||||
FileTimeDiff := FileTimeCompare(FFileL.ModificationTime, FFileR.ModificationTime, FForm.FNtfsShift);
|
||||
if ((FileTimeDiff = 0) or ignoreDate) and (FFileL.Size = FFileR.Size) then
|
||||
if ((FileTimeDiff = 0) or ignoreDate) and
|
||||
((FFileL.Size = FFileR.Size) or AreEquivalentLinks) then
|
||||
FState := srsEqual
|
||||
else
|
||||
if not ignoreDate then
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue