6161// type is not zero-value-safe, use the New function to initialize it.
6262type 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
287294func (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
306324func (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
319337func (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
332350func (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