@@ -53,6 +53,7 @@ const (
53
53
DiffFileChange
54
54
DiffFileDel
55
55
DiffFileRename
56
+ DiffFileCopy
56
57
)
57
58
58
59
// DiffLineExpandDirection represents the DiffLineSection expand direction
@@ -481,6 +482,31 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
481
482
}
482
483
line := linebuf .String ()
483
484
485
+ if strings .HasPrefix (line , "--- " ) {
486
+ if line [4 ] == '"' {
487
+ fmt .Sscanf (line [4 :], "%q" , & curFile .OldName )
488
+ } else {
489
+ curFile .OldName = line [4 :]
490
+ }
491
+ if curFile .OldName [0 :2 ] == "a/" {
492
+ curFile .OldName = curFile .OldName [2 :]
493
+ }
494
+ continue
495
+ } else if strings .HasPrefix (line , "+++ " ) {
496
+ if line [4 ] == '"' {
497
+ fmt .Sscanf (line [4 :], "%q" , & curFile .Name )
498
+ } else {
499
+ curFile .Name = line [4 :]
500
+ }
501
+ if curFile .Name [0 :2 ] == "b/" {
502
+ curFile .Name = curFile .Name [2 :]
503
+ }
504
+ curFile .IsRenamed = (curFile .Name != curFile .OldName ) && ! (curFile .IsCreated || curFile .IsDeleted )
505
+ continue
506
+ } else if len (line ) == 0 {
507
+ continue
508
+ }
509
+
484
510
if strings .HasPrefix (line , "+++ " ) || strings .HasPrefix (line , "--- " ) || len (line ) == 0 {
485
511
continue
486
512
}
@@ -569,36 +595,10 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
569
595
break
570
596
}
571
597
572
- // Note: In case file name is surrounded by double quotes (it happens only in git-shell).
573
- // e.g. diff --git "a/xxx" "b/xxx"
574
- var a string
575
- var b string
576
-
577
- rd := strings .NewReader (line [len (cmdDiffHead ):])
578
- char , _ := rd .ReadByte ()
579
- _ = rd .UnreadByte ()
580
- if char == '"' {
581
- fmt .Fscanf (rd , "%q " , & a )
582
- } else {
583
- fmt .Fscanf (rd , "%s " , & a )
584
- }
585
- char , _ = rd .ReadByte ()
586
- _ = rd .UnreadByte ()
587
- if char == '"' {
588
- fmt .Fscanf (rd , "%q" , & b )
589
- } else {
590
- fmt .Fscanf (rd , "%s" , & b )
591
- }
592
- a = a [2 :]
593
- b = b [2 :]
594
-
595
598
curFile = & DiffFile {
596
- Name : b ,
597
- OldName : a ,
598
- Index : len (diff .Files ) + 1 ,
599
- Type : DiffFileChange ,
600
- Sections : make ([]* DiffSection , 0 , 10 ),
601
- IsRenamed : a != b ,
599
+ Index : len (diff .Files ) + 1 ,
600
+ Type : DiffFileChange ,
601
+ Sections : make ([]* DiffSection , 0 , 10 ),
602
602
}
603
603
diff .Files = append (diff .Files , curFile )
604
604
curFileLinesCount = 0
@@ -607,6 +607,7 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
607
607
curFileLFSPrefix = false
608
608
609
609
// Check file diff type and is submodule.
610
+ loop:
610
611
for {
611
612
line , err := input .ReadString ('\n' )
612
613
if err != nil {
@@ -617,23 +618,63 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
617
618
}
618
619
}
619
620
620
- switch {
621
- case strings .HasPrefix (line , "new file" ):
622
- curFile .Type = DiffFileAdd
623
- curFile .IsCreated = true
624
- case strings .HasPrefix (line , "deleted" ):
625
- curFile .Type = DiffFileDel
626
- curFile .IsDeleted = true
627
- case strings .HasPrefix (line , "index" ):
628
- curFile .Type = DiffFileChange
629
- case strings .HasPrefix (line , "similarity index 100%" ):
630
- curFile .Type = DiffFileRename
631
- }
632
- if curFile .Type > 0 {
633
- if strings .HasSuffix (line , " 160000\n " ) {
634
- curFile .IsSubmodule = true
621
+ if curFile .Type != DiffFileRename {
622
+ switch {
623
+ case strings .HasPrefix (line , "new file" ):
624
+ curFile .Type = DiffFileAdd
625
+ curFile .IsCreated = true
626
+ case strings .HasPrefix (line , "deleted" ):
627
+ curFile .Type = DiffFileDel
628
+ curFile .IsDeleted = true
629
+ case strings .HasPrefix (line , "index" ):
630
+ curFile .Type = DiffFileChange
631
+ case strings .HasPrefix (line , "similarity index 100%" ):
632
+ curFile .Type = DiffFileRename
633
+ }
634
+ if curFile .Type > 0 && curFile .Type != DiffFileRename {
635
+ if strings .HasSuffix (line , " 160000\n " ) {
636
+ curFile .IsSubmodule = true
637
+ }
638
+ break
639
+ }
640
+ } else {
641
+ switch {
642
+ case strings .HasPrefix (line , "rename from " ):
643
+ if line [12 ] == '"' {
644
+ fmt .Sscanf (line [12 :], "%q" , & curFile .OldName )
645
+ } else {
646
+ curFile .OldName = line [12 :]
647
+ }
648
+ case strings .HasPrefix (line , "rename to " ):
649
+ if line [10 ] == '"' {
650
+ fmt .Sscanf (line [10 :], "%q" , & curFile .Name )
651
+ } else {
652
+ curFile .Name = line [10 :]
653
+ }
654
+ curFile .IsRenamed = true
655
+ break loop
656
+ case strings .HasPrefix (line , "copy from " ):
657
+ if line [10 ] == '"' {
658
+ fmt .Sscanf (line [10 :], "%q" , & curFile .OldName )
659
+ } else {
660
+ curFile .OldName = line [10 :]
661
+ }
662
+ case strings .HasPrefix (line , "copy to " ):
663
+ if line [8 ] == '"' {
664
+ fmt .Sscanf (line [8 :], "%q" , & curFile .Name )
665
+ } else {
666
+ curFile .Name = line [8 :]
667
+ }
668
+ curFile .IsRenamed = true
669
+ curFile .Type = DiffFileCopy
670
+ break loop
671
+ default :
672
+ if strings .HasSuffix (line , " 160000\n " ) {
673
+ curFile .IsSubmodule = true
674
+ } else {
675
+ break loop
676
+ }
635
677
}
636
- break
637
678
}
638
679
}
639
680
}
0 commit comments