@@ -5,6 +5,7 @@ package repo
5
5
6
6
import (
7
7
"net/http"
8
+ "strings"
8
9
9
10
pull_model "code.gitea.io/gitea/models/pull"
10
11
"code.gitea.io/gitea/modules/base"
@@ -57,34 +58,85 @@ func isExcludedEntry(entry *git.TreeEntry) bool {
57
58
return false
58
59
}
59
60
60
- type FileDiffFile struct {
61
- Name string
61
+ // WebDiffFileItem is used by frontend, check the field names in frontend before changing
62
+ type WebDiffFileItem struct {
63
+ FullName string
64
+ DisplayName string
62
65
NameHash string
63
- IsSubmodule bool
66
+ DiffStatus string
67
+ EntryMode string
64
68
IsViewed bool
65
- Status string
69
+ Children []* WebDiffFileItem
70
+ // TODO: add icon support in the future
66
71
}
67
72
68
- // transformDiffTreeForUI transforms a DiffTree into a slice of FileDiffFile for UI rendering
73
+ // WebDiffFileTree is used by frontend, check the field names in frontend before changing
74
+ type WebDiffFileTree struct {
75
+ TreeRoot WebDiffFileItem
76
+ }
77
+
78
+ // transformDiffTreeForWeb transforms a gitdiff.DiffTree into a WebDiffFileTree for Web UI rendering
69
79
// it also takes a map of file names to their viewed state, which is used to mark files as viewed
70
- func transformDiffTreeForUI (diffTree * gitdiff.DiffTree , filesViewedState map [string ]pull_model.ViewedState ) []FileDiffFile {
71
- files := make ([]FileDiffFile , 0 , len (diffTree .Files ))
80
+ func transformDiffTreeForWeb (diffTree * gitdiff.DiffTree , filesViewedState map [string ]pull_model.ViewedState ) (dft WebDiffFileTree ) {
81
+ dirNodes := map [string ]* WebDiffFileItem {"" : & dft .TreeRoot }
82
+ addItem := func (item * WebDiffFileItem ) {
83
+ var parentPath string
84
+ pos := strings .LastIndexByte (item .FullName , '/' )
85
+ if pos == - 1 {
86
+ item .DisplayName = item .FullName
87
+ } else {
88
+ parentPath = item .FullName [:pos ]
89
+ item .DisplayName = item .FullName [pos + 1 :]
90
+ }
91
+ parentNode , parentExists := dirNodes [parentPath ]
92
+ if ! parentExists {
93
+ parentNode = & dft .TreeRoot
94
+ fields := strings .Split (parentPath , "/" )
95
+ for idx , field := range fields {
96
+ nodePath := strings .Join (fields [:idx + 1 ], "/" )
97
+ node , ok := dirNodes [nodePath ]
98
+ if ! ok {
99
+ node = & WebDiffFileItem {EntryMode : "tree" , DisplayName : field , FullName : nodePath }
100
+ dirNodes [nodePath ] = node
101
+ parentNode .Children = append (parentNode .Children , node )
102
+ }
103
+ parentNode = node
104
+ }
105
+ }
106
+ parentNode .Children = append (parentNode .Children , item )
107
+ }
72
108
73
109
for _ , file := range diffTree .Files {
74
- nameHash := git .HashFilePathForWebUI (file .HeadPath )
75
- isSubmodule := file .HeadMode == git .EntryModeCommit
76
- isViewed := filesViewedState [file .HeadPath ] == pull_model .Viewed
77
-
78
- files = append (files , FileDiffFile {
79
- Name : file .HeadPath ,
80
- NameHash : nameHash ,
81
- IsSubmodule : isSubmodule ,
82
- IsViewed : isViewed ,
83
- Status : file .Status ,
84
- })
110
+ item := & WebDiffFileItem {FullName : file .HeadPath , DiffStatus : file .Status }
111
+ item .IsViewed = filesViewedState [item .FullName ] == pull_model .Viewed
112
+ item .NameHash = git .HashFilePathForWebUI (item .FullName )
113
+
114
+ switch file .HeadMode {
115
+ case git .EntryModeTree :
116
+ item .EntryMode = "tree"
117
+ case git .EntryModeCommit :
118
+ item .EntryMode = "commit" // submodule
119
+ default :
120
+ // default to empty, and will be treated as "blob" file because there is no "symlink" support yet
121
+ }
122
+ addItem (item )
85
123
}
86
124
87
- return files
125
+ var mergeSingleDir func (node * WebDiffFileItem )
126
+ mergeSingleDir = func (node * WebDiffFileItem ) {
127
+ if len (node .Children ) == 1 {
128
+ if child := node .Children [0 ]; child .EntryMode == "tree" {
129
+ node .FullName = child .FullName
130
+ node .DisplayName = node .DisplayName + "/" + child .DisplayName
131
+ node .Children = child .Children
132
+ mergeSingleDir (node )
133
+ }
134
+ }
135
+ }
136
+ for _ , node := range dft .TreeRoot .Children {
137
+ mergeSingleDir (node )
138
+ }
139
+ return dft
88
140
}
89
141
90
142
func TreeViewNodes (ctx * context.Context ) {
0 commit comments