diff --git a/src/cmds/restic/integration_helpers_test.go b/src/cmds/restic/integration_helpers_test.go index 72fb09f44..9e162a7f2 100644 --- a/src/cmds/restic/integration_helpers_test.go +++ b/src/cmds/restic/integration_helpers_test.go @@ -15,6 +15,7 @@ import ( type dirEntry struct { path string fi os.FileInfo + link uint64 } func walkDir(dir string) <-chan *dirEntry { @@ -32,10 +33,16 @@ func walkDir(dir string) <-chan *dirEntry { fmt.Fprintf(os.Stderr, "error: %v\n", err) return nil } - + + stat, err := toStatT(info.Sys()) + if !err { + return nil + } + ch <- &dirEntry{ path: name, fi: info, + link: stat.nlink(), } return nil diff --git a/src/cmds/restic/integration_test.go b/src/cmds/restic/integration_test.go index 426367724..365a00773 100644 --- a/src/cmds/restic/integration_test.go +++ b/src/cmds/restic/integration_test.go @@ -1011,3 +1011,42 @@ func TestPrune(t *testing.T) { testRunCheck(t, gopts) }) } + +func TestHardLink(t *testing.T) { + withTestEnvironment(t, func(env *testEnvironment, gopts GlobalOptions) { + datafile := filepath.Join("testdata", "test.hl.tar.gz") + fd, err := os.Open(datafile) + if os.IsNotExist(errors.Cause(err)) { + t.Skipf("unable to find data file %q, skipping", datafile) + return + } + OK(t, err) + OK(t, fd.Close()) + + testRunInit(t, gopts) + + SetupTarTestFixture(t, env.testdata, datafile) + opts := BackupOptions{} + + // first backup + testRunBackup(t, []string{env.testdata}, opts, gopts) + snapshotIDs := testRunList(t, "snapshots", gopts) + Assert(t, len(snapshotIDs) == 1, + "expected one snapshot, got %v", snapshotIDs) + + testRunCheck(t, gopts) + stat1 := dirStats(env.repo) + + // restore all backups and compare + for i, snapshotID := range snapshotIDs { + restoredir := filepath.Join(env.base, fmt.Sprintf("restore%d", i)) + t.Logf("restoring snapshot %v to %v", snapshotID.Str(), restoredir) + testRunRestore(t, gopts, restoredir, snapshotIDs[0]) + Assert(t, directoriesEqualContents(env.testdata, filepath.Join(restoredir, "testdata")), + "directories are not equal") + } + + testRunCheck(t, gopts) + }) +} + diff --git a/src/cmds/restic/testdata/test.hl.tar.gz b/src/cmds/restic/testdata/test.hl.tar.gz new file mode 100644 index 000000000..33e580939 Binary files /dev/null and b/src/cmds/restic/testdata/test.hl.tar.gz differ diff --git a/src/restic/node.go b/src/restic/node.go index ecea28321..ea8109727 100644 --- a/src/restic/node.go +++ b/src/restic/node.go @@ -495,7 +495,6 @@ func (node *Node) fillExtra(path string, fi os.FileInfo) error { node.Size = uint64(stat.size()) node.Links = uint64(stat.nlink()) case "dir": - node.Links = uint64(stat.nlink()) case "symlink": node.LinkTarget, err = fs.Readlink(path) node.Links = uint64(stat.nlink())