Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit 5cc316b

Browse files
authored
Merge pull request #935 from jfontan/improvement/cache-incoming-directory
storage/dotgit: search for incoming dir only once
2 parents 005d5dc + b1da90b commit 5cc316b

File tree

1 file changed

+36
-18
lines changed

1 file changed

+36
-18
lines changed

storage/filesystem/dotgit/dotgit.go

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ var (
6161
// type is not zero-value-safe, use the New function to initialize it.
6262
type DotGit struct {
6363
fs billy.Filesystem
64+
65+
// incoming object directory information
66+
incomingChecked bool
67+
incomingDirName string
6468
}
6569

6670
// New returns a DotGit value ready to be used. The path argument must
@@ -279,33 +283,47 @@ func (d *DotGit) objectPath(h plumbing.Hash) string {
279283
return d.fs.Join(objectsPath, hash[0:2], hash[2:40])
280284
}
281285

282-
//incomingObjectPath is intended to add support for a git pre-recieve hook to be written
283-
//it adds support for go-git to find objects in an "incoming" directory, so that the library
284-
//can be used to write a pre-recieve hook that deals with the incoming objects.
285-
//More on git hooks found here : https://git-scm.com/docs/githooks
286-
//More on 'quarantine'/incoming directory here : https://git-scm.com/docs/git-receive-pack
286+
// incomingObjectPath is intended to add support for a git pre-receive hook
287+
// to be written it adds support for go-git to find objects in an "incoming"
288+
// directory, so that the library can be used to write a pre-receive hook
289+
// that deals with the incoming objects.
290+
//
291+
// More on git hooks found here : https://git-scm.com/docs/githooks
292+
// More on 'quarantine'/incoming directory here:
293+
// https://git-scm.com/docs/git-receive-pack
287294
func (d *DotGit) incomingObjectPath(h plumbing.Hash) string {
288295
hString := h.String()
289-
directoryContents, err := d.fs.ReadDir(objectsPath)
290-
if err != nil {
296+
297+
if d.incomingDirName == "" {
291298
return d.fs.Join(objectsPath, hString[0:2], hString[2:40])
292299
}
293-
var incomingDirName string
294-
for _, file := range directoryContents {
295-
if strings.Split(file.Name(), "-")[0] == "incoming" && file.IsDir() {
296-
incomingDirName = file.Name()
300+
301+
return d.fs.Join(objectsPath, d.incomingDirName, hString[0:2], hString[2:40])
302+
}
303+
304+
// hasIncomingObjects searches for an incoming directory and keeps its name
305+
// so it doesn't have to be found each time an object is accessed.
306+
func (d *DotGit) hasIncomingObjects() bool {
307+
if !d.incomingChecked {
308+
directoryContents, err := d.fs.ReadDir(objectsPath)
309+
if err == nil {
310+
for _, file := range directoryContents {
311+
if strings.HasPrefix(file.Name(), "incoming-") && file.IsDir() {
312+
d.incomingDirName = file.Name()
313+
}
314+
}
297315
}
316+
317+
d.incomingChecked = true
298318
}
299-
if incomingDirName == "" {
300-
return d.fs.Join(objectsPath, hString[0:2], hString[2:40])
301-
}
302-
return d.fs.Join(objectsPath, incomingDirName, hString[0:2], hString[2:40])
319+
320+
return d.incomingDirName != ""
303321
}
304322

305323
// Object returns a fs.File pointing the object file, if exists
306324
func (d *DotGit) Object(h plumbing.Hash) (billy.File, error) {
307325
obj1, err1 := d.fs.Open(d.objectPath(h))
308-
if os.IsNotExist(err1) {
326+
if os.IsNotExist(err1) && d.hasIncomingObjects() {
309327
obj2, err2 := d.fs.Open(d.incomingObjectPath(h))
310328
if err2 != nil {
311329
return obj1, err1
@@ -318,7 +336,7 @@ func (d *DotGit) Object(h plumbing.Hash) (billy.File, error) {
318336
// ObjectStat returns a os.FileInfo pointing the object file, if exists
319337
func (d *DotGit) ObjectStat(h plumbing.Hash) (os.FileInfo, error) {
320338
obj1, err1 := d.fs.Stat(d.objectPath(h))
321-
if os.IsNotExist(err1) {
339+
if os.IsNotExist(err1) && d.hasIncomingObjects() {
322340
obj2, err2 := d.fs.Stat(d.incomingObjectPath(h))
323341
if err2 != nil {
324342
return obj1, err1
@@ -331,7 +349,7 @@ func (d *DotGit) ObjectStat(h plumbing.Hash) (os.FileInfo, error) {
331349
// ObjectDelete removes the object file, if exists
332350
func (d *DotGit) ObjectDelete(h plumbing.Hash) error {
333351
err1 := d.fs.Remove(d.objectPath(h))
334-
if os.IsNotExist(err1) {
352+
if os.IsNotExist(err1) && d.hasIncomingObjects() {
335353
err2 := d.fs.Remove(d.incomingObjectPath(h))
336354
if err2 != nil {
337355
return err1

0 commit comments

Comments
 (0)