Implement version vectors
This commit is contained in:
@@ -17,7 +17,6 @@ import (
|
||||
|
||||
"github.com/syncthing/protocol"
|
||||
"github.com/syncthing/syncthing/internal/ignore"
|
||||
"github.com/syncthing/syncthing/internal/lamport"
|
||||
"github.com/syncthing/syncthing/internal/symlinks"
|
||||
"golang.org/x/text/unicode/norm"
|
||||
)
|
||||
@@ -61,6 +60,8 @@ type Walker struct {
|
||||
AutoNormalize bool
|
||||
// Number of routines to use for hashing
|
||||
Hashers int
|
||||
// Our vector clock id
|
||||
ShortID uint64
|
||||
}
|
||||
|
||||
type TempNamer interface {
|
||||
@@ -203,6 +204,9 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
|
||||
rn = normalizedRn
|
||||
}
|
||||
|
||||
var cf protocol.FileInfo
|
||||
var ok bool
|
||||
|
||||
// Index wise symlinks are always files, regardless of what the target
|
||||
// is, because symlinks carry their target path as their content.
|
||||
if info.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||
@@ -243,7 +247,7 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
|
||||
// - it wasn't invalid
|
||||
// - the symlink type (file/dir) was the same
|
||||
// - the block list (i.e. hash of target) was the same
|
||||
cf, ok := w.CurrentFiler.CurrentFile(rn)
|
||||
cf, ok = w.CurrentFiler.CurrentFile(rn)
|
||||
if ok && !cf.IsDeleted() && cf.IsSymlink() && !cf.IsInvalid() && SymlinkTypeEqual(flags, cf.Flags) && BlocksEqual(cf.Blocks, blocks) {
|
||||
return skip
|
||||
}
|
||||
@@ -251,7 +255,7 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
|
||||
|
||||
f := protocol.FileInfo{
|
||||
Name: rn,
|
||||
Version: lamport.Default.Tick(0),
|
||||
Version: cf.Version.Update(w.ShortID),
|
||||
Flags: protocol.FlagSymlink | flags | protocol.FlagNoPermBits | 0666,
|
||||
Modified: 0,
|
||||
Blocks: blocks,
|
||||
@@ -275,7 +279,7 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
|
||||
// - was a directory previously (not a file or something else)
|
||||
// - was not a symlink (since it's a directory now)
|
||||
// - was not invalid (since it looks valid now)
|
||||
cf, ok := w.CurrentFiler.CurrentFile(rn)
|
||||
cf, ok = w.CurrentFiler.CurrentFile(rn)
|
||||
permUnchanged := w.IgnorePerms || !cf.HasPermissionBits() || PermsEqual(cf.Flags, uint32(info.Mode()))
|
||||
if ok && permUnchanged && !cf.IsDeleted() && cf.IsDirectory() && !cf.IsSymlink() && !cf.IsInvalid() {
|
||||
return nil
|
||||
@@ -290,7 +294,7 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
|
||||
}
|
||||
f := protocol.FileInfo{
|
||||
Name: rn,
|
||||
Version: lamport.Default.Tick(0),
|
||||
Version: cf.Version.Update(w.ShortID),
|
||||
Flags: flags,
|
||||
Modified: info.ModTime().Unix(),
|
||||
}
|
||||
@@ -312,7 +316,7 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
|
||||
// - was not a symlink (since it's a file now)
|
||||
// - was not invalid (since it looks valid now)
|
||||
// - has the same size as previously
|
||||
cf, ok := w.CurrentFiler.CurrentFile(rn)
|
||||
cf, ok = w.CurrentFiler.CurrentFile(rn)
|
||||
permUnchanged := w.IgnorePerms || !cf.HasPermissionBits() || PermsEqual(cf.Flags, uint32(info.Mode()))
|
||||
if ok && permUnchanged && !cf.IsDeleted() && cf.Modified == info.ModTime().Unix() && !cf.IsDirectory() &&
|
||||
!cf.IsSymlink() && !cf.IsInvalid() && cf.Size() == info.Size() {
|
||||
@@ -331,7 +335,7 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
|
||||
|
||||
f := protocol.FileInfo{
|
||||
Name: rn,
|
||||
Version: lamport.Default.Tick(0),
|
||||
Version: cf.Version.Update(w.ShortID),
|
||||
Flags: flags,
|
||||
Modified: info.ModTime().Unix(),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user