From b3b6e51565dcdbf81546f1d8f0121874a4e4fce9 Mon Sep 17 00:00:00 2001 From: Máximo Cuadros Date: Sun, 12 Feb 2017 23:03:47 +0100 Subject: submodule init implementation --- repository.go | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'repository.go') diff --git a/repository.go b/repository.go index a8dd7ef..2f5ff82 100644 --- a/repository.go +++ b/repository.go @@ -10,6 +10,7 @@ import ( "srcd.works/go-git.v4/plumbing" "srcd.works/go-git.v4/plumbing/object" "srcd.works/go-git.v4/plumbing/storer" + "srcd.works/go-git.v4/storage" "srcd.works/go-git.v4/storage/filesystem" "srcd.works/go-billy.v1" @@ -29,7 +30,7 @@ var ( // Repository represents a git repository type Repository struct { - Storer Storer + Storer storage.Storer r map[string]*Remote wt billy.Filesystem @@ -38,7 +39,7 @@ type Repository struct { // Init creates an empty git repository, based on the given Storer and worktree. // The worktree Filesystem is optional, if nil a bare repository is created. If // the given storer is not empty ErrRepositoryAlreadyExists is returned -func Init(s Storer, worktree billy.Filesystem) (*Repository, error) { +func Init(s storage.Storer, worktree billy.Filesystem) (*Repository, error) { r := newRepository(s, worktree) _, err := r.Reference(plumbing.HEAD, false) switch err { @@ -66,7 +67,7 @@ func Init(s Storer, worktree billy.Filesystem) (*Repository, error) { // The worktree can be nil when the repository being opened is bare, if the // repository is a normal one (not bare) and worktree is nil the err // ErrWorktreeNotProvided is returned -func Open(s Storer, worktree billy.Filesystem) (*Repository, error) { +func Open(s storage.Storer, worktree billy.Filesystem) (*Repository, error) { _, err := s.Reference(plumbing.HEAD) if err == plumbing.ErrReferenceNotFound { return nil, ErrRepositoryNotExists @@ -91,7 +92,7 @@ func Open(s Storer, worktree billy.Filesystem) (*Repository, error) { // Clone a repository into the given Storer and worktree Filesystem with the // given options, if worktree is nil a bare repository is created. If the given // storer is not empty ErrRepositoryAlreadyExists is returned -func Clone(s Storer, worktree billy.Filesystem, o *CloneOptions) (*Repository, error) { +func Clone(s storage.Storer, worktree billy.Filesystem, o *CloneOptions) (*Repository, error) { r, err := Init(s, worktree) if err != nil { return nil, err @@ -159,7 +160,7 @@ func PlainClone(path string, isBare bool, o *CloneOptions) (*Repository, error) return r, r.clone(o) } -func newRepository(s Storer, worktree billy.Filesystem) *Repository { +func newRepository(s storage.Storer, worktree billy.Filesystem) *Repository { return &Repository{ Storer: s, wt: worktree, @@ -247,12 +248,6 @@ func (r *Repository) clone(o *CloneOptions) error { return err } - // marks the repository as bare in the config, until we have Worktree, all - // the repository are bare - if err := r.setIsBare(true); err != nil { - return err - } - c := &config.RemoteConfig{ Name: o.RemoteName, URL: o.URL, @@ -270,11 +265,13 @@ func (r *Repository) clone(o *CloneOptions) error { Progress: o.Progress, }) if err != nil { + return err } head, err := storer.ResolveReference(remoteRefs, o.ReferenceName) if err != nil { + return err } @@ -283,12 +280,33 @@ func (r *Repository) clone(o *CloneOptions) error { } if err := r.updateWorktree(); err != nil { + fmt.Println("q", err) return err } + if o.RecursiveSubmodules && r.wt != nil { + if err := r.initSubmodules(); err != nil { + return err + } + } + return r.updateRemoteConfig(remote, o, c, head) } +func (r *Repository) initSubmodules() error { + w, err := r.Worktree() + if err != nil { + return err + } + + s, err := w.Submodules() + if err != nil { + return err + } + + return s.Init() +} + func (r *Repository) cloneRefSpec(o *CloneOptions, c *config.RemoteConfig) []config.RefSpec { -- cgit From 65351f835dcaa4b50dd44bce7bf3f2e31582dadc Mon Sep 17 00:00:00 2001 From: Máximo Cuadros Date: Mon, 13 Feb 2017 23:59:49 +0100 Subject: Repository.Init now handles non-standard .git location --- repository.go | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) (limited to 'repository.go') diff --git a/repository.go b/repository.go index 2f5ff82..4c184ab 100644 --- a/repository.go +++ b/repository.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "os" + "path/filepath" "srcd.works/go-git.v4/config" "srcd.works/go-git.v4/internal/revision" @@ -57,9 +58,75 @@ func Init(s storage.Storer, worktree billy.Filesystem) (*Repository, error) { if worktree == nil { r.setIsBare(true) + return r, nil } - return r, nil + return r, setWorktreeAndStoragePaths(r, worktree) +} + +func setWorktreeAndStoragePaths(r *Repository, worktree billy.Filesystem) error { + type fsBased interface { + Filesystem() billy.Filesystem + } + + // .git file is only created if the storage is file based and the file + // system is osfs.OS + fs, isFSBased := r.Storer.(fsBased) + if !isFSBased { + return nil + } + + _, isOS := fs.Filesystem().(*osfs.OS) + if !isOS { + return nil + } + + if err := createDotGitFile(worktree, fs.Filesystem()); err != nil { + return err + } + + return setConfigWorktree(r, worktree, fs.Filesystem()) +} + +func createDotGitFile(worktree, storage billy.Filesystem) error { + path, err := filepath.Rel(worktree.Base(), storage.Base()) + if err != nil { + path = storage.Base() + } + + if path == ".git" { + // not needed, since the folder is the default place + return nil + } + + f, err := worktree.Create(".git") + if err != nil { + return err + } + + defer f.Close() + _, err = fmt.Fprintf(f, "gitdir: %s\n", path) + return err +} + +func setConfigWorktree(r *Repository, worktree, storage billy.Filesystem) error { + path, err := filepath.Rel(storage.Base(), worktree.Base()) + if err != nil { + path = worktree.Base() + } + + if path == ".." { + // not needed, since the folder is the default place + return nil + } + + cfg, err := r.Storer.Config() + if err != nil { + return err + } + + cfg.Core.Worktree = path + return r.Storer.SetConfig(cfg) } // Open opens a git repository using the given Storer and worktree filesystem, @@ -280,7 +347,6 @@ func (r *Repository) clone(o *CloneOptions) error { } if err := r.updateWorktree(); err != nil { - fmt.Println("q", err) return err } -- cgit From d6a6decd1be0515faf36256ce06c58c7d662bbd0 Mon Sep 17 00:00:00 2001 From: Máximo Cuadros Date: Tue, 14 Feb 2017 19:26:32 +0100 Subject: submodule update implementation --- repository.go | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'repository.go') diff --git a/repository.go b/repository.go index 4c184ab..9969b86 100644 --- a/repository.go +++ b/repository.go @@ -350,8 +350,8 @@ func (r *Repository) clone(o *CloneOptions) error { return err } - if o.RecursiveSubmodules && r.wt != nil { - if err := r.initSubmodules(); err != nil { + if o.RecurseSubmodules != NoRecursivity && r.wt != nil { + if err := r.updateSubmodules(o.RecurseSubmodules); err != nil { return err } } @@ -359,7 +359,7 @@ func (r *Repository) clone(o *CloneOptions) error { return r.updateRemoteConfig(remote, o, c, head) } -func (r *Repository) initSubmodules() error { +func (r *Repository) updateSubmodules(recursion SubmoduleRescursivity) error { w, err := r.Worktree() if err != nil { return err @@ -370,7 +370,10 @@ func (r *Repository) initSubmodules() error { return err } - return s.Init() + return s.Update(&SubmoduleUpdateOptions{ + Init: true, + RecurseSubmodules: recursion, + }) } func (r *Repository) cloneRefSpec(o *CloneOptions, @@ -546,7 +549,17 @@ func (r *Repository) Pull(o *PullOptions) error { return NoErrAlreadyUpToDate } - return r.updateWorktree() + if err := r.updateWorktree(); err != nil { + return err + } + + if o.RecurseSubmodules != NoRecursivity && r.wt != nil { + if err := r.updateSubmodules(o.RecurseSubmodules); err != nil { + return err + } + } + + return nil } func (r *Repository) updateWorktree() error { -- cgit From ed288b30de1ac3dcb3ce675c4b9af89eb4e6fcba Mon Sep 17 00:00:00 2001 From: Máximo Cuadros Date: Tue, 21 Feb 2017 16:03:39 +0100 Subject: documentation and API improvements --- repository.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'repository.go') diff --git a/repository.go b/repository.go index 9969b86..c065a26 100644 --- a/repository.go +++ b/repository.go @@ -332,13 +332,11 @@ func (r *Repository) clone(o *CloneOptions) error { Progress: o.Progress, }) if err != nil { - return err } head, err := storer.ResolveReference(remoteRefs, o.ReferenceName) if err != nil { - return err } @@ -350,7 +348,7 @@ func (r *Repository) clone(o *CloneOptions) error { return err } - if o.RecurseSubmodules != NoRecursivity && r.wt != nil { + if o.RecurseSubmodules != NoRecurseSubmodules && r.wt != nil { if err := r.updateSubmodules(o.RecurseSubmodules); err != nil { return err } @@ -553,7 +551,7 @@ func (r *Repository) Pull(o *PullOptions) error { return err } - if o.RecurseSubmodules != NoRecursivity && r.wt != nil { + if o.RecurseSubmodules != NoRecurseSubmodules && r.wt != nil { if err := r.updateSubmodules(o.RecurseSubmodules); err != nil { return err } -- cgit