move out git module and #1573 send push hook
This commit is contained in:
		
							parent
							
								
									bd5dc626e8
								
							
						
					
					
						commit
						9a2e43bff2
					
				| @ -20,6 +20,7 @@ github.com/gogits/chardet = commit:2404f77725 | |||||||
| github.com/gogits/git-shell =  | github.com/gogits/git-shell =  | ||||||
| github.com/gogits/go-gogs-client = commit:4b541fa | github.com/gogits/go-gogs-client = commit:4b541fa | ||||||
| github.com/issue9/identicon = commit:f8c0d2c | github.com/issue9/identicon = commit:f8c0d2c | ||||||
|  | github.com/kardianos/minwinsvc =  | ||||||
| github.com/klauspost/compress = commit:bcd0709 | github.com/klauspost/compress = commit:bcd0709 | ||||||
| github.com/klauspost/cpuid = commit:8d9fe96 | github.com/klauspost/cpuid = commit:8d9fe96 | ||||||
| github.com/klauspost/crc32 = commit:0aff1ea | github.com/klauspost/crc32 = commit:0aff1ea | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ Gogs - Go Git Service [ |  | ||||||
| 
 | 
 | ||||||
| ##### Current version: 0.7.36 Beta | ##### Current version: 0.7.37 Beta | ||||||
| 
 | 
 | ||||||
| | Web | UI  | Preview  | | | Web | UI  | Preview  | | ||||||
| |:-------------:|:-------:|:-------:| | |:-------------:|:-------:|:-------:| | ||||||
|  | |||||||
| @ -29,6 +29,8 @@ import ( | |||||||
| 	"gopkg.in/ini.v1" | 	"gopkg.in/ini.v1" | ||||||
| 	"gopkg.in/macaron.v1" | 	"gopkg.in/macaron.v1" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/gogits/git-shell" | ||||||
|  | 
 | ||||||
| 	"github.com/gogits/gogs/models" | 	"github.com/gogits/gogs/models" | ||||||
| 	"github.com/gogits/gogs/modules/auth" | 	"github.com/gogits/gogs/modules/auth" | ||||||
| 	"github.com/gogits/gogs/modules/avatar" | 	"github.com/gogits/gogs/modules/avatar" | ||||||
| @ -78,7 +80,6 @@ func checkVersion() { | |||||||
| 	// Check dependency version.
 | 	// Check dependency version.
 | ||||||
| 	checkers := []VerChecker{ | 	checkers := []VerChecker{ | ||||||
| 		{"github.com/go-xorm/xorm", func() string { return xorm.Version }, "0.4.4.1029"}, | 		{"github.com/go-xorm/xorm", func() string { return xorm.Version }, "0.4.4.1029"}, | ||||||
| 		{"github.com/Unknwon/macaron", macaron.Version, "0.5.4"}, |  | ||||||
| 		{"github.com/go-macaron/binding", binding.Version, "0.1.0"}, | 		{"github.com/go-macaron/binding", binding.Version, "0.1.0"}, | ||||||
| 		{"github.com/go-macaron/cache", cache.Version, "0.1.2"}, | 		{"github.com/go-macaron/cache", cache.Version, "0.1.2"}, | ||||||
| 		{"github.com/go-macaron/csrf", csrf.Version, "0.0.3"}, | 		{"github.com/go-macaron/csrf", csrf.Version, "0.0.3"}, | ||||||
| @ -86,10 +87,12 @@ func checkVersion() { | |||||||
| 		{"github.com/go-macaron/session", session.Version, "0.1.6"}, | 		{"github.com/go-macaron/session", session.Version, "0.1.6"}, | ||||||
| 		{"github.com/go-macaron/toolbox", toolbox.Version, "0.1.0"}, | 		{"github.com/go-macaron/toolbox", toolbox.Version, "0.1.0"}, | ||||||
| 		{"gopkg.in/ini.v1", ini.Version, "1.8.1"}, | 		{"gopkg.in/ini.v1", ini.Version, "1.8.1"}, | ||||||
|  | 		{"gopkg.in/macaron.v1", macaron.Version, "0.8.0"}, | ||||||
|  | 		{"github.com/gogits/git-shell", git.Version, "0.1.0"}, | ||||||
| 	} | 	} | ||||||
| 	for _, c := range checkers { | 	for _, c := range checkers { | ||||||
| 		if !version.Compare(c.Version(), c.Expected, ">=") { | 		if !version.Compare(c.Version(), c.Expected, ">=") { | ||||||
| 			log.Fatal(4, "Package '%s' version is too old(%s -> %s), did you forget to update?", c.ImportPath, c.Version(), c.Expected) | 			log.Fatal(4, "Package '%s' version is too old (%s -> %s), did you forget to update?", c.ImportPath, c.Version(), c.Expected) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							| @ -18,7 +18,7 @@ import ( | |||||||
| 	"github.com/gogits/gogs/modules/setting" | 	"github.com/gogits/gogs/modules/setting" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const APP_VER = "0.7.36.1209 Beta" | const APP_VER = "0.7.37.1209 Beta" | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	runtime.GOMAXPROCS(runtime.NumCPU()) | 	runtime.GOMAXPROCS(runtime.NumCPU()) | ||||||
|  | |||||||
| @ -17,10 +17,10 @@ import ( | |||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/gogits/git-shell" | ||||||
| 	api "github.com/gogits/go-gogs-client" | 	api "github.com/gogits/go-gogs-client" | ||||||
| 
 | 
 | ||||||
| 	"github.com/gogits/gogs/modules/base" | 	"github.com/gogits/gogs/modules/base" | ||||||
| 	"github.com/gogits/gogs/modules/git" |  | ||||||
| 	"github.com/gogits/gogs/modules/log" | 	"github.com/gogits/gogs/modules/log" | ||||||
| 	"github.com/gogits/gogs/modules/setting" | 	"github.com/gogits/gogs/modules/setting" | ||||||
| ) | ) | ||||||
| @ -229,6 +229,28 @@ func NewPushCommits() *PushCommits { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (pc *PushCommits) ToApiPayloadCommits(repoLink string) []*api.PayloadCommit { | ||||||
|  | 	commits := make([]*api.PayloadCommit, len(pc.Commits)) | ||||||
|  | 	for i, cmt := range pc.Commits { | ||||||
|  | 		author_username := "" | ||||||
|  | 		author, err := GetUserByEmail(cmt.AuthorEmail) | ||||||
|  | 		if err == nil { | ||||||
|  | 			author_username = author.Name | ||||||
|  | 		} | ||||||
|  | 		commits[i] = &api.PayloadCommit{ | ||||||
|  | 			ID:      cmt.Sha1, | ||||||
|  | 			Message: cmt.Message, | ||||||
|  | 			URL:     fmt.Sprintf("%s/commit/%s", repoLink, cmt.Sha1), | ||||||
|  | 			Author: &api.PayloadAuthor{ | ||||||
|  | 				Name:     cmt.AuthorName, | ||||||
|  | 				Email:    cmt.AuthorEmail, | ||||||
|  | 				UserName: author_username, | ||||||
|  | 			}, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return commits | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // AvatarLink tries to match user in database with e-mail
 | // AvatarLink tries to match user in database with e-mail
 | ||||||
| // in order to show custom avatar, and falls back to general avatar link.
 | // in order to show custom avatar, and falls back to general avatar link.
 | ||||||
| func (push *PushCommits) AvatarLink(email string) string { | func (push *PushCommits) AvatarLink(email string) string { | ||||||
| @ -413,7 +435,7 @@ func CommitRepoAction( | |||||||
| 	} else { | 	} else { | ||||||
| 		// if not the first commit, set the compareUrl
 | 		// if not the first commit, set the compareUrl
 | ||||||
| 		if !strings.HasPrefix(oldCommitID, "0000000") { | 		if !strings.HasPrefix(oldCommitID, "0000000") { | ||||||
| 			commit.CompareUrl = fmt.Sprintf("%s/%s/compare/%s...%s", repoUserName, repoName, oldCommitID, newCommitID) | 			commit.CompareUrl = repo.ComposeCompareURL(oldCommitID, newCommitID) | ||||||
| 		} else { | 		} else { | ||||||
| 			isNewBranch = true | 			isNewBranch = true | ||||||
| 		} | 		} | ||||||
| @ -469,30 +491,12 @@ func CommitRepoAction( | |||||||
| 
 | 
 | ||||||
| 	switch opType { | 	switch opType { | ||||||
| 	case COMMIT_REPO: // Push
 | 	case COMMIT_REPO: // Push
 | ||||||
| 		commits := make([]*api.PayloadCommit, len(commit.Commits)) |  | ||||||
| 		for i, cmt := range commit.Commits { |  | ||||||
| 			author_username := "" |  | ||||||
| 			author, err := GetUserByEmail(cmt.AuthorEmail) |  | ||||||
| 			if err == nil { |  | ||||||
| 				author_username = author.Name |  | ||||||
| 			} |  | ||||||
| 			commits[i] = &api.PayloadCommit{ |  | ||||||
| 				ID:      cmt.Sha1, |  | ||||||
| 				Message: cmt.Message, |  | ||||||
| 				URL:     fmt.Sprintf("%s/commit/%s", repo.FullRepoLink(), cmt.Sha1), |  | ||||||
| 				Author: &api.PayloadAuthor{ |  | ||||||
| 					Name:     cmt.AuthorName, |  | ||||||
| 					Email:    cmt.AuthorEmail, |  | ||||||
| 					UserName: author_username, |  | ||||||
| 				}, |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		p := &api.PushPayload{ | 		p := &api.PushPayload{ | ||||||
| 			Ref:        refFullName, | 			Ref:        refFullName, | ||||||
| 			Before:     oldCommitID, | 			Before:     oldCommitID, | ||||||
| 			After:      newCommitID, | 			After:      newCommitID, | ||||||
| 			CompareUrl: setting.AppUrl + commit.CompareUrl, | 			CompareUrl: setting.AppUrl + commit.CompareUrl, | ||||||
| 			Commits:    commits, | 			Commits:    commit.ToApiPayloadCommits(repo.FullRepoLink()), | ||||||
| 			Repo:       payloadRepo, | 			Repo:       payloadRepo, | ||||||
| 			Pusher: &api.PayloadAuthor{ | 			Pusher: &api.PayloadAuthor{ | ||||||
| 				Name:     pusher_name, | 				Name:     pusher_name, | ||||||
|  | |||||||
| @ -14,7 +14,9 @@ import ( | |||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| 
 | 
 | ||||||
| 	"github.com/gogits/gogs/modules/git" | 	"github.com/gogits/git-shell" | ||||||
|  | 	api "github.com/gogits/go-gogs-client" | ||||||
|  | 
 | ||||||
| 	"github.com/gogits/gogs/modules/log" | 	"github.com/gogits/gogs/modules/log" | ||||||
| 	"github.com/gogits/gogs/modules/process" | 	"github.com/gogits/gogs/modules/process" | ||||||
| 	"github.com/gogits/gogs/modules/setting" | 	"github.com/gogits/gogs/modules/setting" | ||||||
| @ -124,6 +126,12 @@ func (pr *PullRequest) CanAutoMerge() bool { | |||||||
| 
 | 
 | ||||||
| // Merge merges pull request to base repository.
 | // Merge merges pull request to base repository.
 | ||||||
| func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error) { | func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error) { | ||||||
|  | 	if err = pr.GetHeadRepo(); err != nil { | ||||||
|  | 		return fmt.Errorf("GetHeadRepo: %v", err) | ||||||
|  | 	} else if err = pr.GetBaseRepo(); err != nil { | ||||||
|  | 		return fmt.Errorf("GetBaseRepo: %v", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	sess := x.NewSession() | 	sess := x.NewSession() | ||||||
| 	defer sessionRelease(sess) | 	defer sessionRelease(sess) | ||||||
| 	if err = sess.Begin(); err != nil { | 	if err = sess.Begin(); err != nil { | ||||||
| @ -134,18 +142,14 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error | |||||||
| 		return fmt.Errorf("Issue.changeStatus: %v", err) | 		return fmt.Errorf("Issue.changeStatus: %v", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err = pr.getHeadRepo(sess); err != nil { |  | ||||||
| 		return fmt.Errorf("getHeadRepo: %v", err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	headRepoPath := RepoPath(pr.HeadUserName, pr.HeadRepo.Name) | 	headRepoPath := RepoPath(pr.HeadUserName, pr.HeadRepo.Name) | ||||||
| 	headGitRepo, err := git.OpenRepository(headRepoPath) | 	headGitRepo, err := git.OpenRepository(headRepoPath) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("OpenRepository: %v", err) | 		return fmt.Errorf("OpenRepository: %v", err) | ||||||
| 	} | 	} | ||||||
| 	pr.MergedCommitID, err = headGitRepo.GetCommitIdOfBranch(pr.HeadBranch) | 	pr.MergedCommitID, err = headGitRepo.GetBranchCommitID(pr.HeadBranch) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("GetCommitIdOfBranch: %v", err) | 		return fmt.Errorf("GetBranchCommitID: %v", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err = mergePullRequestAction(sess, doer, pr.Issue.Repo, pr.Issue); err != nil { | 	if err = mergePullRequestAction(sess, doer, pr.Issue.Repo, pr.Issue); err != nil { | ||||||
| @ -213,7 +217,38 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error | |||||||
| 		return fmt.Errorf("git push: %s", stderr) | 		return fmt.Errorf("git push: %s", stderr) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return sess.Commit() | 	if err = sess.Commit(); err != nil { | ||||||
|  | 		return fmt.Errorf("Commit: %v", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Compose commit repository action
 | ||||||
|  | 	l, err := headGitRepo.CommitsBetweenIDs(pr.MergedCommitID, pr.MergeBase) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("CommitsBetween: %v", err) | ||||||
|  | 	} | ||||||
|  | 	p := &api.PushPayload{ | ||||||
|  | 		Ref:        "refs/heads/" + pr.BaseBranch, | ||||||
|  | 		Before:     pr.MergeBase, | ||||||
|  | 		After:      pr.MergedCommitID, | ||||||
|  | 		CompareUrl: setting.AppUrl + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID), | ||||||
|  | 		Commits:    ListToPushCommits(l).ToApiPayloadCommits(pr.BaseRepo.FullRepoLink()), | ||||||
|  | 		Repo:       pr.BaseRepo.ComposePayload(), | ||||||
|  | 		Pusher: &api.PayloadAuthor{ | ||||||
|  | 			Name:     pr.HeadRepo.MustOwner().DisplayName(), | ||||||
|  | 			Email:    pr.HeadRepo.MustOwner().Email, | ||||||
|  | 			UserName: pr.HeadRepo.MustOwner().Name, | ||||||
|  | 		}, | ||||||
|  | 		Sender: &api.PayloadUser{ | ||||||
|  | 			UserName:  doer.Name, | ||||||
|  | 			ID:        doer.Id, | ||||||
|  | 			AvatarUrl: setting.AppUrl + doer.RelAvatarLink(), | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	if err = PrepareWebhooks(pr.BaseRepo, HOOK_EVENT_PUSH, p); err != nil { | ||||||
|  | 		return fmt.Errorf("PrepareWebhooks: %v", err) | ||||||
|  | 	} | ||||||
|  | 	go HookQueue.Add(pr.BaseRepo.ID) | ||||||
|  | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // patchConflicts is a list of conflit description from Git.
 | // patchConflicts is a list of conflit description from Git.
 | ||||||
| @ -411,8 +446,6 @@ func (pr *PullRequest) UpdatePatch() (err error) { | |||||||
| 
 | 
 | ||||||
| 	if err = pr.GetBaseRepo(); err != nil { | 	if err = pr.GetBaseRepo(); err != nil { | ||||||
| 		return fmt.Errorf("GetBaseRepo: %v", err) | 		return fmt.Errorf("GetBaseRepo: %v", err) | ||||||
| 	} else if err = pr.BaseRepo.GetOwner(); err != nil { |  | ||||||
| 		return fmt.Errorf("GetOwner: %v", err) |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath()) | 	headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath()) | ||||||
| @ -422,7 +455,7 @@ func (pr *PullRequest) UpdatePatch() (err error) { | |||||||
| 
 | 
 | ||||||
| 	// Add a temporary remote.
 | 	// Add a temporary remote.
 | ||||||
| 	tmpRemote := com.ToStr(time.Now().UnixNano()) | 	tmpRemote := com.ToStr(time.Now().UnixNano()) | ||||||
| 	if err = headGitRepo.AddRemote(tmpRemote, RepoPath(pr.BaseRepo.Owner.Name, pr.BaseRepo.Name)); err != nil { | 	if err = headGitRepo.AddRemote(tmpRemote, RepoPath(pr.BaseRepo.MustOwner().Name, pr.BaseRepo.Name), true); err != nil { | ||||||
| 		return fmt.Errorf("AddRemote: %v", err) | 		return fmt.Errorf("AddRemote: %v", err) | ||||||
| 	} | 	} | ||||||
| 	defer func() { | 	defer func() { | ||||||
|  | |||||||
| @ -12,7 +12,8 @@ import ( | |||||||
| 
 | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| 
 | 
 | ||||||
| 	"github.com/gogits/gogs/modules/git" | 	"github.com/gogits/git-shell" | ||||||
|  | 
 | ||||||
| 	"github.com/gogits/gogs/modules/process" | 	"github.com/gogits/gogs/modules/process" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @ -27,8 +28,8 @@ type Release struct { | |||||||
| 	Target           string | 	Target           string | ||||||
| 	Title            string | 	Title            string | ||||||
| 	Sha1             string `xorm:"VARCHAR(40)"` | 	Sha1             string `xorm:"VARCHAR(40)"` | ||||||
| 	NumCommits       int | 	NumCommits       int64 | ||||||
| 	NumCommitsBehind int    `xorm:"-"` | 	NumCommitsBehind int64  `xorm:"-"` | ||||||
| 	Note             string `xorm:"TEXT"` | 	Note             string `xorm:"TEXT"` | ||||||
| 	IsDraft          bool   `xorm:"NOT NULL DEFAULT false"` | 	IsDraft          bool   `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	IsPrerelease     bool | 	IsPrerelease     bool | ||||||
| @ -51,31 +52,27 @@ func IsReleaseExist(repoID int64, tagName string) (bool, error) { | |||||||
| 	return x.Get(&Release{RepoID: repoID, LowerTagName: strings.ToLower(tagName)}) | 	return x.Get(&Release{RepoID: repoID, LowerTagName: strings.ToLower(tagName)}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func init() { |  | ||||||
| 	git.GetVersion() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func createTag(gitRepo *git.Repository, rel *Release) error { | func createTag(gitRepo *git.Repository, rel *Release) error { | ||||||
| 	// Only actual create when publish.
 | 	// Only actual create when publish.
 | ||||||
| 	if !rel.IsDraft { | 	if !rel.IsDraft { | ||||||
| 		if !gitRepo.IsTagExist(rel.TagName) { | 		if !gitRepo.IsTagExist(rel.TagName) { | ||||||
| 			commit, err := gitRepo.GetCommitOfBranch(rel.Target) | 			commit, err := gitRepo.GetBranchCommit(rel.Target) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return fmt.Errorf("GetBranchCommit: %v", err) | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if err = gitRepo.CreateTag(rel.TagName, commit.ID.String()); err != nil { | 			if err = gitRepo.CreateTag(rel.TagName, commit.ID.String()); err != nil { | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			commit, err := gitRepo.GetCommitOfTag(rel.TagName) | 			commit, err := gitRepo.GetTagCommit(rel.TagName) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return fmt.Errorf("GetTagCommit: %v", err) | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			rel.NumCommits, err = commit.CommitsCount() | 			rel.NumCommits, err = commit.CommitsCount() | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return fmt.Errorf("CommitsCount: %v", err) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -98,7 +98,7 @@ func NewRepoContext() { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Check Git version.
 | 	// Check Git version.
 | ||||||
| 	gitVer, err := git.Version() | 	gitVer, err := git.BinVersion() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Fatal(4, "Fail to get Git version: %v", err) | 		log.Fatal(4, "Fail to get Git version: %v", err) | ||||||
| 	} | 	} | ||||||
| @ -309,6 +309,10 @@ func (repo *Repository) RepoLink() string { | |||||||
| 	return setting.AppSubUrl + "/" + repo.MustOwner().Name + "/" + repo.Name | 	return setting.AppSubUrl + "/" + repo.MustOwner().Name + "/" + repo.Name | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (repo *Repository) ComposeCompareURL(oldCommitID, newCommitID string) string { | ||||||
|  | 	return fmt.Sprintf("%s/%s/compare/%s...%s", repo.MustOwner().Name, repo.Name, oldCommitID, newCommitID) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (repo *Repository) FullRepoLink() string { | func (repo *Repository) FullRepoLink() string { | ||||||
| 	return setting.AppUrl + repo.MustOwner().Name + "/" + repo.Name | 	return setting.AppUrl + repo.MustOwner().Name + "/" + repo.Name | ||||||
| } | } | ||||||
|  | |||||||
| @ -10,7 +10,8 @@ import ( | |||||||
| 	"os/exec" | 	"os/exec" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/gogits/gogs/modules/git" | 	"github.com/gogits/git-shell" | ||||||
|  | 
 | ||||||
| 	"github.com/gogits/gogs/modules/log" | 	"github.com/gogits/gogs/modules/log" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @ -46,6 +47,24 @@ func DeleteUpdateTaskByUUID(uuid string) error { | |||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func ListToPushCommits(l *list.List) *PushCommits { | ||||||
|  | 	commits := make([]*PushCommit, 0) | ||||||
|  | 	var actEmail string | ||||||
|  | 	for e := l.Front(); e != nil; e = e.Next() { | ||||||
|  | 		commit := e.Value.(*git.Commit) | ||||||
|  | 		if actEmail == "" { | ||||||
|  | 			actEmail = commit.Committer.Email | ||||||
|  | 		} | ||||||
|  | 		commits = append(commits, | ||||||
|  | 			&PushCommit{commit.ID.String(), | ||||||
|  | 				commit.Message(), | ||||||
|  | 				commit.Author.Email, | ||||||
|  | 				commit.Author.Name, | ||||||
|  | 			}) | ||||||
|  | 	} | ||||||
|  | 	return &PushCommits{l.Len(), commits, "", nil} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName string, userID int64) error { | func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName string, userID int64) error { | ||||||
| 	isNew := strings.HasPrefix(oldCommitID, "0000000") | 	isNew := strings.HasPrefix(oldCommitID, "0000000") | ||||||
| 	if isNew && | 	if isNew && | ||||||
| @ -131,24 +150,8 @@ func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName | |||||||
| 		return fmt.Errorf("runUpdate.Commit repoId: %v", err) | 		return fmt.Errorf("runUpdate.Commit repoId: %v", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Push commits.
 | 	if err = CommitRepoAction(userID, user.Id, userName, user.Email, | ||||||
| 	commits := make([]*PushCommit, 0) | 		repo.ID, repoUserName, repoName, refName, ListToPushCommits(l), oldCommitID, newCommitID); err != nil { | ||||||
| 	var actEmail string |  | ||||||
| 	for e := l.Front(); e != nil; e = e.Next() { |  | ||||||
| 		commit := e.Value.(*git.Commit) |  | ||||||
| 		if actEmail == "" { |  | ||||||
| 			actEmail = commit.Committer.Email |  | ||||||
| 		} |  | ||||||
| 		commits = append(commits, |  | ||||||
| 			&PushCommit{commit.ID.String(), |  | ||||||
| 				commit.Message(), |  | ||||||
| 				commit.Author.Email, |  | ||||||
| 				commit.Author.Name, |  | ||||||
| 			}) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err = CommitRepoAction(userID, user.Id, userName, actEmail, |  | ||||||
| 		repo.ID, repoUserName, repoName, refName, &PushCommits{l.Len(), commits, "", nil}, oldCommitID, newCommitID); err != nil { |  | ||||||
| 		return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err) | 		return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
|  | |||||||
| @ -29,7 +29,6 @@ import ( | |||||||
| 
 | 
 | ||||||
| 	"github.com/gogits/gogs/modules/avatar" | 	"github.com/gogits/gogs/modules/avatar" | ||||||
| 	"github.com/gogits/gogs/modules/base" | 	"github.com/gogits/gogs/modules/base" | ||||||
| 	oldgit "github.com/gogits/gogs/modules/git" |  | ||||||
| 	"github.com/gogits/gogs/modules/log" | 	"github.com/gogits/gogs/modules/log" | ||||||
| 	"github.com/gogits/gogs/modules/setting" | 	"github.com/gogits/gogs/modules/setting" | ||||||
| ) | ) | ||||||
| @ -940,11 +939,11 @@ func MakeEmailPrimary(email *EmailAddress) error { | |||||||
| // UserCommit represents a commit with validation of user.
 | // UserCommit represents a commit with validation of user.
 | ||||||
| type UserCommit struct { | type UserCommit struct { | ||||||
| 	User *User | 	User *User | ||||||
| 	*oldgit.Commit | 	*git.Commit | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ValidateCommitWithEmail chceck if author's e-mail of commit is corresponsind to a user.
 | // ValidateCommitWithEmail chceck if author's e-mail of commit is corresponsind to a user.
 | ||||||
| func ValidateCommitWithEmail(c *oldgit.Commit) *User { | func ValidateCommitWithEmail(c *git.Commit) *User { | ||||||
| 	u, err := GetUserByEmail(c.Author.Email) | 	u, err := GetUserByEmail(c.Author.Email) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil | 		return nil | ||||||
| @ -961,7 +960,7 @@ func ValidateCommitsWithEmails(oldCommits *list.List) *list.List { | |||||||
| 		e          = oldCommits.Front() | 		e          = oldCommits.Front() | ||||||
| 	) | 	) | ||||||
| 	for e != nil { | 	for e != nil { | ||||||
| 		c := e.Value.(*oldgit.Commit) | 		c := e.Value.(*git.Commit) | ||||||
| 
 | 
 | ||||||
| 		if v, ok := emails[c.Author.Email]; !ok { | 		if v, ok := emails[c.Author.Email]; !ok { | ||||||
| 			u, _ = GetUserByEmail(c.Author.Email) | 			u, _ = GetUserByEmail(c.Author.Email) | ||||||
|  | |||||||
| @ -10,9 +10,8 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/gogits/git-shell" | ||||||
| 	api "github.com/gogits/go-gogs-client" | 	api "github.com/gogits/go-gogs-client" | ||||||
| 
 |  | ||||||
| 	"github.com/gogits/gogs/modules/git" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type SlackMeta struct { | type SlackMeta struct { | ||||||
|  | |||||||
| @ -1,26 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"errors" |  | ||||||
| 	"io" |  | ||||||
| 
 |  | ||||||
| 	"github.com/Unknwon/com" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type Blob struct { |  | ||||||
| 	repo *Repository |  | ||||||
| 	*TreeEntry |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (b *Blob) Data() (io.Reader, error) { |  | ||||||
| 	stdout, stderr, err := com.ExecCmdDirBytes(b.repo.Path, "git", "show", b.ID.String()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, errors.New(string(stderr)) |  | ||||||
| 	} |  | ||||||
| 	return bytes.NewBuffer(stdout), nil |  | ||||||
| } |  | ||||||
| @ -1,162 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"bufio" |  | ||||||
| 	"container/list" |  | ||||||
| 	"net/http" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Commit represents a git commit.
 |  | ||||||
| type Commit struct { |  | ||||||
| 	Tree |  | ||||||
| 	ID            sha1 // The id of this commit object
 |  | ||||||
| 	Author        *Signature |  | ||||||
| 	Committer     *Signature |  | ||||||
| 	CommitMessage string |  | ||||||
| 
 |  | ||||||
| 	parents    []sha1 // sha1 strings
 |  | ||||||
| 	submodules map[string]*SubModule |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Return the commit message. Same as retrieving CommitMessage directly.
 |  | ||||||
| func (c *Commit) Message() string { |  | ||||||
| 	return c.CommitMessage |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *Commit) Summary() string { |  | ||||||
| 	return strings.Split(c.CommitMessage, "\n")[0] |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // 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 |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	return c.parents[n], nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Return parent number n (0-based index)
 |  | ||||||
| func (c *Commit) Parent(n int) (*Commit, error) { |  | ||||||
| 	id, err := c.ParentId(n) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	parent, err := c.repo.getCommit(id) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return parent, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Return the number of parents of the commit. 0 if this is the
 |  | ||||||
| // root commit, otherwise 1,2,...
 |  | ||||||
| func (c *Commit) ParentCount() int { |  | ||||||
| 	return len(c.parents) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *Commit) CommitsBefore() (*list.List, error) { |  | ||||||
| 	return c.repo.getCommitsBefore(c.ID) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *Commit) CommitsBeforeUntil(commitId string) (*list.List, error) { |  | ||||||
| 	ec, err := c.repo.GetCommit(commitId) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return c.repo.CommitsBetween(c, ec) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *Commit) CommitsCount() (int, error) { |  | ||||||
| 	return c.repo.commitsCount(c.ID) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *Commit) SearchCommits(keyword string) (*list.List, error) { |  | ||||||
| 	return c.repo.searchCommits(c.ID, keyword) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *Commit) CommitsByRange(page int) (*list.List, error) { |  | ||||||
| 	return c.repo.commitsByRange(c.ID, page) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *Commit) GetCommitOfRelPath(relPath string) (*Commit, error) { |  | ||||||
| 	return c.repo.getCommitOfRelPath(c.ID, relPath) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *Commit) GetSubModule(entryname string) (*SubModule, error) { |  | ||||||
| 	modules, err := c.GetSubModules() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return modules[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 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func isImageFile(data []byte) (string, bool) { |  | ||||||
| 	contentType := http.DetectContentType(data) |  | ||||||
| 	if strings.Index(contentType, "image/") != -1 { |  | ||||||
| 		return contentType, true |  | ||||||
| 	} |  | ||||||
| 	return contentType, false |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *Commit) IsImageFile(name string) bool { |  | ||||||
| 	blob, err := c.GetBlobByPath(name) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	dataRc, err := blob.Data() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	buf := make([]byte, 1024) |  | ||||||
| 	n, _ := dataRc.Read(buf) |  | ||||||
| 	if n > 0 { |  | ||||||
| 		buf = buf[:n] |  | ||||||
| 	} |  | ||||||
| 	_, isImage := isImageFile(buf) |  | ||||||
| 	return isImage |  | ||||||
| } |  | ||||||
| @ -1,36 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"fmt" |  | ||||||
| 
 |  | ||||||
| 	"github.com/Unknwon/com" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type ArchiveType int |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	ZIP ArchiveType = iota + 1 |  | ||||||
| 	TARGZ |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func (c *Commit) CreateArchive(path string, archiveType ArchiveType) error { |  | ||||||
| 	var format string |  | ||||||
| 	switch archiveType { |  | ||||||
| 	case ZIP: |  | ||||||
| 		format = "zip" |  | ||||||
| 	case TARGZ: |  | ||||||
| 		format = "tar.gz" |  | ||||||
| 	default: |  | ||||||
| 		return fmt.Errorf("unknown format: %v", archiveType) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	_, stderr, err := com.ExecCmdDir(c.repo.Path, "git", "archive", "--format="+format, "-o", path, c.ID.String()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("%s", stderr) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| @ -1,22 +0,0 @@ | |||||||
| // 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) |  | ||||||
| } |  | ||||||
| @ -1,125 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"errors" |  | ||||||
| 	"io/ioutil" |  | ||||||
| 	"os" |  | ||||||
| 	"path" |  | ||||||
| 	"strings" |  | ||||||
| 
 |  | ||||||
| 	"github.com/Unknwon/com" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // hookNames is a list of Git hooks' name that are supported.
 |  | ||||||
| var hookNames = []string{ |  | ||||||
| 	"applypatch-msg", |  | ||||||
| 	"pre-applypatch", |  | ||||||
| 	"post-applypatch", |  | ||||||
| 	"pre-commit", |  | ||||||
| 	"prepare-commit-msg", |  | ||||||
| 	"commit-msg", |  | ||||||
| 	"post-commit", |  | ||||||
| 	"pre-rebase", |  | ||||||
| 	"post-checkout", |  | ||||||
| 	"post-merge", |  | ||||||
| 	"pre-push", |  | ||||||
| 	"pre-receive", |  | ||||||
| 	// "update",
 |  | ||||||
| 	"post-receive", |  | ||||||
| 	"post-update", |  | ||||||
| 	"push-to-checkout", |  | ||||||
| 	"pre-auto-gc", |  | ||||||
| 	"post-rewrite", |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	ErrNotValidHook = errors.New("not a valid Git hook") |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // IsValidHookName returns true if given name is a valid Git hook.
 |  | ||||||
| func IsValidHookName(name string) bool { |  | ||||||
| 	for _, hn := range hookNames { |  | ||||||
| 		if hn == name { |  | ||||||
| 			return true |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Hook represents a Git hook.
 |  | ||||||
| type Hook struct { |  | ||||||
| 	name     string |  | ||||||
| 	IsActive bool   // Indicates whether repository has this hook.
 |  | ||||||
| 	Content  string // Content of hook if it's active.
 |  | ||||||
| 	Sample   string // Sample content from Git.
 |  | ||||||
| 	path     string // Hook file path.
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetHook returns a Git hook by given name and repository.
 |  | ||||||
| func GetHook(repoPath, name string) (*Hook, error) { |  | ||||||
| 	if !IsValidHookName(name) { |  | ||||||
| 		return nil, ErrNotValidHook |  | ||||||
| 	} |  | ||||||
| 	h := &Hook{ |  | ||||||
| 		name: name, |  | ||||||
| 		path: path.Join(repoPath, "hooks", name), |  | ||||||
| 	} |  | ||||||
| 	if isFile(h.path) { |  | ||||||
| 		data, err := ioutil.ReadFile(h.path) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		h.IsActive = true |  | ||||||
| 		h.Content = string(data) |  | ||||||
| 	} else if isFile(h.path + ".sample") { |  | ||||||
| 		data, err := ioutil.ReadFile(h.path + ".sample") |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		h.Sample = string(data) |  | ||||||
| 	} |  | ||||||
| 	return h, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (h *Hook) Name() string { |  | ||||||
| 	return h.name |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Update updates hook settings.
 |  | ||||||
| func (h *Hook) Update() error { |  | ||||||
| 	if len(strings.TrimSpace(h.Content)) == 0 { |  | ||||||
| 		if com.IsExist(h.path) { |  | ||||||
| 			return os.Remove(h.path) |  | ||||||
| 		} |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return ioutil.WriteFile(h.path, []byte(strings.Replace(h.Content, "\r", "", -1)), os.ModePerm) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ListHooks returns a list of Git hooks of given repository.
 |  | ||||||
| func ListHooks(repoPath string) (_ []*Hook, err error) { |  | ||||||
| 	if !isDir(path.Join(repoPath, "hooks")) { |  | ||||||
| 		return nil, errors.New("hooks path does not exist") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	hooks := make([]*Hook, len(hookNames)) |  | ||||||
| 	for i, name := range hookNames { |  | ||||||
| 		hooks[i], err = GetHook(repoPath, name) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return hooks, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) GetHook(name string) (*Hook, error) { |  | ||||||
| 	return GetHook(repo.Path, name) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) Hooks() ([]*Hook, error) { |  | ||||||
| 	return ListHooks(repo.Path) |  | ||||||
| } |  | ||||||
| @ -1,30 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"errors" |  | ||||||
| 	"path/filepath" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Repository represents a Git repository.
 |  | ||||||
| type Repository struct { |  | ||||||
| 	Path string |  | ||||||
| 
 |  | ||||||
| 	commitCache map[sha1]*Commit |  | ||||||
| 	tagCache    map[sha1]*Tag |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // OpenRepository opens the repository at the given path.
 |  | ||||||
| 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 |  | ||||||
| } |  | ||||||
| @ -1,50 +0,0 @@ | |||||||
| // 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" |  | ||||||
| 
 |  | ||||||
| 	"github.com/Unknwon/com" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func IsBranchExist(repoPath, branchName string) bool { |  | ||||||
| 	_, _, err := com.ExecCmdDir(repoPath, "git", "show-ref", "--verify", "refs/heads/"+branchName) |  | ||||||
| 	return err == nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) IsBranchExist(branchName string) bool { |  | ||||||
| 	return IsBranchExist(repo.Path, branchName) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) GetBranches() ([]string, error) { |  | ||||||
| 	stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "show-ref", "--heads") |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, concatenateError(err, stderr) |  | ||||||
| 	} |  | ||||||
| 	infos := strings.Split(stdout, "\n") |  | ||||||
| 	branches := make([]string, len(infos)-1) |  | ||||||
| 	for i, info := range infos[:len(infos)-1] { |  | ||||||
| 		parts := strings.Split(info, " ") |  | ||||||
| 		if len(parts) != 2 { |  | ||||||
| 			continue // NOTE: I should believe git will not give me wrong string.
 |  | ||||||
| 		} |  | ||||||
| 		branches[i] = strings.TrimPrefix(parts[1], "refs/heads/") |  | ||||||
| 	} |  | ||||||
| 	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 |  | ||||||
| } |  | ||||||
| @ -1,341 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"container/list" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"strings" |  | ||||||
| 	"sync" |  | ||||||
| 
 |  | ||||||
| 	"github.com/Unknwon/com" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) getCommitIdOfRef(refpath string) (string, error) { |  | ||||||
| 	stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "show-ref", "--verify", refpath) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "", errors.New(stderr) |  | ||||||
| 	} |  | ||||||
| 	return strings.Split(stdout, " ")[0], nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) GetCommitIdOfBranch(branchName string) (string, error) { |  | ||||||
| 	return repo.getCommitIdOfRef("refs/heads/" + branchName) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // get branch's last commit or a special commit by id string
 |  | ||||||
| func (repo *Repository) GetCommitOfBranch(branchName string) (*Commit, error) { |  | ||||||
| 	commitId, err := repo.GetCommitIdOfBranch(branchName) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return repo.GetCommit(commitId) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) GetCommitIdOfTag(tagName string) (string, error) { |  | ||||||
| 	return repo.getCommitIdOfRef("refs/tags/" + tagName) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) GetCommitOfTag(tagName string) (*Commit, error) { |  | ||||||
| 	tag, err := repo.GetTag(tagName) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return tag.Commit() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Parse commit information from the (uncompressed) raw
 |  | ||||||
| // data from the commit object.
 |  | ||||||
| // \n\n separate headers from message
 |  | ||||||
| func parseCommitData(data []byte) (*Commit, error) { |  | ||||||
| 	commit := new(Commit) |  | ||||||
| 	commit.parents = make([]sha1, 0, 1) |  | ||||||
| 	// we now have the contents of the commit object. Let's investigate...
 |  | ||||||
| 	nextline := 0 |  | ||||||
| l: |  | ||||||
| 	for { |  | ||||||
| 		eol := bytes.IndexByte(data[nextline:], '\n') |  | ||||||
| 		switch { |  | ||||||
| 		case eol > 0: |  | ||||||
| 			line := data[nextline : nextline+eol] |  | ||||||
| 			spacepos := bytes.IndexByte(line, ' ') |  | ||||||
| 			reftype := line[:spacepos] |  | ||||||
| 			switch string(reftype) { |  | ||||||
| 			case "tree": |  | ||||||
| 				id, err := NewIdFromString(string(line[spacepos+1:])) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return nil, err |  | ||||||
| 				} |  | ||||||
| 				commit.Tree.ID = id |  | ||||||
| 			case "parent": |  | ||||||
| 				// A commit can have one or more parents
 |  | ||||||
| 				oid, err := NewIdFromString(string(line[spacepos+1:])) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return nil, err |  | ||||||
| 				} |  | ||||||
| 				commit.parents = append(commit.parents, oid) |  | ||||||
| 			case "author": |  | ||||||
| 				sig, err := newSignatureFromCommitline(line[spacepos+1:]) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return nil, err |  | ||||||
| 				} |  | ||||||
| 				commit.Author = sig |  | ||||||
| 			case "committer": |  | ||||||
| 				sig, err := newSignatureFromCommitline(line[spacepos+1:]) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return nil, err |  | ||||||
| 				} |  | ||||||
| 				commit.Committer = sig |  | ||||||
| 			} |  | ||||||
| 			nextline += eol + 1 |  | ||||||
| 		case eol == 0: |  | ||||||
| 			commit.CommitMessage = string(data[nextline+1:]) |  | ||||||
| 			break l |  | ||||||
| 		default: |  | ||||||
| 			break l |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return commit, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) getCommit(id sha1) (*Commit, error) { |  | ||||||
| 	if repo.commitCache != nil { |  | ||||||
| 		if c, ok := repo.commitCache[id]; ok { |  | ||||||
| 			return c, nil |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		repo.commitCache = make(map[sha1]*Commit, 10) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	data, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "cat-file", "-p", id.String()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, concatenateError(err, string(stderr)) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	commit, err := parseCommitData(data) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	commit.repo = repo |  | ||||||
| 	commit.ID = id |  | ||||||
| 
 |  | ||||||
| 	repo.commitCache[id] = commit |  | ||||||
| 	return commit, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Find the commit object in the repository.
 |  | ||||||
| func (repo *Repository) GetCommit(commitId string) (*Commit, error) { |  | ||||||
| 	id, err := NewIdFromString(commitId) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return repo.getCommit(id) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 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) |  | ||||||
| 	} |  | ||||||
| 	return com.StrTo(strings.TrimSpace(stdout)).Int() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) CommitsCount(commitId string) (int, error) { |  | ||||||
| 	id, err := NewIdFromString(commitId) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
| 	return repo.commitsCount(id) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) commitsCountBetween(start, end sha1) (int, error) { |  | ||||||
| 	if gitVer.LessThan(MustParseVersion("1.8.0")) { |  | ||||||
| 		stdout, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "log", |  | ||||||
| 			"--pretty=format:''", start.String()+"..."+end.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", |  | ||||||
| 		start.String()+"..."+end.String()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, errors.New(stderr) |  | ||||||
| 	} |  | ||||||
| 	return com.StrTo(strings.TrimSpace(stdout)).Int() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) CommitsCountBetween(startCommitID, endCommitID string) (int, error) { |  | ||||||
| 	start, err := NewIdFromString(startCommitID) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
| 	end, err := NewIdFromString(endCommitID) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, err |  | ||||||
| 	} |  | ||||||
| 	return repo.commitsCountBetween(start, end) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) FilesCountBetween(startCommitID, endCommitID string) (int, error) { |  | ||||||
| 	stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "diff", "--name-only", |  | ||||||
| 		startCommitID+"..."+endCommitID) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, fmt.Errorf("list changed files: %v", concatenateError(err, stderr)) |  | ||||||
| 	} |  | ||||||
| 	return len(strings.Split(stdout, "\n")) - 1, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // used only for single tree, (]
 |  | ||||||
| func (repo *Repository) CommitsBetween(last *Commit, before *Commit) (*list.List, error) { |  | ||||||
| 	l := list.New() |  | ||||||
| 	if last == nil || last.ParentCount() == 0 { |  | ||||||
| 		return l, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var err error |  | ||||||
| 	cur := last |  | ||||||
| 	for { |  | ||||||
| 		if cur.ID.Equal(before.ID) { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		l.PushBack(cur) |  | ||||||
| 		if cur.ParentCount() == 0 { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 		cur, err = cur.Parent(0) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return l, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) commitsBefore(lock *sync.Mutex, l *list.List, parent *list.Element, id sha1, limit int) error { |  | ||||||
| 	commit, err := repo.getCommit(id) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("getCommit: %v", err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var e *list.Element |  | ||||||
| 	if parent == nil { |  | ||||||
| 		e = l.PushBack(commit) |  | ||||||
| 	} else { |  | ||||||
| 		var in = parent |  | ||||||
| 		for { |  | ||||||
| 			if in == nil { |  | ||||||
| 				break |  | ||||||
| 			} else if in.Value.(*Commit).ID.Equal(commit.ID) { |  | ||||||
| 				return nil |  | ||||||
| 			} else { |  | ||||||
| 				if in.Next() == nil { |  | ||||||
| 					break |  | ||||||
| 				} |  | ||||||
| 				if in.Value.(*Commit).Committer.When.Equal(commit.Committer.When) { |  | ||||||
| 					break |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				if in.Value.(*Commit).Committer.When.After(commit.Committer.When) && |  | ||||||
| 					in.Next().Value.(*Commit).Committer.When.Before(commit.Committer.When) { |  | ||||||
| 					break |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			in = in.Next() |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		e = l.InsertAfter(commit, in) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var pr = parent |  | ||||||
| 	if commit.ParentCount() > 1 { |  | ||||||
| 		pr = e |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for i := 0; i < commit.ParentCount(); i++ { |  | ||||||
| 		id, err := commit.ParentId(i) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		err = repo.commitsBefore(lock, l, pr, id, 0) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) FileCommitsCount(branch, file string) (int, error) { |  | ||||||
| 	stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "rev-list", "--count", |  | ||||||
| 		branch, "--", file) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0, errors.New(stderr) |  | ||||||
| 	} |  | ||||||
| 	return com.StrTo(strings.TrimSpace(stdout)).Int() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) CommitsByFileAndRange(branch, file string, page int) (*list.List, error) { |  | ||||||
| 	stdout, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "log", branch, |  | ||||||
| 		"--skip="+com.ToStr((page-1)*50), "--max-count=50", prettyLogFormat, "--", file) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, errors.New(string(stderr)) |  | ||||||
| 	} |  | ||||||
| 	return parsePrettyFormatLog(repo, stdout) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) getCommitsBefore(id sha1) (*list.List, error) { |  | ||||||
| 	l := list.New() |  | ||||||
| 	lock := new(sync.Mutex) |  | ||||||
| 	return l, repo.commitsBefore(lock, l, nil, id, 0) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) searchCommits(id sha1, keyword string) (*list.List, error) { |  | ||||||
| 	stdout, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "log", id.String(), "-100", |  | ||||||
| 		"-i", "--grep="+keyword, prettyLogFormat) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} else if len(stderr) > 0 { |  | ||||||
| 		return nil, errors.New(string(stderr)) |  | ||||||
| 	} |  | ||||||
| 	return parsePrettyFormatLog(repo, stdout) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var CommitsRangeSize = 50 |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) commitsByRange(id sha1, page int) (*list.List, error) { |  | ||||||
| 	stdout, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "log", id.String(), |  | ||||||
| 		"--skip="+com.ToStr((page-1)*CommitsRangeSize), "--max-count="+com.ToStr(CommitsRangeSize), prettyLogFormat) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, errors.New(string(stderr)) |  | ||||||
| 	} |  | ||||||
| 	return parsePrettyFormatLog(repo, stdout) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) getCommitOfRelPath(id sha1, relPath string) (*Commit, error) { |  | ||||||
| 	stdout, _, err := com.ExecCmdDir(repo.Path, "git", "log", "-1", prettyLogFormat, id.String(), "--", relPath) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	id, err = NewIdFromString(string(stdout)) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return repo.getCommit(id) |  | ||||||
| } |  | ||||||
| @ -1,14 +0,0 @@ | |||||||
| // 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 |  | ||||||
| 
 |  | ||||||
| type ObjectType string |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	COMMIT ObjectType = "commit" |  | ||||||
| 	TREE   ObjectType = "tree" |  | ||||||
| 	BLOB   ObjectType = "blob" |  | ||||||
| 	TAG    ObjectType = "tag" |  | ||||||
| ) |  | ||||||
| @ -1,104 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"container/list" |  | ||||||
| 	"fmt" |  | ||||||
| 	"strings" |  | ||||||
| 	"time" |  | ||||||
| 
 |  | ||||||
| 	"github.com/Unknwon/com" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type PullRequestInfo struct { |  | ||||||
| 	MergeBase string |  | ||||||
| 	Commits   *list.List |  | ||||||
| 	// Diff      *Diff
 |  | ||||||
| 	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, err error) { |  | ||||||
| 	// Add a temporary remote.
 |  | ||||||
| 	tmpRemote := com.ToStr(time.Now().UnixNano()) |  | ||||||
| 	if err = repo.AddRemote(tmpRemote, basePath); err != nil { |  | ||||||
| 		return nil, fmt.Errorf("AddRemote: %v", err) |  | ||||||
| 	} |  | ||||||
| 	defer func() { |  | ||||||
| 		repo.RemoveRemote(tmpRemote) |  | ||||||
| 	}() |  | ||||||
| 
 |  | ||||||
| 	remoteBranch := "remotes/" + tmpRemote + "/" + baseBranch |  | ||||||
| 
 |  | ||||||
| 	prInfo := new(PullRequestInfo) |  | ||||||
| 	prInfo.MergeBase, err = repo.GetMergeBase(remoteBranch, headBranch) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, fmt.Errorf("GetMergeBase: %v", err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	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)) |  | ||||||
| 	} |  | ||||||
| 	prInfo.Commits, err = parsePrettyFormatLog(repo, []byte(stdout)) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, fmt.Errorf("parsePrettyFormatLog: %v", err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Count number of changed files.
 |  | ||||||
| 	stdout, stderr, err = com.ExecCmdDir(repo.Path, "git", "diff", "--name-only", remoteBranch+"..."+headBranch) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, fmt.Errorf("list changed files: %v", concatenateError(err, stderr)) |  | ||||||
| 	} |  | ||||||
| 	prInfo.NumFiles = len(strings.Split(stdout, "\n")) - 1 |  | ||||||
| 
 |  | ||||||
| 	return prInfo, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // 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", "--binary", mergeBase, headBranch) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, concatenateError(err, string(stderr)) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return stdout, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Merge merges pull request from head repository and branch.
 |  | ||||||
| func (repo *Repository) Merge(headRepoPath string, baseBranch, headBranch string) error { |  | ||||||
| 
 |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| @ -1,117 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"errors" |  | ||||||
| 	"strings" |  | ||||||
| 
 |  | ||||||
| 	"github.com/Unknwon/com" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func IsTagExist(repoPath, tagName string) bool { |  | ||||||
| 	_, _, err := com.ExecCmdDir(repoPath, "git", "show-ref", "--verify", "refs/tags/"+tagName) |  | ||||||
| 	return err == nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) IsTagExist(tagName string) bool { |  | ||||||
| 	return IsTagExist(repo.Path, tagName) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) getTagsReversed() ([]string, error) { |  | ||||||
| 	stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "tag", "-l", "--sort=-v:refname") |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, concatenateError(err, stderr) |  | ||||||
| 	} |  | ||||||
| 	tags := strings.Split(stdout, "\n") |  | ||||||
| 	return tags[:len(tags)-1], nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetTags returns all tags of given repository.
 |  | ||||||
| func (repo *Repository) GetTags() ([]string, error) { |  | ||||||
| 	if gitVer.AtLeast(MustParseVersion("2.0.0")) { |  | ||||||
| 		return repo.getTagsReversed() |  | ||||||
| 	} |  | ||||||
| 	stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "tag", "-l") |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, concatenateError(err, stderr) |  | ||||||
| 	} |  | ||||||
| 	tags := strings.Split(stdout, "\n") |  | ||||||
| 	return tags[:len(tags)-1], nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) CreateTag(tagName, idStr string) error { |  | ||||||
| 	_, stderr, err := com.ExecCmdDir(repo.Path, "git", "tag", tagName, idStr) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return errors.New(stderr) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) getTag(id sha1) (*Tag, error) { |  | ||||||
| 	if repo.tagCache != nil { |  | ||||||
| 		if t, ok := repo.tagCache[id]; ok { |  | ||||||
| 			return t, nil |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		repo.tagCache = make(map[sha1]*Tag, 10) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Get tag type.
 |  | ||||||
| 	tp, stderr, err := com.ExecCmdDir(repo.Path, "git", "cat-file", "-t", id.String()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, errors.New(stderr) |  | ||||||
| 	} |  | ||||||
| 	tp = strings.TrimSpace(tp) |  | ||||||
| 
 |  | ||||||
| 	// Tag is a commit.
 |  | ||||||
| 	if ObjectType(tp) == COMMIT { |  | ||||||
| 		tag := &Tag{ |  | ||||||
| 			ID:     id, |  | ||||||
| 			Object: id, |  | ||||||
| 			Type:   string(COMMIT), |  | ||||||
| 			repo:   repo, |  | ||||||
| 		} |  | ||||||
| 		repo.tagCache[id] = tag |  | ||||||
| 		return tag, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Tag with message.
 |  | ||||||
| 	data, bytErr, err := com.ExecCmdDirBytes(repo.Path, "git", "cat-file", "-p", id.String()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, errors.New(string(bytErr)) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	tag, err := parseTagData(data) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	tag.ID = id |  | ||||||
| 	tag.repo = repo |  | ||||||
| 
 |  | ||||||
| 	repo.tagCache[id] = tag |  | ||||||
| 	return tag, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetTag returns a Git tag by given name.
 |  | ||||||
| func (repo *Repository) GetTag(tagName string) (*Tag, error) { |  | ||||||
| 	stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "show-ref", "--tags", tagName) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, errors.New(stderr) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	id, err := NewIdFromString(strings.Split(stdout, " ")[0]) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	tag, err := repo.getTag(id) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	tag.Name = tagName |  | ||||||
| 	return tag, nil |  | ||||||
| } |  | ||||||
| @ -1,32 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"fmt" |  | ||||||
| 
 |  | ||||||
| 	"github.com/Unknwon/com" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Find the tree object in the repository.
 |  | ||||||
| func (repo *Repository) GetTree(idStr string) (*Tree, error) { |  | ||||||
| 	id, err := NewIdFromString(idStr) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return repo.getTree(id) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (repo *Repository) getTree(id sha1) (*Tree, error) { |  | ||||||
| 	treePath := filepathFromSHA1(repo.Path, id.String()) |  | ||||||
| 	if !com.IsFile(treePath) { |  | ||||||
| 		_, _, err := com.ExecCmdDir(repo.Path, "git", "ls-tree", id.String()) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, fmt.Errorf("repo.getTree: %v", ErrNotExist) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return NewTree(repo, id), nil |  | ||||||
| } |  | ||||||
| @ -1,87 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"encoding/hex" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	IDNotExist = errors.New("sha1 ID does not exist") |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type sha1 [20]byte |  | ||||||
| 
 |  | ||||||
| // Return true if s has the same sha1 as caller.
 |  | ||||||
| // Support 40-length-string, []byte, sha1
 |  | ||||||
| func (id sha1) Equal(s2 interface{}) bool { |  | ||||||
| 	switch v := s2.(type) { |  | ||||||
| 	case string: |  | ||||||
| 		if len(v) != 40 { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 		return v == id.String() |  | ||||||
| 	case []byte: |  | ||||||
| 		if len(v) != 20 { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 		for i, v := range v { |  | ||||||
| 			if id[i] != v { |  | ||||||
| 				return false |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	case sha1: |  | ||||||
| 		for i, v := range v { |  | ||||||
| 			if id[i] != v { |  | ||||||
| 				return false |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	default: |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Return string (hex) representation of the Oid
 |  | ||||||
| func (s sha1) String() string { |  | ||||||
| 	result := make([]byte, 0, 40) |  | ||||||
| 	hexvalues := []byte("0123456789abcdef") |  | ||||||
| 	for i := 0; i < 20; i++ { |  | ||||||
| 		result = append(result, hexvalues[s[i]>>4]) |  | ||||||
| 		result = append(result, hexvalues[s[i]&0xf]) |  | ||||||
| 	} |  | ||||||
| 	return string(result) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Create a new sha1 from a 20 byte slice.
 |  | ||||||
| func NewId(b []byte) (sha1, error) { |  | ||||||
| 	var id sha1 |  | ||||||
| 	if len(b) != 20 { |  | ||||||
| 		return id, errors.New("Length must be 20") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for i := 0; i < 20; i++ { |  | ||||||
| 		id[i] = b[i] |  | ||||||
| 	} |  | ||||||
| 	return id, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Create a new sha1 from a Sha1 string of length 40.
 |  | ||||||
| func NewIdFromString(s string) (sha1, error) { |  | ||||||
| 	s = strings.TrimSpace(s) |  | ||||||
| 	var id sha1 |  | ||||||
| 	if len(s) != 40 { |  | ||||||
| 		return id, fmt.Errorf("Length must be 40") |  | ||||||
| 	} |  | ||||||
| 	b, err := hex.DecodeString(s) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return id, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return NewId(b) |  | ||||||
| } |  | ||||||
| @ -1,51 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"strconv" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Author and Committer information
 |  | ||||||
| type Signature struct { |  | ||||||
| 	Email string |  | ||||||
| 	Name  string |  | ||||||
| 	When  time.Time |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Helper to get a signature from the commit line, which looks like these:
 |  | ||||||
| //     author Patrick Gundlach <gundlach@speedata.de> 1378823654 +0200
 |  | ||||||
| //     author Patrick Gundlach <gundlach@speedata.de> Thu, 07 Apr 2005 22:13:13 +0200
 |  | ||||||
| // but without the "author " at the beginning (this method should)
 |  | ||||||
| // be used for author and committer.
 |  | ||||||
| //
 |  | ||||||
| // 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]) |  | ||||||
| 	emailEnd := bytes.IndexByte(line, '>') |  | ||||||
| 	sig.Email = string(line[emailStart+1 : emailEnd]) |  | ||||||
| 
 |  | ||||||
| 	// Check date format.
 |  | ||||||
| 	firstChar := line[emailEnd+2] |  | ||||||
| 	if firstChar >= 48 && firstChar <= 57 { |  | ||||||
| 		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[emailEnd+2:])) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return sig, nil |  | ||||||
| } |  | ||||||
| @ -1,20 +0,0 @@ | |||||||
| // 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) |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| @ -1,70 +0,0 @@ | |||||||
| // 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" |  | ||||||
| 
 |  | ||||||
| 	"github.com/gogits/gogs/modules/setting" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| 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 { |  | ||||||
| 	if sf.refUrl == "" { |  | ||||||
| 		return "" |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	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 { |  | ||||||
| 		// fix problem with reverse proxy works only with local server
 |  | ||||||
| 		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:] |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return url |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // RefId returns reference ID.
 |  | ||||||
| func (sf *SubModuleFile) RefId() string { |  | ||||||
| 	return sf.refId |  | ||||||
| } |  | ||||||
| @ -1,67 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"bytes" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Tag represents a Git tag.
 |  | ||||||
| type Tag struct { |  | ||||||
| 	Name       string |  | ||||||
| 	ID         sha1 |  | ||||||
| 	repo       *Repository |  | ||||||
| 	Object     sha1 // The id of this commit object
 |  | ||||||
| 	Type       string |  | ||||||
| 	Tagger     *Signature |  | ||||||
| 	TagMessage string |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (tag *Tag) Commit() (*Commit, error) { |  | ||||||
| 	return tag.repo.getCommit(tag.Object) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Parse commit information from the (uncompressed) raw
 |  | ||||||
| // data from the commit object.
 |  | ||||||
| // \n\n separate headers from message
 |  | ||||||
| func parseTagData(data []byte) (*Tag, error) { |  | ||||||
| 	tag := new(Tag) |  | ||||||
| 	// we now have the contents of the commit object. Let's investigate...
 |  | ||||||
| 	nextline := 0 |  | ||||||
| l: |  | ||||||
| 	for { |  | ||||||
| 		eol := bytes.IndexByte(data[nextline:], '\n') |  | ||||||
| 		switch { |  | ||||||
| 		case eol > 0: |  | ||||||
| 			line := data[nextline : nextline+eol] |  | ||||||
| 			spacepos := bytes.IndexByte(line, ' ') |  | ||||||
| 			reftype := line[:spacepos] |  | ||||||
| 			switch string(reftype) { |  | ||||||
| 			case "object": |  | ||||||
| 				id, err := NewIdFromString(string(line[spacepos+1:])) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return nil, err |  | ||||||
| 				} |  | ||||||
| 				tag.Object = id |  | ||||||
| 			case "type": |  | ||||||
| 				// A commit can have one or more parents
 |  | ||||||
| 				tag.Type = string(line[spacepos+1:]) |  | ||||||
| 			case "tagger": |  | ||||||
| 				sig, err := newSignatureFromCommitline(line[spacepos+1:]) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return nil, err |  | ||||||
| 				} |  | ||||||
| 				tag.Tagger = sig |  | ||||||
| 			} |  | ||||||
| 			nextline += eol + 1 |  | ||||||
| 		case eol == 0: |  | ||||||
| 			tag.TagMessage = string(data[nextline+1:]) |  | ||||||
| 			break l |  | ||||||
| 		default: |  | ||||||
| 			break l |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return tag, nil |  | ||||||
| } |  | ||||||
| @ -1,157 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"errors" |  | ||||||
| 	"strings" |  | ||||||
| 
 |  | ||||||
| 	"github.com/Unknwon/com" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	ErrNotExist = errors.New("error not exist") |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // A tree is a flat directory listing.
 |  | ||||||
| type Tree struct { |  | ||||||
| 	ID   sha1 |  | ||||||
| 	repo *Repository |  | ||||||
| 
 |  | ||||||
| 	// parent tree
 |  | ||||||
| 	ptree *Tree |  | ||||||
| 
 |  | ||||||
| 	entries       Entries |  | ||||||
| 	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) { |  | ||||||
| 	entries := make([]*TreeEntry, 0, 10) |  | ||||||
| 	l := len(data) |  | ||||||
| 	pos := 0 |  | ||||||
| 	for pos < l { |  | ||||||
| 		entry := new(TreeEntry) |  | ||||||
| 		entry.ptree = tree |  | ||||||
| 		step := 6 |  | ||||||
| 		switch string(data[pos : pos+step]) { |  | ||||||
| 		case "100644": |  | ||||||
| 			entry.mode = ModeBlob |  | ||||||
| 			entry.Type = BLOB |  | ||||||
| 		case "100755": |  | ||||||
| 			entry.mode = ModeExec |  | ||||||
| 			entry.Type = BLOB |  | ||||||
| 		case "120000": |  | ||||||
| 			entry.mode = ModeSymlink |  | ||||||
| 			entry.Type = BLOB |  | ||||||
| 		case "160000": |  | ||||||
| 			entry.mode = ModeCommit |  | ||||||
| 			entry.Type = COMMIT |  | ||||||
| 
 |  | ||||||
| 			step = 8 |  | ||||||
| 		case "040000": |  | ||||||
| 			entry.mode = ModeTree |  | ||||||
| 			entry.Type = TREE |  | ||||||
| 		default: |  | ||||||
| 			return nil, errors.New("unknown type: " + string(data[pos:pos+step])) |  | ||||||
| 		} |  | ||||||
| 		pos += step + 6 // Skip string type of entry type.
 |  | ||||||
| 
 |  | ||||||
| 		step = 40 |  | ||||||
| 		id, err := NewIdFromString(string(data[pos : pos+step])) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		entry.ID = id |  | ||||||
| 		pos += step + 1 // Skip half of sha1.
 |  | ||||||
| 
 |  | ||||||
| 		step = bytes.IndexByte(data[pos:], '\n') |  | ||||||
| 
 |  | ||||||
| 		// In case entry name is surrounded by double quotes(it happens only in git-shell).
 |  | ||||||
| 		if data[pos] == '"' { |  | ||||||
| 			entry.name = string(UnescapeChars(data[pos+1 : pos+step-1])) |  | ||||||
| 		} else { |  | ||||||
| 			entry.name = string(data[pos : pos+step]) |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		pos += step + 1 |  | ||||||
| 		entries = append(entries, entry) |  | ||||||
| 	} |  | ||||||
| 	return entries, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *Tree) SubTree(rpath string) (*Tree, error) { |  | ||||||
| 	if len(rpath) == 0 { |  | ||||||
| 		return t, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	paths := strings.Split(rpath, "/") |  | ||||||
| 	var err error |  | ||||||
| 	var g = t |  | ||||||
| 	var p = t |  | ||||||
| 	var te *TreeEntry |  | ||||||
| 	for _, name := range paths { |  | ||||||
| 		te, err = p.GetTreeEntryByPath(name) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		g, err = t.repo.getTree(te.ID) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		g.ptree = p |  | ||||||
| 		p = g |  | ||||||
| 	} |  | ||||||
| 	return g, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *Tree) ListEntries(relpath string) (Entries, error) { |  | ||||||
| 	if t.entriesParsed { |  | ||||||
| 		return t.entries, nil |  | ||||||
| 	} |  | ||||||
| 	t.entriesParsed = true |  | ||||||
| 
 |  | ||||||
| 	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) |  | ||||||
| 	return t.entries, err |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewTree(repo *Repository, id sha1) *Tree { |  | ||||||
| 	tree := new(Tree) |  | ||||||
| 	tree.ID = id |  | ||||||
| 	tree.repo = repo |  | ||||||
| 	return tree |  | ||||||
| } |  | ||||||
| @ -1,59 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"fmt" |  | ||||||
| 	"path" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func (t *Tree) GetTreeEntryByPath(relpath string) (*TreeEntry, error) { |  | ||||||
| 	if len(relpath) == 0 { |  | ||||||
| 		return &TreeEntry{ |  | ||||||
| 			ID:   t.ID, |  | ||||||
| 			Type: TREE, |  | ||||||
| 			mode: ModeTree, |  | ||||||
| 		}, nil |  | ||||||
| 		// return nil, fmt.Errorf("GetTreeEntryByPath(empty relpath): %v", ErrNotExist)
 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	relpath = path.Clean(relpath) |  | ||||||
| 	parts := strings.Split(relpath, "/") |  | ||||||
| 	var err error |  | ||||||
| 	tree := t |  | ||||||
| 	for i, name := range parts { |  | ||||||
| 		if i == len(parts)-1 { |  | ||||||
| 			entries, err := tree.ListEntries(path.Dir(relpath)) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, err |  | ||||||
| 			} |  | ||||||
| 			for _, v := range entries { |  | ||||||
| 				if v.name == name { |  | ||||||
| 					return v, nil |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			tree, err = tree.SubTree(name) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil, fmt.Errorf("GetTreeEntryByPath: %v", ErrNotExist) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (t *Tree) GetBlobByPath(rpath string) (*Blob, error) { |  | ||||||
| 	entry, err := t.GetTreeEntryByPath(rpath) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if !entry.IsDir() { |  | ||||||
| 		return entry.Blob(), nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return nil, ErrNotExist |  | ||||||
| } |  | ||||||
| @ -1,113 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"sort" |  | ||||||
| 	"strings" |  | ||||||
| 
 |  | ||||||
| 	"github.com/Unknwon/com" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type EntryMode int |  | ||||||
| 
 |  | ||||||
| // There are only a few file modes in Git. They look like unix file modes, but they can only be
 |  | ||||||
| // one of these.
 |  | ||||||
| const ( |  | ||||||
| 	ModeBlob    EntryMode = 0100644 |  | ||||||
| 	ModeExec    EntryMode = 0100755 |  | ||||||
| 	ModeSymlink EntryMode = 0120000 |  | ||||||
| 	ModeCommit  EntryMode = 0160000 |  | ||||||
| 	ModeTree    EntryMode = 0040000 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type TreeEntry struct { |  | ||||||
| 	ID   sha1 |  | ||||||
| 	Type ObjectType |  | ||||||
| 
 |  | ||||||
| 	mode EntryMode |  | ||||||
| 	name string |  | ||||||
| 
 |  | ||||||
| 	ptree *Tree |  | ||||||
| 
 |  | ||||||
| 	commited bool |  | ||||||
| 
 |  | ||||||
| 	size  int64 |  | ||||||
| 	sized bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (te *TreeEntry) Name() string { |  | ||||||
| 	return te.name |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (te *TreeEntry) Size() int64 { |  | ||||||
| 	if te.IsDir() { |  | ||||||
| 		return 0 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if te.sized { |  | ||||||
| 		return te.size |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	stdout, _, err := com.ExecCmdDir(te.ptree.repo.Path, "git", "cat-file", "-s", te.ID.String()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return 0 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	te.sized = true |  | ||||||
| 	te.size = com.StrTo(strings.TrimSpace(stdout)).MustInt64() |  | ||||||
| 	return te.size |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (te *TreeEntry) IsSubModule() bool { |  | ||||||
| 	return te.mode == ModeCommit |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (te *TreeEntry) IsDir() bool { |  | ||||||
| 	return te.mode == ModeTree |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (te *TreeEntry) EntryMode() EntryMode { |  | ||||||
| 	return te.mode |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (te *TreeEntry) Blob() *Blob { |  | ||||||
| 	return &Blob{ |  | ||||||
| 		repo:      te.ptree.repo, |  | ||||||
| 		TreeEntry: te, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type Entries []*TreeEntry |  | ||||||
| 
 |  | ||||||
| var sorter = []func(t1, t2 *TreeEntry) bool{ |  | ||||||
| 	func(t1, t2 *TreeEntry) bool { |  | ||||||
| 		return (t1.IsDir() || t1.IsSubModule()) && !t2.IsDir() && !t2.IsSubModule() |  | ||||||
| 	}, |  | ||||||
| 	func(t1, t2 *TreeEntry) bool { |  | ||||||
| 		return t1.name < t2.name |  | ||||||
| 	}, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (bs Entries) Len() int      { return len(bs) } |  | ||||||
| func (bs Entries) Swap(i, j int) { bs[i], bs[j] = bs[j], bs[i] } |  | ||||||
| func (bs Entries) Less(i, j int) bool { |  | ||||||
| 	t1, t2 := bs[i], bs[j] |  | ||||||
| 	var k int |  | ||||||
| 	for k = 0; k < len(sorter)-1; k++ { |  | ||||||
| 		sort := sorter[k] |  | ||||||
| 		switch { |  | ||||||
| 		case sort(t1, t2): |  | ||||||
| 			return true |  | ||||||
| 		case sort(t2, t1): |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return sorter[k](t1, t2) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (bs Entries) Sort() { |  | ||||||
| 	sort.Sort(bs) |  | ||||||
| } |  | ||||||
| @ -1,82 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"container/list" |  | ||||||
| 	"fmt" |  | ||||||
| 	"os" |  | ||||||
| 	"path/filepath" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| const prettyLogFormat = `--pretty=format:%H` |  | ||||||
| 
 |  | ||||||
| func parsePrettyFormatLog(repo *Repository, logByts []byte) (*list.List, error) { |  | ||||||
| 	l := list.New() |  | ||||||
| 	if len(logByts) == 0 { |  | ||||||
| 		return l, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	parts := bytes.Split(logByts, []byte{'\n'}) |  | ||||||
| 
 |  | ||||||
| 	for _, commitId := range parts { |  | ||||||
| 		commit, err := repo.GetCommit(string(commitId)) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		l.PushBack(commit) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return l, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 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:] |  | ||||||
| 	} |  | ||||||
| 	return refStr |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // If the object is stored in its own file (i.e not in a pack file),
 |  | ||||||
| // this function returns the full path to the object file.
 |  | ||||||
| // It does not test if the file exists.
 |  | ||||||
| func filepathFromSHA1(rootdir, sha1 string) string { |  | ||||||
| 	return filepath.Join(rootdir, "objects", sha1[:2], sha1[2:]) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // isDir returns true if given path is a directory,
 |  | ||||||
| // or returns false when it's a file or does not exist.
 |  | ||||||
| func isDir(dir string) bool { |  | ||||||
| 	f, e := os.Stat(dir) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	return f.IsDir() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // isFile returns true if given path is a file,
 |  | ||||||
| // or returns false when it's a directory or does not exist.
 |  | ||||||
| func isFile(filePath string) bool { |  | ||||||
| 	f, e := os.Stat(filePath) |  | ||||||
| 	if e != nil { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	return !f.IsDir() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func concatenateError(err error, stderr string) error { |  | ||||||
| 	if len(stderr) == 0 { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return fmt.Errorf("%v: %s", err, stderr) |  | ||||||
| } |  | ||||||
| @ -1,104 +0,0 @@ | |||||||
| // 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 ( |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"strings" |  | ||||||
| 
 |  | ||||||
| 	"github.com/Unknwon/com" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	// Cached Git version.
 |  | ||||||
| 	gitVer *Version |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Version represents version of Git.
 |  | ||||||
| type Version struct { |  | ||||||
| 	Major, Minor, Patch int |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func ParseVersion(verStr string) (*Version, error) { |  | ||||||
| 	infos := strings.Split(verStr, ".") |  | ||||||
| 	if len(infos) < 3 { |  | ||||||
| 		return nil, errors.New("incorrect version input") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	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(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 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (v *Version) AtLeast(that *Version) bool { |  | ||||||
| 	return v.Compare(that) >= 0 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (v *Version) String() string { |  | ||||||
| 	return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // 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 |  | ||||||
| } |  | ||||||
| @ -18,10 +18,11 @@ import ( | |||||||
| 	"github.com/go-macaron/session" | 	"github.com/go-macaron/session" | ||||||
| 	"gopkg.in/macaron.v1" | 	"gopkg.in/macaron.v1" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/gogits/git-shell" | ||||||
|  | 
 | ||||||
| 	"github.com/gogits/gogs/models" | 	"github.com/gogits/gogs/models" | ||||||
| 	"github.com/gogits/gogs/modules/auth" | 	"github.com/gogits/gogs/modules/auth" | ||||||
| 	"github.com/gogits/gogs/modules/base" | 	"github.com/gogits/gogs/modules/base" | ||||||
| 	"github.com/gogits/gogs/modules/git" |  | ||||||
| 	"github.com/gogits/gogs/modules/log" | 	"github.com/gogits/gogs/modules/log" | ||||||
| 	"github.com/gogits/gogs/modules/setting" | 	"github.com/gogits/gogs/modules/setting" | ||||||
| ) | ) | ||||||
| @ -43,7 +44,7 @@ type RepoContext struct { | |||||||
| 	CommitID     string | 	CommitID     string | ||||||
| 	RepoLink     string | 	RepoLink     string | ||||||
| 	CloneLink    models.CloneLink | 	CloneLink    models.CloneLink | ||||||
| 	CommitsCount int | 	CommitsCount int64 | ||||||
| 	Mirror       *models.Mirror | 	Mirror       *models.Mirror | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -11,8 +11,9 @@ import ( | |||||||
| 
 | 
 | ||||||
| 	"gopkg.in/macaron.v1" | 	"gopkg.in/macaron.v1" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/gogits/git-shell" | ||||||
|  | 
 | ||||||
| 	"github.com/gogits/gogs/models" | 	"github.com/gogits/gogs/models" | ||||||
| 	"github.com/gogits/gogs/modules/git" |  | ||||||
| 	"github.com/gogits/gogs/modules/log" | 	"github.com/gogits/gogs/modules/log" | ||||||
| 	"github.com/gogits/gogs/modules/setting" | 	"github.com/gogits/gogs/modules/setting" | ||||||
| ) | ) | ||||||
| @ -257,9 +258,9 @@ func RepoRef() macaron.Handler { | |||||||
| 				} | 				} | ||||||
| 				refName = brs[0] | 				refName = brs[0] | ||||||
| 			} | 			} | ||||||
| 			ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommitOfBranch(refName) | 			ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				ctx.Handle(500, "GetCommitOfBranch", err) | 				ctx.Handle(500, "GetBranchCommit", err) | ||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
| 			ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() | 			ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() | ||||||
| @ -288,18 +289,18 @@ func RepoRef() macaron.Handler { | |||||||
| 			if ctx.Repo.GitRepo.IsBranchExist(refName) { | 			if ctx.Repo.GitRepo.IsBranchExist(refName) { | ||||||
| 				ctx.Repo.IsViewBranch = true | 				ctx.Repo.IsViewBranch = true | ||||||
| 
 | 
 | ||||||
| 				ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommitOfBranch(refName) | 				ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					ctx.Handle(500, "GetCommitOfBranch", err) | 					ctx.Handle(500, "GetBranchCommit", err) | ||||||
| 					return | 					return | ||||||
| 				} | 				} | ||||||
| 				ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() | 				ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() | ||||||
| 
 | 
 | ||||||
| 			} else if ctx.Repo.GitRepo.IsTagExist(refName) { | 			} else if ctx.Repo.GitRepo.IsTagExist(refName) { | ||||||
| 				ctx.Repo.IsViewTag = true | 				ctx.Repo.IsViewTag = true | ||||||
| 				ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommitOfTag(refName) | 				ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					ctx.Handle(500, "GetCommitOfTag", err) | 					ctx.Handle(500, "GetTagCommit", err) | ||||||
| 					return | 					return | ||||||
| 				} | 				} | ||||||
| 				ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() | 				ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() | ||||||
|  | |||||||
| @ -5,8 +5,9 @@ | |||||||
| package repo | package repo | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"github.com/gogits/git-shell" | ||||||
|  | 
 | ||||||
| 	"github.com/gogits/gogs/models" | 	"github.com/gogits/gogs/models" | ||||||
| 	"github.com/gogits/gogs/modules/git" |  | ||||||
| 	"github.com/gogits/gogs/modules/middleware" | 	"github.com/gogits/gogs/modules/middleware" | ||||||
| 	"github.com/gogits/gogs/routers/repo" | 	"github.com/gogits/gogs/routers/repo" | ||||||
| ) | ) | ||||||
| @ -20,7 +21,7 @@ func GetRawFile(ctx *middleware.Context) { | |||||||
| 
 | 
 | ||||||
| 	blob, err := ctx.Repo.Commit.GetBlobByPath(ctx.Repo.TreeName) | 	blob, err := ctx.Repo.Commit.GetBlobByPath(ctx.Repo.TreeName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if err == git.ErrNotExist { | 		if git.IsErrNotExist(err) { | ||||||
| 			ctx.Error(404) | 			ctx.Error(404) | ||||||
| 		} else { | 		} else { | ||||||
| 			ctx.APIError(500, "GetBlobByPath", err) | 			ctx.APIError(500, "GetBlobByPath", err) | ||||||
|  | |||||||
| @ -10,9 +10,10 @@ import ( | |||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/paginater" | 	"github.com/Unknwon/paginater" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/gogits/git-shell" | ||||||
|  | 
 | ||||||
| 	"github.com/gogits/gogs/models" | 	"github.com/gogits/gogs/models" | ||||||
| 	"github.com/gogits/gogs/modules/base" | 	"github.com/gogits/gogs/modules/base" | ||||||
| 	"github.com/gogits/gogs/modules/git" |  | ||||||
| 	"github.com/gogits/gogs/modules/middleware" | 	"github.com/gogits/gogs/modules/middleware" | ||||||
| 	"github.com/gogits/gogs/modules/setting" | 	"github.com/gogits/gogs/modules/setting" | ||||||
| ) | ) | ||||||
| @ -55,7 +56,7 @@ func Commits(ctx *middleware.Context) { | |||||||
| 	if page <= 1 { | 	if page <= 1 { | ||||||
| 		page = 1 | 		page = 1 | ||||||
| 	} | 	} | ||||||
| 	ctx.Data["Page"] = paginater.New(commitsCount, git.CommitsRangeSize, page, 5) | 	ctx.Data["Page"] = paginater.New(int(commitsCount), git.CommitsRangeSize, page, 5) | ||||||
| 
 | 
 | ||||||
| 	// Both `git log branchName` and `git log commitId` work.
 | 	// Both `git log branchName` and `git log commitId` work.
 | ||||||
| 	commits, err := ctx.Repo.Commit.CommitsByRange(page) | 	commits, err := ctx.Repo.Commit.CommitsByRange(page) | ||||||
| @ -123,7 +124,7 @@ func FileHistory(ctx *middleware.Context) { | |||||||
| 	if page <= 1 { | 	if page <= 1 { | ||||||
| 		page = 1 | 		page = 1 | ||||||
| 	} | 	} | ||||||
| 	ctx.Data["Page"] = paginater.New(commitsCount, git.CommitsRangeSize, page, 5) | 	ctx.Data["Page"] = paginater.New(int(commitsCount), git.CommitsRangeSize, page, 5) | ||||||
| 
 | 
 | ||||||
| 	commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(branchName, fileName, page) | 	commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(branchName, fileName, page) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @ -159,7 +160,7 @@ func Diff(ctx *middleware.Context) { | |||||||
| 
 | 
 | ||||||
| 	parents := make([]string, commit.ParentCount()) | 	parents := make([]string, commit.ParentCount()) | ||||||
| 	for i := 0; i < commit.ParentCount(); i++ { | 	for i := 0; i < commit.ParentCount(); i++ { | ||||||
| 		sha, err := commit.ParentId(i) | 		sha, err := commit.ParentID(i) | ||||||
| 		parents[i] = sha.String() | 		parents[i] = sha.String() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Handle(404, "repo.Diff", err) | 			ctx.Handle(404, "repo.Diff", err) | ||||||
|  | |||||||
| @ -8,8 +8,9 @@ import ( | |||||||
| 	"io" | 	"io" | ||||||
| 	"path" | 	"path" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/gogits/git-shell" | ||||||
|  | 
 | ||||||
| 	"github.com/gogits/gogs/modules/base" | 	"github.com/gogits/gogs/modules/base" | ||||||
| 	"github.com/gogits/gogs/modules/git" |  | ||||||
| 	"github.com/gogits/gogs/modules/middleware" | 	"github.com/gogits/gogs/modules/middleware" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @ -21,7 +22,7 @@ func ServeData(ctx *middleware.Context, name string, reader io.Reader) error { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	_, isTextFile := base.IsTextFile(buf) | 	_, isTextFile := base.IsTextFile(buf) | ||||||
| 	if ! isTextFile { | 	if !isTextFile { | ||||||
| 		_, isImageFile := base.IsImageFile(buf) | 		_, isImageFile := base.IsImageFile(buf) | ||||||
| 		if !isImageFile { | 		if !isImageFile { | ||||||
| 			ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+path.Base(ctx.Repo.TreeName)) | 			ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+path.Base(ctx.Repo.TreeName)) | ||||||
| @ -45,7 +46,7 @@ func ServeBlob(ctx *middleware.Context, blob *git.Blob) error { | |||||||
| func SingleDownload(ctx *middleware.Context) { | func SingleDownload(ctx *middleware.Context) { | ||||||
| 	blob, err := ctx.Repo.Commit.GetBlobByPath(ctx.Repo.TreeName) | 	blob, err := ctx.Repo.Commit.GetBlobByPath(ctx.Repo.TreeName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if err == git.ErrNotExist { | 		if git.IsErrNotExist(err) { | ||||||
| 			ctx.Handle(404, "GetBlobByPath", nil) | 			ctx.Handle(404, "GetBlobByPath", nil) | ||||||
| 		} else { | 		} else { | ||||||
| 			ctx.Handle(500, "GetBlobByPath", err) | 			ctx.Handle(500, "GetBlobByPath", err) | ||||||
|  | |||||||
| @ -12,10 +12,11 @@ import ( | |||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/gogits/git-shell" | ||||||
|  | 
 | ||||||
| 	"github.com/gogits/gogs/models" | 	"github.com/gogits/gogs/models" | ||||||
| 	"github.com/gogits/gogs/modules/auth" | 	"github.com/gogits/gogs/modules/auth" | ||||||
| 	"github.com/gogits/gogs/modules/base" | 	"github.com/gogits/gogs/modules/base" | ||||||
| 	"github.com/gogits/gogs/modules/git" |  | ||||||
| 	"github.com/gogits/gogs/modules/log" | 	"github.com/gogits/gogs/modules/log" | ||||||
| 	"github.com/gogits/gogs/modules/middleware" | 	"github.com/gogits/gogs/modules/middleware" | ||||||
| 	"github.com/gogits/gogs/modules/setting" | 	"github.com/gogits/gogs/modules/setting" | ||||||
| @ -328,9 +329,9 @@ func ViewPullFiles(ctx *middleware.Context) { | |||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		headCommitID, err := headGitRepo.GetCommitIdOfBranch(pull.HeadBranch) | 		headCommitID, err := headGitRepo.GetBranchCommitID(pull.HeadBranch) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Handle(500, "GetCommitIdOfBranch", err) | 			ctx.Handle(500, "GetBranchCommitID", err) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @ -492,9 +493,9 @@ func PrepareCompareDiff( | |||||||
| 	// Get diff information.
 | 	// Get diff information.
 | ||||||
| 	ctx.Data["CommitRepoLink"] = headRepo.RepoLink() | 	ctx.Data["CommitRepoLink"] = headRepo.RepoLink() | ||||||
| 
 | 
 | ||||||
| 	headCommitID, err := headGitRepo.GetCommitIdOfBranch(headBranch) | 	headCommitID, err := headGitRepo.GetBranchCommitID(headBranch) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Handle(500, "GetCommitIdOfBranch", err) | 		ctx.Handle(500, "GetBranchCommitID", err) | ||||||
| 		return false | 		return false | ||||||
| 	} | 	} | ||||||
| 	ctx.Data["AfterCommitID"] = headCommitID | 	ctx.Data["AfterCommitID"] = headCommitID | ||||||
|  | |||||||
| @ -34,7 +34,7 @@ func Releases(ctx *middleware.Context) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Temproray cache commits count of used branches to speed up.
 | 	// Temproray cache commits count of used branches to speed up.
 | ||||||
| 	countCache := make(map[string]int) | 	countCache := make(map[string]int64) | ||||||
| 
 | 
 | ||||||
| 	tags := make([]*models.Release, len(rawTags)) | 	tags := make([]*models.Release, len(rawTags)) | ||||||
| 	for i, rawTag := range rawTags { | 	for i, rawTag := range rawTags { | ||||||
| @ -45,7 +45,7 @@ func Releases(ctx *middleware.Context) { | |||||||
| 			if rel.TagName == rawTag { | 			if rel.TagName == rawTag { | ||||||
| 				rel.Publisher, err = models.GetUserByID(rel.PublisherID) | 				rel.Publisher, err = models.GetUserByID(rel.PublisherID) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					ctx.Handle(500, "GetUserById", err) | 					ctx.Handle(500, "GetUserByID", err) | ||||||
| 					return | 					return | ||||||
| 				} | 				} | ||||||
| 				// FIXME: duplicated code.
 | 				// FIXME: duplicated code.
 | ||||||
| @ -53,14 +53,14 @@ func Releases(ctx *middleware.Context) { | |||||||
| 				if ctx.Repo.BranchName != rel.Target { | 				if ctx.Repo.BranchName != rel.Target { | ||||||
| 					// Get count if not exists.
 | 					// Get count if not exists.
 | ||||||
| 					if _, ok := countCache[rel.Target]; !ok { | 					if _, ok := countCache[rel.Target]; !ok { | ||||||
| 						commit, err := ctx.Repo.GitRepo.GetCommitOfBranch(ctx.Repo.BranchName) | 						commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.BranchName) | ||||||
| 						if err != nil { | 						if err != nil { | ||||||
| 							ctx.Handle(500, "GetCommitOfBranch", err) | 							ctx.Handle(500, "GetBranchCommit", err) | ||||||
| 							return | 							return | ||||||
| 						} | 						} | ||||||
| 						countCache[ctx.Repo.BranchName], err = commit.CommitsCount() | 						countCache[ctx.Repo.BranchName], err = commit.CommitsCount() | ||||||
| 						if err != nil { | 						if err != nil { | ||||||
| 							ctx.Handle(500, "CommitsCount2", err) | 							ctx.Handle(500, "CommitsCount", err) | ||||||
| 							return | 							return | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| @ -77,9 +77,9 @@ func Releases(ctx *middleware.Context) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if tags[i] == nil { | 		if tags[i] == nil { | ||||||
| 			commit, err := ctx.Repo.GitRepo.GetCommitOfTag(rawTag) | 			commit, err := ctx.Repo.GitRepo.GetTagCommit(rawTag) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				ctx.Handle(500, "GetCommitOfTag2", err) | 				ctx.Handle(500, "GetTagCommit", err) | ||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| @ -89,7 +89,7 @@ func Releases(ctx *middleware.Context) { | |||||||
| 				Sha1:    commit.ID.String(), | 				Sha1:    commit.ID.String(), | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			tags[i].NumCommits, err = ctx.Repo.GitRepo.CommitsCount(commit.ID.String()) | 			tags[i].NumCommits, err = commit.CommitsCount() | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				ctx.Handle(500, "CommitsCount", err) | 				ctx.Handle(500, "CommitsCount", err) | ||||||
| 				return | 				return | ||||||
| @ -105,7 +105,7 @@ func Releases(ctx *middleware.Context) { | |||||||
| 
 | 
 | ||||||
| 		rel.Publisher, err = models.GetUserByID(rel.PublisherID) | 		rel.Publisher, err = models.GetUserByID(rel.PublisherID) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Handle(500, "GetUserById", err) | 			ctx.Handle(500, "GetUserByID", err) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		// FIXME: duplicated code.
 | 		// FIXME: duplicated code.
 | ||||||
| @ -113,14 +113,14 @@ func Releases(ctx *middleware.Context) { | |||||||
| 		if ctx.Repo.BranchName != rel.Target { | 		if ctx.Repo.BranchName != rel.Target { | ||||||
| 			// Get count if not exists.
 | 			// Get count if not exists.
 | ||||||
| 			if _, ok := countCache[rel.Target]; !ok { | 			if _, ok := countCache[rel.Target]; !ok { | ||||||
| 				commit, err := ctx.Repo.GitRepo.GetCommitOfBranch(ctx.Repo.BranchName) | 				commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.BranchName) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					ctx.Handle(500, "GetCommitOfBranch", err) | 					ctx.Handle(500, "GetBranchCommit", err) | ||||||
| 					return | 					return | ||||||
| 				} | 				} | ||||||
| 				countCache[ctx.Repo.BranchName], err = commit.CommitsCount() | 				countCache[ctx.Repo.BranchName], err = commit.CommitsCount() | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					ctx.Handle(500, "CommitsCount2", err) | 					ctx.Handle(500, "CommitsCount", err) | ||||||
| 					return | 					return | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| @ -158,9 +158,9 @@ func NewReleasePost(ctx *middleware.Context, form auth.NewReleaseForm) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	commit, err := ctx.Repo.GitRepo.GetCommitOfBranch(form.Target) | 	commit, err := ctx.Repo.GitRepo.GetBranchCommit(form.Target) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Handle(500, "GetCommitOfBranch", err) | 		ctx.Handle(500, "GetBranchCommit", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -12,10 +12,11 @@ import ( | |||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/gogits/git-shell" | ||||||
|  | 
 | ||||||
| 	"github.com/gogits/gogs/models" | 	"github.com/gogits/gogs/models" | ||||||
| 	"github.com/gogits/gogs/modules/auth" | 	"github.com/gogits/gogs/modules/auth" | ||||||
| 	"github.com/gogits/gogs/modules/base" | 	"github.com/gogits/gogs/modules/base" | ||||||
| 	"github.com/gogits/gogs/modules/git" |  | ||||||
| 	"github.com/gogits/gogs/modules/log" | 	"github.com/gogits/gogs/modules/log" | ||||||
| 	"github.com/gogits/gogs/modules/middleware" | 	"github.com/gogits/gogs/modules/middleware" | ||||||
| 	"github.com/gogits/gogs/modules/setting" | 	"github.com/gogits/gogs/modules/setting" | ||||||
| @ -294,21 +295,21 @@ func Download(ctx *middleware.Context) { | |||||||
| 	) | 	) | ||||||
| 	gitRepo := ctx.Repo.GitRepo | 	gitRepo := ctx.Repo.GitRepo | ||||||
| 	if gitRepo.IsBranchExist(refName) { | 	if gitRepo.IsBranchExist(refName) { | ||||||
| 		commit, err = gitRepo.GetCommitOfBranch(refName) | 		commit, err = gitRepo.GetBranchCommit(refName) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Handle(500, "Download", err) | 			ctx.Handle(500, "GetBranchCommit", err) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 	} else if gitRepo.IsTagExist(refName) { | 	} else if gitRepo.IsTagExist(refName) { | ||||||
| 		commit, err = gitRepo.GetCommitOfTag(refName) | 		commit, err = gitRepo.GetTagCommit(refName) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Handle(500, "Download", err) | 			ctx.Handle(500, "GetTagCommit", err) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 	} else if len(refName) == 40 { | 	} else if len(refName) == 40 { | ||||||
| 		commit, err = gitRepo.GetCommit(refName) | 		commit, err = gitRepo.GetCommit(refName) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Handle(404, "Download", nil) | 			ctx.Handle(404, "GetCommit", nil) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
|  | |||||||
| @ -8,10 +8,11 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/gogits/git-shell" | ||||||
|  | 
 | ||||||
| 	"github.com/gogits/gogs/models" | 	"github.com/gogits/gogs/models" | ||||||
| 	"github.com/gogits/gogs/modules/auth" | 	"github.com/gogits/gogs/modules/auth" | ||||||
| 	"github.com/gogits/gogs/modules/base" | 	"github.com/gogits/gogs/modules/base" | ||||||
| 	"github.com/gogits/gogs/modules/git" |  | ||||||
| 	"github.com/gogits/gogs/modules/log" | 	"github.com/gogits/gogs/modules/log" | ||||||
| 	"github.com/gogits/gogs/modules/mailer" | 	"github.com/gogits/gogs/modules/mailer" | ||||||
| 	"github.com/gogits/gogs/modules/middleware" | 	"github.com/gogits/gogs/modules/middleware" | ||||||
|  | |||||||
| @ -13,9 +13,10 @@ import ( | |||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/paginater" | 	"github.com/Unknwon/paginater" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/gogits/git-shell" | ||||||
|  | 
 | ||||||
| 	"github.com/gogits/gogs/models" | 	"github.com/gogits/gogs/models" | ||||||
| 	"github.com/gogits/gogs/modules/base" | 	"github.com/gogits/gogs/modules/base" | ||||||
| 	"github.com/gogits/gogs/modules/git" |  | ||||||
| 	"github.com/gogits/gogs/modules/log" | 	"github.com/gogits/gogs/modules/log" | ||||||
| 	"github.com/gogits/gogs/modules/middleware" | 	"github.com/gogits/gogs/modules/middleware" | ||||||
| 	"github.com/gogits/gogs/modules/template" | 	"github.com/gogits/gogs/modules/template" | ||||||
| @ -59,7 +60,7 @@ func Home(ctx *middleware.Context) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treename) | 	entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treename) | ||||||
| 	if err != nil && err != git.ErrNotExist { | 	if err != nil && git.IsErrNotExist(err) { | ||||||
| 		ctx.Handle(404, "GetTreeEntryByPath", err) | 		ctx.Handle(404, "GetTreeEntryByPath", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| @ -126,7 +127,7 @@ func Home(ctx *middleware.Context) { | |||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		entries, err := tree.ListEntries(treename) | 		entries, err := tree.ListEntries() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Handle(500, "ListEntries", err) | 			ctx.Handle(500, "ListEntries", err) | ||||||
| 			return | 			return | ||||||
| @ -135,10 +136,10 @@ func Home(ctx *middleware.Context) { | |||||||
| 
 | 
 | ||||||
| 		files := make([][]interface{}, 0, len(entries)) | 		files := make([][]interface{}, 0, len(entries)) | ||||||
| 		for _, te := range entries { | 		for _, te := range entries { | ||||||
| 			if te.Type != git.COMMIT { | 			if te.Type != git.OBJECT_COMMIT { | ||||||
| 				c, err := ctx.Repo.Commit.GetCommitOfRelPath(filepath.Join(treePath, te.Name())) | 				c, err := ctx.Repo.Commit.GetCommitByPath(filepath.Join(treePath, te.Name())) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					ctx.Handle(500, "GetCommitOfRelPath", err) | 					ctx.Handle(500, "GetCommitByPath", err) | ||||||
| 					return | 					return | ||||||
| 				} | 				} | ||||||
| 				files = append(files, []interface{}{te, c}) | 				files = append(files, []interface{}{te, c}) | ||||||
| @ -153,9 +154,9 @@ func Home(ctx *middleware.Context) { | |||||||
| 					smUrl = sm.Url | 					smUrl = sm.Url | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				c, err := ctx.Repo.Commit.GetCommitOfRelPath(filepath.Join(treePath, te.Name())) | 				c, err := ctx.Repo.Commit.GetCommitByPath(filepath.Join(treePath, te.Name())) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					ctx.Handle(500, "GetCommitOfRelPath", err) | 					ctx.Handle(500, "GetCommitByPath", err) | ||||||
| 					return | 					return | ||||||
| 				} | 				} | ||||||
| 				files = append(files, []interface{}{te, git.NewSubModuleFile(c, smUrl, te.ID.String())}) | 				files = append(files, []interface{}{te, git.NewSubModuleFile(c, smUrl, te.ID.String())}) | ||||||
| @ -209,9 +210,9 @@ func Home(ctx *middleware.Context) { | |||||||
| 
 | 
 | ||||||
| 		lastCommit := ctx.Repo.Commit | 		lastCommit := ctx.Repo.Commit | ||||||
| 		if len(treePath) > 0 { | 		if len(treePath) > 0 { | ||||||
| 			c, err := ctx.Repo.Commit.GetCommitOfRelPath(treePath) | 			c, err := ctx.Repo.Commit.GetCommitByPath(treePath) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				ctx.Handle(500, "GetCommitOfRelPath", err) | 				ctx.Handle(500, "GetCommitByPath", err) | ||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
| 			lastCommit = c | 			lastCommit = c | ||||||
|  | |||||||
| @ -42,9 +42,9 @@ func renderWikiPage(ctx *middleware.Context, isViewPage bool) (*git.Repository, | |||||||
| 		ctx.Handle(500, "OpenRepository", err) | 		ctx.Handle(500, "OpenRepository", err) | ||||||
| 		return nil, "" | 		return nil, "" | ||||||
| 	} | 	} | ||||||
| 	commit, err := wikiRepo.GetCommitOfBranch("master") | 	commit, err := wikiRepo.GetBranchCommit("master") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Handle(500, "GetCommitOfBranch", err) | 		ctx.Handle(500, "GetBranchCommit", err) | ||||||
| 		return nil, "" | 		return nil, "" | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -147,9 +147,9 @@ func WikiPages(ctx *middleware.Context) { | |||||||
| 		ctx.Handle(500, "OpenRepository", err) | 		ctx.Handle(500, "OpenRepository", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	commit, err := wikiRepo.GetCommitOfBranch("master") | 	commit, err := wikiRepo.GetBranchCommit("master") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Handle(500, "GetCommitOfBranch", err) | 		ctx.Handle(500, "GetBranchCommit", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1 +1 @@ | |||||||
| 0.7.36.1209 Beta | 0.7.37.1209 Beta | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user