Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-workhorse
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-workhorse
Commits
db9743d1
Commit
db9743d1
authored
Apr 06, 2017
by
Nick Thomas
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'gitaly-repository-fix' into 'master'
Gitaly cleanup See merge request !152
parents
97d3583a
ed934d46
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
94 additions
and
80 deletions
+94
-80
internal/api/api.go
internal/api/api.go
+0
-8
internal/git/receive-pack.go
internal/git/receive-pack.go
+1
-1
internal/git/upload-pack.go
internal/git/upload-pack.go
+1
-1
internal/gitaly/smarthttp.go
internal/gitaly/smarthttp.go
+3
-7
internal/testhelper/gitaly.go
internal/testhelper/gitaly.go
+42
-2
main_test.go
main_test.go
+47
-61
No files found.
internal/api/api.go
View file @
db9743d1
...
@@ -89,8 +89,6 @@ type Response struct {
...
@@ -89,8 +89,6 @@ type Response struct {
Entry
string
`json:"entry"`
Entry
string
`json:"entry"`
// Used to communicate terminal session details
// Used to communicate terminal session details
Terminal
*
TerminalSettings
Terminal
*
TerminalSettings
// Path to Gitaly Socket (deprecated in favor of GitalyAddress)
GitalySocketPath
string
// GitalyAddress is a unix:// or tcp:// address to reach a Gitaly service on
// GitalyAddress is a unix:// or tcp:// address to reach a Gitaly service on
GitalyAddress
string
GitalyAddress
string
// Repository object for making gRPC requests to Gitaly. This will
// Repository object for making gRPC requests to Gitaly. This will
...
@@ -222,12 +220,6 @@ func (api *API) PreAuthorize(suffix string, r *http.Request) (httpResponse *http
...
@@ -222,12 +220,6 @@ func (api *API) PreAuthorize(suffix string, r *http.Request) (httpResponse *http
authResponse
.
Repository
.
Path
=
authResponse
.
RepoPath
authResponse
.
Repository
.
Path
=
authResponse
.
RepoPath
}
}
if
socketPath
:=
authResponse
.
GitalySocketPath
;
socketPath
!=
""
&&
authResponse
.
GitalyAddress
==
""
{
// We are transitioning away from the GitalySocketPath response field.
// Until all the new code is in place, keep backwards compatibility.
authResponse
.
GitalyAddress
=
"unix://"
+
socketPath
}
return
httpResponse
,
authResponse
,
nil
return
httpResponse
,
authResponse
,
nil
}
}
...
...
internal/git/receive-pack.go
View file @
db9743d1
...
@@ -51,7 +51,7 @@ func handleReceivePackWithGitaly(a *api.Response, clientRequest io.Reader, clien
...
@@ -51,7 +51,7 @@ func handleReceivePackWithGitaly(a *api.Response, clientRequest io.Reader, clien
return
fmt
.
Errorf
(
"smarthttp.ReceivePack: %v"
,
err
)
return
fmt
.
Errorf
(
"smarthttp.ReceivePack: %v"
,
err
)
}
}
if
err
:=
smarthttp
.
ReceivePack
(
a
,
clientRequest
,
clientResponse
);
err
!=
nil
{
if
err
:=
smarthttp
.
ReceivePack
(
&
a
.
Repository
,
a
.
GL_ID
,
clientRequest
,
clientResponse
);
err
!=
nil
{
return
fmt
.
Errorf
(
"smarthttp.ReceivePack: %v"
,
err
)
return
fmt
.
Errorf
(
"smarthttp.ReceivePack: %v"
,
err
)
}
}
...
...
internal/git/upload-pack.go
View file @
db9743d1
...
@@ -63,7 +63,7 @@ func handleUploadPackWithGitaly(a *api.Response, clientRequest io.Reader, client
...
@@ -63,7 +63,7 @@ func handleUploadPackWithGitaly(a *api.Response, clientRequest io.Reader, client
return
fmt
.
Errorf
(
"smarthttp.UploadPack: %v"
,
err
)
return
fmt
.
Errorf
(
"smarthttp.UploadPack: %v"
,
err
)
}
}
if
err
:=
smarthttp
.
UploadPack
(
a
,
clientRequest
,
clientResponse
);
err
!=
nil
{
if
err
:=
smarthttp
.
UploadPack
(
&
a
.
Repository
,
clientRequest
,
clientResponse
);
err
!=
nil
{
return
fmt
.
Errorf
(
"smarthttp.UploadPack: %v"
,
err
)
return
fmt
.
Errorf
(
"smarthttp.UploadPack: %v"
,
err
)
}
}
...
...
internal/gitaly/smarthttp.go
View file @
db9743d1
...
@@ -4,8 +4,6 @@ import (
...
@@ -4,8 +4,6 @@ import (
"fmt"
"fmt"
"io"
"io"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/api"
pb
"gitlab.com/gitlab-org/gitaly-proto/go"
pb
"gitlab.com/gitlab-org/gitaly-proto/go"
pbhelper
"gitlab.com/gitlab-org/gitaly-proto/go/helper"
pbhelper
"gitlab.com/gitlab-org/gitaly-proto/go/helper"
...
@@ -48,8 +46,7 @@ func (client *SmartHTTPClient) InfoRefsResponseWriterTo(repo *pb.Repository, rpc
...
@@ -48,8 +46,7 @@ func (client *SmartHTTPClient) InfoRefsResponseWriterTo(repo *pb.Repository, rpc
return
&
pbhelper
.
InfoRefsClientWriterTo
{
c
},
nil
return
&
pbhelper
.
InfoRefsClientWriterTo
{
c
},
nil
}
}
func
(
client
*
SmartHTTPClient
)
ReceivePack
(
a
*
api
.
Response
,
clientRequest
io
.
Reader
,
clientResponse
io
.
Writer
)
error
{
func
(
client
*
SmartHTTPClient
)
ReceivePack
(
repo
*
pb
.
Repository
,
GlId
string
,
clientRequest
io
.
Reader
,
clientResponse
io
.
Writer
)
error
{
repo
:=
&
pb
.
Repository
{
Path
:
a
.
RepoPath
}
stream
,
err
:=
client
.
PostReceivePack
(
context
.
Background
())
stream
,
err
:=
client
.
PostReceivePack
(
context
.
Background
())
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
@@ -57,7 +54,7 @@ func (client *SmartHTTPClient) ReceivePack(a *api.Response, clientRequest io.Rea
...
@@ -57,7 +54,7 @@ func (client *SmartHTTPClient) ReceivePack(a *api.Response, clientRequest io.Rea
rpcRequest
:=
&
pb
.
PostReceivePackRequest
{
rpcRequest
:=
&
pb
.
PostReceivePackRequest
{
Repository
:
repo
,
Repository
:
repo
,
GlId
:
a
.
GL_ID
,
GlId
:
GlId
,
}
}
if
err
:=
stream
.
Send
(
rpcRequest
);
err
!=
nil
{
if
err
:=
stream
.
Send
(
rpcRequest
);
err
!=
nil
{
...
@@ -84,8 +81,7 @@ func (client *SmartHTTPClient) ReceivePack(a *api.Response, clientRequest io.Rea
...
@@ -84,8 +81,7 @@ func (client *SmartHTTPClient) ReceivePack(a *api.Response, clientRequest io.Rea
return
nil
return
nil
}
}
func
(
client
*
SmartHTTPClient
)
UploadPack
(
a
*
api
.
Response
,
clientRequest
io
.
Reader
,
clientResponse
io
.
Writer
)
error
{
func
(
client
*
SmartHTTPClient
)
UploadPack
(
repo
*
pb
.
Repository
,
clientRequest
io
.
Reader
,
clientResponse
io
.
Writer
)
error
{
repo
:=
&
pb
.
Repository
{
Path
:
a
.
RepoPath
}
stream
,
err
:=
client
.
PostUploadPack
(
context
.
Background
())
stream
,
err
:=
client
.
PostUploadPack
(
context
.
Background
())
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
...
internal/testhelper/gitaly.go
View file @
db9743d1
package
testhelper
package
testhelper
import
(
import
(
"fmt"
"io"
"io"
"io/ioutil"
"io/ioutil"
"log"
"log"
"path"
"path"
"strings"
pb
"gitlab.com/gitlab-org/gitaly-proto/go"
pb
"gitlab.com/gitlab-org/gitaly-proto/go"
)
)
...
@@ -31,6 +33,10 @@ func NewGitalyServer() *GitalyTestServer {
...
@@ -31,6 +33,10 @@ func NewGitalyServer() *GitalyTestServer {
}
}
func
(
s
*
GitalyTestServer
)
InfoRefsUploadPack
(
in
*
pb
.
InfoRefsRequest
,
stream
pb
.
SmartHTTP_InfoRefsUploadPackServer
)
error
{
func
(
s
*
GitalyTestServer
)
InfoRefsUploadPack
(
in
*
pb
.
InfoRefsRequest
,
stream
pb
.
SmartHTTP_InfoRefsUploadPackServer
)
error
{
if
err
:=
validateRepository
(
in
.
GetRepository
());
err
!=
nil
{
return
err
}
response
:=
&
pb
.
InfoRefsResponse
{
response
:=
&
pb
.
InfoRefsResponse
{
Data
:
[]
byte
(
GitalyInfoRefsResponseMock
),
Data
:
[]
byte
(
GitalyInfoRefsResponseMock
),
}
}
...
@@ -38,6 +44,10 @@ func (s *GitalyTestServer) InfoRefsUploadPack(in *pb.InfoRefsRequest, stream pb.
...
@@ -38,6 +44,10 @@ func (s *GitalyTestServer) InfoRefsUploadPack(in *pb.InfoRefsRequest, stream pb.
}
}
func
(
s
*
GitalyTestServer
)
InfoRefsReceivePack
(
in
*
pb
.
InfoRefsRequest
,
stream
pb
.
SmartHTTP_InfoRefsReceivePackServer
)
error
{
func
(
s
*
GitalyTestServer
)
InfoRefsReceivePack
(
in
*
pb
.
InfoRefsRequest
,
stream
pb
.
SmartHTTP_InfoRefsReceivePackServer
)
error
{
if
err
:=
validateRepository
(
in
.
GetRepository
());
err
!=
nil
{
return
err
}
response
:=
&
pb
.
InfoRefsResponse
{
response
:=
&
pb
.
InfoRefsResponse
{
Data
:
[]
byte
(
GitalyInfoRefsResponseMock
),
Data
:
[]
byte
(
GitalyInfoRefsResponseMock
),
}
}
...
@@ -50,8 +60,17 @@ func (s *GitalyTestServer) PostReceivePack(stream pb.SmartHTTP_PostReceivePackSe
...
@@ -50,8 +60,17 @@ func (s *GitalyTestServer) PostReceivePack(stream pb.SmartHTTP_PostReceivePackSe
return
err
return
err
}
}
repo
:=
req
.
GetRepository
()
if
err
:=
validateRepository
(
req
.
GetRepository
());
err
!=
nil
{
return
err
}
response
:=
&
pb
.
PostReceivePackResponse
{
response
:=
&
pb
.
PostReceivePackResponse
{
Data
:
[]
byte
(
req
.
Repository
.
GetPath
()
+
req
.
GlId
),
Data
:
[]
byte
(
strings
.
Join
([]
string
{
repo
.
GetPath
(),
repo
.
GetStorageName
(),
repo
.
GetRelativePath
(),
req
.
GlId
,
},
"
\0
00"
)
+
"
\0
00"
),
}
}
if
err
:=
stream
.
Send
(
response
);
err
!=
nil
{
if
err
:=
stream
.
Send
(
response
);
err
!=
nil
{
return
err
return
err
...
@@ -84,8 +103,16 @@ func (s *GitalyTestServer) PostUploadPack(stream pb.SmartHTTP_PostUploadPackServ
...
@@ -84,8 +103,16 @@ func (s *GitalyTestServer) PostUploadPack(stream pb.SmartHTTP_PostUploadPackServ
return
err
return
err
}
}
repo
:=
req
.
GetRepository
()
if
err
:=
validateRepository
(
req
.
GetRepository
());
err
!=
nil
{
return
err
}
response
:=
&
pb
.
PostUploadPackResponse
{
response
:=
&
pb
.
PostUploadPackResponse
{
Data
:
[]
byte
(
req
.
Repository
.
GetPath
()),
Data
:
[]
byte
(
strings
.
Join
([]
string
{
repo
.
GetPath
(),
repo
.
GetStorageName
(),
repo
.
GetRelativePath
(),
},
"
\0
00"
)
+
"
\0
00"
),
}
}
if
err
:=
stream
.
Send
(
response
);
err
!=
nil
{
if
err
:=
stream
.
Send
(
response
);
err
!=
nil
{
return
err
return
err
...
@@ -111,3 +138,16 @@ func (s *GitalyTestServer) PostUploadPack(stream pb.SmartHTTP_PostUploadPackServ
...
@@ -111,3 +138,16 @@ func (s *GitalyTestServer) PostUploadPack(stream pb.SmartHTTP_PostUploadPackServ
return
nil
return
nil
}
}
func
validateRepository
(
repo
*
pb
.
Repository
)
error
{
if
len
(
repo
.
GetPath
())
==
0
{
return
fmt
.
Errorf
(
"missing path: %v"
,
repo
)
}
if
len
(
repo
.
GetStorageName
())
==
0
{
return
fmt
.
Errorf
(
"missing storage_name: %v"
,
repo
)
}
if
len
(
repo
.
GetRelativePath
())
==
0
{
return
fmt
.
Errorf
(
"missing relative_path: %v"
,
repo
)
}
return
nil
}
main_test.go
View file @
db9743d1
...
@@ -145,7 +145,7 @@ func TestFailedCloneNoGitaly(t *testing.T) {
...
@@ -145,7 +145,7 @@ func TestFailedCloneNoGitaly(t *testing.T) {
GL_ID
:
"user-123"
,
GL_ID
:
"user-123"
,
RepoPath
:
repoPath
(
t
),
RepoPath
:
repoPath
(
t
),
// This will create a failure to connect to Gitaly
// This will create a failure to connect to Gitaly
Gitaly
SocketPath
:
"
/nonexistent"
,
Gitaly
Address
:
"unix:
/nonexistent"
,
}
}
// Prepare test server and backend
// Prepare test server and backend
...
@@ -599,66 +599,34 @@ func TestApiContentTypeBlock(t *testing.T) {
...
@@ -599,66 +599,34 @@ func TestApiContentTypeBlock(t *testing.T) {
func
TestGetInfoRefsProxiedToGitalySuccessfully
(
t
*
testing
.
T
)
{
func
TestGetInfoRefsProxiedToGitalySuccessfully
(
t
*
testing
.
T
)
{
apiResponse
:=
gitOkBody
(
t
)
apiResponse
:=
gitOkBody
(
t
)
repoPath
:=
apiResponse
.
RepoPath
gitalyServer
,
socketPath
:=
startGitalyServer
(
t
)
gitalyServer
,
socketPath
:=
startGitalyServer
(
t
)
defer
gitalyServer
.
Stop
()
defer
gitalyServer
.
Stop
()
gitalyAddress
:=
"unix://"
+
socketPath
gitalyAddress
:=
"unix://"
+
socketPath
apiResponse
.
GitalyAddress
=
gitalyAddress
addressCases
:=
[]
struct
{
ts
:=
testAuthServer
(
nil
,
200
,
apiResponse
)
socketPath
string
defer
ts
.
Close
()
address
string
}{
{
socketPath
:
"/nonexistent,/should/be/ignored"
,
address
:
gitalyAddress
},
{
socketPath
:
socketPath
},
}
repoCases
:=
[]
struct
{
ws
:=
startWorkhorseServer
(
ts
.
URL
)
repoPath
string
defer
ws
.
Close
()
repository
pb
.
Repository
}{
resource
:=
"/gitlab-org/gitlab-test.git/info/refs?service=git-upload-pack"
{
resp
,
err
:=
http
.
Get
(
ws
.
URL
+
resource
)
repoPath
:
repoPath
,
if
err
!=
nil
{
},
t
.
Fatal
(
err
)
{
}
repoPath
:
repoPath
,
defer
resp
.
Body
.
Close
()
repository
:
pb
.
Repository
{
Path
:
repoPath
,
StorageName
:
"foobar"
,
RelativePath
:
"baz.git"
},
responseBody
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
},
if
err
!=
nil
{
t
.
Error
(
err
)
}
}
for
_
,
ac
:=
range
addressCases
{
expectedContent
:=
testhelper
.
GitalyInfoRefsResponseMock
for
_
,
rc
:=
range
repoCases
{
if
!
bytes
.
Equal
(
responseBody
,
[]
byte
(
expectedContent
))
{
func
()
{
t
.
Errorf
(
"GET %q: Expected %q, got %q"
,
resource
,
expectedContent
,
responseBody
)
apiResponse
.
RepoPath
=
rc
.
repoPath
apiResponse
.
Repository
=
rc
.
repository
apiResponse
.
GitalySocketPath
=
ac
.
socketPath
apiResponse
.
GitalyAddress
=
ac
.
address
ts
:=
testAuthServer
(
nil
,
200
,
apiResponse
)
defer
ts
.
Close
()
ws
:=
startWorkhorseServer
(
ts
.
URL
)
defer
ws
.
Close
()
resource
:=
"/gitlab-org/gitlab-test.git/info/refs?service=git-upload-pack"
resp
,
err
:=
http
.
Get
(
ws
.
URL
+
resource
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
defer
resp
.
Body
.
Close
()
responseBody
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
expectedContent
:=
testhelper
.
GitalyInfoRefsResponseMock
if
!
bytes
.
Equal
(
responseBody
,
[]
byte
(
expectedContent
))
{
t
.
Errorf
(
"GET %q: Expected %q, got %q"
,
resource
,
expectedContent
,
responseBody
)
}
}()
}
}
}
}
}
func
TestPostReceivePackProxiedToGitalySuccessfully
(
t
*
testing
.
T
)
{
func
TestPostReceivePackProxiedToGitalySuccessfully
(
t
*
testing
.
T
)
{
...
@@ -692,9 +660,15 @@ func TestPostReceivePackProxiedToGitalySuccessfully(t *testing.T) {
...
@@ -692,9 +660,15 @@ func TestPostReceivePackProxiedToGitalySuccessfully(t *testing.T) {
if
resp
.
StatusCode
!=
200
{
if
resp
.
StatusCode
!=
200
{
t
.
Errorf
(
"GET %q: expected 200, got %d"
,
resource
,
resp
.
StatusCode
)
t
.
Errorf
(
"GET %q: expected 200, got %d"
,
resource
,
resp
.
StatusCode
)
}
}
expectedResponse
:=
strings
.
Join
([]
string
{
if
string
(
responseBody
)
!=
apiResponse
.
RepoPath
+
apiResponse
.
GL_ID
+
string
(
testhelper
.
GitalyReceivePackResponseMock
)
{
apiResponse
.
RepoPath
,
t
.
Errorf
(
"GET %q: Unexpected response"
,
resource
)
apiResponse
.
Repository
.
StorageName
,
apiResponse
.
Repository
.
RelativePath
,
apiResponse
.
GL_ID
,
string
(
testhelper
.
GitalyReceivePackResponseMock
),
},
"
\0
00"
)
if
string
(
responseBody
)
!=
expectedResponse
{
t
.
Errorf
(
"GET %q: Unexpected response %.100q"
,
resource
,
responseBody
)
}
}
}
}
...
@@ -730,8 +704,14 @@ func TestPostUploadPackProxiedToGitalySuccessfully(t *testing.T) {
...
@@ -730,8 +704,14 @@ func TestPostUploadPackProxiedToGitalySuccessfully(t *testing.T) {
t
.
Errorf
(
"GET %q: expected 200, got %d"
,
resource
,
resp
.
StatusCode
)
t
.
Errorf
(
"GET %q: expected 200, got %d"
,
resource
,
resp
.
StatusCode
)
}
}
if
string
(
responseBody
)
!=
apiResponse
.
RepoPath
+
string
(
testhelper
.
GitalyUploadPackResponseMock
)
{
expected
:=
strings
.
Join
([]
string
{
t
.
Errorf
(
"GET %q: Unexpected response"
,
resource
)
apiResponse
.
RepoPath
,
apiResponse
.
Repository
.
StorageName
,
apiResponse
.
Repository
.
RelativePath
,
string
(
testhelper
.
GitalyUploadPackResponseMock
),
},
"
\0
00"
)
if
string
(
responseBody
)
!=
expected
{
t
.
Errorf
(
"GET %q: Unexpected response: %.100q"
,
resource
,
responseBody
)
}
}
}
}
...
@@ -740,7 +720,7 @@ func TestGetInfoRefsHandledLocallyDueToEmptyGitalySocketPath(t *testing.T) {
...
@@ -740,7 +720,7 @@ func TestGetInfoRefsHandledLocallyDueToEmptyGitalySocketPath(t *testing.T) {
defer
gitalyServer
.
Stop
()
defer
gitalyServer
.
Stop
()
apiResponse
:=
gitOkBody
(
t
)
apiResponse
:=
gitOkBody
(
t
)
apiResponse
.
Gitaly
SocketPath
=
""
apiResponse
.
Gitaly
Address
=
""
ts
:=
testAuthServer
(
nil
,
200
,
apiResponse
)
ts
:=
testAuthServer
(
nil
,
200
,
apiResponse
)
defer
ts
.
Close
()
defer
ts
.
Close
()
...
@@ -773,7 +753,7 @@ func TestPostReceivePackHandledLocallyDueToEmptyGitalySocketPath(t *testing.T) {
...
@@ -773,7 +753,7 @@ func TestPostReceivePackHandledLocallyDueToEmptyGitalySocketPath(t *testing.T) {
defer
gitalyServer
.
Stop
()
defer
gitalyServer
.
Stop
()
apiResponse
:=
gitOkBody
(
t
)
apiResponse
:=
gitOkBody
(
t
)
apiResponse
.
Gitaly
SocketPath
=
""
apiResponse
.
Gitaly
Address
=
""
ts
:=
testAuthServer
(
nil
,
200
,
apiResponse
)
ts
:=
testAuthServer
(
nil
,
200
,
apiResponse
)
defer
ts
.
Close
()
defer
ts
.
Close
()
...
@@ -804,7 +784,7 @@ func TestPostUploadPackHandledLocallyDueToEmptyGitalySocketPath(t *testing.T) {
...
@@ -804,7 +784,7 @@ func TestPostUploadPackHandledLocallyDueToEmptyGitalySocketPath(t *testing.T) {
defer
gitalyServer
.
Stop
()
defer
gitalyServer
.
Stop
()
apiResponse
:=
gitOkBody
(
t
)
apiResponse
:=
gitOkBody
(
t
)
apiResponse
.
Gitaly
SocketPath
=
""
apiResponse
.
Gitaly
Address
=
""
ts
:=
testAuthServer
(
nil
,
200
,
apiResponse
)
ts
:=
testAuthServer
(
nil
,
200
,
apiResponse
)
defer
ts
.
Close
()
defer
ts
.
Close
()
...
@@ -1027,9 +1007,15 @@ func runOrFail(t *testing.T, cmd *exec.Cmd) {
...
@@ -1027,9 +1007,15 @@ func runOrFail(t *testing.T, cmd *exec.Cmd) {
}
}
func
gitOkBody
(
t
*
testing
.
T
)
*
api
.
Response
{
func
gitOkBody
(
t
*
testing
.
T
)
*
api
.
Response
{
repoPath
:=
repoPath
(
t
)
return
&
api
.
Response
{
return
&
api
.
Response
{
GL_ID
:
"user-123"
,
GL_ID
:
"user-123"
,
RepoPath
:
repoPath
(
t
),
RepoPath
:
repoPath
,
Repository
:
pb
.
Repository
{
Path
:
repoPath
,
StorageName
:
"default"
,
RelativePath
:
"foo/bar.git"
,
},
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment