@@ -448,46 +448,7 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
448448 }
449449 line := linebuf .String ()
450450
451- if strings .HasPrefix (line , "--- " ) {
452- if line [4 ] == '"' {
453- fmt .Sscanf (line [4 :], "%q" , & curFile .OldName )
454- } else {
455- curFile .OldName = line [4 :]
456- if strings .Contains (curFile .OldName , " " ) {
457- // Git adds a terminal \t if there is a space in the name
458- curFile .OldName = curFile .OldName [:len (curFile .OldName )- 1 ]
459- }
460- }
461- if curFile .OldName [0 :2 ] == "a/" {
462- curFile .OldName = curFile .OldName [2 :]
463- }
464- continue
465- } else if strings .HasPrefix (line , "+++ " ) {
466- if line [4 ] == '"' {
467- fmt .Sscanf (line [4 :], "%q" , & curFile .Name )
468- } else {
469- curFile .Name = line [4 :]
470- if strings .Contains (curFile .Name , " " ) {
471- // Git adds a terminal \t if there is a space in the name
472- curFile .Name = curFile .Name [:len (curFile .Name )- 1 ]
473- }
474- }
475- if curFile .Name [0 :2 ] == "b/" {
476- curFile .Name = curFile .Name [2 :]
477- }
478- curFile .IsRenamed = (curFile .Name != curFile .OldName ) && ! (curFile .IsCreated || curFile .IsDeleted )
479- if curFile .IsDeleted {
480- curFile .Name = curFile .OldName
481- curFile .OldName = ""
482- } else if curFile .IsCreated {
483- curFile .OldName = ""
484- }
485- continue
486- } else if len (line ) == 0 {
487- continue
488- }
489-
490- if strings .HasPrefix (line , "+++" ) || strings .HasPrefix (line , "---" ) || len (line ) == 0 {
451+ if strings .HasPrefix (line , "+++ " ) || strings .HasPrefix (line , "--- " ) || len (line ) == 0 {
491452 continue
492453 }
493454
@@ -571,10 +532,42 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
571532 break
572533 }
573534
535+ // Note: In case file name is surrounded by double quotes (it happens only in git-shell).
536+ // e.g. diff --git "a/xxx" "b/xxx"
537+ var a string
538+ var b string
539+
540+ rd := strings .NewReader (line [len (cmdDiffHead ):])
541+ char , _ := rd .ReadByte ()
542+ _ = rd .UnreadByte ()
543+ if char == '"' {
544+ fmt .Fscanf (rd , "%q " , & a )
545+ if a [0 ] == '\\' {
546+ a = a [1 :]
547+ }
548+ } else {
549+ fmt .Fscanf (rd , "%s " , & a )
550+ }
551+ char , _ = rd .ReadByte ()
552+ _ = rd .UnreadByte ()
553+ if char == '"' {
554+ fmt .Fscanf (rd , "%q" , & b )
555+ if b [0 ] == '\\' {
556+ b = b [1 :]
557+ }
558+ } else {
559+ fmt .Fscanf (rd , "%s" , & b )
560+ }
561+ a = a [2 :]
562+ b = b [2 :]
563+
574564 curFile = & DiffFile {
575- Index : len (diff .Files ) + 1 ,
576- Type : DiffFileChange ,
577- Sections : make ([]* DiffSection , 0 , 10 ),
565+ Name : b ,
566+ OldName : a ,
567+ Index : len (diff .Files ) + 1 ,
568+ Type : DiffFileChange ,
569+ Sections : make ([]* DiffSection , 0 , 10 ),
570+ IsRenamed : a != b ,
578571 }
579572 diff .Files = append (diff .Files , curFile )
580573 curFileLinesCount = 0
@@ -583,7 +576,6 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
583576 curFileLFSPrefix = false
584577
585578 // Check file diff type and is submodule.
586- loop:
587579 for {
588580 line , err := input .ReadString ('\n' )
589581 if err != nil {
@@ -594,67 +586,29 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
594586 }
595587 }
596588
597- if curFile .Type != DiffFileRename {
598- switch {
599- case strings .HasPrefix (line , "new file" ):
600- curFile .Type = DiffFileAdd
601- curFile .IsCreated = true
602- case strings .HasPrefix (line , "deleted" ):
603- curFile .Type = DiffFileDel
604- curFile .IsDeleted = true
605- case strings .HasPrefix (line , "index" ):
606- curFile .Type = DiffFileChange
607- case strings .HasPrefix (line , "similarity index 100%" ):
608- curFile .Type = DiffFileRename
609- }
610- if curFile .Type > 0 && curFile .Type != DiffFileRename {
611- if strings .HasSuffix (line , " 160000\n " ) {
612- curFile .IsSubmodule = true
613- }
614- break
615- }
616- } else {
617- switch {
618- case strings .HasPrefix (line , "rename from " ):
619- if line [12 ] == '"' {
620- fmt .Sscanf (line [12 :], "%q" , & curFile .OldName )
621- } else {
622- curFile .OldName = line [12 :]
623- curFile .OldName = curFile .OldName [:len (curFile .OldName )- 1 ]
624- }
625- case strings .HasPrefix (line , "rename to " ):
626- if line [10 ] == '"' {
627- fmt .Sscanf (line [10 :], "%q" , & curFile .Name )
628- } else {
629- curFile .Name = line [10 :]
630- curFile .Name = curFile .Name [:len (curFile .Name )- 1 ]
631- }
632- curFile .IsRenamed = true
633- break loop
634- case strings .HasPrefix (line , "copy from " ):
635- if line [10 ] == '"' {
636- fmt .Sscanf (line [10 :], "%q" , & curFile .OldName )
637- } else {
638- curFile .OldName = line [10 :]
639- curFile .OldName = curFile .OldName [:len (curFile .OldName )- 1 ]
640- }
641- case strings .HasPrefix (line , "copy to " ):
642- if line [8 ] == '"' {
643- fmt .Sscanf (line [8 :], "%q" , & curFile .Name )
644- } else {
645- curFile .Name = line [8 :]
646- curFile .Name = curFile .Name [:len (curFile .Name )- 1 ]
647- }
648- curFile .IsRenamed = true
649- curFile .Type = DiffFileCopy
650- break loop
651- default :
652- if strings .HasSuffix (line , " 160000\n " ) {
653- curFile .IsSubmodule = true
654- } else {
655- break loop
656- }
589+ switch {
590+ case strings .HasPrefix (line , "copy from " ):
591+ curFile .IsRenamed = true
592+ curFile .Type = DiffFileCopy
593+ case strings .HasPrefix (line , "copy to " ):
594+ curFile .IsRenamed = true
595+ curFile .Type = DiffFileCopy
596+ case strings .HasPrefix (line , "new file" ):
597+ curFile .Type = DiffFileAdd
598+ curFile .IsCreated = true
599+ case strings .HasPrefix (line , "deleted" ):
600+ curFile .Type = DiffFileDel
601+ curFile .IsDeleted = true
602+ case strings .HasPrefix (line , "index" ):
603+ curFile .Type = DiffFileChange
604+ case strings .HasPrefix (line , "similarity index 100%" ):
605+ curFile .Type = DiffFileRename
606+ }
607+ if curFile .Type > 0 {
608+ if strings .HasSuffix (line , " 160000\n " ) {
609+ curFile .IsSubmodule = true
657610 }
611+ break
658612 }
659613 }
660614 }
@@ -723,7 +677,7 @@ func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID
723677 parentCommit , _ := commit .Parent (0 )
724678 actualBeforeCommitID = parentCommit .ID .String ()
725679 }
726- diffArgs := []string {"diff" , "-M" }
680+ diffArgs := []string {"diff" , "--src-prefix= \\ a/" , "--dst-prefix= \\ b/" , "- M" }
727681 if len (whitespaceBehavior ) != 0 {
728682 diffArgs = append (diffArgs , whitespaceBehavior )
729683 }
0 commit comments