Skip to content

Commit 93563a5

Browse files
committed
Fix yet another bug with diff file names
Following further testing it has become apparent that the diff line cannot be used to determine filenames for diffs with any sort of predictability the answer therefore is to use the other lines that are provided with a diff Fix go-gitea#12768 Signed-off-by: Andrew Thornton <[email protected]>
1 parent bea343c commit 93563a5

File tree

2 files changed

+87
-46
lines changed

2 files changed

+87
-46
lines changed

modules/templates/helper.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ func ActionContent2Commits(act Actioner) *repository.PushCommits {
694694
// DiffTypeToStr returns diff type name
695695
func DiffTypeToStr(diffType int) string {
696696
diffTypes := map[int]string{
697-
1: "add", 2: "modify", 3: "del", 4: "rename",
697+
1: "add", 2: "modify", 3: "del", 4: "rename", 5: "copy",
698698
}
699699
return diffTypes[diffType]
700700
}

services/gitdiff/gitdiff.go

Lines changed: 86 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ const (
5353
DiffFileChange
5454
DiffFileDel
5555
DiffFileRename
56+
DiffFileCopy
5657
)
5758

5859
// DiffLineExpandDirection represents the DiffLineSection expand direction
@@ -481,6 +482,31 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
481482
}
482483
line := linebuf.String()
483484

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+
484510
if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") || len(line) == 0 {
485511
continue
486512
}
@@ -569,36 +595,10 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
569595
break
570596
}
571597

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-
595598
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),
602602
}
603603
diff.Files = append(diff.Files, curFile)
604604
curFileLinesCount = 0
@@ -607,6 +607,7 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
607607
curFileLFSPrefix = false
608608

609609
// Check file diff type and is submodule.
610+
loop:
610611
for {
611612
line, err := input.ReadString('\n')
612613
if err != nil {
@@ -617,23 +618,63 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
617618
}
618619
}
619620

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+
}
635677
}
636-
break
637678
}
638679
}
639680
}

0 commit comments

Comments
 (0)