diff --git a/Gopkg.lock b/Gopkg.lock index 8ac5f6263..ba868948d 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -613,12 +613,13 @@ version = "v3.1.1" [[projects]] - digest = "1:a72d911e18578e34367f4b849340501c7e6a2787a3a05651b3d53c6cb96990f4" + digest = "1:aadbd12dc57bf65f52231789a0bd4c8d7bcd8a1f7cddb98b602a3f6b82711ad4" name = "gopkg.in/src-d/go-git.v4" packages = [ ".", "config", "internal/revision", + "internal/url", "plumbing", "plumbing/cache", "plumbing/filemode", @@ -658,9 +659,8 @@ "utils/merkletrie/noder", ] pruneopts = "" - revision = "a1f6ef44dfed1253ef7f3bc049f66b15f8fc2ab2" + revision = "4d8bd13a73d6efd41b6be0b2eba5130c498fae0d" source = "github.com/src-d/go-git" - version = "v4.9.1" [[projects]] digest = "1:0056c43a3fc6780d46aeedf43d08a039801668c6e6f6b33b97f2d53822e434e8" diff --git a/Gopkg.toml b/Gopkg.toml index d5dcd4274..6263cbc3b 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -17,7 +17,7 @@ [[constraint]] name = "gopkg.in/src-d/go-git.v4" source = "github.com/src-d/go-git" - version = "4.9.1" + revision = "4d8bd13a73d6efd41b6be0b2eba5130c498fae0d" [[constraint]] name = "gopkg.in/src-d/go-git-fixtures.v3" diff --git a/commit_blobs.go b/commit_blobs.go index 056963466..22a8863dd 100644 --- a/commit_blobs.go +++ b/commit_blobs.go @@ -4,6 +4,7 @@ import ( "bytes" "io" + git "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/object" "gopkg.in/src-d/go-mysql-server.v0/sql" @@ -219,7 +220,9 @@ func (i *commitBlobsRowIter) init() error { if len(i.commits) > 0 { i.iter, err = NewCommitsByHashIter(i.repo, i.commits) } else { - i.iter, err = i.repo.CommitObjects() + i.iter, err = i.repo.Log(&git.LogOptions{ + All: true, + }) } return err diff --git a/commit_files.go b/commit_files.go index 611459374..68876d4fb 100644 --- a/commit_files.go +++ b/commit_files.go @@ -5,6 +5,7 @@ import ( "io" "github.com/sirupsen/logrus" + git "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/filemode" "gopkg.in/src-d/go-git.v4/plumbing/object" @@ -196,7 +197,10 @@ func (i *commitFilesRowIter) init() error { if len(i.commitHashes) > 0 { i.commits, err = NewCommitsByHashIter(i.repo, i.commitHashes) } else { - i.commits, err = i.repo.CommitObjects() + i.commits, err = i.repo. + Log(&git.LogOptions{ + All: true, + }) } return err @@ -433,7 +437,10 @@ func newCommitFilesKeyValueIter( return nil, err } - commits, err := repo.CommitObjects() + commits, err := repo. + Log(&git.LogOptions{ + All: true, + }) if err != nil { return nil, err } diff --git a/commit_files_test.go b/commit_files_test.go index 402cfcc32..ffb9ec80a 100644 --- a/commit_files_test.go +++ b/commit_files_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/require" + git "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-mysql-server.v0/sql" "gopkg.in/src-d/go-mysql-server.v0/sql/expression" @@ -35,7 +36,9 @@ func TestCommitFilesTableRowIter(t *testing.T) { require.NoError(err) - commits, err := repo.CommitObjects() + commits, err := repo.Log(&git.LogOptions{ + All: true, + }) require.NoError(err) for { diff --git a/commit_trees.go b/commit_trees.go index 18a89c7af..938d6752c 100644 --- a/commit_trees.go +++ b/commit_trees.go @@ -4,6 +4,7 @@ import ( "bytes" "io" + git "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/filemode" @@ -215,7 +216,9 @@ func (i *commitTreesRowIter) init() error { if len(i.commitHashes) > 0 { i.commits, err = NewCommitsByHashIter(i.repo, i.commitHashes) } else { - i.commits, err = i.repo.CommitObjects() + i.commits, err = i.repo.Log(&git.LogOptions{ + All: true, + }) } return err diff --git a/commit_trees_test.go b/commit_trees_test.go index bcaa9b7ed..992a739da 100644 --- a/commit_trees_test.go +++ b/commit_trees_test.go @@ -23,17 +23,17 @@ func TestCommitTreesRowIter(t *testing.T) { } expected := []sql.Row{ - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "dbd3641b371024f44d0e469a9c8f5457b0660de1"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "a39771a7651f97faf5c72e08224d857fc35133db"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "5a877e6a906a2743ad6e45d99c1793642aaf8eda"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "586af567d0bb5e771e49bdd9434f5e0fb76d25fa"}, - {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "a8d315b2b1c615d43042c3a62402b8a54288cf5c"}, {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "a39771a7651f97faf5c72e08224d857fc35133db"}, {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "5a877e6a906a2743ad6e45d99c1793642aaf8eda"}, {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "586af567d0bb5e771e49bdd9434f5e0fb76d25fa"}, {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "cf4aa3b38974fb7d81f367c0830f7d78d65ab86b"}, + {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "dbd3641b371024f44d0e469a9c8f5457b0660de1"}, + {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "a39771a7651f97faf5c72e08224d857fc35133db"}, + {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "5a877e6a906a2743ad6e45d99c1793642aaf8eda"}, + {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "586af567d0bb5e771e49bdd9434f5e0fb76d25fa"}, + {"918c48b83bd081e863dbe1b80f8998f058cd8294", "fb72698cab7617ac416264415f13224dfd7a165e"}, {"918c48b83bd081e863dbe1b80f8998f058cd8294", "a39771a7651f97faf5c72e08224d857fc35133db"}, {"918c48b83bd081e863dbe1b80f8998f058cd8294", "5a877e6a906a2743ad6e45d99c1793642aaf8eda"}, @@ -44,13 +44,13 @@ func TestCommitTreesRowIter(t *testing.T) { {"1669dce138d9b841a518c64b10914d88f5e488ea", "eba74343e2f15d62adedfd8c883ee0262b5c8021"}, - {"a5b8b09e2f8fcb0bb99d3ccb0958157b40890d69", "c2d30fa8ef288618f65f6eed6e168e0d514886f4"}, - - {"b8e471f58bcbca63b07bda20e428190409c2db47", "c2d30fa8ef288618f65f6eed6e168e0d514886f4"}, - {"35e85108805c84807bc66a02d91535e1e24b38b9", "8dcef98b1d52143e1e2dbc458ffe38f925786bf2"}, {"b029517f6300c2da0f4b651b8642506cd6aaf45d", "aa9b383c260e1d05fbbf6b30a02914555e20c725"}, + + {"a5b8b09e2f8fcb0bb99d3ccb0958157b40890d69", "c2d30fa8ef288618f65f6eed6e168e0d514886f4"}, + + {"b8e471f58bcbca63b07bda20e428190409c2db47", "c2d30fa8ef288618f65f6eed6e168e0d514886f4"}, } require.Equal(expected, rows) @@ -90,8 +90,8 @@ func TestCommitTreesPushdown(t *testing.T) { ), }, []sql.Row{ - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "586af567d0bb5e771e49bdd9434f5e0fb76d25fa"}, {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "586af567d0bb5e771e49bdd9434f5e0fb76d25fa"}, + {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "586af567d0bb5e771e49bdd9434f5e0fb76d25fa"}, {"918c48b83bd081e863dbe1b80f8998f058cd8294", "586af567d0bb5e771e49bdd9434f5e0fb76d25fa"}, }, }, diff --git a/commits.go b/commits.go index 2abfe5754..6b40e0748 100644 --- a/commits.go +++ b/commits.go @@ -3,6 +3,7 @@ package gitbase import ( "io" + git "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-mysql-server.v0/sql" "gopkg.in/src-d/go-git.v4/plumbing" @@ -161,7 +162,10 @@ func (i *commitIter) init() error { if len(i.hashes) > 0 { i.iter, err = NewCommitsByHashIter(i.repo, i.hashes) } else { - i.iter, err = i.repo.CommitObjects() + i.iter, err = + i.repo.Log(&git.LogOptions{ + All: true, + }) } return err @@ -245,7 +249,10 @@ func NewCommitsByHashIter( var commitIter object.CommitIter var err error if len(hashes) == 0 { - commitIter, err = repo.CommitObjects() + commitIter, err = + repo.Log(&git.LogOptions{ + All: true, + }) if err != nil { return nil, err } @@ -333,7 +340,10 @@ func newCommitsKeyValueIter( return nil, err } - commits, err := repo.CommitObjects() + commits, err := + repo.Log(&git.LogOptions{ + All: true, + }) if err != nil { return nil, err } diff --git a/commits_test.go b/commits_test.go index 0735c89ad..4eec6d8de 100644 --- a/commits_test.go +++ b/commits_test.go @@ -101,14 +101,14 @@ func TestCommitsParents(t *testing.T) { }{ { name: "test commits parents 1", - hash: "e8d3ffab552895c19b9fcf7aa264d277cde33881", + hash: "6ecf0ef2c2dffb796033e5a02219af86ec6584e5", parents: []string{ "918c48b83bd081e863dbe1b80f8998f058cd8294", }, }, { name: "test commits parents 2", - hash: "6ecf0ef2c2dffb796033e5a02219af86ec6584e5", + hash: "e8d3ffab552895c19b9fcf7aa264d277cde33881", parents: []string{ "918c48b83bd081e863dbe1b80f8998f058cd8294", }, @@ -137,30 +137,30 @@ func TestCommitsParents(t *testing.T) { }, { name: "test commits parents 6", - hash: "a5b8b09e2f8fcb0bb99d3ccb0958157b40890d69", + hash: "35e85108805c84807bc66a02d91535e1e24b38b9", parents: []string{ "b029517f6300c2da0f4b651b8642506cd6aaf45d", - "b8e471f58bcbca63b07bda20e428190409c2db47", }, }, { - name: "test commits parents 7", - hash: "b8e471f58bcbca63b07bda20e428190409c2db47", - parents: []string{ - "b029517f6300c2da0f4b651b8642506cd6aaf45d", - }, + name: "test commits parents 7", + hash: "b029517f6300c2da0f4b651b8642506cd6aaf45d", + parents: []string{}, }, { name: "test commits parents 8", - hash: "35e85108805c84807bc66a02d91535e1e24b38b9", + hash: "a5b8b09e2f8fcb0bb99d3ccb0958157b40890d69", parents: []string{ "b029517f6300c2da0f4b651b8642506cd6aaf45d", + "b8e471f58bcbca63b07bda20e428190409c2db47", }, }, { - name: "test commits parents 9", - hash: "b029517f6300c2da0f4b651b8642506cd6aaf45d", - parents: []string{}, + name: "test commits parents 9", + hash: "b8e471f58bcbca63b07bda20e428190409c2db47", + parents: []string{ + "b029517f6300c2da0f4b651b8642506cd6aaf45d", + }, }, } @@ -188,10 +188,10 @@ func TestCommitsIndexKeyValueIter(t *testing.T) { assertEncodeKey(t, &packOffsetIndexKey{ Repository: path, Packfile: "323a4b6b5de684f9966953a043bc800154e5dbfa", - Offset: 682, + Offset: 186, }), []interface{}{ - "1669dce138d9b841a518c64b10914d88f5e488ea", + "6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "mcuadros@gmail.com", }, }, @@ -199,10 +199,10 @@ func TestCommitsIndexKeyValueIter(t *testing.T) { assertEncodeKey(t, &packOffsetIndexKey{ Repository: path, Packfile: "323a4b6b5de684f9966953a043bc800154e5dbfa", - Offset: 1292, + Offset: 12, }), []interface{}{ - "35e85108805c84807bc66a02d91535e1e24b38b9", + "e8d3ffab552895c19b9fcf7aa264d277cde33881", "mcuadros@gmail.com", }, }, @@ -210,10 +210,10 @@ func TestCommitsIndexKeyValueIter(t *testing.T) { assertEncodeKey(t, &packOffsetIndexKey{ Repository: path, Packfile: "323a4b6b5de684f9966953a043bc800154e5dbfa", - Offset: 186, + Offset: 353, }), []interface{}{ - "6ecf0ef2c2dffb796033e5a02219af86ec6584e5", + "918c48b83bd081e863dbe1b80f8998f058cd8294", "mcuadros@gmail.com", }, }, @@ -221,10 +221,10 @@ func TestCommitsIndexKeyValueIter(t *testing.T) { assertEncodeKey(t, &packOffsetIndexKey{ Repository: path, Packfile: "323a4b6b5de684f9966953a043bc800154e5dbfa", - Offset: 353, + Offset: 516, }), []interface{}{ - "918c48b83bd081e863dbe1b80f8998f058cd8294", + "af2d6a6954d532f8ffb47615169c8fdf9d383a1a", "mcuadros@gmail.com", }, }, @@ -232,10 +232,10 @@ func TestCommitsIndexKeyValueIter(t *testing.T) { assertEncodeKey(t, &packOffsetIndexKey{ Repository: path, Packfile: "323a4b6b5de684f9966953a043bc800154e5dbfa", - Offset: 905, + Offset: 682, }), []interface{}{ - "a5b8b09e2f8fcb0bb99d3ccb0958157b40890d69", + "1669dce138d9b841a518c64b10914d88f5e488ea", "mcuadros@gmail.com", }, }, @@ -243,10 +243,10 @@ func TestCommitsIndexKeyValueIter(t *testing.T) { assertEncodeKey(t, &packOffsetIndexKey{ Repository: path, Packfile: "323a4b6b5de684f9966953a043bc800154e5dbfa", - Offset: 516, + Offset: 1292, }), []interface{}{ - "af2d6a6954d532f8ffb47615169c8fdf9d383a1a", + "35e85108805c84807bc66a02d91535e1e24b38b9", "mcuadros@gmail.com", }, }, @@ -265,22 +265,22 @@ func TestCommitsIndexKeyValueIter(t *testing.T) { assertEncodeKey(t, &packOffsetIndexKey{ Repository: path, Packfile: "323a4b6b5de684f9966953a043bc800154e5dbfa", - Offset: 1130, + Offset: 905, }), []interface{}{ - "b8e471f58bcbca63b07bda20e428190409c2db47", - "daniel@lordran.local", + "a5b8b09e2f8fcb0bb99d3ccb0958157b40890d69", + "mcuadros@gmail.com", }, }, { assertEncodeKey(t, &packOffsetIndexKey{ Repository: path, Packfile: "323a4b6b5de684f9966953a043bc800154e5dbfa", - Offset: 12, + Offset: 1130, }), []interface{}{ - "e8d3ffab552895c19b9fcf7aa264d277cde33881", - "mcuadros@gmail.com", + "b8e471f58bcbca63b07bda20e428190409c2db47", + "daniel@lordran.local", }, }, } diff --git a/files.go b/files.go index a09c38ccb..7f0b34d48 100644 --- a/files.go +++ b/files.go @@ -4,6 +4,7 @@ import ( "bytes" "io" + git "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/filemode" "gopkg.in/src-d/go-git.v4/plumbing/object" @@ -192,7 +193,9 @@ type filesRowIter struct { func (i *filesRowIter) init() error { var err error i.seen = make(map[plumbing.Hash]struct{}) - i.commits, err = i.repo.CommitObjects() + i.commits, err = i.repo.Log(&git.LogOptions{ + All: true, + }) return err } @@ -411,7 +414,9 @@ func newFilesKeyValueIter(pool *RepositoryPool, repo *Repository, columns []stri return nil, err } - commits, err := repo.CommitObjects() + commits, err := repo.Log(&git.LogOptions{ + All: true, + }) if err != nil { return nil, err } diff --git a/files_test.go b/files_test.go index 1b8e2cd7a..cb1defa48 100644 --- a/files_test.go +++ b/files_test.go @@ -105,8 +105,8 @@ func TestFilesTablePushdownFilters(t *testing.T) { ), }, []sql.Row{ - {"binary.jpg", "d5c0f4ab811897cadf03aec358ae60d21f91c50d", "dbd3641b371024f44d0e469a9c8f5457b0660de1", "0100644"}, {"binary.jpg", "d5c0f4ab811897cadf03aec358ae60d21f91c50d", "a8d315b2b1c615d43042c3a62402b8a54288cf5c", "0100644"}, + {"binary.jpg", "d5c0f4ab811897cadf03aec358ae60d21f91c50d", "dbd3641b371024f44d0e469a9c8f5457b0660de1", "0100644"}, {"binary.jpg", "d5c0f4ab811897cadf03aec358ae60d21f91c50d", "fb72698cab7617ac416264415f13224dfd7a165e", "0100644"}, {"binary.jpg", "d5c0f4ab811897cadf03aec358ae60d21f91c50d", "4d081c50e250fa32ea8b1313cf8bb7c2ad7627fd", "0100644"}, {"binary.jpg", "d5c0f4ab811897cadf03aec358ae60d21f91c50d", "eba74343e2f15d62adedfd8c883ee0262b5c8021", "0100644"}, @@ -122,14 +122,14 @@ func TestFilesTablePushdownFilters(t *testing.T) { ), }, []sql.Row{ - {"LICENSE", "c192bd6a24ea1ab01d78686e417c8bdc7c3d197f", "dbd3641b371024f44d0e469a9c8f5457b0660de1", "0100644"}, {"LICENSE", "c192bd6a24ea1ab01d78686e417c8bdc7c3d197f", "a8d315b2b1c615d43042c3a62402b8a54288cf5c", "0100644"}, + {"LICENSE", "c192bd6a24ea1ab01d78686e417c8bdc7c3d197f", "dbd3641b371024f44d0e469a9c8f5457b0660de1", "0100644"}, {"LICENSE", "c192bd6a24ea1ab01d78686e417c8bdc7c3d197f", "fb72698cab7617ac416264415f13224dfd7a165e", "0100644"}, {"LICENSE", "c192bd6a24ea1ab01d78686e417c8bdc7c3d197f", "4d081c50e250fa32ea8b1313cf8bb7c2ad7627fd", "0100644"}, {"LICENSE", "c192bd6a24ea1ab01d78686e417c8bdc7c3d197f", "eba74343e2f15d62adedfd8c883ee0262b5c8021", "0100644"}, - {"LICENSE", "c192bd6a24ea1ab01d78686e417c8bdc7c3d197f", "c2d30fa8ef288618f65f6eed6e168e0d514886f4", "0100644"}, {"LICENSE", "c192bd6a24ea1ab01d78686e417c8bdc7c3d197f", "8dcef98b1d52143e1e2dbc458ffe38f925786bf2", "0100644"}, {"LICENSE", "c192bd6a24ea1ab01d78686e417c8bdc7c3d197f", "aa9b383c260e1d05fbbf6b30a02914555e20c725", "0100644"}, + {"LICENSE", "c192bd6a24ea1ab01d78686e417c8bdc7c3d197f", "c2d30fa8ef288618f65f6eed6e168e0d514886f4", "0100644"}, }, }, } diff --git a/index_test.go b/index_test.go index 30a5dc70a..5b4156390 100644 --- a/index_test.go +++ b/index_test.go @@ -76,6 +76,7 @@ func assertIndexKeyValueIter(t *testing.T, iter sql.PartitionIndexKeyValueIter, } require.NoError(iter.Close()) + require.Equal(len(expected), len(result)) require.ElementsMatch(expected, result) } diff --git a/integration_test.go b/integration_test.go index 5fa683c46..4df7396e4 100644 --- a/integration_test.go +++ b/integration_test.go @@ -264,14 +264,14 @@ func TestIntegration(t *testing.T) { WHERE te.repository_id='worktree' LIMIT 8`, []sql.Row{ - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "Máximo Cuadros Ortiz", ".gitignore"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "Máximo Cuadros Ortiz", "CHANGELOG"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "Máximo Cuadros Ortiz", "LICENSE"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "Máximo Cuadros Ortiz", "README"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "Máximo Cuadros Ortiz", "binary.jpg"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "Máximo Cuadros Ortiz", "go"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "Máximo Cuadros Ortiz", "json"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "Máximo Cuadros Ortiz", "php"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "Máximo Cuadros Ortiz", ".gitignore"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "Máximo Cuadros Ortiz", "CHANGELOG"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "Máximo Cuadros Ortiz", "LICENSE"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "Máximo Cuadros Ortiz", "binary.jpg"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "Máximo Cuadros Ortiz", "go"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "Máximo Cuadros Ortiz", "json"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "Máximo Cuadros Ortiz", "php"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "Máximo Cuadros Ortiz", "vendor"}, }, }, { @@ -287,14 +287,14 @@ func TestIntegration(t *testing.T) { WHERE te.repository_id='worktree' LIMIT 8`, []sql.Row{ - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", ".gitignore", "dbd3641b371024f44d0e469a9c8f5457b0660de1"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "CHANGELOG", "dbd3641b371024f44d0e469a9c8f5457b0660de1"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "LICENSE", "dbd3641b371024f44d0e469a9c8f5457b0660de1"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "README", "dbd3641b371024f44d0e469a9c8f5457b0660de1"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "binary.jpg", "dbd3641b371024f44d0e469a9c8f5457b0660de1"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "go", "dbd3641b371024f44d0e469a9c8f5457b0660de1"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "json", "dbd3641b371024f44d0e469a9c8f5457b0660de1"}, - {"e8d3ffab552895c19b9fcf7aa264d277cde33881", "some code in a branch\n", "php", "dbd3641b371024f44d0e469a9c8f5457b0660de1"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", ".gitignore", "a8d315b2b1c615d43042c3a62402b8a54288cf5c"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "CHANGELOG", "a8d315b2b1c615d43042c3a62402b8a54288cf5c"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "LICENSE", "a8d315b2b1c615d43042c3a62402b8a54288cf5c"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "binary.jpg", "a8d315b2b1c615d43042c3a62402b8a54288cf5c"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "go", "a8d315b2b1c615d43042c3a62402b8a54288cf5c"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "json", "a8d315b2b1c615d43042c3a62402b8a54288cf5c"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "php", "a8d315b2b1c615d43042c3a62402b8a54288cf5c"}, + {"6ecf0ef2c2dffb796033e5a02219af86ec6584e5", "vendor stuff\n", "vendor", "a8d315b2b1c615d43042c3a62402b8a54288cf5c"}, }, }, { diff --git a/repository_pool_test.go b/repository_pool_test.go index ecb9145e5..4345268e9 100644 --- a/repository_pool_test.go +++ b/repository_pool_test.go @@ -90,7 +90,9 @@ func TestRepositoryPoolGit(t *testing.T) { require.NotNil(repo) require.NoError(err) - iter, err := repo.CommitObjects() + iter, err := repo.Log(&git.LogOptions{ + All: true, + }) require.NoError(err) count := 0 @@ -167,14 +169,16 @@ func TestRepositoryPoolSiva(t *testing.T) { require.Equal(expectedRepos, len(pool.repositories)) - expected := []int{606, 452, 75} + expected := []int{606, 380, 69} result := make([]int, expectedRepos) for i := 0; i < expectedRepos; i++ { repo, err := pool.GetPos(i) require.NoError(err) - iter, err := repo.CommitObjects() + iter, err := repo.Log(&git.LogOptions{ + All: true, + }) require.NoError(err) require.NoError(iter.ForEach(func(c *object.Commit) error { diff --git a/squash_iterator.go b/squash_iterator.go index 32d7b2900..c954deb37 100644 --- a/squash_iterator.go +++ b/squash_iterator.go @@ -1307,7 +1307,10 @@ func (i *squashCommitsIter) New(ctx *sql.Context, repo *Repository) (ChainableIt return nil, err } - commits, err := repo.CommitObjects() + commits, err := repo. + Log(&git.LogOptions{ + All: true, + }) if err != nil { logrus.WithFields(logrus.Fields{ "repo": repo.ID, @@ -1533,7 +1536,10 @@ func (i *squashRepoCommitsIter) Advance() error { return err } - i.commits, err = i.repos.Repository().CommitObjects() + i.commits, err = i.repos.Repository(). + Log(&git.LogOptions{ + All: true, + }) if err != nil { logrus.WithFields(logrus.Fields{ "repo": i.repos.Repository().ID, diff --git a/vendor/gopkg.in/src-d/go-git.v4/config/config.go b/vendor/gopkg.in/src-d/go-git.v4/config/config.go index a637f6d70..2c3b8b968 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/config/config.go +++ b/vendor/gopkg.in/src-d/go-git.v4/config/config.go @@ -8,6 +8,7 @@ import ( "sort" "strconv" + "gopkg.in/src-d/go-git.v4/internal/url" format "gopkg.in/src-d/go-git.v4/plumbing/format/config" ) @@ -399,3 +400,7 @@ func (c *RemoteConfig) marshal() *format.Subsection { return c.raw } + +func (c *RemoteConfig) IsFirstURLLocal() bool { + return url.IsLocalEndpoint(c.URLs[0]) +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/internal/url/url.go b/vendor/gopkg.in/src-d/go-git.v4/internal/url/url.go new file mode 100644 index 000000000..0f0d709d9 --- /dev/null +++ b/vendor/gopkg.in/src-d/go-git.v4/internal/url/url.go @@ -0,0 +1,37 @@ +package url + +import ( + "regexp" +) + +var ( + isSchemeRegExp = regexp.MustCompile(`^[^:]+://`) + scpLikeUrlRegExp = regexp.MustCompile(`^(?:(?P[^@]+)@)?(?P[^:\s]+):(?:(?P[0-9]{1,5})/)?(?P[^\\].*)$`) +) + +// MatchesScheme returns true if the given string matches a URL-like +// format scheme. +func MatchesScheme(url string) bool { + return isSchemeRegExp.MatchString(url) +} + +// MatchesScpLike returns true if the given string matches an SCP-like +// format scheme. +func MatchesScpLike(url string) bool { + return scpLikeUrlRegExp.MatchString(url) +} + +// FindScpLikeComponents returns the user, host, port and path of the +// given SCP-like URL. +func FindScpLikeComponents(url string) (user, host, port, path string) { + m := scpLikeUrlRegExp.FindStringSubmatch(url) + return m[1], m[2], m[3], m[4] +} + +// IsLocalEndpoint returns true if the given URL string specifies a +// local file endpoint. For example, on a Linux machine, +// `/home/user/src/go-git` would match as a local endpoint, but +// `https://github.com/src-d/go-git` would not. +func IsLocalEndpoint(url string) bool { + return !MatchesScheme(url) && !MatchesScpLike(url) +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/plumbing/format/packfile/packfile.go b/vendor/gopkg.in/src-d/go-git.v4/plumbing/format/packfile/packfile.go index 1e7ef2694..69b6e85d0 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/plumbing/format/packfile/packfile.go +++ b/vendor/gopkg.in/src-d/go-git.v4/plumbing/format/packfile/packfile.go @@ -107,7 +107,7 @@ func (p *Packfile) GetSizeByOffset(o int64) (size int64, err error) { if err != nil { return 0, err } - return h.Length, nil + return p.getObjectSize(h) } func (p *Packfile) objectHeaderAtOffset(offset int64) (*ObjectHeader, error) { diff --git a/vendor/gopkg.in/src-d/go-git.v4/plumbing/format/packfile/packfile_test.go b/vendor/gopkg.in/src-d/go-git.v4/plumbing/format/packfile/packfile_test.go index 05dc8a7ac..455fe65f5 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/plumbing/format/packfile/packfile_test.go +++ b/vendor/gopkg.in/src-d/go-git.v4/plumbing/format/packfile/packfile_test.go @@ -277,3 +277,29 @@ func getIndexFromIdxFile(r io.Reader) idxfile.Index { return idxf } + +func (s *PackfileSuite) TestSize(c *C) { + f := fixtures.Basic().ByTag("ref-delta").One() + + index := getIndexFromIdxFile(f.Idx()) + fs := osfs.New("") + pf, err := fs.Open(f.Packfile().Name()) + c.Assert(err, IsNil) + + packfile := packfile.NewPackfile(index, fs, pf) + defer packfile.Close() + + // Get the size of binary.jpg, which is not delta-encoded. + offset, err := packfile.FindOffset(plumbing.NewHash("d5c0f4ab811897cadf03aec358ae60d21f91c50d")) + c.Assert(err, IsNil) + size, err := packfile.GetSizeByOffset(offset) + c.Assert(err, IsNil) + c.Assert(size, Equals, int64(76110)) + + // Get the size of the root commit, which is delta-encoded. + offset, err = packfile.FindOffset(f.Head) + c.Assert(err, IsNil) + size, err = packfile.GetSizeByOffset(offset) + c.Assert(err, IsNil) + c.Assert(size, Equals, int64(245)) +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/plumbing/object/commit_walker.go b/vendor/gopkg.in/src-d/go-git.v4/plumbing/object/commit_walker.go index 8c76557c4..0eff05912 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/plumbing/object/commit_walker.go +++ b/vendor/gopkg.in/src-d/go-git.v4/plumbing/object/commit_walker.go @@ -197,26 +197,38 @@ func NewCommitAllIter(repoStorer storage.Storer, commitIterFunc func(*Commit) Co commitsPath := list.New() commitsLookup := make(map[plumbing.Hash]*list.Element) head, err := storer.ResolveReference(repoStorer, plumbing.HEAD) - if err != nil { - return nil, err + if err == nil { + err = addReference(repoStorer, commitIterFunc, head, commitsPath, commitsLookup) } - // add all references along with the HEAD - if err = addReference(repoStorer, commitIterFunc, head, commitsPath, commitsLookup); err != nil { + if err != nil && err != plumbing.ErrReferenceNotFound { return nil, err } + + // add all references along with the HEAD refIter, err := repoStorer.IterReferences() if err != nil { return nil, err } defer refIter.Close() - err = refIter.ForEach( - func(ref *plumbing.Reference) error { - return addReference(repoStorer, commitIterFunc, ref, commitsPath, commitsLookup) - }, - ) - if err != nil { - return nil, err + + for { + ref, err := refIter.Next() + if err == io.EOF { + break + } + + if err == plumbing.ErrReferenceNotFound { + continue + } + + if err != nil { + return nil, err + } + + if err = addReference(repoStorer, commitIterFunc, ref, commitsPath, commitsLookup); err != nil { + return nil, err + } } return &commitAllIterator{commitsPath.Front()}, nil diff --git a/vendor/gopkg.in/src-d/go-git.v4/plumbing/revlist/revlist.go b/vendor/gopkg.in/src-d/go-git.v4/plumbing/revlist/revlist.go index 0a9d1e812..7ad71ac04 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/plumbing/revlist/revlist.go +++ b/vendor/gopkg.in/src-d/go-git.v4/plumbing/revlist/revlist.go @@ -21,7 +21,20 @@ func Objects( objs, ignore []plumbing.Hash, ) ([]plumbing.Hash, error) { - ignore, err := objects(s, ignore, nil, true) + return ObjectsWithStorageForIgnores(s, s, objs, ignore) +} + +// ObjectsWithStorageForIgnores is the same as Objects, but a +// secondary storage layer can be provided, to be used to finding the +// full set of objects to be ignored while finding the reachable +// objects. This is useful when the main `s` storage layer is slow +// and/or remote, while the ignore list is available somewhere local. +func ObjectsWithStorageForIgnores( + s, ignoreStore storer.EncodedObjectStorer, + objs, + ignore []plumbing.Hash, +) ([]plumbing.Hash, error) { + ignore, err := objects(ignoreStore, ignore, nil, true) if err != nil { return nil, err } @@ -114,7 +127,6 @@ func reachableObjects( i := object.NewCommitPreorderIter(commit, seen, ignore) pending := make(map[plumbing.Hash]bool) addPendingParents(pending, visited, commit) - for { commit, err := i.Next() if err == io.EOF { diff --git a/vendor/gopkg.in/src-d/go-git.v4/plumbing/revlist/revlist_test.go b/vendor/gopkg.in/src-d/go-git.v4/plumbing/revlist/revlist_test.go index dea1c73d9..ceae72743 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/plumbing/revlist/revlist_test.go +++ b/vendor/gopkg.in/src-d/go-git.v4/plumbing/revlist/revlist_test.go @@ -129,6 +129,32 @@ func (s *RevListSuite) TestRevListObjectsTagObject(c *C) { c.Assert(len(hist), Equals, len(expected)) } +func (s *RevListSuite) TestRevListObjectsWithStorageForIgnores(c *C) { + sto := filesystem.NewStorage( + fixtures.ByTag("merge-conflict").One().DotGit(), + cache.NewObjectLRUDefault()) + + // The "merge-conflict" repo has one extra commit in it, with a + // two files modified in two different subdirs. + expected := map[string]bool{ + "1980fcf55330d9d94c34abee5ab734afecf96aba": true, // commit + "73d9cf44e9045254346c73f6646b08f9302c8570": true, // root dir + "e8435d512a98586bd2e4fcfcdf04101b0bb1b500": true, // go/ + "257cc5642cb1a054f08cc83f2d943e56fd3ebe99": true, // haskal.hs + "d499a1a0b79b7d87a35155afd0c1cce78b37a91c": true, // example.go + "d108adc364fb6f21395d011ae2c8a11d96905b0d": true, // haskal/ + } + + hist, err := ObjectsWithStorageForIgnores(sto, s.Storer, []plumbing.Hash{plumbing.NewHash("1980fcf55330d9d94c34abee5ab734afecf96aba")}, []plumbing.Hash{plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")}) + c.Assert(err, IsNil) + + for _, h := range hist { + c.Assert(expected[h.String()], Equals, true) + } + + c.Assert(len(hist), Equals, len(expected)) +} + // --- // | |\ // | | * b8e471f Creating changelog diff --git a/vendor/gopkg.in/src-d/go-git.v4/plumbing/storer/object.go b/vendor/gopkg.in/src-d/go-git.v4/plumbing/storer/object.go index 2ac9b091e..98d1ec3fe 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/plumbing/storer/object.go +++ b/vendor/gopkg.in/src-d/go-git.v4/plumbing/storer/object.go @@ -222,7 +222,7 @@ type MultiEncodedObjectIter struct { } // NewMultiEncodedObjectIter returns an object iterator for the given slice of -// objects. +// EncodedObjectIters. func NewMultiEncodedObjectIter(iters []EncodedObjectIter) EncodedObjectIter { return &MultiEncodedObjectIter{iters: iters} } diff --git a/vendor/gopkg.in/src-d/go-git.v4/plumbing/storer/reference.go b/vendor/gopkg.in/src-d/go-git.v4/plumbing/storer/reference.go index 5e85a3be4..cce72b4aa 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/plumbing/storer/reference.go +++ b/vendor/gopkg.in/src-d/go-git.v4/plumbing/storer/reference.go @@ -131,9 +131,27 @@ func (iter *ReferenceSliceIter) Next() (*plumbing.Reference, error) { // an error happens or the end of the iter is reached. If ErrStop is sent // the iteration is stop but no error is returned. The iterator is closed. func (iter *ReferenceSliceIter) ForEach(cb func(*plumbing.Reference) error) error { + return forEachReferenceIter(iter, cb) +} + +type bareReferenceIterator interface { + Next() (*plumbing.Reference, error) + Close() +} + +func forEachReferenceIter(iter bareReferenceIterator, cb func(*plumbing.Reference) error) error { defer iter.Close() - for _, r := range iter.series { - if err := cb(r); err != nil { + for { + obj, err := iter.Next() + if err != nil { + if err == io.EOF { + return nil + } + + return err + } + + if err := cb(obj); err != nil { if err == ErrStop { return nil } @@ -141,8 +159,6 @@ func (iter *ReferenceSliceIter) ForEach(cb func(*plumbing.Reference) error) erro return err } } - - return nil } // Close releases any resources used by the iterator. @@ -150,6 +166,52 @@ func (iter *ReferenceSliceIter) Close() { iter.pos = len(iter.series) } +// MultiReferenceIter implements ReferenceIter. It iterates over several +// ReferenceIter, +// +// The MultiReferenceIter must be closed with a call to Close() when it is no +// longer needed. +type MultiReferenceIter struct { + iters []ReferenceIter +} + +// NewMultiReferenceIter returns an reference iterator for the given slice of +// EncodedObjectIters. +func NewMultiReferenceIter(iters []ReferenceIter) ReferenceIter { + return &MultiReferenceIter{iters: iters} +} + +// Next returns the next reference from the iterator, if one iterator reach +// io.EOF is removed and the next one is used. +func (iter *MultiReferenceIter) Next() (*plumbing.Reference, error) { + if len(iter.iters) == 0 { + return nil, io.EOF + } + + obj, err := iter.iters[0].Next() + if err == io.EOF { + iter.iters[0].Close() + iter.iters = iter.iters[1:] + return iter.Next() + } + + return obj, err +} + +// ForEach call the cb function for each reference contained on this iter until +// an error happens or the end of the iter is reached. If ErrStop is sent +// the iteration is stop but no error is returned. The iterator is closed. +func (iter *MultiReferenceIter) ForEach(cb func(*plumbing.Reference) error) error { + return forEachReferenceIter(iter, cb) +} + +// Close releases any resources used by the iterator. +func (iter *MultiReferenceIter) Close() { + for _, i := range iter.iters { + i.Close() + } +} + // ResolveReference resolves a SymbolicReference to a HashReference. func ResolveReference(s ReferenceStorer, n plumbing.ReferenceName) (*plumbing.Reference, error) { r, err := s.Reference(n) diff --git a/vendor/gopkg.in/src-d/go-git.v4/plumbing/storer/reference_test.go b/vendor/gopkg.in/src-d/go-git.v4/plumbing/storer/reference_test.go index 490ec9519..1d02c22d1 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/plumbing/storer/reference_test.go +++ b/vendor/gopkg.in/src-d/go-git.v4/plumbing/storer/reference_test.go @@ -172,3 +172,26 @@ func (s *ReferenceSuite) TestReferenceFilteredIterForEachStop(c *C) { c.Assert(count, Equals, 1) } + +func (s *ReferenceSuite) TestMultiReferenceIterForEach(c *C) { + i := NewMultiReferenceIter( + []ReferenceIter{ + NewReferenceSliceIter([]*plumbing.Reference{ + plumbing.NewReferenceFromStrings("foo", "foo"), + }), + NewReferenceSliceIter([]*plumbing.Reference{ + plumbing.NewReferenceFromStrings("bar", "bar"), + }), + }, + ) + + var result []string + err := i.ForEach(func(r *plumbing.Reference) error { + result = append(result, r.Name().String()) + return nil + }) + + c.Assert(err, IsNil) + c.Assert(result, HasLen, 2) + c.Assert(result, DeepEquals, []string{"foo", "bar"}) +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/plumbing/transport/common.go b/vendor/gopkg.in/src-d/go-git.v4/plumbing/transport/common.go index f7b882b8b..dcf9391d5 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/plumbing/transport/common.go +++ b/vendor/gopkg.in/src-d/go-git.v4/plumbing/transport/common.go @@ -19,10 +19,10 @@ import ( "fmt" "io" "net/url" - "regexp" "strconv" "strings" + giturl "gopkg.in/src-d/go-git.v4/internal/url" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp" "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/capability" @@ -224,34 +224,28 @@ func getPath(u *url.URL) string { return res } -var ( - isSchemeRegExp = regexp.MustCompile(`^[^:]+://`) - scpLikeUrlRegExp = regexp.MustCompile(`^(?:(?P[^@]+)@)?(?P[^:\s]+):(?:(?P[0-9]{1,5})/)?(?P[^\\].*)$`) -) - func parseSCPLike(endpoint string) (*Endpoint, bool) { - if isSchemeRegExp.MatchString(endpoint) || !scpLikeUrlRegExp.MatchString(endpoint) { + if giturl.MatchesScheme(endpoint) || !giturl.MatchesScpLike(endpoint) { return nil, false } - m := scpLikeUrlRegExp.FindStringSubmatch(endpoint) - - port, err := strconv.Atoi(m[3]) + user, host, portStr, path := giturl.FindScpLikeComponents(endpoint) + port, err := strconv.Atoi(portStr) if err != nil { port = 22 } return &Endpoint{ Protocol: "ssh", - User: m[1], - Host: m[2], + User: user, + Host: host, Port: port, - Path: m[4], + Path: path, }, true } func parseFile(endpoint string) (*Endpoint, bool) { - if isSchemeRegExp.MatchString(endpoint) { + if giturl.MatchesScheme(endpoint) { return nil, false } diff --git a/vendor/gopkg.in/src-d/go-git.v4/remote.go b/vendor/gopkg.in/src-d/go-git.v4/remote.go index 8f4e41d72..de537ce8e 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/remote.go +++ b/vendor/gopkg.in/src-d/go-git.v4/remote.go @@ -6,8 +6,10 @@ import ( "fmt" "io" + "gopkg.in/src-d/go-billy.v4/osfs" "gopkg.in/src-d/go-git.v4/config" "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/plumbing/cache" "gopkg.in/src-d/go-git.v4/plumbing/format/packfile" "gopkg.in/src-d/go-git.v4/plumbing/object" "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp" @@ -18,6 +20,7 @@ import ( "gopkg.in/src-d/go-git.v4/plumbing/transport" "gopkg.in/src-d/go-git.v4/plumbing/transport/client" "gopkg.in/src-d/go-git.v4/storage" + "gopkg.in/src-d/go-git.v4/storage/filesystem" "gopkg.in/src-d/go-git.v4/storage/memory" "gopkg.in/src-d/go-git.v4/utils/ioutil" ) @@ -149,7 +152,17 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) { var hashesToPush []plumbing.Hash // Avoid the expensive revlist operation if we're only doing deletes. if !allDelete { - hashesToPush, err = revlist.Objects(r.s, objects, haves) + if r.c.IsFirstURLLocal() { + // If we're are pushing to a local repo, it might be much + // faster to use a local storage layer to get the commits + // to ignore, when calculating the object revlist. + localStorer := filesystem.NewStorage( + osfs.New(r.c.URLs[0]), cache.NewObjectLRUDefault()) + hashesToPush, err = revlist.ObjectsWithStorageForIgnores( + r.s, localStorer, objects, haves) + } else { + hashesToPush, err = revlist.Objects(r.s, objects, haves) + } if err != nil { return err } diff --git a/vendor/gopkg.in/src-d/go-git.v4/repository_test.go b/vendor/gopkg.in/src-d/go-git.v4/repository_test.go index 2a56dd21c..154973779 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/repository_test.go +++ b/vendor/gopkg.in/src-d/go-git.v4/repository_test.go @@ -1256,8 +1256,18 @@ func (s *RepositorySuite) TestLogAll(c *C) { err := r.clone(context.Background(), &CloneOptions{ URL: s.GetBasicLocalRepositoryURL(), }) + c.Assert(err, IsNil) + + rIter, err := r.Storer.IterReferences() + c.Assert(err, IsNil) + refCount := 0 + err = rIter.ForEach(func(ref *plumbing.Reference) error { + refCount++ + return nil + }) c.Assert(err, IsNil) + c.Assert(refCount, Equals, 5) cIter, err := r.Log(&LogOptions{ All: true, @@ -1286,6 +1296,58 @@ func (s *RepositorySuite) TestLogAll(c *C) { cIter.Close() } +func (s *RepositorySuite) TestLogAllMissingReferences(c *C) { + r, _ := Init(memory.NewStorage(), nil) + err := r.clone(context.Background(), &CloneOptions{ + URL: s.GetBasicLocalRepositoryURL(), + }) + c.Assert(err, IsNil) + err = r.Storer.RemoveReference(plumbing.HEAD) + c.Assert(err, IsNil) + + rIter, err := r.Storer.IterReferences() + c.Assert(err, IsNil) + + refCount := 0 + err = rIter.ForEach(func(ref *plumbing.Reference) error { + refCount++ + return nil + }) + c.Assert(err, IsNil) + c.Assert(refCount, Equals, 4) + + err = r.Storer.SetReference(plumbing.NewHashReference(plumbing.ReferenceName("DUMMY"), plumbing.NewHash("DUMMY"))) + c.Assert(err, IsNil) + + rIter, err = r.Storer.IterReferences() + c.Assert(err, IsNil) + + refCount = 0 + err = rIter.ForEach(func(ref *plumbing.Reference) error { + refCount++ + return nil + }) + c.Assert(err, IsNil) + c.Assert(refCount, Equals, 5) + + cIter, err := r.Log(&LogOptions{ + All: true, + }) + c.Assert(cIter, NotNil) + c.Assert(err, IsNil) + + cCount := 0 + cIter.ForEach(func(c *object.Commit) error { + cCount++ + return nil + }) + c.Assert(cCount, Equals, 9) + + _, err = cIter.Next() + c.Assert(err, Equals, io.EOF) + cIter.Close() +} + func (s *RepositorySuite) TestLogAllOrderByTime(c *C) { r, _ := Init(memory.NewStorage(), nil) err := r.clone(context.Background(), &CloneOptions{ diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/filesystem/dotgit/dotgit.go b/vendor/gopkg.in/src-d/go-git.v4/storage/filesystem/dotgit/dotgit.go index a58c2482a..ba9667e65 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/storage/filesystem/dotgit/dotgit.go +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/filesystem/dotgit/dotgit.go @@ -14,6 +14,7 @@ import ( "gopkg.in/src-d/go-billy.v4/osfs" "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/storage" "gopkg.in/src-d/go-git.v4/utils/ioutil" "gopkg.in/src-d/go-billy.v4" @@ -596,7 +597,7 @@ func (d *DotGit) checkReferenceAndTruncate(f billy.File, old *plumbing.Reference return err } if ref.Hash() != old.Hash() { - return fmt.Errorf("reference has changed concurrently") + return storage.ErrReferenceHasChanged } _, err = f.Seek(0, io.SeekStart) if err != nil { diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/memory/storage.go b/vendor/gopkg.in/src-d/go-git.v4/storage/memory/storage.go index 6e1174240..f240f2a1f 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/storage/memory/storage.go +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/memory/storage.go @@ -13,7 +13,6 @@ import ( ) var ErrUnsupportedObjectType = fmt.Errorf("unsupported object type") -var ErrRefHasChanged = fmt.Errorf("reference has changed concurrently") // Storage is an implementation of git.Storer that stores data on memory, being // ephemeral. The use of this storage should be done in controlled envoriments, @@ -258,7 +257,7 @@ func (r ReferenceStorage) CheckAndSetReference(ref, old *plumbing.Reference) err if old != nil { tmp := r[ref.Name()] if tmp != nil && tmp.Hash() != old.Hash() { - return ErrRefHasChanged + return storage.ErrReferenceHasChanged } } r[ref.Name()] = ref diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/storer.go b/vendor/gopkg.in/src-d/go-git.v4/storage/storer.go index d1a94f2a7..5de0cfb96 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/storage/storer.go +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/storer.go @@ -1,10 +1,14 @@ package storage import ( + "errors" + "gopkg.in/src-d/go-git.v4/config" "gopkg.in/src-d/go-git.v4/plumbing/storer" ) +var ErrReferenceHasChanged = errors.New("reference has changed concurrently") + // Storer is a generic storage of objects, references and any information // related to a particular repository. The package gopkg.in/src-d/go-git.v4/storage // contains two implementation a filesystem base implementation (such as `.git`) diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/test/storage_suite.go b/vendor/gopkg.in/src-d/go-git.v4/storage/test/storage_suite.go index 79a12c5d6..e050b73ab 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/storage/test/storage_suite.go +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/test/storage_suite.go @@ -280,6 +280,57 @@ func (s *BaseStorageSuite) TestSetReferenceAndGetReference(c *C) { c.Assert(e.Hash().String(), Equals, "bc9968d75e48de59f0870ffb71f5e160bbbdcf52") } +func (s *BaseStorageSuite) TestCheckAndSetReference(c *C) { + err := s.Storer.SetReference( + plumbing.NewReferenceFromStrings("foo", "482e0eada5de4039e6f216b45b3c9b683b83bfa"), + ) + c.Assert(err, IsNil) + + err = s.Storer.CheckAndSetReference( + plumbing.NewReferenceFromStrings("foo", "bc9968d75e48de59f0870ffb71f5e160bbbdcf52"), + plumbing.NewReferenceFromStrings("foo", "482e0eada5de4039e6f216b45b3c9b683b83bfa"), + ) + c.Assert(err, IsNil) + + e, err := s.Storer.Reference(plumbing.ReferenceName("foo")) + c.Assert(err, IsNil) + c.Assert(e.Hash().String(), Equals, "bc9968d75e48de59f0870ffb71f5e160bbbdcf52") +} + +func (s *BaseStorageSuite) TestCheckAndSetReferenceNil(c *C) { + err := s.Storer.SetReference( + plumbing.NewReferenceFromStrings("foo", "482e0eada5de4039e6f216b45b3c9b683b83bfa"), + ) + c.Assert(err, IsNil) + + err = s.Storer.CheckAndSetReference( + plumbing.NewReferenceFromStrings("foo", "bc9968d75e48de59f0870ffb71f5e160bbbdcf52"), + nil, + ) + c.Assert(err, IsNil) + + e, err := s.Storer.Reference(plumbing.ReferenceName("foo")) + c.Assert(err, IsNil) + c.Assert(e.Hash().String(), Equals, "bc9968d75e48de59f0870ffb71f5e160bbbdcf52") +} + +func (s *BaseStorageSuite) TestCheckAndSetReferenceError(c *C) { + err := s.Storer.SetReference( + plumbing.NewReferenceFromStrings("foo", "c3f4688a08fd86f1bf8e055724c84b7a40a09733"), + ) + c.Assert(err, IsNil) + + err = s.Storer.CheckAndSetReference( + plumbing.NewReferenceFromStrings("foo", "bc9968d75e48de59f0870ffb71f5e160bbbdcf52"), + plumbing.NewReferenceFromStrings("foo", "482e0eada5de4039e6f216b45b3c9b683b83bfa"), + ) + c.Assert(err, Equals, storage.ErrReferenceHasChanged) + + e, err := s.Storer.Reference(plumbing.ReferenceName("foo")) + c.Assert(err, IsNil) + c.Assert(e.Hash().String(), Equals, "c3f4688a08fd86f1bf8e055724c84b7a40a09733") +} + func (s *BaseStorageSuite) TestRemoveReference(c *C) { err := s.Storer.SetReference( plumbing.NewReferenceFromStrings("foo", "bc9968d75e48de59f0870ffb71f5e160bbbdcf52"), diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/config.go b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/config.go new file mode 100644 index 000000000..4d8efe1d9 --- /dev/null +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/config.go @@ -0,0 +1,50 @@ +package transactional + +import "gopkg.in/src-d/go-git.v4/config" + +// ConfigStorage implements the storer.ConfigStorage for the transactional package. +type ConfigStorage struct { + config.ConfigStorer + temporal config.ConfigStorer + + set bool +} + +// NewConfigStorage returns a new ConfigStorer based on a base storer and a +// temporal storer. +func NewConfigStorage(s, temporal config.ConfigStorer) *ConfigStorage { + return &ConfigStorage{ConfigStorer: s, temporal: temporal} +} + +// SetConfig honors the storer.ConfigStorer interface. +func (c *ConfigStorage) SetConfig(cfg *config.Config) error { + if err := c.temporal.SetConfig(cfg); err != nil { + return err + } + + c.set = true + return nil +} + +// Config honors the storer.ConfigStorer interface. +func (c *ConfigStorage) Config() (*config.Config, error) { + if !c.set { + return c.ConfigStorer.Config() + } + + return c.temporal.Config() +} + +// Commit it copies the config from the temporal storage into the base storage. +func (c *ConfigStorage) Commit() error { + if !c.set { + return nil + } + + cfg, err := c.temporal.Config() + if err != nil { + return err + } + + return c.ConfigStorer.SetConfig(cfg) +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/config_test.go b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/config_test.go new file mode 100644 index 000000000..5d1e01994 --- /dev/null +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/config_test.go @@ -0,0 +1,82 @@ +package transactional + +import ( + . "gopkg.in/check.v1" + "gopkg.in/src-d/go-git.v4/config" + "gopkg.in/src-d/go-git.v4/storage/memory" +) + +var _ = Suite(&ConfigSuite{}) + +type ConfigSuite struct{} + +func (s *ConfigSuite) TestSetConfigBase(c *C) { + cfg := config.NewConfig() + cfg.Core.Worktree = "foo" + + base := memory.NewStorage() + err := base.SetConfig(cfg) + c.Assert(err, IsNil) + + temporal := memory.NewStorage() + cs := NewConfigStorage(base, temporal) + + cfg, err = cs.Config() + c.Assert(err, IsNil) + c.Assert(cfg.Core.Worktree, Equals, "foo") +} + +func (s *ConfigSuite) TestSetConfigTemporal(c *C) { + cfg := config.NewConfig() + cfg.Core.Worktree = "foo" + + base := memory.NewStorage() + err := base.SetConfig(cfg) + c.Assert(err, IsNil) + + temporal := memory.NewStorage() + + cfg = config.NewConfig() + cfg.Core.Worktree = "bar" + + cs := NewConfigStorage(base, temporal) + err = cs.SetConfig(cfg) + c.Assert(err, IsNil) + + baseCfg, err := base.Config() + c.Assert(err, IsNil) + c.Assert(baseCfg.Core.Worktree, Equals, "foo") + + temporalCfg, err := temporal.Config() + c.Assert(err, IsNil) + c.Assert(temporalCfg.Core.Worktree, Equals, "bar") + + cfg, err = cs.Config() + c.Assert(err, IsNil) + c.Assert(temporalCfg.Core.Worktree, Equals, "bar") +} + +func (s *ConfigSuite) TestCommit(c *C) { + cfg := config.NewConfig() + cfg.Core.Worktree = "foo" + + base := memory.NewStorage() + err := base.SetConfig(cfg) + c.Assert(err, IsNil) + + temporal := memory.NewStorage() + + cfg = config.NewConfig() + cfg.Core.Worktree = "bar" + + cs := NewConfigStorage(base, temporal) + err = cs.SetConfig(cfg) + c.Assert(err, IsNil) + + err = cs.Commit() + c.Assert(err, IsNil) + + baseCfg, err := base.Config() + c.Assert(err, IsNil) + c.Assert(baseCfg.Core.Worktree, Equals, "bar") +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/doc.go b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/doc.go new file mode 100644 index 000000000..3a68f5f1d --- /dev/null +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/doc.go @@ -0,0 +1,7 @@ +// Package transactional is a transactional implementation of git.Storer, it +// demux the write and read operation of two separate storers, allowing to merge +// content calling Storage.Commit. +// +// The API and functionality of this package are considered EXPERIMENTAL and is +// not considered stable nor production ready. +package transactional diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/index.go b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/index.go new file mode 100644 index 000000000..84e0e2f83 --- /dev/null +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/index.go @@ -0,0 +1,56 @@ +package transactional + +import ( + "gopkg.in/src-d/go-git.v4/plumbing/format/index" + "gopkg.in/src-d/go-git.v4/plumbing/storer" +) + +// IndexStorage implements the storer.IndexStorage for the transactional package. +type IndexStorage struct { + storer.IndexStorer + temporal storer.IndexStorer + + set bool +} + +// NewIndexStorage returns a new IndexStorer based on a base storer and a +// temporal storer. +func NewIndexStorage(s, temporal storer.IndexStorer) *IndexStorage { + return &IndexStorage{ + IndexStorer: s, + temporal: temporal, + } +} + +// SetIndex honors the storer.IndexStorer interface. +func (s *IndexStorage) SetIndex(idx *index.Index) (err error) { + if err := s.temporal.SetIndex(idx); err != nil { + return err + } + + s.set = true + return nil +} + +// Index honors the storer.IndexStorer interface. +func (s *IndexStorage) Index() (*index.Index, error) { + if !s.set { + return s.IndexStorer.Index() + } + + return s.temporal.Index() +} + +// Commit it copies the index from the temporal storage into the base storage. +func (s *IndexStorage) Commit() error { + if !s.set { + return nil + } + + idx, err := s.temporal.Index() + if err != nil { + return err + } + + return s.IndexStorer.SetIndex(idx) +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/index_test.go b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/index_test.go new file mode 100644 index 000000000..e1c571abc --- /dev/null +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/index_test.go @@ -0,0 +1,52 @@ +package transactional + +import ( + . "gopkg.in/check.v1" + "gopkg.in/src-d/go-git.v4/plumbing/format/index" + "gopkg.in/src-d/go-git.v4/storage/memory" +) + +var _ = Suite(&IndexSuite{}) + +type IndexSuite struct{} + +func (s *IndexSuite) TestSetIndexBase(c *C) { + idx := &index.Index{} + idx.Version = 2 + + base := memory.NewStorage() + err := base.SetIndex(idx) + c.Assert(err, IsNil) + + temporal := memory.NewStorage() + cs := NewIndexStorage(base, temporal) + + idx, err = cs.Index() + c.Assert(err, IsNil) + c.Assert(idx.Version, Equals, uint32(2)) +} + +func (s *IndexSuite) TestCommit(c *C) { + idx := &index.Index{} + idx.Version = 2 + + base := memory.NewStorage() + err := base.SetIndex(idx) + c.Assert(err, IsNil) + + temporal := memory.NewStorage() + + idx = &index.Index{} + idx.Version = 3 + + is := NewIndexStorage(base, temporal) + err = is.SetIndex(idx) + c.Assert(err, IsNil) + + err = is.Commit() + c.Assert(err, IsNil) + + baseIndex, err := base.Index() + c.Assert(err, IsNil) + c.Assert(baseIndex.Version, Equals, uint32(3)) +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/object.go b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/object.go new file mode 100644 index 000000000..beb63d621 --- /dev/null +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/object.go @@ -0,0 +1,84 @@ +package transactional + +import ( + "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/plumbing/storer" +) + +// ObjectStorage implements the storer.EncodedObjectStorer for the transactional package. +type ObjectStorage struct { + storer.EncodedObjectStorer + temporal storer.EncodedObjectStorer +} + +// NewObjectStorage returns a new EncodedObjectStorer based on a base storer and +// a temporal storer. +func NewObjectStorage(base, temporal storer.EncodedObjectStorer) *ObjectStorage { + return &ObjectStorage{EncodedObjectStorer: base, temporal: temporal} +} + +// SetEncodedObject honors the storer.EncodedObjectStorer interface. +func (o *ObjectStorage) SetEncodedObject(obj plumbing.EncodedObject) (plumbing.Hash, error) { + return o.temporal.SetEncodedObject(obj) +} + +// HasEncodedObject honors the storer.EncodedObjectStorer interface. +func (o *ObjectStorage) HasEncodedObject(h plumbing.Hash) error { + err := o.EncodedObjectStorer.HasEncodedObject(h) + if err == plumbing.ErrObjectNotFound { + return o.temporal.HasEncodedObject(h) + } + + return err +} + +// EncodedObjectSize honors the storer.EncodedObjectStorer interface. +func (o *ObjectStorage) EncodedObjectSize(h plumbing.Hash) (int64, error) { + sz, err := o.EncodedObjectStorer.EncodedObjectSize(h) + if err == plumbing.ErrObjectNotFound { + return o.temporal.EncodedObjectSize(h) + } + + return sz, err +} + +// EncodedObject honors the storer.EncodedObjectStorer interface. +func (o *ObjectStorage) EncodedObject(t plumbing.ObjectType, h plumbing.Hash) (plumbing.EncodedObject, error) { + obj, err := o.EncodedObjectStorer.EncodedObject(t, h) + if err == plumbing.ErrObjectNotFound { + return o.temporal.EncodedObject(t, h) + } + + return obj, err +} + +// IterEncodedObjects honors the storer.EncodedObjectStorer interface. +func (o *ObjectStorage) IterEncodedObjects(t plumbing.ObjectType) (storer.EncodedObjectIter, error) { + baseIter, err := o.EncodedObjectStorer.IterEncodedObjects(t) + if err != nil { + return nil, err + } + + temporalIter, err := o.temporal.IterEncodedObjects(t) + if err != nil { + return nil, err + } + + return storer.NewMultiEncodedObjectIter([]storer.EncodedObjectIter{ + baseIter, + temporalIter, + }), nil +} + +// Commit it copies the objects of the temporal storage into the base storage. +func (o *ObjectStorage) Commit() error { + iter, err := o.temporal.IterEncodedObjects(plumbing.AnyObject) + if err != nil { + return err + } + + return iter.ForEach(func(obj plumbing.EncodedObject) error { + _, err := o.EncodedObjectStorer.SetEncodedObject(obj) + return err + }) +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/object_test.go b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/object_test.go new file mode 100644 index 000000000..10b63185e --- /dev/null +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/object_test.go @@ -0,0 +1,153 @@ +package transactional + +import ( + . "gopkg.in/check.v1" + "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/storage/memory" +) + +var _ = Suite(&ObjectSuite{}) + +type ObjectSuite struct{} + +func (s *ObjectSuite) TestHasEncodedObject(c *C) { + base := memory.NewStorage() + temporal := memory.NewStorage() + + os := NewObjectStorage(base, temporal) + + commit := base.NewEncodedObject() + commit.SetType(plumbing.CommitObject) + + ch, err := base.SetEncodedObject(commit) + c.Assert(ch.IsZero(), Equals, false) + c.Assert(err, IsNil) + + tree := base.NewEncodedObject() + tree.SetType(plumbing.TreeObject) + + th, err := os.SetEncodedObject(tree) + c.Assert(th.IsZero(), Equals, false) + c.Assert(err, IsNil) + + err = os.HasEncodedObject(th) + c.Assert(err, IsNil) + + err = os.HasEncodedObject(ch) + c.Assert(err, IsNil) + + err = base.HasEncodedObject(th) + c.Assert(err, Equals, plumbing.ErrObjectNotFound) +} + +func (s *ObjectSuite) TestEncodedObjectAndEncodedObjectSize(c *C) { + base := memory.NewStorage() + temporal := memory.NewStorage() + + os := NewObjectStorage(base, temporal) + + commit := base.NewEncodedObject() + commit.SetType(plumbing.CommitObject) + + ch, err := base.SetEncodedObject(commit) + c.Assert(ch.IsZero(), Equals, false) + c.Assert(err, IsNil) + + tree := base.NewEncodedObject() + tree.SetType(plumbing.TreeObject) + + th, err := os.SetEncodedObject(tree) + c.Assert(th.IsZero(), Equals, false) + c.Assert(err, IsNil) + + otree, err := os.EncodedObject(plumbing.TreeObject, th) + c.Assert(err, IsNil) + c.Assert(otree.Hash(), Equals, tree.Hash()) + + treeSz, err := os.EncodedObjectSize(th) + c.Assert(err, IsNil) + c.Assert(treeSz, Equals, int64(0)) + + ocommit, err := os.EncodedObject(plumbing.CommitObject, ch) + c.Assert(err, IsNil) + c.Assert(ocommit.Hash(), Equals, commit.Hash()) + + commitSz, err := os.EncodedObjectSize(ch) + c.Assert(err, IsNil) + c.Assert(commitSz, Equals, int64(0)) + + _, err = base.EncodedObject(plumbing.TreeObject, th) + c.Assert(err, Equals, plumbing.ErrObjectNotFound) + + _, err = base.EncodedObjectSize(th) + c.Assert(err, Equals, plumbing.ErrObjectNotFound) +} + +func (s *ObjectSuite) TestIterEncodedObjects(c *C) { + base := memory.NewStorage() + temporal := memory.NewStorage() + + os := NewObjectStorage(base, temporal) + + commit := base.NewEncodedObject() + commit.SetType(plumbing.CommitObject) + + ch, err := base.SetEncodedObject(commit) + c.Assert(ch.IsZero(), Equals, false) + c.Assert(err, IsNil) + + tree := base.NewEncodedObject() + tree.SetType(plumbing.TreeObject) + + th, err := os.SetEncodedObject(tree) + c.Assert(th.IsZero(), Equals, false) + c.Assert(err, IsNil) + + iter, err := os.IterEncodedObjects(plumbing.AnyObject) + c.Assert(err, IsNil) + + var hashes []plumbing.Hash + err = iter.ForEach(func(obj plumbing.EncodedObject) error { + hashes = append(hashes, obj.Hash()) + return nil + }) + + c.Assert(err, IsNil) + c.Assert(hashes, HasLen, 2) + c.Assert(hashes[0], Equals, ch) + c.Assert(hashes[1], Equals, th) +} + +func (s *ObjectSuite) TestCommit(c *C) { + base := memory.NewStorage() + temporal := memory.NewStorage() + + os := NewObjectStorage(base, temporal) + + commit := base.NewEncodedObject() + commit.SetType(plumbing.CommitObject) + + _, err := os.SetEncodedObject(commit) + c.Assert(err, IsNil) + + tree := base.NewEncodedObject() + tree.SetType(plumbing.TreeObject) + + _, err = os.SetEncodedObject(tree) + c.Assert(err, IsNil) + + err = os.Commit() + c.Assert(err, IsNil) + + iter, err := base.IterEncodedObjects(plumbing.AnyObject) + c.Assert(err, IsNil) + + var hashes []plumbing.Hash + err = iter.ForEach(func(obj plumbing.EncodedObject) error { + hashes = append(hashes, obj.Hash()) + return nil + }) + + c.Assert(err, IsNil) + c.Assert(hashes, HasLen, 2) +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/reference.go b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/reference.go new file mode 100644 index 000000000..a7be532ba --- /dev/null +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/reference.go @@ -0,0 +1,138 @@ +package transactional + +import ( + "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/plumbing/storer" + "gopkg.in/src-d/go-git.v4/storage" +) + +// ReferenceStorage implements the storer.ReferenceStorage for the transactional package. +type ReferenceStorage struct { + storer.ReferenceStorer + temporal storer.ReferenceStorer + + // deleted, remaining references at this maps are going to be deleted when + // commit is requested, the entries are added when RemoveReference is called + // and deleted if SetReference is called. + deleted map[plumbing.ReferenceName]struct{} + // packRefs if true PackRefs is going to be called in the based storer when + // commit is called. + packRefs bool +} + +// NewReferenceStorage returns a new ReferenceStorer based on a base storer and +// a temporal storer. +func NewReferenceStorage(base, temporal storer.ReferenceStorer) *ReferenceStorage { + return &ReferenceStorage{ + ReferenceStorer: base, + temporal: temporal, + + deleted: make(map[plumbing.ReferenceName]struct{}, 0), + } +} + +// SetReference honors the storer.ReferenceStorer interface. +func (r *ReferenceStorage) SetReference(ref *plumbing.Reference) error { + delete(r.deleted, ref.Name()) + return r.temporal.SetReference(ref) +} + +// SetReference honors the storer.ReferenceStorer interface. +func (r *ReferenceStorage) CheckAndSetReference(ref, old *plumbing.Reference) error { + if old == nil { + return r.SetReference(ref) + } + + tmp, err := r.temporal.Reference(old.Name()) + if err == plumbing.ErrReferenceNotFound { + tmp, err = r.ReferenceStorer.Reference(old.Name()) + } + + if err != nil { + return err + } + + if tmp.Hash() != old.Hash() { + return storage.ErrReferenceHasChanged + } + + return r.SetReference(ref) +} + +// Reference honors the storer.ReferenceStorer interface. +func (r ReferenceStorage) Reference(n plumbing.ReferenceName) (*plumbing.Reference, error) { + if _, deleted := r.deleted[n]; deleted { + return nil, plumbing.ErrReferenceNotFound + } + + ref, err := r.temporal.Reference(n) + if err == plumbing.ErrReferenceNotFound { + return r.ReferenceStorer.Reference(n) + } + + return ref, err +} + +// IterReferences honors the storer.ReferenceStorer interface. +func (r ReferenceStorage) IterReferences() (storer.ReferenceIter, error) { + baseIter, err := r.ReferenceStorer.IterReferences() + if err != nil { + return nil, err + } + + temporalIter, err := r.temporal.IterReferences() + if err != nil { + return nil, err + } + + return storer.NewMultiReferenceIter([]storer.ReferenceIter{ + baseIter, + temporalIter, + }), nil +} + +// CountLooseRefs honors the storer.ReferenceStorer interface. +func (r ReferenceStorage) CountLooseRefs() (int, error) { + tc, err := r.temporal.CountLooseRefs() + if err != nil { + return -1, err + } + + bc, err := r.ReferenceStorer.CountLooseRefs() + if err != nil { + return -1, err + } + + return tc + bc, nil +} + +// PackRefs honors the storer.ReferenceStorer interface. +func (r ReferenceStorage) PackRefs() error { + r.packRefs = true + return nil +} + +// RemoveReference honors the storer.ReferenceStorer interface. +func (r ReferenceStorage) RemoveReference(n plumbing.ReferenceName) error { + r.deleted[n] = struct{}{} + return r.temporal.RemoveReference(n) +} + +// Commit it copies the reference information of the temporal storage into the +// base storage. +func (r ReferenceStorage) Commit() error { + for name := range r.deleted { + if err := r.ReferenceStorer.RemoveReference(name); err != nil { + return err + } + } + + iter, err := r.temporal.IterReferences() + if err != nil { + return err + } + + return iter.ForEach(func(ref *plumbing.Reference) error { + return r.ReferenceStorer.SetReference(ref) + }) +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/reference_test.go b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/reference_test.go new file mode 100644 index 000000000..57935497b --- /dev/null +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/reference_test.go @@ -0,0 +1,157 @@ +package transactional + +import ( + . "gopkg.in/check.v1" + "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/storage/memory" +) + +var _ = Suite(&ReferenceSuite{}) + +type ReferenceSuite struct{} + +func (s *ReferenceSuite) TestReference(c *C) { + base := memory.NewStorage() + temporal := memory.NewStorage() + + rs := NewReferenceStorage(base, temporal) + + refA := plumbing.NewReferenceFromStrings("refs/a", "bc9968d75e48de59f0870ffb71f5e160bbbdcf52") + refB := plumbing.NewReferenceFromStrings("refs/b", "bc9968d75e48de59f0870ffb71f5e160bbbdcf52") + + err := base.SetReference(refA) + c.Assert(err, IsNil) + + err = rs.SetReference(refB) + c.Assert(err, IsNil) + + _, err = rs.Reference("refs/a") + c.Assert(err, IsNil) + + _, err = rs.Reference("refs/b") + c.Assert(err, IsNil) + + _, err = base.Reference("refs/b") + c.Assert(err, Equals, plumbing.ErrReferenceNotFound) +} + +func (s *ReferenceSuite) TestRemoveReferenceTemporal(c *C) { + base := memory.NewStorage() + temporal := memory.NewStorage() + + ref := plumbing.NewReferenceFromStrings("refs/a", "bc9968d75e48de59f0870ffb71f5e160bbbdcf52") + + rs := NewReferenceStorage(base, temporal) + err := rs.SetReference(ref) + c.Assert(err, IsNil) + + err = rs.RemoveReference("refs/a") + c.Assert(err, IsNil) + + _, err = rs.Reference("refs/a") + c.Assert(err, Equals, plumbing.ErrReferenceNotFound) +} + +func (s *ReferenceSuite) TestRemoveReferenceBase(c *C) { + base := memory.NewStorage() + temporal := memory.NewStorage() + + ref := plumbing.NewReferenceFromStrings("refs/a", "bc9968d75e48de59f0870ffb71f5e160bbbdcf52") + + rs := NewReferenceStorage(base, temporal) + err := base.SetReference(ref) + c.Assert(err, IsNil) + + err = rs.RemoveReference("refs/a") + c.Assert(err, IsNil) + + _, err = rs.Reference("refs/a") + c.Assert(err, Equals, plumbing.ErrReferenceNotFound) +} + +func (s *ReferenceSuite) TestCheckAndSetReferenceInBase(c *C) { + base := memory.NewStorage() + temporal := memory.NewStorage() + rs := NewReferenceStorage(base, temporal) + + err := base.SetReference( + plumbing.NewReferenceFromStrings("foo", "482e0eada5de4039e6f216b45b3c9b683b83bfa"), + ) + c.Assert(err, IsNil) + + err = rs.CheckAndSetReference( + plumbing.NewReferenceFromStrings("foo", "bc9968d75e48de59f0870ffb71f5e160bbbdcf52"), + plumbing.NewReferenceFromStrings("foo", "482e0eada5de4039e6f216b45b3c9b683b83bfa"), + ) + c.Assert(err, IsNil) + + e, err := rs.Reference(plumbing.ReferenceName("foo")) + c.Assert(err, IsNil) + c.Assert(e.Hash().String(), Equals, "bc9968d75e48de59f0870ffb71f5e160bbbdcf52") +} + +func (s *ReferenceSuite) TestCommit(c *C) { + base := memory.NewStorage() + temporal := memory.NewStorage() + + refA := plumbing.NewReferenceFromStrings("refs/a", "bc9968d75e48de59f0870ffb71f5e160bbbdcf52") + refB := plumbing.NewReferenceFromStrings("refs/b", "b66c08ba28aa1f81eb06a1127aa3936ff77e5e2c") + refC := plumbing.NewReferenceFromStrings("refs/c", "c3f4688a08fd86f1bf8e055724c84b7a40a09733") + + rs := NewReferenceStorage(base, temporal) + c.Assert(rs.SetReference(refA), IsNil) + c.Assert(rs.SetReference(refB), IsNil) + c.Assert(rs.SetReference(refC), IsNil) + + err := rs.Commit() + c.Assert(err, IsNil) + + iter, err := base.IterReferences() + c.Assert(err, IsNil) + + var count int + iter.ForEach(func(ref *plumbing.Reference) error { + count++ + return nil + }) + + c.Assert(count, Equals, 3) +} + +func (s *ReferenceSuite) TestCommitDelete(c *C) { + base := memory.NewStorage() + temporal := memory.NewStorage() + + refA := plumbing.NewReferenceFromStrings("refs/a", "bc9968d75e48de59f0870ffb71f5e160bbbdcf52") + refB := plumbing.NewReferenceFromStrings("refs/b", "b66c08ba28aa1f81eb06a1127aa3936ff77e5e2c") + refC := plumbing.NewReferenceFromStrings("refs/c", "c3f4688a08fd86f1bf8e055724c84b7a40a09733") + + rs := NewReferenceStorage(base, temporal) + c.Assert(base.SetReference(refA), IsNil) + c.Assert(base.SetReference(refB), IsNil) + c.Assert(base.SetReference(refC), IsNil) + + c.Assert(rs.RemoveReference(refA.Name()), IsNil) + c.Assert(rs.RemoveReference(refB.Name()), IsNil) + c.Assert(rs.RemoveReference(refC.Name()), IsNil) + c.Assert(rs.SetReference(refC), IsNil) + + err := rs.Commit() + c.Assert(err, IsNil) + + iter, err := base.IterReferences() + c.Assert(err, IsNil) + + var count int + iter.ForEach(func(ref *plumbing.Reference) error { + count++ + return nil + }) + + c.Assert(count, Equals, 1) + + ref, err := rs.Reference(refC.Name()) + c.Assert(err, IsNil) + c.Assert(ref.Hash().String(), Equals, "c3f4688a08fd86f1bf8e055724c84b7a40a09733") + +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/shallow.go b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/shallow.go new file mode 100644 index 000000000..bedc32596 --- /dev/null +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/shallow.go @@ -0,0 +1,51 @@ +package transactional + +import ( + "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/plumbing/storer" +) + +// ShallowStorage implements the storer.ShallowStorer for the transactional package. +type ShallowStorage struct { + storer.ShallowStorer + temporal storer.ShallowStorer +} + +// NewShallowStorage returns a new ShallowStorage based on a base storer and +// a temporal storer. +func NewShallowStorage(base, temporal storer.ShallowStorer) *ShallowStorage { + return &ShallowStorage{ + ShallowStorer: base, + temporal: temporal, + } +} + +// SetShallow honors the storer.ShallowStorer interface. +func (s *ShallowStorage) SetShallow(commits []plumbing.Hash) error { + return s.temporal.SetShallow(commits) +} + +// Shallow honors the storer.ShallowStorer interface. +func (s *ShallowStorage) Shallow() ([]plumbing.Hash, error) { + shallow, err := s.temporal.Shallow() + if err != nil { + return nil, err + } + + if len(shallow) != 0 { + return shallow, nil + } + + return s.ShallowStorer.Shallow() +} + +// Commit it copies the shallow information of the temporal storage into the +// base storage. +func (s *ShallowStorage) Commit() error { + commits, err := s.temporal.Shallow() + if err != nil || len(commits) == 0 { + return err + } + + return s.ShallowStorer.SetShallow(commits) +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/shallow_test.go b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/shallow_test.go new file mode 100644 index 000000000..5141782db --- /dev/null +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/shallow_test.go @@ -0,0 +1,62 @@ +package transactional + +import ( + . "gopkg.in/check.v1" + "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/storage/memory" +) + +var _ = Suite(&ShallowSuite{}) + +type ShallowSuite struct{} + +func (s *ShallowSuite) TestShallow(c *C) { + base := memory.NewStorage() + temporal := memory.NewStorage() + + rs := NewShallowStorage(base, temporal) + + commitA := plumbing.NewHash("bc9968d75e48de59f0870ffb71f5e160bbbdcf52") + commitB := plumbing.NewHash("aa9968d75e48de59f0870ffb71f5e160bbbdcf52") + + err := base.SetShallow([]plumbing.Hash{commitA}) + c.Assert(err, IsNil) + + err = rs.SetShallow([]plumbing.Hash{commitB}) + c.Assert(err, IsNil) + + commits, err := rs.Shallow() + c.Assert(err, IsNil) + c.Assert(commits, HasLen, 1) + c.Assert(commits[0], Equals, commitB) + + commits, err = base.Shallow() + c.Assert(err, IsNil) + c.Assert(commits, HasLen, 1) + c.Assert(commits[0], Equals, commitA) +} + +func (s *ShallowSuite) TestCommit(c *C) { + base := memory.NewStorage() + temporal := memory.NewStorage() + + rs := NewShallowStorage(base, temporal) + + commitA := plumbing.NewHash("bc9968d75e48de59f0870ffb71f5e160bbbdcf52") + commitB := plumbing.NewHash("aa9968d75e48de59f0870ffb71f5e160bbbdcf52") + + c.Assert(base.SetShallow([]plumbing.Hash{commitA}), IsNil) + c.Assert(rs.SetShallow([]plumbing.Hash{commitB}), IsNil) + + c.Assert(rs.Commit(), IsNil) + + commits, err := rs.Shallow() + c.Assert(err, IsNil) + c.Assert(commits, HasLen, 1) + c.Assert(commits[0], Equals, commitB) + + commits, err = base.Shallow() + c.Assert(err, IsNil) + c.Assert(commits, HasLen, 1) + c.Assert(commits[0], Equals, commitB) +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/storage.go b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/storage.go new file mode 100644 index 000000000..fbb3d3588 --- /dev/null +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/storage.go @@ -0,0 +1,69 @@ +package transactional + +import ( + "gopkg.in/src-d/go-git.v4/storage" +) + +// Storage is a transactional implementation of git.Storer, it demux the write +// and read operation of two separate storers, allowing to merge content calling +// Storage.Commit. +// +// The API and functionality of this package are considered EXPERIMENTAL and is +// not considered stable nor production ready. +type Storage struct { + s, temporal storage.Storer + + *ObjectStorage + *ReferenceStorage + *IndexStorage + *ShallowStorage + *ConfigStorage +} + +// NewStorage returns a new Storage based on two repositories, base is the base +// repository where the read operations are read and temportal is were all +// the write operations are stored. +func NewStorage(base, temporal storage.Storer) *Storage { + return &Storage{ + s: base, + temporal: temporal, + + ObjectStorage: NewObjectStorage(base, temporal), + ReferenceStorage: NewReferenceStorage(base, temporal), + IndexStorage: NewIndexStorage(base, temporal), + ShallowStorage: NewShallowStorage(base, temporal), + ConfigStorage: NewConfigStorage(base, temporal), + } +} + +// Module it honors the storage.ModuleStorer interface. +func (s *Storage) Module(name string) (storage.Storer, error) { + base, err := s.s.Module(name) + if err != nil { + return nil, err + } + + temporal, err := s.temporal.Module(name) + if err != nil { + return nil, err + } + + return NewStorage(base, temporal), nil +} + +// Commit it copies the content of the temporal storage into the base storage. +func (s *Storage) Commit() error { + for _, c := range []interface{ Commit() error }{ + s.ObjectStorage, + s.ReferenceStorage, + s.IndexStorage, + s.ShallowStorage, + s.ConfigStorage, + } { + if err := c.Commit(); err != nil { + return err + } + } + + return nil +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/storage_test.go b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/storage_test.go new file mode 100644 index 000000000..6aaea0d18 --- /dev/null +++ b/vendor/gopkg.in/src-d/go-git.v4/storage/transactional/storage_test.go @@ -0,0 +1,52 @@ +package transactional + +import ( + "testing" + + . "gopkg.in/check.v1" + "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/storage/memory" + "gopkg.in/src-d/go-git.v4/storage/test" +) + +func Test(t *testing.T) { TestingT(t) } + +type StorageSuite struct { + test.BaseStorageSuite +} + +var _ = Suite(&StorageSuite{}) + +func (s *StorageSuite) SetUpTest(c *C) { + base := memory.NewStorage() + temporal := memory.NewStorage() + + s.BaseStorageSuite = test.NewBaseStorageSuite(NewStorage(base, temporal)) + s.BaseStorageSuite.SetUpTest(c) +} + +func (s *StorageSuite) TestCommit(c *C) { + base := memory.NewStorage() + temporal := memory.NewStorage() + st := NewStorage(base, temporal) + + commit := base.NewEncodedObject() + commit.SetType(plumbing.CommitObject) + + _, err := st.SetEncodedObject(commit) + c.Assert(err, IsNil) + + ref := plumbing.NewHashReference("refs/a", commit.Hash()) + c.Assert(st.SetReference(ref), IsNil) + + err = st.Commit() + c.Assert(err, IsNil) + + ref, err = base.Reference(ref.Name()) + c.Assert(err, IsNil) + c.Assert(ref.Hash(), Equals, commit.Hash()) + + obj, err := base.EncodedObject(plumbing.AnyObject, commit.Hash()) + c.Assert(err, IsNil) + c.Assert(obj.Hash(), Equals, commit.Hash()) +} diff --git a/vendor/gopkg.in/src-d/go-git.v4/worktree.go b/vendor/gopkg.in/src-d/go-git.v4/worktree.go index e45d81548..a14fd8d6c 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/worktree.go +++ b/vendor/gopkg.in/src-d/go-git.v4/worktree.go @@ -25,10 +25,11 @@ import ( ) var ( - ErrWorktreeNotClean = errors.New("worktree is not clean") - ErrSubmoduleNotFound = errors.New("submodule not found") - ErrUnstagedChanges = errors.New("worktree contains unstaged changes") - ErrGitModulesSymlink = errors.New(gitmodulesFile + " is a symlink") + ErrWorktreeNotClean = errors.New("worktree is not clean") + ErrSubmoduleNotFound = errors.New("submodule not found") + ErrUnstagedChanges = errors.New("worktree contains unstaged changes") + ErrGitModulesSymlink = errors.New(gitmodulesFile + " is a symlink") + ErrNonFastForwardUpdate = errors.New("non-fast-forward update") ) // Worktree represents a git worktree. @@ -101,7 +102,7 @@ func (w *Worktree) PullContext(ctx context.Context, o *PullOptions) error { } if !ff { - return fmt.Errorf("non-fast-forward update") + return ErrNonFastForwardUpdate } } diff --git a/vendor/gopkg.in/src-d/go-git.v4/worktree_test.go b/vendor/gopkg.in/src-d/go-git.v4/worktree_test.go index c714011c0..26b7da0dc 100644 --- a/vendor/gopkg.in/src-d/go-git.v4/worktree_test.go +++ b/vendor/gopkg.in/src-d/go-git.v4/worktree_test.go @@ -119,7 +119,7 @@ func (s *WorktreeSuite) TestPullNonFastForward(c *C) { c.Assert(err, IsNil) err = w.Pull(&PullOptions{}) - c.Assert(err, ErrorMatches, "non-fast-forward update") + c.Assert(err, Equals, ErrNonFastForwardUpdate) } func (s *WorktreeSuite) TestPullUpdateReferencesIfNeeded(c *C) {