aboutsummaryrefslogtreecommitdiff
path: root/modules/git
diff options
context:
space:
mode:
Diffstat (limited to 'modules/git')
-rw-r--r--modules/git/blob.go2
-rw-r--r--modules/git/commit.go14
-rw-r--r--modules/git/commit_archive.go2
-rw-r--r--modules/git/error.go22
-rw-r--r--modules/git/repo.go3
-rw-r--r--modules/git/repo_branch.go13
-rw-r--r--modules/git/repo_commit.go8
-rw-r--r--modules/git/repo_pull.go52
-rw-r--r--modules/git/repo_tag.go4
-rw-r--r--modules/git/sha1.go2
-rw-r--r--modules/git/signature.go16
-rw-r--r--modules/git/signature_test.go20
-rw-r--r--modules/git/submodule.go3
-rw-r--r--modules/git/tag.go2
-rw-r--r--modules/git/tree.go39
-rw-r--r--modules/git/tree_blob.go2
-rw-r--r--modules/git/tree_entry.go4
-rw-r--r--modules/git/utils.go5
18 files changed, 161 insertions, 52 deletions
diff --git a/modules/git/blob.go b/modules/git/blob.go
index 3ce462a3..bdf0cae4 100644
--- a/modules/git/blob.go
+++ b/modules/git/blob.go
@@ -18,7 +18,7 @@ type Blob struct {
}
func (b *Blob) Data() (io.Reader, error) {
- stdout, stderr, err := com.ExecCmdDirBytes(b.repo.Path, "git", "show", b.Id.String())
+ stdout, stderr, err := com.ExecCmdDirBytes(b.repo.Path, "git", "show", b.ID.String())
if err != nil {
return nil, errors.New(string(stderr))
}
diff --git a/modules/git/commit.go b/modules/git/commit.go
index da0ab644..674a0b85 100644
--- a/modules/git/commit.go
+++ b/modules/git/commit.go
@@ -14,7 +14,7 @@ import (
// Commit represents a git commit.
type Commit struct {
Tree
- Id sha1 // The id of this commit object
+ ID sha1 // The id of this commit object
Author *Signature
Committer *Signature
CommitMessage string
@@ -35,7 +35,7 @@ func (c *Commit) Summary() string {
// Return oid of the parent number n (0-based index). Return nil if no such parent exists.
func (c *Commit) ParentId(n int) (id sha1, err error) {
if n >= len(c.parents) {
- err = IdNotExist
+ err = IDNotExist
return
}
return c.parents[n], nil
@@ -61,7 +61,7 @@ func (c *Commit) ParentCount() int {
}
func (c *Commit) CommitsBefore() (*list.List, error) {
- return c.repo.getCommitsBefore(c.Id)
+ return c.repo.getCommitsBefore(c.ID)
}
func (c *Commit) CommitsBeforeUntil(commitId string) (*list.List, error) {
@@ -73,19 +73,19 @@ func (c *Commit) CommitsBeforeUntil(commitId string) (*list.List, error) {
}
func (c *Commit) CommitsCount() (int, error) {
- return c.repo.commitsCount(c.Id)
+ return c.repo.commitsCount(c.ID)
}
func (c *Commit) SearchCommits(keyword string) (*list.List, error) {
- return c.repo.searchCommits(c.Id, keyword)
+ return c.repo.searchCommits(c.ID, keyword)
}
func (c *Commit) CommitsByRange(page int) (*list.List, error) {
- return c.repo.commitsByRange(c.Id, page)
+ return c.repo.commitsByRange(c.ID, page)
}
func (c *Commit) GetCommitOfRelPath(relPath string) (*Commit, error) {
- return c.repo.getCommitOfRelPath(c.Id, relPath)
+ return c.repo.getCommitOfRelPath(c.ID, relPath)
}
func (c *Commit) GetSubModule(entryname string) (*SubModule, error) {
diff --git a/modules/git/commit_archive.go b/modules/git/commit_archive.go
index 23b4b058..8bb6b129 100644
--- a/modules/git/commit_archive.go
+++ b/modules/git/commit_archive.go
@@ -28,7 +28,7 @@ func (c *Commit) CreateArchive(path string, archiveType ArchiveType) error {
return fmt.Errorf("unknown format: %v", archiveType)
}
- _, stderr, err := com.ExecCmdDir(c.repo.Path, "git", "archive", "--format="+format, "-o", path, c.Id.String())
+ _, stderr, err := com.ExecCmdDir(c.repo.Path, "git", "archive", "--format="+format, "-o", path, c.ID.String())
if err != nil {
return fmt.Errorf("%s", stderr)
}
diff --git a/modules/git/error.go b/modules/git/error.go
new file mode 100644
index 00000000..c86c56e5
--- /dev/null
+++ b/modules/git/error.go
@@ -0,0 +1,22 @@
+// Copyright 2015 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 (
+ "fmt"
+)
+
+type ErrUnsupportedVersion struct {
+ Required string
+}
+
+func IsErrUnsupportedVersion(err error) bool {
+ _, ok := err.(ErrUnsupportedVersion)
+ return ok
+}
+
+func (err ErrUnsupportedVersion) Error() string {
+ return fmt.Sprintf("Operation requires higher version [required: %s]", err.Required)
+}
diff --git a/modules/git/repo.go b/modules/git/repo.go
index 14ac39a3..39fad97d 100644
--- a/modules/git/repo.go
+++ b/modules/git/repo.go
@@ -5,6 +5,7 @@
package git
import (
+ "errors"
"path/filepath"
)
@@ -21,6 +22,8 @@ func OpenRepository(repoPath string) (*Repository, error) {
repoPath, err := filepath.Abs(repoPath)
if err != nil {
return nil, err
+ } else if !isDir(repoPath) {
+ return nil, errors.New("no such file or directory")
}
return &Repository{Path: repoPath}, nil
diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go
index a4e06053..86c4f538 100644
--- a/modules/git/repo_branch.go
+++ b/modules/git/repo_branch.go
@@ -35,3 +35,16 @@ func (repo *Repository) GetBranches() ([]string, error) {
}
return branches, nil
}
+
+// SetDefaultBranch sets default branch of repository.
+func (repo *Repository) SetDefaultBranch(branchName string) error {
+ if gitVer.LessThan(MustParseVersion("1.7.10")) {
+ return ErrUnsupportedVersion{"1.7.10"}
+ }
+
+ _, stderr, err := com.ExecCmdDir(repo.Path, "git", "symbolic-ref", "HEAD", "refs/heads/"+branchName)
+ if err != nil {
+ return concatenateError(err, stderr)
+ }
+ return nil
+}
diff --git a/modules/git/repo_commit.go b/modules/git/repo_commit.go
index e8ac2dfc..28633058 100644
--- a/modules/git/repo_commit.go
+++ b/modules/git/repo_commit.go
@@ -70,7 +70,7 @@ l:
if err != nil {
return nil, err
}
- commit.Tree.Id = id
+ commit.Tree.ID = id
case "parent":
// A commit can have one or more parents
oid, err := NewIdFromString(string(line[spacepos+1:]))
@@ -121,7 +121,7 @@ func (repo *Repository) getCommit(id sha1) (*Commit, error) {
return nil, err
}
commit.repo = repo
- commit.Id = id
+ commit.ID = id
repo.commitCache[id] = commit
return commit, nil
@@ -211,7 +211,7 @@ func (repo *Repository) CommitsBetween(last *Commit, before *Commit) (*list.List
var err error
cur := last
for {
- if cur.Id.Equal(before.Id) {
+ if cur.ID.Equal(before.ID) {
break
}
l.PushBack(cur)
@@ -240,7 +240,7 @@ func (repo *Repository) commitsBefore(lock *sync.Mutex, l *list.List, parent *li
for {
if in == nil {
break
- } else if in.Value.(*Commit).Id.Equal(commit.Id) {
+ } else if in.Value.(*Commit).ID.Equal(commit.ID) {
return nil
} else {
if in.Next() == nil {
diff --git a/modules/git/repo_pull.go b/modules/git/repo_pull.go
index a9cc33a1..f9ea7100 100644
--- a/modules/git/repo_pull.go
+++ b/modules/git/repo_pull.go
@@ -20,31 +20,55 @@ type PullRequestInfo struct {
NumFiles int
}
+// GetMergeBase checks and returns merge base of two branches.
+func (repo *Repository) GetMergeBase(remoteBranch, headBranch string) (string, error) {
+ // Get merge base commit.
+ stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "merge-base", remoteBranch, headBranch)
+ if err != nil {
+ return "", fmt.Errorf("get merge base: %v", concatenateError(err, stderr))
+ }
+ return strings.TrimSpace(stdout), nil
+}
+
+// AddRemote adds a remote to repository.
+func (repo *Repository) AddRemote(name, path string) error {
+ _, stderr, err := com.ExecCmdDir(repo.Path, "git", "remote", "add", "-f", name, path)
+ if err != nil {
+ return fmt.Errorf("add remote(%s - %s): %v", name, path, concatenateError(err, stderr))
+ }
+ return nil
+}
+
+// RemoveRemote removes a remote from repository.
+func (repo *Repository) RemoveRemote(name string) error {
+ _, stderr, err := com.ExecCmdDir(repo.Path, "git", "remote", "remove", name)
+ if err != nil {
+ return fmt.Errorf("remove remote(%s): %v", name, concatenateError(err, stderr))
+ }
+ return nil
+}
+
// GetPullRequestInfo generates and returns pull request information
// between base and head branches of repositories.
-func (repo *Repository) GetPullRequestInfo(basePath, baseBranch, headBranch string) (*PullRequestInfo, error) {
+func (repo *Repository) GetPullRequestInfo(basePath, baseBranch, headBranch string) (_ *PullRequestInfo, err error) {
// Add a temporary remote.
tmpRemote := com.ToStr(time.Now().UnixNano())
- _, stderr, err := com.ExecCmdDir(repo.Path, "git", "remote", "add", "-f", tmpRemote, basePath)
- if err != nil {
- return nil, fmt.Errorf("add base as remote: %v", concatenateError(err, stderr))
+ if err = repo.AddRemote(tmpRemote, basePath); err != nil {
+ return nil, fmt.Errorf("AddRemote: %v", err)
}
defer func() {
- com.ExecCmdDir(repo.Path, "git", "remote", "remove", tmpRemote)
+ repo.RemoveRemote(tmpRemote)
}()
- prInfo := new(PullRequestInfo)
-
- var stdout string
remoteBranch := "remotes/" + tmpRemote + "/" + baseBranch
- // Get merge base commit.
- stdout, stderr, err = com.ExecCmdDir(repo.Path, "git", "merge-base", remoteBranch, headBranch)
+
+ prInfo := new(PullRequestInfo)
+ prInfo.MergeBase, err = repo.GetMergeBase(remoteBranch, headBranch)
if err != nil {
- return nil, fmt.Errorf("get merge base: %v", concatenateError(err, stderr))
+ return nil, fmt.Errorf("GetMergeBase: %v", err)
}
- prInfo.MergeBase = strings.TrimSpace(stdout)
- stdout, stderr, err = com.ExecCmdDir(repo.Path, "git", "log", prInfo.MergeBase+"..."+headBranch, prettyLogFormat)
+ stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "log", prInfo.MergeBase+"..."+headBranch, prettyLogFormat)
if err != nil {
return nil, fmt.Errorf("list diff logs: %v", concatenateError(err, stderr))
}
@@ -65,7 +89,7 @@ func (repo *Repository) GetPullRequestInfo(basePath, baseBranch, headBranch stri
// GetPatch generates and returns patch data between given branches.
func (repo *Repository) GetPatch(mergeBase, headBranch string) ([]byte, error) {
- stdout, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "diff", "-p", mergeBase, headBranch)
+ stdout, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "diff", "-p", "--binary", mergeBase, headBranch)
if err != nil {
return nil, concatenateError(err, string(stderr))
}
diff --git a/modules/git/repo_tag.go b/modules/git/repo_tag.go
index 8f37d31a..a1f81649 100644
--- a/modules/git/repo_tag.go
+++ b/modules/git/repo_tag.go
@@ -69,7 +69,7 @@ func (repo *Repository) getTag(id sha1) (*Tag, error) {
// Tag is a commit.
if ObjectType(tp) == COMMIT {
tag := &Tag{
- Id: id,
+ ID: id,
Object: id,
Type: string(COMMIT),
repo: repo,
@@ -89,7 +89,7 @@ func (repo *Repository) getTag(id sha1) (*Tag, error) {
return nil, err
}
- tag.Id = id
+ tag.ID = id
tag.repo = repo
repo.tagCache[id] = tag
diff --git a/modules/git/sha1.go b/modules/git/sha1.go
index 5c57e89b..f286f35a 100644
--- a/modules/git/sha1.go
+++ b/modules/git/sha1.go
@@ -12,7 +12,7 @@ import (
)
var (
- IdNotExist = errors.New("sha1 id not exist")
+ IDNotExist = errors.New("sha1 ID does not exist")
)
type sha1 [20]byte
diff --git a/modules/git/signature.go b/modules/git/signature.go
index b77f7a44..6cd92943 100644
--- a/modules/git/signature.go
+++ b/modules/git/signature.go
@@ -26,23 +26,23 @@ type Signature struct {
// FIXME: include timezone for timestamp!
func newSignatureFromCommitline(line []byte) (_ *Signature, err error) {
sig := new(Signature)
- emailstart := bytes.IndexByte(line, '<')
- sig.Name = string(line[:emailstart-1])
- emailstop := bytes.IndexByte(line, '>')
- sig.Email = string(line[emailstart+1 : emailstop])
+ emailStart := bytes.IndexByte(line, '<')
+ sig.Name = string(line[:emailStart-1])
+ emailEnd := bytes.IndexByte(line, '>')
+ sig.Email = string(line[emailStart+1 : emailEnd])
// Check date format.
- firstChar := line[emailstop+2]
+ firstChar := line[emailEnd+2]
if firstChar >= 48 && firstChar <= 57 {
- timestop := bytes.IndexByte(line[emailstop+2:], ' ')
- timestring := string(line[emailstop+2 : emailstop+2+timestop])
+ timestop := bytes.IndexByte(line[emailEnd+2:], ' ')
+ timestring := string(line[emailEnd+2 : emailEnd+2+timestop])
seconds, err := strconv.ParseInt(timestring, 10, 64)
if err != nil {
return nil, err
}
sig.When = time.Unix(seconds, 0)
} else {
- sig.When, err = time.Parse("Mon Jan _2 15:04:05 2006 -0700", string(line[emailstop+2:]))
+ sig.When, err = time.Parse("Mon Jan _2 15:04:05 2006 -0700", string(line[emailEnd+2:]))
if err != nil {
return nil, err
}
diff --git a/modules/git/signature_test.go b/modules/git/signature_test.go
new file mode 100644
index 00000000..a84f9b3d
--- /dev/null
+++ b/modules/git/signature_test.go
@@ -0,0 +1,20 @@
+// Copyright 2015 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 (
+ "testing"
+
+ . "github.com/smartystreets/goconvey/convey"
+)
+
+func Test_newSignatureFromCommitline(t *testing.T) {
+ Convey("Parse signature from commit line", t, func() {
+ line := "Intern <intern@macbook-intern.(none)> 1445412825 +0200"
+ sig, err := newSignatureFromCommitline([]byte(line))
+ So(err, ShouldBeNil)
+ So(sig, ShouldNotBeNil)
+ })
+}
diff --git a/modules/git/submodule.go b/modules/git/submodule.go
index 0b8efc26..10680c24 100644
--- a/modules/git/submodule.go
+++ b/modules/git/submodule.go
@@ -6,6 +6,7 @@ package git
import (
"strings"
+
"github.com/gogits/gogs/modules/setting"
)
@@ -53,7 +54,7 @@ func (sf *SubModuleFile) RefUrl() string {
j := strings.LastIndex(url, ":")
if i > -1 && j > -1 {
// fix problem with reverse proxy works only with local server
- if strings.Contains(setting.AppUrl,url[i+1:j]) {
+ if strings.Contains(setting.AppUrl, url[i+1:j]) {
return setting.AppUrl + url[j+1:]
} else {
return "http://" + url[i+1:j] + "/" + url[j+1:]
diff --git a/modules/git/tag.go b/modules/git/tag.go
index 7fbbcb1c..8010aa9d 100644
--- a/modules/git/tag.go
+++ b/modules/git/tag.go
@@ -11,7 +11,7 @@ import (
// Tag represents a Git tag.
type Tag struct {
Name string
- Id sha1
+ ID sha1
repo *Repository
Object sha1 // The id of this commit object
Type string
diff --git a/modules/git/tree.go b/modules/git/tree.go
index 27539f06..1a561cf5 100644
--- a/modules/git/tree.go
+++ b/modules/git/tree.go
@@ -18,7 +18,7 @@ var (
// A tree is a flat directory listing.
type Tree struct {
- Id sha1
+ ID sha1
repo *Repository
// parent tree
@@ -28,6 +28,27 @@ type Tree struct {
entriesParsed bool
}
+var escapeChar = []byte("\\")
+
+func UnescapeChars(in []byte) []byte {
+ if bytes.Index(in, escapeChar) == -1 {
+ return in
+ }
+
+ endIdx := len(in) - 1
+ isEscape := false
+ out := make([]byte, 0, endIdx+1)
+ for i := range in {
+ if in[i] == '\\' && !isEscape {
+ isEscape = true
+ continue
+ }
+ isEscape = false
+ out = append(out, in[i])
+ }
+ return out
+}
+
// Parse tree information from the (uncompressed) raw
// data from the tree object.
func parseTreeData(tree *Tree, data []byte) ([]*TreeEntry, error) {
@@ -66,16 +87,16 @@ func parseTreeData(tree *Tree, data []byte) ([]*TreeEntry, error) {
if err != nil {
return nil, err
}
- entry.Id = id
+ entry.ID = id
pos += step + 1 // Skip half of sha1.
step = bytes.IndexByte(data[pos:], '\n')
- entry.name = string(data[pos : pos+step])
// In case entry name is surrounded by double quotes(it happens only in git-shell).
- if entry.name[0] == '"' {
- entry.name = string(data[pos+1 : pos+step-1])
- entry.name = strings.Replace(entry.name, `\"`, `"`, -1)
+ if data[pos] == '"' {
+ entry.name = string(UnescapeChars(data[pos+1 : pos+step-1]))
+ } else {
+ entry.name = string(data[pos : pos+step])
}
pos += step + 1
@@ -100,7 +121,7 @@ func (t *Tree) SubTree(rpath string) (*Tree, error) {
return nil, err
}
- g, err = t.repo.getTree(te.Id)
+ g, err = t.repo.getTree(te.ID)
if err != nil {
return nil, err
}
@@ -117,7 +138,7 @@ func (t *Tree) ListEntries(relpath string) (Entries, error) {
t.entriesParsed = true
stdout, stderr, err := com.ExecCmdDirBytes(t.repo.Path,
- "git", "ls-tree", t.Id.String())
+ "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)))
@@ -130,7 +151,7 @@ func (t *Tree) ListEntries(relpath string) (Entries, error) {
func NewTree(repo *Repository, id sha1) *Tree {
tree := new(Tree)
- tree.Id = id
+ tree.ID = id
tree.repo = repo
return tree
}
diff --git a/modules/git/tree_blob.go b/modules/git/tree_blob.go
index f996aba3..44c5d0c8 100644
--- a/modules/git/tree_blob.go
+++ b/modules/git/tree_blob.go
@@ -13,7 +13,7 @@ import (
func (t *Tree) GetTreeEntryByPath(relpath string) (*TreeEntry, error) {
if len(relpath) == 0 {
return &TreeEntry{
- Id: t.Id,
+ ID: t.ID,
Type: TREE,
mode: ModeTree,
}, nil
diff --git a/modules/git/tree_entry.go b/modules/git/tree_entry.go
index e403e93e..18250257 100644
--- a/modules/git/tree_entry.go
+++ b/modules/git/tree_entry.go
@@ -24,7 +24,7 @@ const (
)
type TreeEntry struct {
- Id sha1
+ ID sha1
Type ObjectType
mode EntryMode
@@ -51,7 +51,7 @@ func (te *TreeEntry) Size() int64 {
return te.size
}
- stdout, _, err := com.ExecCmdDir(te.ptree.repo.Path, "git", "cat-file", "-s", te.Id.String())
+ stdout, _, err := com.ExecCmdDir(te.ptree.repo.Path, "git", "cat-file", "-s", te.ID.String())
if err != nil {
return 0
}
diff --git a/modules/git/utils.go b/modules/git/utils.go
index 78792aaf..d2d0c19e 100644
--- a/modules/git/utils.go
+++ b/modules/git/utils.go
@@ -35,6 +35,11 @@ func parsePrettyFormatLog(repo *Repository, logByts []byte) (*list.List, error)
}
func RefEndName(refStr string) string {
+ if strings.HasPrefix(refStr, "refs/heads/") {
+ // trim the "refs/heads/"
+ return refStr[len("refs/heads/"):]
+ }
+
index := strings.LastIndex(refStr, "/")
if index != -1 {
return refStr[index+1:]