@@ -482,46 +482,7 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
482482 }
483483 line := linebuf .String ()
484484
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- if strings .Contains (curFile .OldName , " " ) {
491- // Git adds a terminal \t if there is a space in the name
492- curFile .OldName = curFile .OldName [:len (curFile .OldName )- 1 ]
493- }
494- }
495- if curFile .OldName [0 :2 ] == "a/" {
496- curFile .OldName = curFile .OldName [2 :]
497- }
498- continue
499- } else if strings .HasPrefix (line , "+++ " ) {
500- if line [4 ] == '"' {
501- fmt .Sscanf (line [4 :], "%q" , & curFile .Name )
502- } else {
503- curFile .Name = line [4 :]
504- if strings .Contains (curFile .Name , " " ) {
505- // Git adds a terminal \t if there is a space in the name
506- curFile .Name = curFile .Name [:len (curFile .Name )- 1 ]
507- }
508- }
509- if curFile .Name [0 :2 ] == "b/" {
510- curFile .Name = curFile .Name [2 :]
511- }
512- curFile .IsRenamed = (curFile .Name != curFile .OldName ) && ! (curFile .IsCreated || curFile .IsDeleted )
513- if curFile .IsDeleted {
514- curFile .Name = curFile .OldName
515- curFile .OldName = ""
516- } else if curFile .IsCreated {
517- curFile .OldName = ""
518- }
519- continue
520- } else if len (line ) == 0 {
521- continue
522- }
523-
524- if strings .HasPrefix (line , "+++" ) || strings .HasPrefix (line , "---" ) || len (line ) == 0 {
485+ if strings .HasPrefix (line , "+++ " ) || strings .HasPrefix (line , "--- " ) || len (line ) == 0 {
525486 continue
526487 }
527488
@@ -609,10 +570,43 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
609570 break
610571 }
611572
573+ // Note: In case file name is surrounded by double quotes (it happens only in git-shell).
574+ // e.g. diff --git "a/xxx" "b/xxx"
575+ var a string
576+ var b string
577+
578+ rd := strings .NewReader (line [len (cmdDiffHead ):])
579+ char , _ := rd .ReadByte ()
580+ _ = rd .UnreadByte ()
581+ if char == '"' {
582+ fmt .Fscanf (rd , "%q " , & a )
583+ fmt .Printf ("read %s" , a )
584+ if a [0 ] == '\\' {
585+ a = a [1 :]
586+ }
587+ } else {
588+ fmt .Fscanf (rd , "%s " , & a )
589+ }
590+ char , _ = rd .ReadByte ()
591+ _ = rd .UnreadByte ()
592+ if char == '"' {
593+ fmt .Fscanf (rd , "%q" , & b )
594+ if b [0 ] == '\\' {
595+ b = b [1 :]
596+ }
597+ } else {
598+ fmt .Fscanf (rd , "%s" , & b )
599+ }
600+ a = a [2 :]
601+ b = b [2 :]
602+
612603 curFile = & DiffFile {
613- Index : len (diff .Files ) + 1 ,
614- Type : DiffFileChange ,
615- Sections : make ([]* DiffSection , 0 , 10 ),
604+ Name : b ,
605+ OldName : a ,
606+ Index : len (diff .Files ) + 1 ,
607+ Type : DiffFileChange ,
608+ Sections : make ([]* DiffSection , 0 , 10 ),
609+ IsRenamed : a != b ,
616610 }
617611 diff .Files = append (diff .Files , curFile )
618612 curFileLinesCount = 0
@@ -621,7 +615,6 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
621615 curFileLFSPrefix = false
622616
623617 // Check file diff type and is submodule.
624- loop:
625618 for {
626619 line , err := input .ReadString ('\n' )
627620 if err != nil {
@@ -632,67 +625,29 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
632625 }
633626 }
634627
635- if curFile .Type != DiffFileRename {
636- switch {
637- case strings .HasPrefix (line , "new file" ):
638- curFile .Type = DiffFileAdd
639- curFile .IsCreated = true
640- case strings .HasPrefix (line , "deleted" ):
641- curFile .Type = DiffFileDel
642- curFile .IsDeleted = true
643- case strings .HasPrefix (line , "index" ):
644- curFile .Type = DiffFileChange
645- case strings .HasPrefix (line , "similarity index 100%" ):
646- curFile .Type = DiffFileRename
647- }
648- if curFile .Type > 0 && curFile .Type != DiffFileRename {
649- if strings .HasSuffix (line , " 160000\n " ) {
650- curFile .IsSubmodule = true
651- }
652- break
653- }
654- } else {
655- switch {
656- case strings .HasPrefix (line , "rename from " ):
657- if line [12 ] == '"' {
658- fmt .Sscanf (line [12 :], "%q" , & curFile .OldName )
659- } else {
660- curFile .OldName = line [12 :]
661- curFile .OldName = curFile .OldName [:len (curFile .OldName )- 1 ]
662- }
663- case strings .HasPrefix (line , "rename to " ):
664- if line [10 ] == '"' {
665- fmt .Sscanf (line [10 :], "%q" , & curFile .Name )
666- } else {
667- curFile .Name = line [10 :]
668- curFile .Name = curFile .Name [:len (curFile .Name )- 1 ]
669- }
670- curFile .IsRenamed = true
671- break loop
672- case strings .HasPrefix (line , "copy from " ):
673- if line [10 ] == '"' {
674- fmt .Sscanf (line [10 :], "%q" , & curFile .OldName )
675- } else {
676- curFile .OldName = line [10 :]
677- curFile .OldName = curFile .OldName [:len (curFile .OldName )- 1 ]
678- }
679- case strings .HasPrefix (line , "copy to " ):
680- if line [8 ] == '"' {
681- fmt .Sscanf (line [8 :], "%q" , & curFile .Name )
682- } else {
683- curFile .Name = line [8 :]
684- curFile .Name = curFile .Name [:len (curFile .Name )- 1 ]
685- }
686- curFile .IsRenamed = true
687- curFile .Type = DiffFileCopy
688- break loop
689- default :
690- if strings .HasSuffix (line , " 160000\n " ) {
691- curFile .IsSubmodule = true
692- } else {
693- break loop
694- }
628+ switch {
629+ case strings .HasPrefix (line , "copy from " ):
630+ curFile .IsRenamed = true
631+ curFile .Type = DiffFileCopy
632+ case strings .HasPrefix (line , "copy to " ):
633+ curFile .IsRenamed = true
634+ curFile .Type = DiffFileCopy
635+ case strings .HasPrefix (line , "new file" ):
636+ curFile .Type = DiffFileAdd
637+ curFile .IsCreated = true
638+ case strings .HasPrefix (line , "deleted" ):
639+ curFile .Type = DiffFileDel
640+ curFile .IsDeleted = true
641+ case strings .HasPrefix (line , "index" ):
642+ curFile .Type = DiffFileChange
643+ case strings .HasPrefix (line , "similarity index 100%" ):
644+ curFile .Type = DiffFileRename
645+ }
646+ if curFile .Type > 0 {
647+ if strings .HasSuffix (line , " 160000\n " ) {
648+ curFile .IsSubmodule = true
695649 }
650+ break
696651 }
697652 }
698653 }
@@ -761,7 +716,7 @@ func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID
761716 parentCommit , _ := commit .Parent (0 )
762717 actualBeforeCommitID = parentCommit .ID .String ()
763718 }
764- diffArgs := []string {"diff" , "-M" }
719+ diffArgs := []string {"diff" , "--src-prefix= \\ a/" , "--dst-prefix= \\ d/" , "- M" }
765720 if len (whitespaceBehavior ) != 0 {
766721 diffArgs = append (diffArgs , whitespaceBehavior )
767722 }
0 commit comments