Skip to content

Commit 507681b

Browse files
bjaroszewskismola
authored andcommitted
repository: added cleanup for the PlainCloneContext()
Signed-off-by: Bartek Jaroszewski <[email protected]>
1 parent dfd6c82 commit 507681b

File tree

2 files changed

+102
-6
lines changed

2 files changed

+102
-6
lines changed

Diff for: repository.go

+59-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"context"
66
"errors"
77
"fmt"
8+
"io"
89
stdioutil "io/ioutil"
910
"os"
1011
"path"
@@ -50,6 +51,7 @@ var (
5051
ErrIsBareRepository = errors.New("worktree not available in a bare repository")
5152
ErrUnableToResolveCommit = errors.New("unable to resolve commit")
5253
ErrPackedObjectsNotSupported = errors.New("Packed objects not supported")
54+
ErrDirNotEmpty = errors.New("directory is not empty")
5355
)
5456

5557
// Repository represents a git repository
@@ -342,12 +344,68 @@ func PlainClone(path string, isBare bool, o *CloneOptions) (*Repository, error)
342344
//
343345
// TODO(mcuadros): move isBare to CloneOptions in v5
344346
func PlainCloneContext(ctx context.Context, path string, isBare bool, o *CloneOptions) (*Repository, error) {
347+
dirEmpty := false
348+
dirExist := false
349+
350+
file, err := os.Stat(path)
351+
if err != nil {
352+
return nil, err
353+
}
354+
355+
if !os.IsNotExist(err) {
356+
dirExist = file.IsDir()
357+
}
358+
359+
if dirExist {
360+
fh, err := os.Open(path)
361+
if err != nil {
362+
return nil, err
363+
}
364+
defer fh.Close()
365+
366+
names, err := fh.Readdirnames(1)
367+
if err != io.EOF && err != nil {
368+
return nil, err
369+
}
370+
if len(names) == 0 {
371+
dirEmpty = true
372+
} else {
373+
return nil, ErrDirNotEmpty
374+
}
375+
}
376+
345377
r, err := PlainInit(path, isBare)
346378
if err != nil {
347379
return nil, err
348380
}
349381

350-
return r, r.clone(ctx, o)
382+
err = r.clone(ctx, o)
383+
if err != nil && err != ErrRepositoryAlreadyExists {
384+
if dirEmpty {
385+
fh, err := os.Open(path)
386+
if err != nil {
387+
return nil, err
388+
}
389+
defer fh.Close()
390+
391+
names, err := fh.Readdirnames(-1)
392+
if err != nil && err != io.EOF {
393+
return nil, err
394+
}
395+
396+
for _, name := range names {
397+
err = os.RemoveAll(filepath.Join(path, name))
398+
if err != nil {
399+
return nil, err
400+
}
401+
}
402+
} else if !dirExist {
403+
os.RemoveAll(path)
404+
return nil, err
405+
}
406+
}
407+
408+
return r, err
351409
}
352410

353411
func newRepository(s storage.Storer, worktree billy.Filesystem) *Repository {

Diff for: repository_test.go

+43-5
Original file line numberDiff line numberDiff line change
@@ -581,17 +581,55 @@ func (s *RepositorySuite) TestPlainCloneWithRemoteName(c *C) {
581581
c.Assert(remote, NotNil)
582582
}
583583

584-
func (s *RepositorySuite) TestPlainCloneContext(c *C) {
584+
func (s *RepositorySuite) TestPlainCloneContextWithProperParameters(c *C) {
585585
ctx, cancel := context.WithCancel(context.Background())
586586
cancel()
587587

588-
_, err := PlainCloneContext(ctx, c.MkDir(), false, &CloneOptions{
588+
r, err := PlainCloneContext(ctx, c.MkDir(), false, &CloneOptions{
589589
URL: s.GetBasicLocalRepositoryURL(),
590590
})
591591

592+
c.Assert(r, NotNil)
592593
c.Assert(err, NotNil)
593594
}
594595

596+
func (s *RepositorySuite) TestPlainCloneContextWithIncorrectRepo(c *C) {
597+
ctx, cancel := context.WithCancel(context.Background())
598+
cancel()
599+
600+
tmpDir := c.MkDir()
601+
repoDir := filepath.Join(tmpDir, "repoDir")
602+
r, err := PlainCloneContext(ctx, repoDir, false, &CloneOptions{
603+
URL: "incorrectOnPurpose",
604+
})
605+
c.Assert(r, IsNil)
606+
c.Assert(err, NotNil)
607+
608+
_, err = os.Stat(repoDir)
609+
dirNotExist := os.IsNotExist(err)
610+
c.Assert(dirNotExist, Equals, true)
611+
}
612+
613+
func (s *RepositorySuite) TestPlainCloneContextWithNotEmptyDir(c *C) {
614+
ctx, cancel := context.WithCancel(context.Background())
615+
cancel()
616+
617+
tmpDir := c.MkDir()
618+
repoDirPath := filepath.Join(tmpDir, "repoDir")
619+
err := os.Mkdir(repoDirPath, 0777)
620+
c.Assert(err, IsNil)
621+
622+
dummyFile := filepath.Join(repoDirPath, "dummyFile")
623+
err = ioutil.WriteFile(dummyFile, []byte(fmt.Sprint("dummyContent")), 0644)
624+
c.Assert(err, IsNil)
625+
626+
r, err := PlainCloneContext(ctx, repoDirPath, false, &CloneOptions{
627+
URL: "incorrectOnPurpose",
628+
})
629+
c.Assert(r, IsNil)
630+
c.Assert(err, Equals, ErrDirNotEmpty)
631+
}
632+
595633
func (s *RepositorySuite) TestPlainCloneWithRecurseSubmodules(c *C) {
596634
if testing.Short() {
597635
c.Skip("skipping test in short mode.")
@@ -2104,9 +2142,9 @@ func (s *RepositorySuite) TestResolveRevisionWithErrors(c *C) {
21042142
c.Assert(err, IsNil)
21052143

21062144
datas := map[string]string{
2107-
"efs/heads/master~": "reference not found",
2108-
"HEAD^3": `Revision invalid : "3" found must be 0, 1 or 2 after "^"`,
2109-
"HEAD^{/whatever}": `No commit message match regexp : "whatever"`,
2145+
"efs/heads/master~": "reference not found",
2146+
"HEAD^3": `Revision invalid : "3" found must be 0, 1 or 2 after "^"`,
2147+
"HEAD^{/whatever}": `No commit message match regexp : "whatever"`,
21102148
"4e1243bd22c66e76c2ba9eddc1f91394e57f9f83": "reference not found",
21112149
"918c48b83bd081e863dbe1b80f8998f058cd8294": `refname "918c48b83bd081e863dbe1b80f8998f058cd8294" is ambiguous`,
21122150
}

0 commit comments

Comments
 (0)