From d8c194d54ab0933a13cd2408f1ba8d58c7a2cacf Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sat, 11 Feb 2023 23:51:32 +0800 Subject: [PATCH 1/4] =?UTF-8?q?:art:=20=E6=96=87=E6=A1=A3=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=96=87=E4=BB=B6=20ID=20=E9=87=8D=E5=A4=8D=E6=97=B6?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E9=87=8D=E7=BD=AE=20ID=20Fix=20https://githu?= =?UTF-8?q?b.com/siyuan-note/siyuan/issues/7340?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/model/index_fix.go | 64 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/kernel/model/index_fix.go b/kernel/model/index_fix.go index c97647c79..f31fc4327 100644 --- a/kernel/model/index_fix.go +++ b/kernel/model/index_fix.go @@ -44,6 +44,8 @@ func FixIndexJob() { task.AppendTask(task.DatabaseIndexFix, removeDuplicateDatabaseIndex) sql.WaitForWritingDatabase() + task.AppendTask(task.DatabaseIndexFix, resetDuplicateTrees) + task.AppendTask(task.DatabaseIndexFix, fixBlockTreeByFileSys) sql.WaitForWritingDatabase() @@ -100,6 +102,68 @@ func removeDuplicateDatabaseIndex() { } } +// resetDuplicateTrees 重置重复 ID 的文档树。 https://github.com/siyuan-note/siyuan/issues/7340 +func resetDuplicateTrees() { + defer logging.Recover() + + autoFixLock.Lock() + defer autoFixLock.Unlock() + + util.PushStatusBar(Conf.Language(58)) + boxes := Conf.GetBoxes() + luteEngine := lute.New() + for _, box := range boxes { + boxPath := filepath.Join(util.DataDir, box.ID) + paths := map[string]string{} + filepath.Walk(boxPath, func(path string, info os.FileInfo, err error) error { + if !info.IsDir() && filepath.Ext(path) == ".sy" && !strings.Contains(filepath.ToSlash(path), "/assets/") { + p := path[len(boxPath):] + p = filepath.ToSlash(p) + paths[p] = path + } + return nil + }) + + names := map[string]bool{} + duplicatedPaths := map[string]string{} + for p, absPath := range paths { + name := path.Base(p) + if !names[name] { + names[name] = true + continue + } + + duplicatedPaths[p] = absPath + } + + for p, absPath := range duplicatedPaths { + logging.LogWarnf("exist more than one file with same id [%s], reset it", p) + + tree, loadErr := filesys.LoadTree(box.ID, p, luteEngine) + if nil != loadErr { + logging.LogWarnf("load tree [%s] failed: %s", p, loadErr) + box.moveCorruptedData(absPath) + continue + } + + resetTree(tree, "Duplicated") + createTreeTx(tree) + if gulu.File.IsDir(strings.TrimSuffix(absPath, ".sy")) { + // 重命名子文档文件夹 + if renameErr := os.Rename(strings.TrimSuffix(absPath, ".sy"), filepath.Join(filepath.Dir(absPath), tree.ID)); nil != renameErr { + logging.LogWarnf("rename [%s] failed: %s", absPath, renameErr) + continue + } + } + os.RemoveAll(absPath) + } + + if util.IsExiting { + break + } + } +} + // fixBlockTreeByFileSys 通过文件系统订正块树。 func fixBlockTreeByFileSys() { defer logging.Recover() From 5c596f142ce8ea01c59e5d68b85103fecfc343d7 Mon Sep 17 00:00:00 2001 From: Percy Ma Date: Sat, 11 Feb 2023 23:56:02 +0800 Subject: [PATCH 2/4] ci: make sure new PRs are sent to dev (#7342) --- .github/workflows/target-branch.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/target-branch.yml diff --git a/.github/workflows/target-branch.yml b/.github/workflows/target-branch.yml new file mode 100644 index 000000000..e644c8305 --- /dev/null +++ b/.github/workflows/target-branch.yml @@ -0,0 +1,20 @@ +name: Make sure new PRs are sent to dev + +on: + pull_request_target: + types: [opened, edited] + +jobs: + check-branch: + runs-on: ubuntu-latest + steps: + - uses: Vankka/pr-target-branch-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + target: master + exclude: dev + change-to: dev + comment: | + Your PR was set to target `master`, PRs should be target `dev` + The base branch of this PR has been automatically changed to `dev`, please check that there are no merge conflicts From 698f130ffaa0f5fa8aab2cf0756b10729bf29a51 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sun, 12 Feb 2023 00:07:20 +0800 Subject: [PATCH 3/4] =?UTF-8?q?:art:=20=E6=96=87=E6=A1=A3=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=96=87=E4=BB=B6=E5=90=8D=E4=B8=8D=E7=AC=A6=E5=90=88?= =?UTF-8?q?=20ID=20=E6=A0=BC=E5=BC=8F=E6=97=B6=E8=87=AA=E5=8A=A8=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E5=88=B0=20corrupted=20=E6=96=87=E4=BB=B6=E5=A4=B9?= =?UTF-8?q?=E4=B8=8B=20Fix=20https://github.com/siyuan-note/siyuan/issues/?= =?UTF-8?q?7343?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/model/index_fix.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/model/index_fix.go b/kernel/model/index_fix.go index f31fc4327..a01c4feeb 100644 --- a/kernel/model/index_fix.go +++ b/kernel/model/index_fix.go @@ -128,6 +128,12 @@ func resetDuplicateTrees() { duplicatedPaths := map[string]string{} for p, absPath := range paths { name := path.Base(p) + if !ast.IsNodeIDPattern(strings.TrimSuffix(name, ".sy")) { + logging.LogWarnf("invalid .sy file name [%s]", p) + box.moveCorruptedData(absPath) + continue + } + if !names[name] { names[name] = true continue From 1015ef4037319fa1c06ecd2ff755302ddfe31430 Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sun, 12 Feb 2023 00:23:53 +0800 Subject: [PATCH 4/4] =?UTF-8?q?:art:=20=E6=96=87=E6=A1=A3=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=96=87=E4=BB=B6=20ID=20=E9=87=8D=E5=A4=8D=E6=97=B6?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E9=87=8D=E7=BD=AE=20ID=20Fix=20https://githu?= =?UTF-8?q?b.com/siyuan-note/siyuan/issues/7340?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/model/index_fix.go | 86 +++++++++++++++++++++------------------ kernel/model/tree.go | 16 +++++--- 2 files changed, 57 insertions(+), 45 deletions(-) diff --git a/kernel/model/index_fix.go b/kernel/model/index_fix.go index a01c4feeb..d795a54d3 100644 --- a/kernel/model/index_fix.go +++ b/kernel/model/index_fix.go @@ -112,61 +112,69 @@ func resetDuplicateTrees() { util.PushStatusBar(Conf.Language(58)) boxes := Conf.GetBoxes() luteEngine := lute.New() + + type TreePath struct { + box *Box + path string + absPath string + } + + var paths []*TreePath for _, box := range boxes { boxPath := filepath.Join(util.DataDir, box.ID) - paths := map[string]string{} filepath.Walk(boxPath, func(path string, info os.FileInfo, err error) error { if !info.IsDir() && filepath.Ext(path) == ".sy" && !strings.Contains(filepath.ToSlash(path), "/assets/") { p := path[len(boxPath):] p = filepath.ToSlash(p) - paths[p] = path + paths = append(paths, &TreePath{box, p, path}) } return nil }) + } - names := map[string]bool{} - duplicatedPaths := map[string]string{} - for p, absPath := range paths { - name := path.Base(p) - if !ast.IsNodeIDPattern(strings.TrimSuffix(name, ".sy")) { - logging.LogWarnf("invalid .sy file name [%s]", p) - box.moveCorruptedData(absPath) - continue - } - - if !names[name] { - names[name] = true - continue - } - - duplicatedPaths[p] = absPath + names := map[string]bool{} + var duplicatedPaths []*TreePath + for _, treePath := range paths { + p := treePath.path + absPath := treePath.absPath + name := path.Base(p) + if !ast.IsNodeIDPattern(strings.TrimSuffix(name, ".sy")) { + logging.LogWarnf("invalid .sy file name [%s]", p) + treePath.box.moveCorruptedData(absPath) + continue } - for p, absPath := range duplicatedPaths { - logging.LogWarnf("exist more than one file with same id [%s], reset it", p) + if !names[name] { + names[name] = true + continue + } - tree, loadErr := filesys.LoadTree(box.ID, p, luteEngine) - if nil != loadErr { - logging.LogWarnf("load tree [%s] failed: %s", p, loadErr) - box.moveCorruptedData(absPath) + duplicatedPaths = append(duplicatedPaths, treePath) + } + + for _, duplicatedPath := range duplicatedPaths { + p := duplicatedPath.path + absPath := duplicatedPath.absPath + box := duplicatedPath.box + logging.LogWarnf("exist more than one file with same id [%s], reset it", p) + + tree, loadErr := filesys.LoadTree(box.ID, p, luteEngine) + if nil != loadErr { + logging.LogWarnf("load tree [%s] failed: %s", p, loadErr) + box.moveCorruptedData(absPath) + continue + } + + resetTree(tree, "") + createTreeTx(tree) + if gulu.File.IsDir(strings.TrimSuffix(absPath, ".sy")) { + // 重命名子文档文件夹 + if renameErr := os.Rename(strings.TrimSuffix(absPath, ".sy"), filepath.Join(filepath.Dir(absPath), tree.ID)); nil != renameErr { + logging.LogWarnf("rename [%s] failed: %s", absPath, renameErr) continue } - - resetTree(tree, "Duplicated") - createTreeTx(tree) - if gulu.File.IsDir(strings.TrimSuffix(absPath, ".sy")) { - // 重命名子文档文件夹 - if renameErr := os.Rename(strings.TrimSuffix(absPath, ".sy"), filepath.Join(filepath.Dir(absPath), tree.ID)); nil != renameErr { - logging.LogWarnf("rename [%s] failed: %s", absPath, renameErr) - continue - } - } - os.RemoveAll(absPath) - } - - if util.IsExiting { - break } + os.RemoveAll(absPath) } } diff --git a/kernel/model/tree.go b/kernel/model/tree.go index 1c4a0ff6c..c13ad975d 100644 --- a/kernel/model/tree.go +++ b/kernel/model/tree.go @@ -38,14 +38,18 @@ import ( func resetTree(tree *parse.Tree, titleSuffix string) { tree.ID = ast.NewNodeID() tree.Root.ID = tree.ID - if t, parseErr := time.Parse("20060102150405", util.TimeFromID(tree.ID)); nil == parseErr { - titleSuffix += " " + t.Format("2006-01-02 15:04:05") - } else { - titleSuffix = "Duplicated " + time.Now().Format("2006-01-02 15:04:05") + + if "" != titleSuffix { + if t, parseErr := time.Parse("20060102150405", util.TimeFromID(tree.ID)); nil == parseErr { + titleSuffix += " " + t.Format("2006-01-02 15:04:05") + } else { + titleSuffix = "Duplicated " + time.Now().Format("2006-01-02 15:04:05") + } + titleSuffix = "(" + titleSuffix + ")" + titleSuffix = " " + titleSuffix } - titleSuffix = "(" + titleSuffix + ")" tree.Root.SetIALAttr("id", tree.ID) - tree.Root.SetIALAttr("title", tree.Root.IALAttr("title")+" "+titleSuffix) + tree.Root.SetIALAttr("title", tree.Root.IALAttr("title")+titleSuffix) tree.Root.RemoveIALAttr("scroll") p := path.Join(path.Dir(tree.Path), tree.ID) + ".sy" tree.Path = p