Skip to content

Commit 73ce53f

Browse files
authored
Merge pull request #299 from vmarkovtsev/master
Fix #294
2 parents 89b5284 + 7153537 commit 73ce53f

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

internal/plumbing/diff.go

+18-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type FileDiff struct {
1818
core.NoopMerger
1919
CleanupDisabled bool
2020
WhitespaceIgnore bool
21+
Timeout time.Duration
2122

2223
l core.Logger
2324
}
@@ -34,6 +35,10 @@ const (
3435
// ConfigFileWhitespaceIgnore is the name of the configuration option (FileDiff.Configure())
3536
// to suppress whitespace changes which can pollute the core diff of the files
3637
ConfigFileWhitespaceIgnore = "FileDiff.WhitespaceIgnore"
38+
39+
// ConfigFileDiffTimeout is the number of milliseconds a single diff calculation may elapse.
40+
// We need this timeout to avoid spending too much time comparing big or "bad" files.
41+
ConfigFileDiffTimeout = "FileDiff.Timeout"
3742
)
3843

3944
// FileDiffData is the type of the dependency provided by FileDiff.
@@ -77,6 +82,12 @@ func (diff *FileDiff) ListConfigurationOptions() []core.ConfigurationOption {
7782
Flag: "no-diff-whitespace",
7883
Type: core.BoolConfigurationOption,
7984
Default: false},
85+
{
86+
Name: ConfigFileDiffTimeout,
87+
Description: "Maximum time in milliseconds a single diff calculation may elapse.",
88+
Flag: "diff-timeout",
89+
Type: core.IntConfigurationOption,
90+
Default: 1000},
8091
}
8192

8293
return options[:]
@@ -93,6 +104,12 @@ func (diff *FileDiff) Configure(facts map[string]interface{}) error {
93104
if val, exists := facts[ConfigFileWhitespaceIgnore].(bool); exists {
94105
diff.WhitespaceIgnore = val
95106
}
107+
if val, exists := facts[ConfigFileDiffTimeout].(int); exists {
108+
if val <= 0 {
109+
diff.l.Warnf("invalid timeout value: %d", val)
110+
}
111+
diff.Timeout = time.Duration(val) * time.Millisecond
112+
}
96113
return nil
97114
}
98115

@@ -133,10 +150,9 @@ func (diff *FileDiff) Consume(deps map[string]interface{}) (map[string]interface
133150
// git/git 4f7770c87ce3c302e1639a7737a6d2531fe4b160 fetch-pack.c is invalid UTF-8
134151
strFrom, strTo := string(blobFrom.Data), string(blobTo.Data)
135152
dmp := diffmatchpatch.New()
136-
dmp.DiffTimeout = time.Hour
153+
dmp.DiffTimeout = diff.Timeout
137154
src, dst, _ := dmp.DiffLinesToRunes(stripWhitespace(strFrom, diff.WhitespaceIgnore), stripWhitespace(strTo, diff.WhitespaceIgnore))
138155
diffs := dmp.DiffMainRunes(src, dst, false)
139-
140156
if !diff.CleanupDisabled {
141157
diffs = dmp.DiffCleanupMerge(dmp.DiffCleanupSemanticLossless(diffs))
142158
}

internal/plumbing/diff_test.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package plumbing_test
22

33
import (
44
"testing"
5+
"time"
56
"unicode/utf8"
67

78
"github.com/sergi/go-diff/diffmatchpatch"
@@ -24,16 +25,19 @@ func TestFileDiffMeta(t *testing.T) {
2425
assert.Equal(t, len(fd.Requires()), 2)
2526
assert.Equal(t, fd.Requires()[0], items.DependencyTreeChanges)
2627
assert.Equal(t, fd.Requires()[1], items.DependencyBlobCache)
27-
assert.Len(t, fd.ListConfigurationOptions(), 2)
28+
assert.Len(t, fd.ListConfigurationOptions(), 3)
2829
assert.Equal(t, fd.ListConfigurationOptions()[0].Name, items.ConfigFileDiffDisableCleanup)
2930
assert.Equal(t, fd.ListConfigurationOptions()[1].Name, items.ConfigFileWhitespaceIgnore)
31+
assert.Equal(t, fd.ListConfigurationOptions()[2].Name, items.ConfigFileDiffTimeout)
3032
assert.NoError(t, fd.Configure(map[string]interface{}{
3133
core.ConfigLogger: core.NewLogger(),
3234
items.ConfigFileDiffDisableCleanup: true,
3335
items.ConfigFileWhitespaceIgnore: true,
36+
items.ConfigFileDiffTimeout: 500,
3437
}))
3538
assert.True(t, fd.CleanupDisabled)
3639
assert.True(t, fd.WhitespaceIgnore)
40+
assert.Equal(t, 500*time.Millisecond, fd.Timeout)
3741
}
3842

3943
func TestFileDiffRegistration(t *testing.T) {

0 commit comments

Comments
 (0)