mirror of https://github.com/restic/restic.git
Merge 50d8377e31
into faffd15d13
This commit is contained in:
commit
11238238b3
|
@ -436,6 +436,26 @@ func (arch *Archiver) save(ctx context.Context, snPath, target string, previous
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case fs.IsRegularFile(fi):
|
case fs.IsRegularFile(fi):
|
||||||
|
if fi.Size() == 0 {
|
||||||
|
// Shortcut for empty files. Git uses lots of these, and
|
||||||
|
// some virtual filesystems (notably juicefs; #4257) present
|
||||||
|
// infinitely-sized special files as empty regular files.
|
||||||
|
// We can also save empty files without being able to open them.
|
||||||
|
debug.Log(" %v empty", target)
|
||||||
|
|
||||||
|
node, err := arch.nodeFromFileInfo(snPath, target, fi)
|
||||||
|
if err != nil {
|
||||||
|
return FutureNode{}, false, err
|
||||||
|
}
|
||||||
|
node.Content = restic.IDs{}
|
||||||
|
fn = newFutureNodeWithResult(futureNodeResult{
|
||||||
|
snPath: snPath,
|
||||||
|
target: target,
|
||||||
|
node: node,
|
||||||
|
})
|
||||||
|
return fn, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
debug.Log(" %v regular file", target)
|
debug.Log(" %v regular file", target)
|
||||||
|
|
||||||
// check if the file has not changed before performing a fopen operation (more expensive, specially
|
// check if the file has not changed before performing a fopen operation (more expensive, specially
|
||||||
|
|
|
@ -23,7 +23,6 @@ type Reader struct {
|
||||||
// for FileInfo
|
// for FileInfo
|
||||||
Mode os.FileMode
|
Mode os.FileMode
|
||||||
ModTime time.Time
|
ModTime time.Time
|
||||||
Size int64
|
|
||||||
|
|
||||||
AllowEmptyFile bool
|
AllowEmptyFile bool
|
||||||
|
|
||||||
|
@ -65,7 +64,6 @@ func (fs *Reader) Open(name string) (f File, err error) {
|
||||||
func (fs *Reader) fi() os.FileInfo {
|
func (fs *Reader) fi() os.FileInfo {
|
||||||
return fakeFileInfo{
|
return fakeFileInfo{
|
||||||
name: fs.Name,
|
name: fs.Name,
|
||||||
size: fs.Size,
|
|
||||||
mode: fs.Mode,
|
mode: fs.Mode,
|
||||||
modtime: fs.ModTime,
|
modtime: fs.ModTime,
|
||||||
}
|
}
|
||||||
|
@ -107,7 +105,6 @@ func (fs *Reader) Lstat(name string) (os.FileInfo, error) {
|
||||||
getDirInfo := func(name string) os.FileInfo {
|
getDirInfo := func(name string) os.FileInfo {
|
||||||
fi := fakeFileInfo{
|
fi := fakeFileInfo{
|
||||||
name: fs.Base(name),
|
name: fs.Base(name),
|
||||||
size: 0,
|
|
||||||
mode: os.ModeDir | 0755,
|
mode: os.ModeDir | 0755,
|
||||||
modtime: time.Now(),
|
modtime: time.Now(),
|
||||||
}
|
}
|
||||||
|
@ -292,7 +289,6 @@ func (d fakeDir) Readdir(n int) ([]os.FileInfo, error) {
|
||||||
// fakeFileInfo implements the bare minimum of os.FileInfo.
|
// fakeFileInfo implements the bare minimum of os.FileInfo.
|
||||||
type fakeFileInfo struct {
|
type fakeFileInfo struct {
|
||||||
name string
|
name string
|
||||||
size int64
|
|
||||||
mode os.FileMode
|
mode os.FileMode
|
||||||
modtime time.Time
|
modtime time.Time
|
||||||
}
|
}
|
||||||
|
@ -302,7 +298,8 @@ func (fi fakeFileInfo) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fi fakeFileInfo) Size() int64 {
|
func (fi fakeFileInfo) Size() int64 {
|
||||||
return fi.size
|
// Fake size to fool the archiver's empty file check.
|
||||||
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fi fakeFileInfo) Mode() os.FileMode {
|
func (fi fakeFileInfo) Mode() os.FileMode {
|
||||||
|
|
|
@ -142,10 +142,6 @@ func verifyDirectoryContentsFI(t testing.TB, fs FS, dir string, want []os.FileIn
|
||||||
t.Errorf("entry %d: wrong value for ModTime: want %v, got %v", i, fi1.ModTime(), fi2.ModTime())
|
t.Errorf("entry %d: wrong value for ModTime: want %v, got %v", i, fi1.ModTime(), fi2.ModTime())
|
||||||
}
|
}
|
||||||
|
|
||||||
if fi1.Size() != fi2.Size() {
|
|
||||||
t.Errorf("entry %d: wrong value for Size: want %v, got %v", i, fi1.Size(), fi2.Size())
|
|
||||||
}
|
|
||||||
|
|
||||||
if fi1.Sys() != fi2.Sys() {
|
if fi1.Sys() != fi2.Sys() {
|
||||||
t.Errorf("entry %d: wrong value for Sys: want %v, got %v", i, fi1.Sys(), fi2.Sys())
|
t.Errorf("entry %d: wrong value for Sys: want %v, got %v", i, fi1.Sys(), fi2.Sys())
|
||||||
}
|
}
|
||||||
|
@ -202,7 +198,6 @@ func TestFSReader(t *testing.T) {
|
||||||
mode: 0644,
|
mode: 0644,
|
||||||
modtime: now,
|
modtime: now,
|
||||||
name: filename,
|
name: filename,
|
||||||
size: int64(len(data)),
|
|
||||||
}
|
}
|
||||||
verifyDirectoryContentsFI(t, fs, "/", []os.FileInfo{fi})
|
verifyDirectoryContentsFI(t, fs, "/", []os.FileInfo{fi})
|
||||||
},
|
},
|
||||||
|
@ -214,7 +209,6 @@ func TestFSReader(t *testing.T) {
|
||||||
mode: 0644,
|
mode: 0644,
|
||||||
modtime: now,
|
modtime: now,
|
||||||
name: filename,
|
name: filename,
|
||||||
size: int64(len(data)),
|
|
||||||
}
|
}
|
||||||
verifyDirectoryContentsFI(t, fs, ".", []os.FileInfo{fi})
|
verifyDirectoryContentsFI(t, fs, ".", []os.FileInfo{fi})
|
||||||
},
|
},
|
||||||
|
@ -324,7 +318,6 @@ func TestFSReader(t *testing.T) {
|
||||||
ReadCloser: io.NopCloser(bytes.NewReader(data)),
|
ReadCloser: io.NopCloser(bytes.NewReader(data)),
|
||||||
|
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
Size: int64(len(data)),
|
|
||||||
ModTime: now,
|
ModTime: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +352,6 @@ func TestFSReaderDir(t *testing.T) {
|
||||||
ReadCloser: io.NopCloser(bytes.NewReader(data)),
|
ReadCloser: io.NopCloser(bytes.NewReader(data)),
|
||||||
|
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
Size: int64(len(data)),
|
|
||||||
ModTime: now,
|
ModTime: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue