mirror of
https://github.com/syncthing/syncthing.git
synced 2024-11-16 10:28:49 -07:00
Allow limiting max conflicts (fixes #2282)
This commit is contained in:
parent
2b56961b54
commit
752533489a
@ -1135,6 +1135,7 @@ angular.module('syncthing.core')
|
||||
};
|
||||
$scope.currentFolder.rescanIntervalS = 60;
|
||||
$scope.currentFolder.minDiskFreePct = 1;
|
||||
$scope.currentFolder.maxConflicts = -1;
|
||||
$scope.currentFolder.order = "random";
|
||||
$scope.currentFolder.fileVersioningSelector = "none";
|
||||
$scope.currentFolder.trashcanClean = 0;
|
||||
@ -1156,6 +1157,7 @@ angular.module('syncthing.core')
|
||||
selectedDevices: {},
|
||||
rescanIntervalS: 60,
|
||||
minDiskFreePct: 1,
|
||||
maxConflicts: -1,
|
||||
order: "random",
|
||||
fileVersioningSelector: "none",
|
||||
trashcanClean: 0,
|
||||
|
File diff suppressed because one or more lines are too long
@ -111,6 +111,7 @@ type FolderConfiguration struct {
|
||||
ScanProgressIntervalS int `xml:"scanProgressIntervalS" json:"scanProgressIntervalS"` // Set to a negative value to disable. Value of 0 will get replaced with value of 2 (default value)
|
||||
PullerSleepS int `xml:"pullerSleepS" json:"pullerSleepS"`
|
||||
PullerPauseS int `xml:"pullerPauseS" json:"pullerPauseS"`
|
||||
MaxConflicts int `xml:"maxConflicts" json:"maxConflicts"`
|
||||
|
||||
Invalid string `xml:"-" json:"invalid"` // Set at runtime when there is an error, not saved
|
||||
}
|
||||
@ -499,14 +500,6 @@ func ChangeRequiresRestart(from, to Configuration) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func convertV10V11(cfg *Configuration) {
|
||||
// Set minimum disk free of existing folders to 1%
|
||||
for i := range cfg.Folders {
|
||||
cfg.Folders[i].MinDiskFreePct = 1
|
||||
}
|
||||
cfg.Version = 11
|
||||
}
|
||||
|
||||
func convertV11V12(cfg *Configuration) {
|
||||
// Change listen address schema
|
||||
for i, addr := range cfg.Options.ListenAddress {
|
||||
@ -550,9 +543,22 @@ func convertV11V12(cfg *Configuration) {
|
||||
cfg.Options.LocalAnnPort = 21027
|
||||
}
|
||||
|
||||
// Set MaxConflicts to unlimited
|
||||
for i := range cfg.Folders {
|
||||
cfg.Folders[i].MaxConflicts = -1
|
||||
}
|
||||
|
||||
cfg.Version = 12
|
||||
}
|
||||
|
||||
func convertV10V11(cfg *Configuration) {
|
||||
// Set minimum disk free of existing folders to 1%
|
||||
for i := range cfg.Folders {
|
||||
cfg.Folders[i].MinDiskFreePct = 1
|
||||
}
|
||||
cfg.Version = 11
|
||||
}
|
||||
|
||||
func convertV9V10(cfg *Configuration) {
|
||||
// Enable auto normalization on existing folders.
|
||||
for i := range cfg.Folders {
|
||||
|
@ -100,6 +100,7 @@ func TestDeviceConfig(t *testing.T) {
|
||||
Hashers: 0,
|
||||
AutoNormalize: true,
|
||||
MinDiskFreePct: 1,
|
||||
MaxConflicts: -1,
|
||||
},
|
||||
}
|
||||
expectedDevices := []DeviceConfiguration{
|
||||
|
1
lib/config/testdata/v12.xml
vendored
1
lib/config/testdata/v12.xml
vendored
@ -3,6 +3,7 @@
|
||||
<device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR"></device>
|
||||
<device id="P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2"></device>
|
||||
<minDiskFreePct>1</minDiskFreePct>
|
||||
<maxConflicts>-1</maxConflicts>
|
||||
</folder>
|
||||
<device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR" name="node one" compression="metadata">
|
||||
<address>tcp://a</address>
|
||||
|
@ -79,17 +79,18 @@ type rwFolder struct {
|
||||
progressEmitter *ProgressEmitter
|
||||
virtualMtimeRepo *db.VirtualMtimeRepo
|
||||
|
||||
folder string
|
||||
dir string
|
||||
scanIntv time.Duration
|
||||
versioner versioner.Versioner
|
||||
ignorePerms bool
|
||||
copiers int
|
||||
pullers int
|
||||
shortID uint64
|
||||
order config.PullOrder
|
||||
sleep time.Duration
|
||||
pause time.Duration
|
||||
folder string
|
||||
dir string
|
||||
scanIntv time.Duration
|
||||
versioner versioner.Versioner
|
||||
ignorePerms bool
|
||||
copiers int
|
||||
pullers int
|
||||
shortID uint64
|
||||
order config.PullOrder
|
||||
maxConflicts int
|
||||
sleep time.Duration
|
||||
pause time.Duration
|
||||
|
||||
stop chan struct{}
|
||||
queue *jobQueue
|
||||
@ -115,14 +116,15 @@ func newRWFolder(m *Model, shortID uint64, cfg config.FolderConfiguration) *rwFo
|
||||
progressEmitter: m.progressEmitter,
|
||||
virtualMtimeRepo: db.NewVirtualMtimeRepo(m.db, cfg.ID),
|
||||
|
||||
folder: cfg.ID,
|
||||
dir: cfg.Path(),
|
||||
scanIntv: time.Duration(cfg.RescanIntervalS) * time.Second,
|
||||
ignorePerms: cfg.IgnorePerms,
|
||||
copiers: cfg.Copiers,
|
||||
pullers: cfg.Pullers,
|
||||
shortID: shortID,
|
||||
order: cfg.Order,
|
||||
folder: cfg.ID,
|
||||
dir: cfg.Path(),
|
||||
scanIntv: time.Duration(cfg.RescanIntervalS) * time.Second,
|
||||
ignorePerms: cfg.IgnorePerms,
|
||||
copiers: cfg.Copiers,
|
||||
pullers: cfg.Pullers,
|
||||
shortID: shortID,
|
||||
order: cfg.Order,
|
||||
maxConflicts: cfg.MaxConflicts,
|
||||
|
||||
stop: make(chan struct{}),
|
||||
queue: newJobQueue(),
|
||||
@ -757,7 +759,7 @@ func (p *rwFolder) deleteFile(file protocol.FileInfo) {
|
||||
// of deleting. Also merge with the version vector we had, to indicate
|
||||
// we have resolved the conflict.
|
||||
file.Version = file.Version.Merge(cur.Version)
|
||||
err = osutil.InWritableDir(moveForConflict, realName)
|
||||
err = osutil.InWritableDir(p.moveForConflict, realName)
|
||||
} else if p.versioner != nil {
|
||||
err = osutil.InWritableDir(p.versioner.Archive, realName)
|
||||
} else {
|
||||
@ -1254,7 +1256,7 @@ func (p *rwFolder) performFinish(state *sharedPullerState) error {
|
||||
// we have resolved the conflict.
|
||||
|
||||
state.file.Version = state.file.Version.Merge(state.version)
|
||||
if err = osutil.InWritableDir(moveForConflict, state.realName); err != nil {
|
||||
if err = osutil.InWritableDir(p.moveForConflict, state.realName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -1447,7 +1449,14 @@ func removeDevice(devices []protocol.DeviceID, device protocol.DeviceID) []proto
|
||||
return devices
|
||||
}
|
||||
|
||||
func moveForConflict(name string) error {
|
||||
func (p *rwFolder) moveForConflict(name string) error {
|
||||
if p.maxConflicts == 0 {
|
||||
if err := osutil.Remove(name); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
ext := filepath.Ext(name)
|
||||
withoutExt := name[:len(name)-len(ext)]
|
||||
newName := withoutExt + time.Now().Format(".sync-conflict-20060102-150405") + ext
|
||||
@ -1457,7 +1466,21 @@ func moveForConflict(name string) error {
|
||||
// the user has already moved it away, or the conflict was between a
|
||||
// remote modification and a local delete. In either way it does not
|
||||
// matter, go ahead as if the move succeeded.
|
||||
return nil
|
||||
err = nil
|
||||
}
|
||||
if p.maxConflicts > -1 {
|
||||
matches, gerr := osutil.Glob(withoutExt + ".sync-conflict-????????-??????" + ext)
|
||||
if gerr == nil && len(matches) > p.maxConflicts {
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(matches)))
|
||||
for _, match := range matches[p.maxConflicts:] {
|
||||
gerr = osutil.Remove(match)
|
||||
if gerr != nil {
|
||||
l.Debugln(p, "removing extra conflict", gerr)
|
||||
}
|
||||
}
|
||||
} else if gerr != nil {
|
||||
l.Debugln(p, "globbing for conflicts", gerr)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user