aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartek Jaroszewski <jaroszewskibartek@gmail.com>2018-07-18 11:43:00 +0200
committerSantiago M. Mola <santi@mola.io>2018-10-30 11:43:00 +0100
commit507681b9a317a91c176460b6aaff1915ba4b9533 (patch)
treeca2f6f6d77dfa9366746f820b32bec2c30d16133
parentdfd6c820e3dc7477eaaf517d4ad3b34b62e6c42e (diff)
downloadgo-git-507681b9a317a91c176460b6aaff1915ba4b9533.tar.gz
repository: added cleanup for the PlainCloneContext()
Signed-off-by: Bartek Jaroszewski <jaroszewskibartek@gmail.com>
-rw-r--r--repository.go60
-rw-r--r--repository_test.go48
2 files changed, 102 insertions, 6 deletions
diff --git a/repository.go b/repository.go
index 507ff44..bb89b28 100644
--- a/repository.go
+++ b/repository.go
@@ -5,6 +5,7 @@ import (
"context"
"errors"
"fmt"
+ "io"
stdioutil "io/ioutil"
"os"
"path"
@@ -50,6 +51,7 @@ var (
ErrIsBareRepository = errors.New("worktree not available in a bare repository")
ErrUnableToResolveCommit = errors.New("unable to resolve commit")
ErrPackedObjectsNotSupported = errors.New("Packed objects not supported")
+ ErrDirNotEmpty = errors.New("directory is not empty")
)
// Repository represents a git repository
@@ -342,12 +344,68 @@ func PlainClone(path string, isBare bool, o *CloneOptions) (*Repository, error)
//
// TODO(mcuadros): move isBare to CloneOptions in v5
func PlainCloneContext(ctx context.Context, path string, isBare bool, o *CloneOptions) (*Repository, error) {
+ dirEmpty := false
+ dirExist := false
+
+ file, err := os.Stat(path)
+ if err != nil {
+ return nil, err
+ }
+
+ if !os.IsNotExist(err) {
+ dirExist = file.IsDir()
+ }
+
+ if dirExist {
+ fh, err := os.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ defer fh.Close()
+
+ names, err := fh.Readdirnames(1)
+ if err != io.EOF && err != nil {
+ return nil, err
+ }
+ if len(names) == 0 {
+ dirEmpty = true
+ } else {
+ return nil, ErrDirNotEmpty
+ }
+ }
+
r, err := PlainInit(path, isBare)
if err != nil {
return nil, err
}
- return r, r.clone(ctx, o)
+ err = r.clone(ctx, o)
+ if err != nil && err != ErrRepositoryAlreadyExists {
+ if dirEmpty {
+ fh, err := os.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ defer fh.Close()
+
+ names, err := fh.Readdirnames(-1)
+ if err != nil && err != io.EOF {
+ return nil, err
+ }
+
+ for _, name := range names {
+ err = os.RemoveAll(filepath.Join(path, name))
+ if err != nil {
+ return nil, err
+ }
+ }
+ } else if !dirExist {
+ os.RemoveAll(path)
+ return nil, err
+ }
+ }
+
+ return r, err
}
func newRepository(s storage.Storer, worktree billy.Filesystem) *Repository {
diff --git a/repository_test.go b/repository_test.go
index 07c3570..887901f 100644
--- a/repository_test.go
+++ b/repository_test.go
@@ -581,17 +581,55 @@ func (s *RepositorySuite) TestPlainCloneWithRemoteName(c *C) {
c.Assert(remote, NotNil)
}
-func (s *RepositorySuite) TestPlainCloneContext(c *C) {
+func (s *RepositorySuite) TestPlainCloneContextWithProperParameters(c *C) {
ctx, cancel := context.WithCancel(context.Background())
cancel()
- _, err := PlainCloneContext(ctx, c.MkDir(), false, &CloneOptions{
+ r, err := PlainCloneContext(ctx, c.MkDir(), false, &CloneOptions{
URL: s.GetBasicLocalRepositoryURL(),
})
+ c.Assert(r, NotNil)
c.Assert(err, NotNil)
}
+func (s *RepositorySuite) TestPlainCloneContextWithIncorrectRepo(c *C) {
+ ctx, cancel := context.WithCancel(context.Background())
+ cancel()
+
+ tmpDir := c.MkDir()
+ repoDir := filepath.Join(tmpDir, "repoDir")
+ r, err := PlainCloneContext(ctx, repoDir, false, &CloneOptions{
+ URL: "incorrectOnPurpose",
+ })
+ c.Assert(r, IsNil)
+ c.Assert(err, NotNil)
+
+ _, err = os.Stat(repoDir)
+ dirNotExist := os.IsNotExist(err)
+ c.Assert(dirNotExist, Equals, true)
+}
+
+func (s *RepositorySuite) TestPlainCloneContextWithNotEmptyDir(c *C) {
+ ctx, cancel := context.WithCancel(context.Background())
+ cancel()
+
+ tmpDir := c.MkDir()
+ repoDirPath := filepath.Join(tmpDir, "repoDir")
+ err := os.Mkdir(repoDirPath, 0777)
+ c.Assert(err, IsNil)
+
+ dummyFile := filepath.Join(repoDirPath, "dummyFile")
+ err = ioutil.WriteFile(dummyFile, []byte(fmt.Sprint("dummyContent")), 0644)
+ c.Assert(err, IsNil)
+
+ r, err := PlainCloneContext(ctx, repoDirPath, false, &CloneOptions{
+ URL: "incorrectOnPurpose",
+ })
+ c.Assert(r, IsNil)
+ c.Assert(err, Equals, ErrDirNotEmpty)
+}
+
func (s *RepositorySuite) TestPlainCloneWithRecurseSubmodules(c *C) {
if testing.Short() {
c.Skip("skipping test in short mode.")
@@ -2104,9 +2142,9 @@ func (s *RepositorySuite) TestResolveRevisionWithErrors(c *C) {
c.Assert(err, IsNil)
datas := map[string]string{
- "efs/heads/master~": "reference not found",
- "HEAD^3": `Revision invalid : "3" found must be 0, 1 or 2 after "^"`,
- "HEAD^{/whatever}": `No commit message match regexp : "whatever"`,
+ "efs/heads/master~": "reference not found",
+ "HEAD^3": `Revision invalid : "3" found must be 0, 1 or 2 after "^"`,
+ "HEAD^{/whatever}": `No commit message match regexp : "whatever"`,
"4e1243bd22c66e76c2ba9eddc1f91394e57f9f83": "reference not found",
"918c48b83bd081e863dbe1b80f8998f058cd8294": `refname "918c48b83bd081e863dbe1b80f8998f058cd8294" is ambiguous`,
}