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 --- worktree.go | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'worktree.go') diff --git a/worktree.go b/worktree.go index 58e008e..8aee0dc 100644 --- a/worktree.go +++ b/worktree.go @@ -4,8 +4,10 @@ import ( "errors" "fmt" "io" + "io/ioutil" "os" + "srcd.works/go-git.v4/config" "srcd.works/go-git.v4/plumbing" "srcd.works/go-git.v4/plumbing/format/index" "srcd.works/go-git.v4/plumbing/object" @@ -104,6 +106,7 @@ func (w *Worktree) Status() (Status, error) { files, err := readDirAll(w.fs) if err != nil { + fmt.Println("ch", err) return nil, err } @@ -167,6 +170,61 @@ func (w *Worktree) getMode(fi billy.FileInfo) os.FileMode { return object.FileMode } +const gitmodulesFile = ".gitmodules" + +func (w *Worktree) Submodules() (Submodules, error) { + l := make(Submodules, 0) + m, err := w.readGitmodulesFile() + if err != nil || m == nil { + return l, err + } + + for _, c := range m.Submodules { + s, err := w.newSubmodule(c) + if err != nil { + return nil, err + } + + l = append(l, s) + } + + return l, nil +} + +func (w *Worktree) newSubmodule(m *config.Submodule) (*Submodule, error) { + s, err := w.r.Storer.Module(m.Name) + if err != nil { + return nil, err + } + + return &Submodule{ + Name: m.Name, + URL: m.URL, + + r: newRepository(s, w.fs.Dir(m.Path)), + }, nil +} + +func (w *Worktree) readGitmodulesFile() (*config.Modules, error) { + f, err := w.fs.Open(gitmodulesFile) + if err != nil { + if os.IsNotExist(err) { + return nil, nil + } + + return nil, err + } + + input, err := ioutil.ReadAll(f) + if err != nil { + return nil, err + } + + m := config.NewModules() + return m, m.Unmarshal(input) + +} + // Status current status of a Worktree type Status map[string]*FileStatus @@ -287,6 +345,10 @@ func doReadDirAll(fs billy.Filesystem, path string, files map[string]billy.FileI l, err := fs.ReadDir(path) if err != nil { + if os.IsNotExist(err) { + return nil + } + return err } -- cgit From c551c29a93882658d4b34860b5300de0f3456059 Mon Sep 17 00:00:00 2001 From: Máximo Cuadros Date: Mon, 13 Feb 2017 00:40:14 +0100 Subject: submodule init implementation --- worktree.go | 58 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 10 deletions(-) (limited to 'worktree.go') diff --git a/worktree.go b/worktree.go index 8aee0dc..473f933 100644 --- a/worktree.go +++ b/worktree.go @@ -37,29 +37,57 @@ func (w *Worktree) Checkout(commit plumbing.Hash) error { return err } - files, err := c.Files() + t, err := c.Tree() if err != nil { return err } idx := &index.Index{Version: 2} - if err := files.ForEach(func(f *object.File) error { - return w.checkoutFile(f, idx) - }); err != nil { - return err + walker := object.NewTreeWalker(t, true) + + for { + _, entry, err := walker.Next() + if err == io.EOF { + break + } + + if err != nil { + return err + } + + if err := w.checkoutEntry(&entry, idx); err != nil { + return err + } } return w.r.Storer.SetIndex(idx) } -func (w *Worktree) checkoutFile(f *object.File, idx *index.Index) error { - from, err := f.Reader() +func (w *Worktree) checkoutEntry(e *object.TreeEntry, idx *index.Index) error { + if e.Mode == object.SubmoduleMode { + return w.indexEntry(e, idx) + } + + if e.Mode.IsDir() { + return nil + } + + return w.checkoutFile(e, idx) +} + +func (w *Worktree) checkoutFile(e *object.TreeEntry, idx *index.Index) error { + blob, err := object.GetBlob(w.r.Storer, e.Hash) + if err != nil { + return err + } + + from, err := blob.Reader() if err != nil { return err } defer from.Close() - to, err := w.fs.OpenFile(f.Name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode.Perm()) + to, err := w.fs.OpenFile(e.Name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, e.Mode.Perm()) if err != nil { return err } @@ -69,12 +97,22 @@ func (w *Worktree) checkoutFile(f *object.File, idx *index.Index) error { } defer to.Close() - return w.indexFile(f, idx) + return w.indexFile(e, idx) } var fillSystemInfo func(e *index.Entry, sys interface{}) -func (w *Worktree) indexFile(f *object.File, idx *index.Index) error { +func (w *Worktree) indexEntry(f *object.TreeEntry, idx *index.Index) error { + idx.Entries = append(idx.Entries, index.Entry{ + Hash: f.Hash, + Name: f.Name, + Mode: object.SubmoduleMode, + }) + + return nil +} + +func (w *Worktree) indexFile(f *object.TreeEntry, idx *index.Index) error { fi, err := w.fs.Stat(f.Name) if err != nil { return err -- cgit From 7e990a811d9e23b5a3573c405b70f06a1be9e7b6 Mon Sep 17 00:00:00 2001 From: Máximo Cuadros Date: Tue, 14 Feb 2017 00:25:09 +0100 Subject: submodule init and update implementation --- worktree.go | 79 ++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 19 deletions(-) (limited to 'worktree.go') diff --git a/worktree.go b/worktree.go index 473f933..2a5b58a 100644 --- a/worktree.go +++ b/worktree.go @@ -16,6 +16,7 @@ import ( ) var ErrWorktreeNotClean = errors.New("worktree is not clean") +var ErrSubmoduleNotFound = errors.New("submodule not found") type Worktree struct { r *Repository @@ -46,7 +47,7 @@ func (w *Worktree) Checkout(commit plumbing.Hash) error { walker := object.NewTreeWalker(t, true) for { - _, entry, err := walker.Next() + name, entry, err := walker.Next() if err == io.EOF { break } @@ -55,7 +56,7 @@ func (w *Worktree) Checkout(commit plumbing.Hash) error { return err } - if err := w.checkoutEntry(&entry, idx); err != nil { + if err := w.checkoutEntry(name, &entry, idx); err != nil { return err } } @@ -63,19 +64,19 @@ func (w *Worktree) Checkout(commit plumbing.Hash) error { return w.r.Storer.SetIndex(idx) } -func (w *Worktree) checkoutEntry(e *object.TreeEntry, idx *index.Index) error { +func (w *Worktree) checkoutEntry(name string, e *object.TreeEntry, idx *index.Index) error { if e.Mode == object.SubmoduleMode { - return w.indexEntry(e, idx) + return w.addIndexFromTreeEntry(name, e, idx) } if e.Mode.IsDir() { return nil } - return w.checkoutFile(e, idx) + return w.checkoutFile(name, e, idx) } -func (w *Worktree) checkoutFile(e *object.TreeEntry, idx *index.Index) error { +func (w *Worktree) checkoutFile(name string, e *object.TreeEntry, idx *index.Index) error { blob, err := object.GetBlob(w.r.Storer, e.Hash) if err != nil { return err @@ -87,7 +88,7 @@ func (w *Worktree) checkoutFile(e *object.TreeEntry, idx *index.Index) error { } defer from.Close() - to, err := w.fs.OpenFile(e.Name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, e.Mode.Perm()) + to, err := w.fs.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, e.Mode.Perm()) if err != nil { return err } @@ -97,30 +98,30 @@ func (w *Worktree) checkoutFile(e *object.TreeEntry, idx *index.Index) error { } defer to.Close() - return w.indexFile(e, idx) + return w.addIndexFromFile(name, e, idx) } var fillSystemInfo func(e *index.Entry, sys interface{}) -func (w *Worktree) indexEntry(f *object.TreeEntry, idx *index.Index) error { +func (w *Worktree) addIndexFromTreeEntry(name string, f *object.TreeEntry, idx *index.Index) error { idx.Entries = append(idx.Entries, index.Entry{ Hash: f.Hash, - Name: f.Name, + Name: name, Mode: object.SubmoduleMode, }) return nil } -func (w *Worktree) indexFile(f *object.TreeEntry, idx *index.Index) error { - fi, err := w.fs.Stat(f.Name) +func (w *Worktree) addIndexFromFile(name string, f *object.TreeEntry, idx *index.Index) error { + fi, err := w.fs.Stat(name) if err != nil { return err } e := index.Entry{ Hash: f.Hash, - Name: f.Name, + Name: name, Mode: w.getMode(fi), ModifiedAt: fi.ModTime(), Size: uint32(fi.Size()), @@ -144,7 +145,6 @@ func (w *Worktree) Status() (Status, error) { files, err := readDirAll(w.fs) if err != nil { - fmt.Println("ch", err) return nil, err } @@ -210,6 +210,22 @@ func (w *Worktree) getMode(fi billy.FileInfo) os.FileMode { const gitmodulesFile = ".gitmodules" +// Submodule returns the submodule with the given name +func (w *Worktree) Submodule(name string) (*Submodule, error) { + m, err := w.readGitmodulesFile() + if err != nil || m == nil { + return nil, err + } + + c, ok := m.Submodules[name] + if !ok { + return nil, ErrSubmoduleNotFound + } + + return w.newSubmodule(c) +} + +// Submodules returns all the available submodules func (w *Worktree) Submodules() (Submodules, error) { l := make(Submodules, 0) m, err := w.readGitmodulesFile() @@ -235,11 +251,15 @@ func (w *Worktree) newSubmodule(m *config.Submodule) (*Submodule, error) { return nil, err } - return &Submodule{ - Name: m.Name, - URL: m.URL, + r, err := Init(s, w.fs.Dir(m.Path)) + if err != nil { + return nil, err + } - r: newRepository(s, w.fs.Dir(m.Path)), + return &Submodule{ + m: m, + w: w, + r: r, }, nil } @@ -263,6 +283,23 @@ func (w *Worktree) readGitmodulesFile() (*config.Modules, error) { } +func (w *Worktree) readIndexEntry(path string) (index.Entry, error) { + var e index.Entry + + idx, err := w.r.Storer.Index() + if err != nil { + return e, err + } + + for _, e := range idx.Entries { + if e.Name == path { + return e, nil + } + } + + return e, fmt.Errorf("unable to find %q entry in the index", path) +} + // Status current status of a Worktree type Status map[string]*FileStatus @@ -377,7 +414,7 @@ func readDirAll(filesystem billy.Filesystem) (map[string]billy.FileInfo, error) } func doReadDirAll(fs billy.Filesystem, path string, files map[string]billy.FileInfo) error { - if path == ".git" { + if path == defaultDotGitPath { return nil } @@ -392,6 +429,10 @@ func doReadDirAll(fs billy.Filesystem, path string, files map[string]billy.FileI for _, info := range l { file := fs.Join(path, info.Name()) + if file == defaultDotGitPath { + continue + } + if !info.IsDir() { files[file] = info continue -- 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 --- worktree.go | 45 +++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 26 deletions(-) (limited to 'worktree.go') diff --git a/worktree.go b/worktree.go index 2a5b58a..2514a0c 100644 --- a/worktree.go +++ b/worktree.go @@ -212,17 +212,18 @@ const gitmodulesFile = ".gitmodules" // Submodule returns the submodule with the given name func (w *Worktree) Submodule(name string) (*Submodule, error) { - m, err := w.readGitmodulesFile() - if err != nil || m == nil { + l, err := w.Submodules() + if err != nil { return nil, err } - c, ok := m.Submodules[name] - if !ok { - return nil, ErrSubmoduleNotFound + for _, m := range l { + if m.Config().Name == name { + return m, nil + } } - return w.newSubmodule(c) + return nil, ErrSubmoduleNotFound } // Submodules returns all the available submodules @@ -233,34 +234,26 @@ func (w *Worktree) Submodules() (Submodules, error) { return l, err } - for _, c := range m.Submodules { - s, err := w.newSubmodule(c) - if err != nil { - return nil, err - } - - l = append(l, s) + c, err := w.r.Config() + for _, s := range m.Submodules { + l = append(l, w.newSubmodule(s, c.Submodules[s.Name])) } return l, nil } -func (w *Worktree) newSubmodule(m *config.Submodule) (*Submodule, error) { - s, err := w.r.Storer.Module(m.Name) - if err != nil { - return nil, err - } +func (w *Worktree) newSubmodule(fromModules, fromConfig *config.Submodule) *Submodule { + m := &Submodule{w: w} + m.initialized = fromConfig != nil - r, err := Init(s, w.fs.Dir(m.Path)) - if err != nil { - return nil, err + if !m.initialized { + m.c = fromModules + return m } - return &Submodule{ - m: m, - w: w, - r: r, - }, nil + m.c = fromConfig + m.c.Path = fromModules.Path + return m } func (w *Worktree) readGitmodulesFile() (*config.Modules, 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 --- worktree.go | 1 - 1 file changed, 1 deletion(-) (limited to 'worktree.go') diff --git a/worktree.go b/worktree.go index 2514a0c..2a4e5d8 100644 --- a/worktree.go +++ b/worktree.go @@ -273,7 +273,6 @@ func (w *Worktree) readGitmodulesFile() (*config.Modules, error) { m := config.NewModules() return m, m.Unmarshal(input) - } func (w *Worktree) readIndexEntry(path string) (index.Entry, error) { -- cgit