lib/model, lib/protocol, lib/scanner: Include symlink target in index, pull symlinks synchronously

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3792
This commit is contained in:
Jakob Borg
2016-12-09 18:02:18 +00:00
committed by Audrius Butkevicius
parent f6a2b6252a
commit 7b07ed6580
12 changed files with 393 additions and 285 deletions

View File

@@ -11,7 +11,6 @@ import (
"os"
"path/filepath"
"runtime"
"strings"
"sync/atomic"
"time"
"unicode/utf8"
@@ -398,21 +397,15 @@ func (w *walker) walkSymlink(absPath, relPath string, dchan chan protocol.FileIn
return true, nil
}
blocks, err := Blocks(strings.NewReader(target), w.BlockSize, -1, nil)
if err != nil {
l.Debugln("hash link error:", absPath, err)
return true, nil
}
// A symlink is "unchanged", if
// - it exists
// - it wasn't deleted (because it isn't now)
// - it was a symlink
// - it wasn't invalid
// - the symlink type (file/dir) was the same
// - the block list (i.e. hash of target) was the same
// - the target was the same
cf, ok := w.CurrentFiler.CurrentFile(relPath)
if ok && !cf.IsDeleted() && cf.IsSymlink() && !cf.IsInvalid() && SymlinkTypeEqual(targetType, cf) && BlocksEqual(cf.Blocks, blocks) {
if ok && !cf.IsDeleted() && cf.IsSymlink() && !cf.IsInvalid() && SymlinkTypeEqual(targetType, cf) && cf.SymlinkTarget == target {
return true, nil
}
@@ -421,7 +414,7 @@ func (w *walker) walkSymlink(absPath, relPath string, dchan chan protocol.FileIn
Type: SymlinkType(targetType),
Version: cf.Version.Update(w.ShortID),
NoPermissions: true, // Symlinks don't have permissions of their own
Blocks: blocks,
SymlinkTarget: target,
}
l.Debugln("symlink changedb:", absPath, f)

View File

@@ -311,23 +311,16 @@ func TestWalkSymlink(t *testing.T) {
files = append(files, f)
}
// Verify that we got one symlink and with the correct block contents
// Verify that we got one symlink and with the correct attributes
if len(files) != 1 {
t.Errorf("expected 1 symlink, not %d", len(files))
}
if len(files[0].Blocks) != 1 {
t.Errorf("expected 1 block, not %d", len(files[0].Blocks))
if len(files[0].Blocks) != 0 {
t.Errorf("expected zero blocks for symlink, not %d", len(files[0].Blocks))
}
if files[0].Blocks[0].Size != int32(len("destination")) {
t.Errorf("expected block length %d, not %d", len("destination"), files[0].Blocks[0].Size)
}
// echo -n "destination" | openssl dgst -sha256
hash := "b5c755aaab1038b3d5627bbde7f47ca80c5f5c0481c6d33f04139d07aa1530e7"
if fmt.Sprintf("%x", files[0].Blocks[0].Hash) != hash {
t.Errorf("incorrect hash")
if files[0].SymlinkTarget != "destination" {
t.Errorf("expected symlink to have target destination, not %q", files[0].SymlinkTarget)
}
}