Skip to content

Add support for parsing multi-file diffs affecting binary files. #10

Closed
@dmitshur

Description

@dmitshur

Unless I'm missing something, it seems the multi-file diff parser skips over changes to binary files (/cc @gbbr). Consider the following multi-file diff:

diff --git a/README.md b/README.md
index 7b73e04..36cde13 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
 Conception-go [![Build Status](https://travis-ci.org/shurcooL/Conception-go.svg?branch=master)](https://travis-ci.org/shurcooL/Conception-go)
 =============

+This is a change.
+
 This is a work in progress Go implementation of [Conception](https://github.com/shurcooL/Conception#demonstration).

 Conception is an experimental project. It's a platform for researching software development tools and techniques. It is driven by a set of guiding principles. Conception-go targets Go development.
diff --git a/data/Font.png b/data/Font.png
index 17a971d..599f8dd 100644
Binary files a/data/Font.png and b/data/Font.png differ
diff --git a/main.go b/main.go
index 1aced1e..98a982e 100644
--- a/main.go
+++ b/main.go
@@ -6710,6 +6710,8 @@ func init() {
 }

 func main() {
+   // Another plain text change.
+
    //defer profile.Start(profile.CPUProfile).Stop()
    //defer profile.Start(profile.MemProfile).Stop()

There are 3 files changed. Two text files (README.md and main.go), one binary file (data/Font.png).

However, if I execute diff.ParseMultiFileDiff on that diff, the output is a slice with just 2 *diff.FileDiff entries, for the two text files. The binary file change is not there.

Reproduce sample

package main

import (
    "fmt"
    "strings"

    "sourcegraph.com/sourcegraph/go-diff/diff"
)

// fileDiffName returns the name of a FileDiff.
func fileDiffName(fileDiff *diff.FileDiff) string {
    var origName, newName string
    if strings.HasPrefix(fileDiff.OrigName, "a/") {
        origName = fileDiff.OrigName[2:]
    }
    if strings.HasPrefix(fileDiff.NewName, "b/") {
        newName = fileDiff.NewName[2:]
    }
    switch {
    case origName != "" && newName != "" && origName == newName: // Modified.
        return newName
    case origName != "" && newName != "" && origName != newName: // Renamed.
        return origName + " -> " + newName
    case origName == "" && newName != "": // Added.
        return newName
    case origName != "" && newName == "": // Removed.
        return "~~" + origName + "~~"
    default:
        panic("unexpected, no names")
    }
}

func main() {
    b := []byte(input)
    var o string
    if fileDiffs, err := diff.ParseMultiFileDiff(b); err == nil {
        for _, fileDiff := range fileDiffs {
            o += "\n" + "## " + fileDiffName(fileDiff) + "\n"
            /*o += "\n```diff\n"
            if hunks, err := diff.PrintHunks(fileDiff.Hunks); err == nil {
                o += string(hunks)
            }
            o += "```\n"*/
        }
    } else {
        o += "\n```\n" + err.Error() + "\n```\n"
    }
    fmt.Println(o)
}

const input = `diff --git a/README.md b/README.md
index 7b73e04..36cde13 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
 Conception-go [![Build Status](https://travis-ci.org/shurcooL/Conception-go.svg?branch=master)](https://travis-ci.org/shurcooL/Conception-go)
 =============

+This is a change.
+
 This is a work in progress Go implementation of [Conception](https://github.com/shurcooL/Conception#demonstration).

 Conception is an experimental project. It's a platform for researching software development tools and techniques. It is driven by a set of guiding principles. Conception-go targets Go development.
diff --git a/data/Font.png b/data/Font.png
index 17a971d..599f8dd 100644
Binary files a/data/Font.png and b/data/Font.png differ
diff --git a/main.go b/main.go
index 1aced1e..98a982e 100644
--- a/main.go
+++ b/main.go
@@ -6710,6 +6710,8 @@ func init() {
 }

 func main() {
+   // Another plain text change.
+
    //defer profile.Start(profile.CPUProfile).Stop()
    //defer profile.Start(profile.MemProfile).Stop()

`

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions