Skip to content

Commit 42ec285

Browse files
authored
cli: detect bareness of git libraries (#897)
cli: detect bareness of git libraries
2 parents 35d6bc7 + 007c0fe commit 42ec285

File tree

7 files changed

+198
-14
lines changed

7 files changed

+198
-14
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
- git libraries bare or non bare format is automatically detected ([#897](https://github.com/src-d/gitbase/pull/897))
10+
911
## [0.22.0-beta1] - 2019-06-20
1012

1113
### Added

cmd/gitbase/command/server.go

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ type Server struct {
5959
Format string `long:"format" default:"git" choice:"git" choice:"siva" description:"Library format"`
6060
Bucket int `long:"bucket" default:"2" description:"Bucketing level to use with siva libraries"`
6161
Bare bool `long:"bare" description:"Sets the library to use bare git repositories, used only with git format libraries"`
62+
NonBare bool `long:"non-bare" description:"Sets the library to use non bare git repositories, used only with git format libraries"`
6263
NonRooted bool `long:"non-rooted" description:"Disables treating siva files as rooted repositories"`
6364
Host string `long:"host" default:"localhost" description:"Host where the server is going to listen"`
6465
Port int `short:"p" long:"port" default:"3306" description:"Port where the server is going to listen"`
@@ -122,6 +123,10 @@ func (c *Server) Execute(args []string) error {
122123
logrus.SetLevel(logrus.DebugLevel)
123124
}
124125

126+
if c.Bare && c.NonBare {
127+
return fmt.Errorf("cannot use both --bare and --non-bare")
128+
}
129+
125130
// info is the default log level
126131
if c.LogLevel != "info" {
127132
level, err := logrus.ParseLevel(c.LogLevel)
@@ -270,11 +275,19 @@ func (c *Server) addDirectories() error {
270275
logrus.Error("at least one folder should be provided.")
271276
}
272277

278+
defaultBare := bareAuto
279+
switch {
280+
case c.Bare:
281+
defaultBare = bareOn
282+
case c.NonBare:
283+
defaultBare = bareOff
284+
}
285+
273286
for _, d := range c.Directories {
274287
dir := directory{
275288
Path: d,
276289
Format: c.Format,
277-
Bare: c.Bare,
290+
Bare: defaultBare,
278291
Bucket: c.Bucket,
279292
Rooted: !c.NonRooted,
280293
}
@@ -327,10 +340,15 @@ func (c *Server) addDirectory(d directory) error {
327340
return nil
328341
}
329342

343+
bare, err := discoverBare(d)
344+
if err != nil {
345+
return err
346+
}
347+
330348
plainOpts := &plain.LocationOptions{
331349
Cache: c.sharedCache,
332350
Performance: true,
333-
Bare: d.Bare,
351+
Bare: bare,
334352
}
335353

336354
if c.plainLibrary == nil {
@@ -354,12 +372,20 @@ func (c *Server) addDirectory(d directory) error {
354372
return nil
355373
}
356374

375+
type bareOpt int
376+
377+
const (
378+
bareAuto bareOpt = iota
379+
bareOn
380+
bareOff
381+
)
382+
357383
type directory struct {
358384
Path string
359385
Format string
360386
Bucket int
361387
Rooted bool
362-
Bare bool
388+
Bare bareOpt
363389
}
364390

365391
var (
@@ -405,12 +431,18 @@ func parseDirectory(dir directory) (directory, error) {
405431
dir.Format = val
406432

407433
case "bare":
408-
if val != "true" && val != "false" {
434+
switch val {
435+
case "true":
436+
dir.Bare = bareOn
437+
case "false":
438+
dir.Bare = bareOff
439+
case "auto":
440+
dir.Bare = bareAuto
441+
default:
409442
logrus.Errorf("invalid value in bare, it can only "+
410-
"be true or false %v", val)
443+
"be true, false, or auto %v", val)
411444
return dir, ErrInvalid
412445
}
413-
dir.Bare = (val == "true")
414446

415447
case "rooted":
416448
if val != "true" && val != "false" {
@@ -436,3 +468,24 @@ func parseDirectory(dir directory) (directory, error) {
436468

437469
return dir, nil
438470
}
471+
472+
func discoverBare(d directory) (bool, error) {
473+
fs := osfs.New(d.Path)
474+
475+
var bare bool
476+
if d.Bare == bareAuto {
477+
b, err := plain.IsFirstRepositoryBare(fs, "/")
478+
if plain.ErrRepositoriesNotFound.Is(err) {
479+
logrus.WithField("path", d.Path).
480+
Errorf("could not find repositories, assuming non bare format")
481+
} else if err != nil {
482+
return false, err
483+
}
484+
485+
bare = b
486+
} else {
487+
bare = d.Bare == bareOn
488+
}
489+
490+
return bare, nil
491+
}

cmd/gitbase/command/server_test.go

Lines changed: 129 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
package command
22

33
import (
4+
"fmt"
5+
"io/ioutil"
6+
"os"
7+
"path/filepath"
48
"testing"
59

10+
fixtures "github.com/src-d/go-git-fixtures"
611
"github.com/stretchr/testify/require"
712
)
813

@@ -70,14 +75,14 @@ func TestDirectories(t *testing.T) {
7075
path: "file:///siva/path?bare=true",
7176
expected: directory{
7277
Path: "/siva/path",
73-
Bare: true,
78+
Bare: bareOn,
7479
},
7580
},
7681
{
7782
path: "file:///siva/path?bare=false",
7883
expected: directory{
7984
Path: "/siva/path",
80-
Bare: false,
85+
Bare: bareOff,
8186
},
8287
},
8388
{
@@ -118,7 +123,7 @@ func TestDirectories(t *testing.T) {
118123
expected: directory{
119124
Path: "/siva/path",
120125
Format: "git",
121-
Bare: false,
126+
Bare: bareOff,
122127
},
123128
},
124129
{
@@ -147,3 +152,124 @@ func TestDirectories(t *testing.T) {
147152
})
148153
}
149154
}
155+
156+
func TestDiscoverBare(t *testing.T) {
157+
defer func() {
158+
require.NoError(t, fixtures.Clean())
159+
}()
160+
161+
tmpDir, err := ioutil.TempDir("", "gitbase")
162+
require.NoError(t, err)
163+
defer os.RemoveAll(tmpDir)
164+
165+
emptyDir := filepath.Join(tmpDir, "empty")
166+
err = os.Mkdir(emptyDir, 0777)
167+
require.NoError(t, err)
168+
169+
bareDir := filepath.Join(tmpDir, "bare")
170+
err = os.Mkdir(bareDir, 0777)
171+
require.NoError(t, err)
172+
dir := fixtures.ByTag("worktree").One().DotGit().Root()
173+
err = os.Rename(dir, filepath.Join(bareDir, "repo"))
174+
require.NoError(t, err)
175+
176+
nonBareDir := filepath.Join(tmpDir, "non_bare")
177+
err = os.Mkdir(nonBareDir, 0777)
178+
require.NoError(t, err)
179+
dir = fixtures.ByTag("worktree").One().Worktree().Root()
180+
err = os.Rename(dir, filepath.Join(nonBareDir, "repo"))
181+
require.NoError(t, err)
182+
183+
tests := []struct {
184+
path string
185+
bare bareOpt
186+
expected bool
187+
err bool
188+
}{
189+
{
190+
path: "/does/not/exist",
191+
err: true,
192+
},
193+
{
194+
path: emptyDir,
195+
bare: bareAuto,
196+
expected: false,
197+
},
198+
{
199+
path: emptyDir,
200+
bare: bareOn,
201+
expected: true,
202+
},
203+
{
204+
path: emptyDir,
205+
bare: bareOff,
206+
expected: false,
207+
},
208+
{
209+
path: bareDir,
210+
bare: bareAuto,
211+
expected: true,
212+
},
213+
{
214+
path: bareDir,
215+
bare: bareOn,
216+
expected: true,
217+
},
218+
{
219+
path: bareDir,
220+
bare: bareOff,
221+
expected: false,
222+
},
223+
{
224+
path: nonBareDir,
225+
bare: bareAuto,
226+
expected: false,
227+
},
228+
{
229+
path: nonBareDir,
230+
bare: bareOn,
231+
expected: true,
232+
},
233+
{
234+
path: nonBareDir,
235+
bare: bareOff,
236+
expected: false,
237+
},
238+
}
239+
240+
for _, test := range tests {
241+
dir := directory{
242+
Path: test.path,
243+
Bare: test.bare,
244+
}
245+
246+
t.Run(bareTestName(dir, test.err), func(t *testing.T) {
247+
bare, err := discoverBare(dir)
248+
if test.err {
249+
require.Error(t, err)
250+
return
251+
}
252+
253+
require.NoError(t, err)
254+
require.Equal(t, test.expected, bare)
255+
})
256+
}
257+
}
258+
259+
func bareTestName(d directory, err bool) string {
260+
bare := ""
261+
switch d.Bare {
262+
case bareOn:
263+
bare = "bare"
264+
case bareOff:
265+
bare = "non-bare"
266+
case bareAuto:
267+
bare = "auto"
268+
}
269+
270+
if err {
271+
bare = "error"
272+
}
273+
274+
return fmt.Sprintf("%s_%s", d.Path, bare)
275+
}

docs/using-gitbase/configuration.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ Help Options:
9292
--bucket= Bucketing level to use with siva libraries (default: 2)
9393
--bare Sets the library to use bare git repositories, used
9494
only with git format libraries
95+
--non-bare Sets the library to use non bare git repositories,
96+
used only with git format libraries
9597
--non-rooted Disables treating siva files as rooted repositories
9698
--host= Host where the server is going to listen (default:
9799
localhost)

docs/using-gitbase/getting-started.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,19 +119,20 @@ mysql -q -u root -h 127.0.0.1 --default-auth=mysql_native_password
119119

120120
## Library format specification
121121

122-
By default the directories added to github should contain normal git repositories. If the format of the repositories is different you have two ways to specify it.
122+
By default the directories added to gitbase should contain git repositories and it detects if they are standard or bare format. Each directory added can only contain one type of repository. If you want to specify the format you have two ways to do it:
123123

124124
If all the directories are in the same format you can set it globally with these parameters:
125125

126126
* `--format`: it can be either `git` for filesystem repositories or `siva` for siva archives
127127
* `--bare`: specifies that git archives are bare, can only be used with `git` format
128+
* `--non-bare`: specifies that git archives are standard, can only be used with `git` format
128129
* `--bucket`: sets the number of characters to use for bucketing, used with `siva` libraries
129130
* `--non-rooted`: disables rooted repositories management in `siva` libraries
130131

131132
If you are mixing formats you can specify each directory as a `file://` URL with these parameters:
132133

133134
* `format`: can be `git` or `siva`
134-
* `bare`: `true` or `false`
135+
* `bare`: `true`, `false` or `auto`
135136
* `bucket`: the characters to use for directory bucketing
136137
* `rooted`: `true` or `false`
137138

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ require (
1414
github.com/opentracing/opentracing-go v1.1.0
1515
github.com/sirupsen/logrus v1.3.0
1616
github.com/src-d/enry/v2 v2.0.0
17-
github.com/src-d/go-borges v0.0.0-20190619084057-d02cf3fd6581
17+
github.com/src-d/go-borges v0.0.0-20190620132223-0499c9b6034b
1818
github.com/src-d/go-git v4.7.0+incompatible
1919
github.com/src-d/go-git-fixtures v3.5.1-0.20190605154830-57f3972b0248+incompatible
2020
github.com/src-d/go-mysql-server v0.4.1-0.20190620142646-9722f31e0f85

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,8 @@ github.com/src-d/enry/v2 v2.0.0 h1:2ADqfDHhroFwL1RGhMS9e15NkEwln8P4AABwVvIdAlo=
217217
github.com/src-d/enry/v2 v2.0.0/go.mod h1:qQeCMRwzMF3ckeGr+h0tJLdxXnq+NVZsIDMELj0t028=
218218
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
219219
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
220-
github.com/src-d/go-borges v0.0.0-20190619084057-d02cf3fd6581 h1:ZOJFuELokTVFnwpgD0tj9PMTXiBwutmGoH2WCaG5dts=
221-
github.com/src-d/go-borges v0.0.0-20190619084057-d02cf3fd6581/go.mod h1:Myl/zHrk3iT/I5T08RTBpuGzchucytSsi6p7KzM2lOA=
220+
github.com/src-d/go-borges v0.0.0-20190620132223-0499c9b6034b h1:c2CSWoLOo1o2ija5OWDETzMUi9kncByT5GL7EkSpzxk=
221+
github.com/src-d/go-borges v0.0.0-20190620132223-0499c9b6034b/go.mod h1:Myl/zHrk3iT/I5T08RTBpuGzchucytSsi6p7KzM2lOA=
222222
github.com/src-d/go-git v4.7.0+incompatible h1:IYSSnbAHeKmsfbQFi9ozbid+KNh0bKjlorMfQehQbcE=
223223
github.com/src-d/go-git v4.7.0+incompatible/go.mod h1:1bQciz+hn0jzPQNsYj0hDFZHLJBdV7gXE2mWhC7EkFk=
224224
github.com/src-d/go-git-fixtures v3.5.1-0.20190605154830-57f3972b0248+incompatible h1:A5bKevhs9C//Nh8QV0J+1KphEaIa25cDe1DTs/yPxDI=

0 commit comments

Comments
 (0)