@@ -10,6 +10,7 @@ import (
10
10
"os"
11
11
"path"
12
12
"path/filepath"
13
+ "strconv"
13
14
"strings"
14
15
"time"
15
16
@@ -72,14 +73,82 @@ func MigrateRepositoryGitData(ctx context.Context, u *models.User, repo *models.
72
73
return repo , fmt .Errorf ("Clone: %v" , err )
73
74
}
74
75
76
+ if opts .Uncyclo {
77
+ wikiPath := models .UncycloPath (u .Name , opts .RepoName )
78
+ wikiRemotePath := UncycloRemoteURL (opts .CloneAddr )
79
+ if len (wikiRemotePath ) > 0 {
80
+ if err := util .RemoveAll (wikiPath ); err != nil {
81
+ return repo , fmt .Errorf ("Failed to remove %s: %v" , wikiPath , err )
82
+ }
83
+
84
+ if err = git .CloneWithContext (ctx , wikiRemotePath , wikiPath , git.CloneRepoOptions {
85
+ Mirror : true ,
86
+ Quiet : true ,
87
+ Timeout : migrateTimeout ,
88
+ Branch : "master" ,
89
+ }); err != nil {
90
+ log .Warn ("Clone wiki: %v" , err )
91
+ if err := util .RemoveAll (wikiPath ); err != nil {
92
+ return repo , fmt .Errorf ("Failed to remove %s: %v" , wikiPath , err )
93
+ }
94
+ }
95
+ }
96
+ }
97
+
98
+ gitRepo , err := git .OpenRepository (repoPath )
99
+ if err != nil {
100
+ return repo , fmt .Errorf ("OpenRepository: %v" , err )
101
+ }
102
+ defer gitRepo .Close ()
103
+
75
104
if opts .LFS {
76
105
lfsFetchDir := filepath .Join (setting .LFS .Path , "tmp" )
77
106
_ , err = git .NewCommand ("config" , "lfs.storage" , lfsFetchDir ).RunInDir (repoPath )
78
107
if err != nil {
79
108
return repo , fmt .Errorf ("Failed `git config lfs.storage lfsFetchDir`: %v" , err )
80
109
}
81
110
82
- _ , err = git .NewCommand ("lfs" , "fetch" , opts .CloneAddr ).RunInDir (repoPath )
111
+ excludedPointersPaths := []string {}
112
+
113
+ // scan repo for pointer files, exclude those exceeding MaxFileSize from being downloaded
114
+ if setting .LFS .MaxFileSize > 0 {
115
+ headBranch , _ := gitRepo .GetHEADBranch ()
116
+ headCommit , _ := gitRepo .GetCommit (headBranch .Name )
117
+ entries , err := headCommit .Tree .ListEntriesRecursive ()
118
+ if err != nil {
119
+ return repo , fmt .Errorf ("Failed to access git files: %v" , err )
120
+ }
121
+
122
+ for _ , entry := range entries {
123
+ entryString , _ := entry .Blob ().GetBlobContent ()
124
+
125
+ if ! strings .HasPrefix (entryString , models .LFSMetaFileIdentifier ) {
126
+ continue
127
+ }
128
+
129
+ splitLines := strings .Split (entryString , "\n " )
130
+ if len (splitLines ) < 3 {
131
+ continue
132
+ }
133
+
134
+ size , err := strconv .ParseInt (strings .TrimPrefix (splitLines [2 ], "size " ), 10 , 64 )
135
+ if err != nil {
136
+ continue
137
+ }
138
+
139
+ if size > setting .LFS .MaxFileSize {
140
+ excludedPointersPaths = append (excludedPointersPaths , entry .Name ())
141
+ log .Info ("Denied LFS[%s] download of size %d to %s/%s because of LFS_MAX_FILE_SIZE=%d" , entry .Name (), entry .Blob ().Size (), u .Name , repo .Name , setting .LFS .MaxFileSize )
142
+ }
143
+ }
144
+ }
145
+
146
+ // fetch LFS files
147
+ cmd := git .NewCommand ("lfs" , "fetch" , opts .CloneAddr )
148
+ if len (excludedPointersPaths ) > 0 {
149
+ cmd .AddArguments ("--exclude" , strings .Join (excludedPointersPaths , "," ))
150
+ }
151
+ _ , err = cmd .RunInDir (repoPath )
83
152
if err != nil {
84
153
return repo , fmt .Errorf ("Failed `lfs fetch` %s: %v" , opts .CloneAddr , err )
85
154
}
@@ -88,7 +157,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *models.User, repo *models.
88
157
lfsDst := path .Join (setting .LFS .Path )
89
158
90
159
// rename LFS files
91
- err : = filepath .Walk (lfsSrc , func (path string , info os.FileInfo , err error ) error {
160
+ err = filepath .Walk (lfsSrc , func (path string , info os.FileInfo , err error ) error {
92
161
var relSrcPath = strings .Replace (path , lfsSrc , "" , 1 )
93
162
if relSrcPath == "" {
94
163
return nil
@@ -143,38 +212,10 @@ func MigrateRepositoryGitData(ctx context.Context, u *models.User, repo *models.
143
212
144
213
err = os .RemoveAll (lfsFetchDir )
145
214
if err != nil {
146
- return repo , fmt .Errorf ("Failed to remove LFS files %s: %v" , repoPath , err )
147
- }
148
- }
149
-
150
- if opts .Uncyclo {
151
- wikiPath := models .UncycloPath (u .Name , opts .RepoName )
152
- wikiRemotePath := UncycloRemoteURL (opts .CloneAddr )
153
- if len (wikiRemotePath ) > 0 {
154
- if err := util .RemoveAll (wikiPath ); err != nil {
155
- return repo , fmt .Errorf ("Failed to remove %s: %v" , wikiPath , err )
156
- }
157
-
158
- if err = git .CloneWithContext (ctx , wikiRemotePath , wikiPath , git.CloneRepoOptions {
159
- Mirror : true ,
160
- Quiet : true ,
161
- Timeout : migrateTimeout ,
162
- Branch : "master" ,
163
- }); err != nil {
164
- log .Warn ("Clone wiki: %v" , err )
165
- if err := util .RemoveAll (wikiPath ); err != nil {
166
- return repo , fmt .Errorf ("Failed to remove %s: %v" , wikiPath , err )
167
- }
168
- }
215
+ return repo , fmt .Errorf ("Failed to delete temporary LFS directories %s: %v" , repoPath , err )
169
216
}
170
217
}
171
218
172
- gitRepo , err := git .OpenRepository (repoPath )
173
- if err != nil {
174
- return repo , fmt .Errorf ("OpenRepository: %v" , err )
175
- }
176
- defer gitRepo .Close ()
177
-
178
219
repo .IsEmpty , err = gitRepo .IsEmpty ()
179
220
if err != nil {
180
221
return repo , fmt .Errorf ("git.IsEmpty: %v" , err )
0 commit comments