7
7
"io"
8
8
"path"
9
9
"path/filepath"
10
+ "sort"
10
11
"strings"
11
12
12
13
"github.com/go-git/go-git/v5/plumbing"
@@ -270,6 +271,28 @@ func (t *Tree) Decode(o plumbing.EncodedObject) (err error) {
270
271
return nil
271
272
}
272
273
274
+ type EntrySorter []TreeEntry
275
+
276
+ func (s EntrySorter ) Len () int {
277
+ return len (s )
278
+ }
279
+
280
+ func (s EntrySorter ) Less (i , j int ) bool {
281
+ name1 := s [i ].Name
282
+ name2 := s [j ].Name
283
+ if s [i ].Mode == filemode .Dir {
284
+ name1 += "/"
285
+ }
286
+ if s [j ].Mode == filemode .Dir {
287
+ name2 += "/"
288
+ }
289
+ return name1 < name2
290
+ }
291
+
292
+ func (s EntrySorter ) Swap (i , j int ) {
293
+ s [i ], s [j ] = s [j ], s [i ]
294
+ }
295
+
273
296
// Encode transforms a Tree into a plumbing.EncodedObject.
274
297
func (t * Tree ) Encode (o plumbing.EncodedObject ) (err error ) {
275
298
o .SetType (plumbing .TreeObject )
@@ -279,7 +302,15 @@ func (t *Tree) Encode(o plumbing.EncodedObject) (err error) {
279
302
}
280
303
281
304
defer ioutil .CheckClose (w , & err )
305
+
306
+ if ! sort .IsSorted (EntrySorter (t .Entries )) {
307
+ return errors .New ("entries in tree is not sorted" )
308
+ }
309
+
282
310
for _ , entry := range t .Entries {
311
+ if strings .IndexByte (entry .Name , 0 ) != - 1 {
312
+ return fmt .Errorf ("malformed filename '%s'" , entry .Name )
313
+ }
283
314
if _ , err = fmt .Fprintf (w , "%o %s" , entry .Mode , entry .Name ); err != nil {
284
315
return err
285
316
}
0 commit comments