aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/vcs/git_test.go
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2026-01-06 19:23:39 +0100
committerAleksandr Nogikh <nogikh@google.com>2026-01-09 14:28:59 +0000
commit8d6fe1046d948f9b31d21d260a8b1d1cb4145930 (patch)
tree20aa2347caa6fd73c74c1343bb3b453744b16b78 /pkg/vcs/git_test.go
parentab680254a62d631fbad7921aa157e4cc37c1dbc6 (diff)
pkg/vcs: find base commit by blob sha hashes
Given a git diff, determine the latest commit where the modified files still have the exact sha hashes they had at the moment the git patch was created.
Diffstat (limited to 'pkg/vcs/git_test.go')
-rw-r--r--pkg/vcs/git_test.go84
1 files changed, 84 insertions, 0 deletions
diff --git a/pkg/vcs/git_test.go b/pkg/vcs/git_test.go
index 5050bcdc0..542b572ac 100644
--- a/pkg/vcs/git_test.go
+++ b/pkg/vcs/git_test.go
@@ -10,7 +10,9 @@ import (
"time"
"github.com/google/go-cmp/cmp"
+ "github.com/google/syzkaller/pkg/debugtracer"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGitParseCommit(t *testing.T) {
@@ -484,3 +486,85 @@ index f70f10e..0000000
},
})
}
+
+func TestGitFileHashes(t *testing.T) {
+ repo := MakeTestRepo(t, t.TempDir())
+ commit1 := repo.commitChangeset("first commit", writeFile{"object.txt", "some text"})
+ commit2 := repo.commitChangeset("second commit", writeFile{"object2.txt", "some text2"})
+
+ map1, err := repo.repo.fileHashes(commit1.Hash, []string{"object.txt", "object2.txt"})
+ require.NoError(t, err)
+ assert.NotEmpty(t, map1["object.txt"])
+
+ map2, err := repo.repo.fileHashes(commit2.Hash, []string{"object.txt", "object2.txt"})
+ require.NoError(t, err)
+ assert.NotEmpty(t, map2["object.txt"])
+ assert.NotEmpty(t, map2["object2.txt"])
+}
+
+func TestBaseForDiff(t *testing.T) {
+ repo := MakeTestRepo(t, t.TempDir())
+ repo.commitChangeset("first commit",
+ writeFile{"a.txt", "content of a.txt"},
+ writeFile{"b.txt", "content of b.txt"},
+ )
+ commit2 := repo.commitChangeset("second commit",
+ writeFile{"c.txt", "content of c.txt"},
+ writeFile{"d.txt", "content of d.txt"},
+ )
+ // Create a diff.
+ commit3 := repo.commitChangeset("third commit",
+ writeFile{"a.txt", "update a.txt"},
+ )
+ diff, err := repo.repo.Diff(commit2.Hash, commit3.Hash)
+ require.NoError(t, err)
+ t.Run("conflicting", func(t *testing.T) {
+ _, err := repo.repo.SwitchCommit(commit2.Hash)
+ require.NoError(t, err)
+ // Create a different change on top of commit2.
+ repo.Git("checkout", "-b", "branch-a")
+ time.Sleep(time.Second)
+ repo.commitChangeset("patch a.txt",
+ writeFile{"a.txt", "another change to a.txt"},
+ )
+ // Yet the patch could only be applied to commit2
+ base, err := repo.repo.BaseForDiff(diff, &debugtracer.TestTracer{T: t})
+ require.NoError(t, err)
+ require.NotNil(t, base)
+ assert.Equal(t, []string{"branch-a", "master"}, base.Branches)
+ assert.Equal(t, commit2.Hash, base.Hash)
+ })
+ t.Run("choose latest", func(t *testing.T) {
+ _, err := repo.repo.SwitchCommit(commit2.Hash)
+ require.NoError(t, err)
+ // Wait a second and add one more commit.
+ // (Otherwise the test might be flaky).
+ time.Sleep(time.Second)
+ repo.Git("checkout", "-b", "branch-b")
+ commit4 := repo.commitChangeset("unrelated commit",
+ writeFile{"new.txt", "create new file"},
+ )
+ // Since the commit did not touch a.txt, it's the expected one.
+ base, err := repo.repo.BaseForDiff(diff, &debugtracer.TestTracer{T: t})
+ require.NoError(t, err)
+ require.NotNil(t, base)
+ assert.Equal(t, []string{"branch-b"}, base.Branches)
+ assert.Equal(t, commit4.Hash, base.Hash)
+ })
+ t.Run("ignore unknown objects", func(t *testing.T) {
+ // It's okay if the diff contains unknown hashes.
+ diff2 := `
+diff --git a/b.txt b/b.txt
+deleted file mode 100644
+index f70f10e..0000000
+--- a/b.txt
++++ /dev/null
+@@ -1 +0,0 @@
+-A`
+ twoDiffs := append(append([]byte{}, diff...), diff2...)
+ base, err := repo.repo.BaseForDiff(twoDiffs, &debugtracer.TestTracer{T: t})
+ require.NoError(t, err)
+ require.NotNil(t, base)
+ assert.Equal(t, []string{"branch-b"}, base.Branches)
+ })
+}