Просмотр исходного кода

Internal support for ignoring permissions

Jakob Borg 11 лет назад
Родитель
Сommit
303ce02271
2 измененных файлов с 25 добавлено и 6 удалено
  1. 4 2
      model/puller.go
  2. 21 4
      scanner/walk.go

+ 4 - 2
model/puller.go

@@ -538,7 +538,7 @@ func (p *puller) handleEmptyBlock(b bqBlock) {
 			delete(p.openFiles, f.Name)
 			return
 		}
-		if os.Chmod(of.temp, os.FileMode(f.Flags&0777)) != nil {
+		if protocol.HasPermissionBits(f.Flags) && os.Chmod(of.temp, os.FileMode(f.Flags&0777)) != nil {
 			delete(p.openFiles, f.Name)
 			return
 		}
@@ -607,7 +607,9 @@ func (p *puller) closeFile(f scanner.File) {
 
 	t := time.Unix(f.Modified, 0)
 	os.Chtimes(of.temp, t, t)
-	os.Chmod(of.temp, os.FileMode(f.Flags&0777))
+	if protocol.HasPermissionBits(f.Flags) {
+		os.Chmod(of.temp, os.FileMode(f.Flags&0777))
+	}
 	defTempNamer.Show(of.temp)
 	if debug {
 		l.Debugf("pull: rename %q / %q: %q", p.repo, f.Name, of.filepath)

+ 21 - 4
scanner/walk.go

@@ -29,6 +29,10 @@ type Walker struct {
 	// Suppressed files will be returned with empty metadata and the Suppressed flag set.
 	// Requires CurrentFiler to be set.
 	Suppressor Suppressor
+	// If IgnorePermissions is true, changes to permission bits will not be
+	// detected. Scanned files will get zero permission bits and the
+	// NoPermissionBits flag set.
+	IgnorePermissions bool
 }
 
 type TempNamer interface {
@@ -162,16 +166,23 @@ func (w *Walker) walkAndHashFiles(res *[]File, ign map[string][]string) filepath
 		if info.Mode().IsDir() {
 			if w.CurrentFiler != nil {
 				cf := w.CurrentFiler.CurrentFile(rn)
-				if cf.Modified == info.ModTime().Unix() && protocol.IsDirectory(cf.Flags) && PermsEqual(cf.Flags, uint32(info.Mode())) {
+				permUnchanged := w.IgnorePermissions || !protocol.HasPermissionBits(cf.Flags) || PermsEqual(cf.Flags, uint32(info.Mode()))
+				if cf.Modified == info.ModTime().Unix() && protocol.IsDirectory(cf.Flags) && permUnchanged {
 					if debug {
 						l.Debugln("unchanged:", cf)
 					}
 					*res = append(*res, cf)
 				} else {
+					var flags uint32 = protocol.FlagDirectory
+					if w.IgnorePermissions {
+						flags |= protocol.FlagNoPermBits
+					} else {
+						flags |= uint32(info.Mode() & os.ModePerm)
+					}
 					f := File{
 						Name:     rn,
 						Version:  lamport.Default.Tick(0),
-						Flags:    uint32(info.Mode()&os.ModePerm) | protocol.FlagDirectory,
+						Flags:    flags,
 						Modified: info.ModTime().Unix(),
 					}
 					if debug {
@@ -186,7 +197,8 @@ func (w *Walker) walkAndHashFiles(res *[]File, ign map[string][]string) filepath
 		if info.Mode().IsRegular() {
 			if w.CurrentFiler != nil {
 				cf := w.CurrentFiler.CurrentFile(rn)
-				if !protocol.IsDeleted(cf.Flags) && cf.Modified == info.ModTime().Unix() && PermsEqual(cf.Flags, uint32(info.Mode())) {
+				permUnchanged := w.IgnorePermissions || !protocol.HasPermissionBits(cf.Flags) || PermsEqual(cf.Flags, uint32(info.Mode()))
+				if !protocol.IsDeleted(cf.Flags) && cf.Modified == info.ModTime().Unix() && permUnchanged {
 					if debug {
 						l.Debugln("unchanged:", cf)
 					}
@@ -235,11 +247,16 @@ func (w *Walker) walkAndHashFiles(res *[]File, ign map[string][]string) filepath
 				t1 := time.Now()
 				l.Debugln("hashed:", rn, ";", len(blocks), "blocks;", info.Size(), "bytes;", int(float64(info.Size())/1024/t1.Sub(t0).Seconds()), "KB/s")
 			}
+
+			var flags = uint32(info.Mode() & os.ModePerm)
+			if w.IgnorePermissions {
+				flags = protocol.FlagNoPermBits
+			}
 			f := File{
 				Name:     rn,
 				Version:  lamport.Default.Tick(0),
 				Size:     info.Size(),
-				Flags:    uint32(info.Mode()),
+				Flags:    flags,
 				Modified: info.ModTime().Unix(),
 				Blocks:   blocks,
 			}