aboutsummaryrefslogtreecommitdiff
path: root/modules/git
diff options
context:
space:
mode:
authorMichael Boke <michael@mbict.nl>2014-10-03 22:51:07 +0200
committerMichael Boke <michael@mbict.nl>2014-10-03 22:51:07 +0200
commitba1270df2d3d835b397317f133963e7b517242f1 (patch)
tree1265a142a1fd9951d30ae11648e7fbfb5806e594 /modules/git
parentba0feadc34400cb91ff23f66096884d862651cdd (diff)
parent405ee14711ab946bd709ec28a526890c40cbc03b (diff)
Merge remote-tracking branch 'upstream/master'
Conflicts: conf/app.ini
Diffstat (limited to 'modules/git')
-rw-r--r--modules/git/commit.go50
-rw-r--r--modules/git/repo_commit.go12
-rw-r--r--modules/git/repo_tag.go1
-rw-r--r--modules/git/submodule.go58
-rw-r--r--modules/git/tree.go7
-rw-r--r--modules/git/tree_entry.go6
-rw-r--r--modules/git/version.go76
7 files changed, 193 insertions, 17 deletions
diff --git a/modules/git/commit.go b/modules/git/commit.go
index 52348fef..d2d373da 100644
--- a/modules/git/commit.go
+++ b/modules/git/commit.go
@@ -5,6 +5,7 @@
package git
import (
+ "bufio"
"container/list"
"strings"
)
@@ -17,7 +18,8 @@ type Commit struct {
Committer *Signature
CommitMessage string
- parents []sha1 // sha1 strings
+ parents []sha1 // sha1 strings
+ submodules map[string]*SubModule
}
// Return the commit message. Same as retrieving CommitMessage directly.
@@ -84,3 +86,49 @@ func (c *Commit) CommitsByRange(page int) (*list.List, error) {
func (c *Commit) GetCommitOfRelPath(relPath string) (*Commit, error) {
return c.repo.getCommitOfRelPath(c.Id, relPath)
}
+
+func (c *Commit) GetSubModule(entryname string) (*SubModule, error) {
+ moduels, err := c.GetSubModules()
+ if err != nil {
+ return nil, err
+ }
+ return moduels[entryname], nil
+}
+
+func (c *Commit) GetSubModules() (map[string]*SubModule, error) {
+ if c.submodules != nil {
+ return c.submodules, nil
+ }
+
+ entry, err := c.GetTreeEntryByPath(".gitmodules")
+ if err != nil {
+ return nil, err
+ }
+ rd, err := entry.Blob().Data()
+ if err != nil {
+ return nil, err
+ }
+
+ scanner := bufio.NewScanner(rd)
+ c.submodules = make(map[string]*SubModule)
+ var ismodule bool
+ var path string
+ for scanner.Scan() {
+ if strings.HasPrefix(scanner.Text(), "[submodule") {
+ ismodule = true
+ continue
+ }
+ if ismodule {
+ fields := strings.Split(scanner.Text(), "=")
+ k := strings.TrimSpace(fields[0])
+ if k == "path" {
+ path = strings.TrimSpace(fields[1])
+ } else if k == "url" {
+ c.submodules[path] = &SubModule{path, strings.TrimSpace(fields[1])}
+ ismodule = false
+ }
+ }
+ }
+
+ return c.submodules, nil
+}
diff --git a/modules/git/repo_commit.go b/modules/git/repo_commit.go
index eebe3dd0..7c47b53d 100644
--- a/modules/git/repo_commit.go
+++ b/modules/git/repo_commit.go
@@ -40,11 +40,11 @@ func (repo *Repository) GetCommitIdOfTag(tagName string) (string, error) {
}
func (repo *Repository) GetCommitOfTag(tagName string) (*Commit, error) {
- commitId, err := repo.GetCommitIdOfTag(tagName)
+ tag, err := repo.GetTag(tagName)
if err != nil {
return nil, err
}
- return repo.GetCommit(commitId)
+ return tag.Commit()
}
// Parse commit information from the (uncompressed) raw
@@ -137,6 +137,14 @@ func (repo *Repository) GetCommit(commitId string) (*Commit, error) {
}
func (repo *Repository) commitsCount(id sha1) (int, error) {
+ if gitVer.LessThan(MustParseVersion("1.8.0")) {
+ stdout, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "log", "--pretty=format:''", id.String())
+ if err != nil {
+ return 0, errors.New(string(stderr))
+ }
+ return len(bytes.Split(stdout, []byte("\n"))), nil
+ }
+
stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "rev-list", "--count", id.String())
if err != nil {
return 0, errors.New(stderr)
diff --git a/modules/git/repo_tag.go b/modules/git/repo_tag.go
index 21818f3e..77ae3db0 100644
--- a/modules/git/repo_tag.go
+++ b/modules/git/repo_tag.go
@@ -52,6 +52,7 @@ func (repo *Repository) getTag(id sha1) (*Tag, error) {
if err != nil {
return nil, errors.New(stderr)
}
+ tp = strings.TrimSpace(tp)
// Tag is a commit.
if ObjectType(tp) == COMMIT {
diff --git a/modules/git/submodule.go b/modules/git/submodule.go
new file mode 100644
index 00000000..6927f8cb
--- /dev/null
+++ b/modules/git/submodule.go
@@ -0,0 +1,58 @@
+// Copyright 2014 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package git
+
+import (
+ "strings"
+)
+
+type SubModule struct {
+ Name string
+ Url string
+}
+
+// SubModuleFile represents a file with submodule type.
+type SubModuleFile struct {
+ *Commit
+
+ refUrl string
+ refId string
+}
+
+func NewSubModuleFile(c *Commit, refUrl, refId string) *SubModuleFile {
+ return &SubModuleFile{
+ Commit: c,
+ refUrl: refUrl,
+ refId: refId,
+ }
+}
+
+// RefUrl guesses and returns reference URL.
+func (sf *SubModuleFile) RefUrl() string {
+ url := strings.TrimSuffix(sf.refUrl, ".git")
+
+ // git://xxx/user/repo
+ if strings.HasPrefix(url, "git://") {
+ return "http://" + strings.TrimPrefix(url, "git://")
+ }
+
+ // http[s]://xxx/user/repo
+ if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
+ return url
+ }
+
+ // sysuser@xxx:user/repo
+ i := strings.Index(url, "@")
+ j := strings.LastIndex(url, ":")
+ if i > -1 && j > -1 {
+ return "http://" + url[i+1:j] + "/" + url[j+1:]
+ }
+ return url
+}
+
+// RefId returns reference ID.
+func (sf *SubModuleFile) RefId() string {
+ return sf.refId
+}
diff --git a/modules/git/tree.go b/modules/git/tree.go
index 03152c34..be77bfce 100644
--- a/modules/git/tree.go
+++ b/modules/git/tree.go
@@ -51,6 +51,8 @@ func parseTreeData(tree *Tree, data []byte) ([]*TreeEntry, error) {
case "160000":
entry.mode = ModeCommit
entry.Type = COMMIT
+
+ step = 8
case "040000":
entry.mode = ModeTree
entry.Type = TREE
@@ -107,9 +109,12 @@ func (t *Tree) ListEntries(relpath string) (Entries, error) {
}
t.entriesParsed = true
- stdout, _, err := com.ExecCmdDirBytes(t.repo.Path,
+ stdout, stderr, err := com.ExecCmdDirBytes(t.repo.Path,
"git", "ls-tree", t.Id.String())
if err != nil {
+ if strings.Contains(err.Error(), "exit status 128") {
+ return nil, errors.New(strings.TrimSpace(string(stderr)))
+ }
return nil, err
}
t.entries, err = parseTreeData(t, stdout)
diff --git a/modules/git/tree_entry.go b/modules/git/tree_entry.go
index e842f233..e403e93e 100644
--- a/modules/git/tree_entry.go
+++ b/modules/git/tree_entry.go
@@ -61,6 +61,10 @@ func (te *TreeEntry) Size() int64 {
return te.size
}
+func (te *TreeEntry) IsSubModule() bool {
+ return te.mode == ModeCommit
+}
+
func (te *TreeEntry) IsDir() bool {
return te.mode == ModeTree
}
@@ -80,7 +84,7 @@ type Entries []*TreeEntry
var sorter = []func(t1, t2 *TreeEntry) bool{
func(t1, t2 *TreeEntry) bool {
- return t1.IsDir() && !t2.IsDir()
+ return (t1.IsDir() || t1.IsSubModule()) && !t2.IsDir() && !t2.IsSubModule()
},
func(t1, t2 *TreeEntry) bool {
return t1.name < t2.name
diff --git a/modules/git/version.go b/modules/git/version.go
index 683e859b..9908d11e 100644
--- a/modules/git/version.go
+++ b/modules/git/version.go
@@ -11,33 +11,85 @@ import (
"github.com/Unknwon/com"
)
+var (
+ // Cached Git version.
+ gitVer *Version
+)
+
// Version represents version of Git.
type Version struct {
Major, Minor, Patch int
}
-// GetVersion returns current Git version installed.
-func GetVersion() (Version, error) {
- stdout, stderr, err := com.ExecCmd("git", "version")
- if err != nil {
- return Version{}, errors.New(stderr)
- }
-
- infos := strings.Split(stdout, " ")
+func ParseVersion(verStr string) (*Version, error) {
+ infos := strings.Split(verStr, ".")
if len(infos) < 3 {
- return Version{}, errors.New("not enough output")
+ return nil, errors.New("incorrect version input")
}
- v := Version{}
- for i, s := range strings.Split(strings.TrimSpace(infos[2]), ".") {
+ v := &Version{}
+ for i, s := range infos {
switch i {
case 0:
v.Major, _ = com.StrTo(s).Int()
case 1:
v.Minor, _ = com.StrTo(s).Int()
case 2:
- v.Patch, _ = com.StrTo(s).Int()
+ v.Patch, _ = com.StrTo(strings.TrimSpace(s)).Int()
}
}
return v, nil
}
+
+func MustParseVersion(verStr string) *Version {
+ v, _ := ParseVersion(verStr)
+ return v
+}
+
+// Compare compares two versions,
+// it returns 1 if original is greater, -1 if original is smaller, 0 if equal.
+func (v *Version) Compare(that *Version) int {
+ if v.Major > that.Major {
+ return 1
+ } else if v.Major < that.Major {
+ return -1
+ }
+
+ if v.Minor > that.Minor {
+ return 1
+ } else if v.Minor < that.Minor {
+ return -1
+ }
+
+ if v.Patch > that.Patch {
+ return 1
+ } else if v.Patch < that.Patch {
+ return -1
+ }
+
+ return 0
+}
+
+func (v *Version) LessThan(that *Version) bool {
+ return v.Compare(that) < 0
+}
+
+// GetVersion returns current Git version installed.
+func GetVersion() (*Version, error) {
+ if gitVer != nil {
+ return gitVer, nil
+ }
+
+ stdout, stderr, err := com.ExecCmd("git", "version")
+ if err != nil {
+ return nil, errors.New(stderr)
+ }
+
+ infos := strings.Split(stdout, " ")
+ if len(infos) < 3 {
+ return nil, errors.New("not enough output")
+ }
+
+ gitVer, err = ParseVersion(infos[2])
+ return gitVer, err
+}