Skip to content

Commit 6db45ca

Browse files
authored
Merge pull request #75 from vitessio/fix-sync-refs
Use GitHub API for push operations
2 parents 40c6cda + a77b323 commit 6db45ca

8 files changed

+343
-29
lines changed

go.mod

+5
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,24 @@ require (
1616
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
1717
github.com/bradleyfalzon/ghinstallation/v2 v2.5.0 // indirect
1818
github.com/cloudflare/circl v1.3.3 // indirect
19+
github.com/davecgh/go-spew v1.1.1 // indirect
1920
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
2021
github.com/golang/protobuf v1.5.2 // indirect
2122
github.com/google/go-querystring v1.1.0 // indirect
2223
github.com/hashicorp/golang-lru v0.6.0 // indirect
2324
github.com/mattn/go-colorable v0.1.12 // indirect
2425
github.com/mattn/go-isatty v0.0.14 // indirect
2526
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
27+
github.com/pmezard/go-difflib v1.0.0 // indirect
2628
github.com/shurcooL/githubv4 v0.0.0-20230424031643-6cea62ecd5a9 // indirect
2729
github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f // indirect
30+
github.com/stretchr/objx v0.5.0 // indirect
31+
github.com/stretchr/testify v1.8.4 // indirect
2832
golang.org/x/crypto v0.10.0 // indirect
2933
golang.org/x/net v0.11.0 // indirect
3034
golang.org/x/oauth2 v0.9.0 // indirect
3135
golang.org/x/sys v0.9.0 // indirect
3236
google.golang.org/appengine v1.6.7 // indirect
3337
google.golang.org/protobuf v1.28.0 // indirect
38+
gopkg.in/yaml.v3 v3.0.1 // indirect
3439
)

go.sum

+17
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtM
99
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
1010
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
1111
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
12+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
13+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
14+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1215
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
1316
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
1417
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
@@ -42,6 +45,8 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR
4245
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
4346
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
4447
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
48+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
49+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
4550
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
4651
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
4752
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
@@ -51,6 +56,14 @@ github.com/shurcooL/githubv4 v0.0.0-20230424031643-6cea62ecd5a9 h1:nCBaIs5/R0HFP
5156
github.com/shurcooL/githubv4 v0.0.0-20230424031643-6cea62ecd5a9/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo=
5257
github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f h1:tygelZueB1EtXkPI6mQ4o9DQ0+FKW41hTbunoXZCTqk=
5358
github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg=
59+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
60+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
61+
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
62+
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
63+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
64+
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
65+
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
66+
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
5467
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
5568
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
5669
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
@@ -117,3 +130,7 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
117130
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
118131
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
119132
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
133+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
134+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
135+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
136+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

go/git/diff_tree.go

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
Copyright 2024 The Vitess Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package git
18+
19+
import (
20+
"fmt"
21+
"os"
22+
"path/filepath"
23+
"regexp"
24+
25+
"github.com/google/go-github/v53/github"
26+
)
27+
28+
/*
29+
Example output of `git diff-tree -r HEAD~1 HEAD` in a sample repo:
30+
31+
:100644 000000 5716ca5987cbf97d6bb54920bea6adde242d87e6 0000000000000000000000000000000000000000 D bar/bar.txt
32+
:000000 100644 0000000000000000000000000000000000000000 76018072e09c5d31c8c6e3113b8aa0fe625195ca A baz.txt
33+
:100644 100644 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 b210800439ffe3f2db0d47d9aab1969b38a770a5 M foo.txt
34+
*/
35+
var diffTreeEntryRegexp = regexp.MustCompile(`^:(?P<oldmode>\d{6}) (?P<newmode>\d{6}) (?P<oldsha>[a-f0-9]{40}) (?P<newsha>[a-f0-9]{40}) [A-Z]\W(?P<path>.*)$`)
36+
37+
// ParseDiffTreeEntry parses a single line from `git diff-tree A B` into a
38+
// TreeEntry object suitable to pass to github's CreateTree method.
39+
//
40+
// See https://docs.github.com/en/rest/git/trees?apiVersion=2022-11-28#create-a-tree.
41+
func ParseDiffTreeEntry(line string, basedir string) (*github.TreeEntry, error) {
42+
match := diffTreeEntryRegexp.FindStringSubmatch(line)
43+
if match == nil {
44+
return nil, fmt.Errorf("invalid diff-tree line format %s", line)
45+
}
46+
47+
oldMode := match[1]
48+
newMode := match[2]
49+
path := match[5]
50+
51+
entry := github.TreeEntry{
52+
Path: &path,
53+
Mode: &newMode,
54+
Type: github.String("blob"),
55+
}
56+
57+
if newMode == "000000" {
58+
// File deleted.
59+
entry.Mode = &oldMode // GitHub API suggests sending 000000 will result in an error, and we're deleting the file anyway.
60+
entry.SHA = nil
61+
62+
return &entry, nil
63+
}
64+
65+
content, err := os.ReadFile(filepath.Join(basedir, path))
66+
if err != nil {
67+
return nil, err
68+
}
69+
70+
entry.Content = github.String(string(content))
71+
72+
return &entry, nil
73+
}

go/git/diff_tree_test.go

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
Copyright 2024 The Vitess Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package git
18+
19+
import (
20+
"os"
21+
"path/filepath"
22+
"testing"
23+
24+
"github.com/google/go-github/v53/github"
25+
"github.com/stretchr/testify/assert"
26+
"github.com/stretchr/testify/require"
27+
)
28+
29+
func TestParseDiffTreeEntry(t *testing.T) {
30+
tmp := t.TempDir()
31+
require.NoError(t, os.WriteFile(filepath.Join(tmp, "baz.txt"), []byte("baz"), 0644))
32+
require.NoError(t, os.WriteFile(filepath.Join(tmp, "foo.txt"), []byte("foo"), 0644))
33+
34+
tcases := []struct {
35+
name string
36+
in string
37+
want *github.TreeEntry
38+
wantErr bool
39+
}{
40+
{
41+
name: "deleted file",
42+
in: ":100644 000000 5716ca5987cbf97d6bb54920bea6adde242d87e6 0000000000000000000000000000000000000000 D bar/bar.txt",
43+
want: &github.TreeEntry{
44+
SHA: nil, // Indicates deletion
45+
Path: github.String("bar/bar.txt"),
46+
Mode: github.String("100644"),
47+
Type: github.String("blob"),
48+
},
49+
},
50+
{
51+
name: "created file",
52+
in: ":000000 100644 0000000000000000000000000000000000000000 76018072e09c5d31c8c6e3113b8aa0fe625195ca A baz.txt",
53+
want: &github.TreeEntry{
54+
Path: github.String("baz.txt"),
55+
Mode: github.String("100644"),
56+
Type: github.String("blob"),
57+
Content: github.String("baz"),
58+
},
59+
},
60+
{
61+
name: "modified file",
62+
in: ":100644 100644 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 b210800439ffe3f2db0d47d9aab1969b38a770a5 M foo.txt",
63+
want: &github.TreeEntry{
64+
Path: github.String("foo.txt"),
65+
Mode: github.String("100644"),
66+
Type: github.String("blob"),
67+
Content: github.String("foo"),
68+
},
69+
},
70+
{
71+
name: "empty line",
72+
in: "",
73+
want: nil,
74+
wantErr: true,
75+
},
76+
}
77+
78+
for _, tc := range tcases {
79+
tc := tc
80+
t.Run(tc.name, func(t *testing.T) {
81+
entry, err := ParseDiffTreeEntry(tc.in, tmp)
82+
if tc.wantErr {
83+
assert.Error(t, err)
84+
return
85+
}
86+
87+
require.NoError(t, err)
88+
assert.Equal(t, tc.want, entry)
89+
})
90+
}
91+
}

go/git/repo.go

+15
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,21 @@ func (r *Repo) Commit(ctx context.Context, msg string, opts CommitOpts) error {
108108
return err
109109
}
110110

111+
type DiffTreeOpts struct {
112+
Recursive bool
113+
}
114+
115+
func (r *Repo) DiffTree(ctx context.Context, baseTreeIsh string, headTreeIsh string, opts DiffTreeOpts) ([]byte, error) {
116+
args := []string{"diff-tree"}
117+
if opts.Recursive {
118+
args = append(args, "-r")
119+
}
120+
121+
args = append(args, baseTreeIsh, headTreeIsh)
122+
123+
return shell.NewContext(ctx, "git", args...).InDir(r.LocalDir).Output()
124+
}
125+
111126
func (r *Repo) Fetch(ctx context.Context, remote string) error {
112127
return r.fetch(ctx, remote)
113128
}

0 commit comments

Comments
 (0)