Skip to content

Commit

Permalink
Fix bug where dirty submodules broke hash generation
Browse files Browse the repository at this point in the history
Instead of appending the entire contents of modified files to the sha256
input, we should only append the diff as computed by `git diff` in order
to handle all modifications properly, including submodules.

This also fixes a bug where the processing of the git status output was
too fragile. It makes it more generic by splitting the status string on
fields instead.

Signed-off-by: Matt Kelly <matt.kelly@containership.io>
  • Loading branch information
Matt Kelly committed Jun 20, 2018
1 parent 64ecf0b commit 35375dc
Showing 1 changed file with 11 additions and 16 deletions.
27 changes: 11 additions & 16 deletions pkg/skaffold/build/tag/git_commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import (
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"sort"
Expand Down Expand Up @@ -152,35 +150,32 @@ func commitOrTag(currentTag string, tags []string, opts *Options) string {
return fmt.Sprintf("%s:%s", opts.ImageName, currentTag)
}

// The file state is dirty. To generate a unique suffix, let's hash all the modified files.
// The file state is dirty. To generate a unique suffix, let's hash the diffs
// of all modified files.
// We add a -dirty-unique-id suffix to work well with local iterations.
func dirtyTag(root string, opts *Options, currentTag string, lines []string) (string, error) {
h := sha256.New()
for _, statusLine := range lines {
if strings.HasPrefix(statusLine, "??") {
statusLine = statusLine[1:]
}

if _, err := h.Write([]byte(statusLine)); err != nil {
return "", errors.Wrap(err, "adding deleted file to diff")
return "", errors.Wrap(err, "adding status line to hash")
}

if strings.HasPrefix(statusLine, "D") {
statusFields := strings.Fields(statusLine)

// If the file has been deleted, there's no diff to generate.
if statusFields[0] == "D" {
continue
}

changedPath := statusLine[2:]
f, err := os.Open(filepath.Join(root, changedPath))
changedPath := filepath.Join(root, statusFields[1])
diff, err := runGit(root, "diff", changedPath)
if err != nil {
return "", errors.Wrap(err, "reading diff")
}

if _, err := io.Copy(h, f); err != nil {
f.Close()
return "", errors.Wrap(err, "reading diff")
if _, err := h.Write([]byte(diff)); err != nil {
return "", errors.Wrap(err, "adding diff to hash")
}

f.Close()
}

sha := h.Sum(nil)
Expand Down

0 comments on commit 35375dc

Please sign in to comment.