aboutsummaryrefslogtreecommitdiffstats
path: root/worktree.go
diff options
context:
space:
mode:
authorMáximo Cuadros <mcuadros@gmail.com>2017-02-14 00:25:09 +0100
committerMáximo Cuadros <mcuadros@gmail.com>2017-02-14 00:25:09 +0100
commit7e990a811d9e23b5a3573c405b70f06a1be9e7b6 (patch)
tree5cf329829edb41a562319f6242c13e90e350d365 /worktree.go
parent65351f835dcaa4b50dd44bce7bf3f2e31582dadc (diff)
downloadgo-git-7e990a811d9e23b5a3573c405b70f06a1be9e7b6.tar.gz
submodule init and update implementation
Diffstat (limited to 'worktree.go')
-rw-r--r--worktree.go79
1 files changed, 60 insertions, 19 deletions
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