9
9
"os"
10
10
"path/filepath"
11
11
"strings"
12
+ "sync"
12
13
13
14
"gopkg.in/src-d/go-git.v4/config"
14
15
"gopkg.in/src-d/go-git.v4/plumbing"
@@ -304,6 +305,7 @@ func (w *Worktree) resetIndex(t *object.Tree) error {
304
305
if err != nil {
305
306
return err
306
307
}
308
+ b := newIndexBuilder (idx )
307
309
308
310
changes , err := w .diffTreeWithStaging (t , true )
309
311
if err != nil {
@@ -330,19 +332,20 @@ func (w *Worktree) resetIndex(t *object.Tree) error {
330
332
name = ch .From .String ()
331
333
}
332
334
333
- _ , _ = idx .Remove (name )
335
+ b .Remove (name )
334
336
if e == nil {
335
337
continue
336
338
}
337
339
338
- idx . Entries = append ( idx . Entries , & index.Entry {
340
+ b . Add ( & index.Entry {
339
341
Name : name ,
340
342
Hash : e .Hash ,
341
343
Mode : e .Mode ,
342
344
})
343
345
344
346
}
345
347
348
+ b .Write (idx )
346
349
return w .r .Storer .SetIndex (idx )
347
350
}
348
351
@@ -356,17 +359,19 @@ func (w *Worktree) resetWorktree(t *object.Tree) error {
356
359
if err != nil {
357
360
return err
358
361
}
362
+ b := newIndexBuilder (idx )
359
363
360
364
for _ , ch := range changes {
361
- if err := w .checkoutChange (ch , t , idx ); err != nil {
365
+ if err := w .checkoutChange (ch , t , b ); err != nil {
362
366
return err
363
367
}
364
368
}
365
369
370
+ b .Write (idx )
366
371
return w .r .Storer .SetIndex (idx )
367
372
}
368
373
369
- func (w * Worktree ) checkoutChange (ch merkletrie.Change , t * object.Tree , idx * index. Index ) error {
374
+ func (w * Worktree ) checkoutChange (ch merkletrie.Change , t * object.Tree , idx * indexBuilder ) error {
370
375
a , err := ch .Action ()
371
376
if err != nil {
372
377
return err
@@ -445,7 +450,7 @@ func (w *Worktree) setHEADCommit(commit plumbing.Hash) error {
445
450
func (w * Worktree ) checkoutChangeSubmodule (name string ,
446
451
a merkletrie.Action ,
447
452
e * object.TreeEntry ,
448
- idx * index. Index ,
453
+ idx * indexBuilder ,
449
454
) error {
450
455
switch a {
451
456
case merkletrie .Modify :
@@ -479,11 +484,11 @@ func (w *Worktree) checkoutChangeRegularFile(name string,
479
484
a merkletrie.Action ,
480
485
t * object.Tree ,
481
486
e * object.TreeEntry ,
482
- idx * index. Index ,
487
+ idx * indexBuilder ,
483
488
) error {
484
489
switch a {
485
490
case merkletrie .Modify :
486
- _ , _ = idx .Remove (name )
491
+ idx .Remove (name )
487
492
488
493
// to apply perm changes the file is deleted, billy doesn't implement
489
494
// chmod
@@ -508,6 +513,12 @@ func (w *Worktree) checkoutChangeRegularFile(name string,
508
513
return nil
509
514
}
510
515
516
+ var copyBufferPool = sync.Pool {
517
+ New : func () interface {} {
518
+ return make ([]byte , 32 * 1024 )
519
+ },
520
+ }
521
+
511
522
func (w * Worktree ) checkoutFile (f * object.File ) (err error ) {
512
523
mode , err := f .Mode .ToOSFileMode ()
513
524
if err != nil {
@@ -531,8 +542,9 @@ func (w *Worktree) checkoutFile(f *object.File) (err error) {
531
542
}
532
543
533
544
defer ioutil .CheckClose (to , & err )
534
-
535
- _ , err = io .Copy (to , from )
545
+ buf := copyBufferPool .Get ().([]byte )
546
+ _ , err = io .CopyBuffer (to , from , buf )
547
+ copyBufferPool .Put (buf )
536
548
return
537
549
}
538
550
@@ -569,19 +581,18 @@ func (w *Worktree) checkoutFileSymlink(f *object.File) (err error) {
569
581
return
570
582
}
571
583
572
- func (w * Worktree ) addIndexFromTreeEntry (name string , f * object.TreeEntry , idx * index. Index ) error {
573
- _ , _ = idx .Remove (name )
574
- idx .Entries = append ( idx . Entries , & index.Entry {
584
+ func (w * Worktree ) addIndexFromTreeEntry (name string , f * object.TreeEntry , idx * indexBuilder ) error {
585
+ idx .Remove (name )
586
+ idx .Add ( & index.Entry {
575
587
Hash : f .Hash ,
576
588
Name : name ,
577
589
Mode : filemode .Submodule ,
578
590
})
579
-
580
591
return nil
581
592
}
582
593
583
- func (w * Worktree ) addIndexFromFile (name string , h plumbing.Hash , idx * index. Index ) error {
584
- _ , _ = idx .Remove (name )
594
+ func (w * Worktree ) addIndexFromFile (name string , h plumbing.Hash , idx * indexBuilder ) error {
595
+ idx .Remove (name )
585
596
fi , err := w .Filesystem .Lstat (name )
586
597
if err != nil {
587
598
return err
@@ -605,8 +616,7 @@ func (w *Worktree) addIndexFromFile(name string, h plumbing.Hash, idx *index.Ind
605
616
if fillSystemInfo != nil {
606
617
fillSystemInfo (e , fi .Sys ())
607
618
}
608
-
609
- idx .Entries = append (idx .Entries , e )
619
+ idx .Add (e )
610
620
return nil
611
621
}
612
622
@@ -913,3 +923,32 @@ func doCleanDirectories(fs billy.Filesystem, dir string) error {
913
923
}
914
924
return nil
915
925
}
926
+
927
+ type indexBuilder struct {
928
+ entries map [string ]* index.Entry
929
+ }
930
+
931
+ func newIndexBuilder (idx * index.Index ) * indexBuilder {
932
+ entries := make (map [string ]* index.Entry , len (idx .Entries ))
933
+ for _ , e := range idx .Entries {
934
+ entries [e .Name ] = e
935
+ }
936
+ return & indexBuilder {
937
+ entries : entries ,
938
+ }
939
+ }
940
+
941
+ func (b * indexBuilder ) Write (idx * index.Index ) {
942
+ idx .Entries = idx .Entries [:0 ]
943
+ for _ , e := range b .entries {
944
+ idx .Entries = append (idx .Entries , e )
945
+ }
946
+ }
947
+
948
+ func (b * indexBuilder ) Add (e * index.Entry ) {
949
+ b .entries [e .Name ] = e
950
+ }
951
+
952
+ func (b * indexBuilder ) Remove (name string ) {
953
+ delete (b .entries , filepath .ToSlash (name ))
954
+ }
0 commit comments