瀏覽代碼

Merge remote-tracking branch 'origin/dev' into dev

Vanessa 2 年之前
父節點
當前提交
32e83f1137
共有 3 個文件被更改,包括 108 次插入6 次删除
  1. 20 0
      .github/workflows/target-branch.yml
  2. 78 0
      kernel/model/index_fix.go
  3. 10 6
      kernel/model/tree.go

+ 20 - 0
.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

+ 78 - 0
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,82 @@ 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()
+
+	type TreePath struct {
+		box     *Box
+		path    string
+		absPath string
+	}
+
+	var paths []*TreePath
+	for _, box := range boxes {
+		boxPath := filepath.Join(util.DataDir, box.ID)
+		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 = append(paths, &TreePath{box, p, path})
+			}
+			return nil
+		})
+	}
+
+	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
+		}
+
+		if !names[name] {
+			names[name] = true
+			continue
+		}
+
+		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
+			}
+		}
+		os.RemoveAll(absPath)
+	}
+}
+
 // fixBlockTreeByFileSys 通过文件系统订正块树。
 func fixBlockTreeByFileSys() {
 	defer logging.Recover()

+ 10 - 6
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