aboutsummaryrefslogtreecommitdiff
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/issue.go2
-rw-r--r--models/org.go38
-rw-r--r--models/pull.go9
-rw-r--r--models/repo.go5
-rw-r--r--models/user.go17
-rw-r--r--models/wiki.go62
6 files changed, 89 insertions, 44 deletions
diff --git a/models/issue.go b/models/issue.go
index 4c33bc6b..a11b9b3f 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -301,7 +301,7 @@ func newIssue(e *xorm.Session, repo *Repository, issue *Issue, labelIDs []int64,
// So we have to get all needed labels first.
labels := make([]*Label, 0, len(labelIDs))
if err = e.In("id", labelIDs).Find(&labels); err != nil {
- return fmt.Errorf("Find all labels: %v", err)
+ return fmt.Errorf("find all labels: %v", err)
}
for _, label := range labels {
diff --git a/models/org.go b/models/org.go
index 680518c1..1fee4f52 100644
--- a/models/org.go
+++ b/models/org.go
@@ -1054,11 +1054,10 @@ func RemoveOrgRepo(orgID, repoID int64) error {
// GetUserRepositories gets all repositories of an organization,
// that the user with the given userID has access to.
func (org *User) GetUserRepositories(userID int64) (err error) {
- teams := make([]*Team, 0, 10)
- if err = x.Where("`team_user`.org_id=?", org.Id).
- And("`team_user`.uid=?", userID).
- Join("INNER", "`team_user`", "`team_user`.team_id=`team`.id").
- Find(&teams); err != nil {
+ teams := make([]*Team, 0, org.NumTeams)
+ if err = x.Sql(`SELECT team.id FROM team
+INNER JOIN team_user ON team_user.team_id = team.id
+WHERE team_user.org_id = ? AND team_user.uid = ?`, org.Id, userID).Find(&teams); err != nil {
return fmt.Errorf("get teams: %v", err)
}
@@ -1071,18 +1070,15 @@ func (org *User) GetUserRepositories(userID int64) (err error) {
teamIDs = append(teamIDs, "-1") // there is no repo with id=-1
}
- // Due to a bug in xorm using IN() together with OR() is impossible.
- // As a workaround, we have to build the IN statement on our own, until this is fixed.
- // https://github.com/go-xorm/xorm/issues/342
-
- if err = x.Join("INNER", "`team_repo`", "`team_repo`.repo_id=`repository`.id").
- Where("`repository`.owner_id=?", org.Id).
- And("`repository`.is_private=?", false).
- Or("`team_repo`.team_id IN (?)", strings.Join(teamIDs, ",")).
- GroupBy("`repository`.id").
- Find(&org.Repos); err != nil {
+ repos := make([]*Repository, 0, 5)
+ if err = x.Sql(`SELECT repository.* FROM repository
+INNER JOIN team_repo ON team_repo.repo_id = repository.id
+WHERE (repository.owner_id = ? AND repository.is_private = ?) OR team_repo.team_id IN (?)
+GROUP BY repository.id`,
+ org.Id, false, strings.Join(teamIDs, ",")).Find(&repos); err != nil {
return fmt.Errorf("get repositories: %v", err)
}
+ org.Repos = repos
// FIXME: should I change this value inside method,
// or only in location of caller where it's really needed?
@@ -1093,12 +1089,12 @@ func (org *User) GetUserRepositories(userID int64) (err error) {
// GetTeams returns all teams that belong to organization,
// and that the user has joined.
func (org *User) GetUserTeams(userID int64) error {
- if err := x.Cols("`team`.*").
- Where("`team_user`.org_id=?", org.Id).
- And("`team_user`.uid=?", userID).
- Join("INNER", "`team_user`", "`team_user`.team_id=`team`.id").
- Find(&org.Teams); err != nil {
- return fmt.Errorf("GetUserTeams: %v", err)
+ teams := make([]*Team, 0, 5)
+ if err := x.Sql(`SELECT team.* FROM team
+INNER JOIN team_user ON team_user.team_id = team.id
+WHERE team_user.org_id = ? AND team_user.uid = ?`,
+ org.Id, userID).Find(&teams); err != nil {
+ return fmt.Errorf("get teams: %v", err)
}
// FIXME: should I change this value inside method,
diff --git a/models/pull.go b/models/pull.go
index 276dc1bc..8103d71e 100644
--- a/models/pull.go
+++ b/models/pull.go
@@ -487,7 +487,7 @@ func (pr *PullRequest) UpdatePatch() (err error) {
// FIXME: could fail after user force push head repo, should we always force push here?
// FIXME: Only push branches that are actually updates?
func (pr *PullRequest) PushToBaseRepo() (err error) {
- log.Trace("PushToBaseRepo[%[1]d]: pushing commits to base repo 'refs/pull/%[1]d/head'", pr.ID)
+ log.Trace("PushToBaseRepo[%d]: pushing commits to base repo 'refs/pull/%d/head'", pr.BaseRepoID, pr.Index)
headRepoPath := pr.HeadRepo.RepoPath()
headGitRepo, err := git.OpenRepository(headRepoPath)
@@ -502,7 +502,12 @@ func (pr *PullRequest) PushToBaseRepo() (err error) {
// Make sure to remove the remote even if the push fails
defer headGitRepo.RemoveRemote(tmpRemoteName)
- if err = git.Push(headRepoPath, tmpRemoteName, fmt.Sprintf("%s:refs/pull/%d/head", pr.HeadBranch, pr.Index)); err != nil {
+ headFile := fmt.Sprintf("refs/pull/%d/head", pr.Index)
+
+ // Remove head in case there is a conflict.
+ os.Remove(path.Join(pr.BaseRepo.RepoPath(), headFile))
+
+ if err = git.Push(headRepoPath, tmpRemoteName, fmt.Sprintf("%s:%s", pr.HeadBranch, headFile)); err != nil {
return fmt.Errorf("Push: %v", err)
}
diff --git a/models/repo.go b/models/repo.go
index a23abc0c..eff66254 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -184,6 +184,11 @@ type Repository struct {
func (repo *Repository) AfterSet(colName string, _ xorm.Cell) {
switch colName {
+ case "default_branch":
+ // FIXME: use models migration to solve all at once.
+ if len(repo.DefaultBranch) == 0 {
+ repo.DefaultBranch = "master"
+ }
case "num_closed_issues":
repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
case "num_closed_pulls":
diff --git a/models/user.go b/models/user.go
index 3264c063..6e7c2729 100644
--- a/models/user.go
+++ b/models/user.go
@@ -348,16 +348,10 @@ func (u *User) UploadAvatar(data []byte) error {
// IsAdminOfRepo returns true if user has admin or higher access of repository.
func (u *User) IsAdminOfRepo(repo *Repository) bool {
- if err := repo.GetOwner(); err != nil {
- log.Error(3, "GetOwner: %v", err)
- return false
- }
-
- if repo.Owner.IsOrganization() {
+ if repo.MustOwner().IsOrganization() {
has, err := HasAccess(u, repo, ACCESS_MODE_ADMIN)
if err != nil {
log.Error(3, "HasAccess: %v", err)
- return false
}
return has
}
@@ -365,6 +359,15 @@ func (u *User) IsAdminOfRepo(repo *Repository) bool {
return repo.IsOwnedBy(u.Id)
}
+// CanWriteTo returns true if user has write access to given repository.
+func (u *User) CanWriteTo(repo *Repository) bool {
+ has, err := HasAccess(u, repo, ACCESS_MODE_WRITE)
+ if err != nil {
+ log.Error(3, "HasAccess: %v", err)
+ }
+ return has
+}
+
// IsOrganization returns true if user is actually a organization.
func (u *User) IsOrganization() bool {
return u.Type == ORGANIZATION
diff --git a/models/wiki.go b/models/wiki.go
index e3eb1f68..fee5a408 100644
--- a/models/wiki.go
+++ b/models/wiki.go
@@ -7,12 +7,12 @@ package models
import (
"fmt"
"io/ioutil"
+ "net/url"
"os"
"path"
"path/filepath"
"strings"
"sync"
- "net/url"
"github.com/Unknwon/com"
@@ -116,6 +116,23 @@ func (repo *Repository) UpdateLocalWiki() error {
return updateLocalCopy(repo.WikiPath(), repo.LocalWikiPath())
}
+// discardLocalWikiChanges discards local commits make sure
+// it is even to remote branch when local copy exists.
+func discardLocalWikiChanges(localPath string) error {
+ if !com.IsExist(localPath) {
+ return nil
+ }
+ // No need to check if nothing in the repository.
+ if !git.IsBranchExist(localPath, "master") {
+ return nil
+ }
+
+ if err := git.ResetHEAD(localPath, true, "origin/master"); err != nil {
+ return fmt.Errorf("ResetHEAD: %v", err)
+ }
+ return nil
+}
+
// updateWikiPage adds new page to repository wiki.
func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, message string, isNew bool) (err error) {
wikiWorkingPool.CheckIn(com.ToStr(repo.ID))
@@ -126,18 +143,9 @@ func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, mes
}
localPath := repo.LocalWikiPath()
-
- // Discard local commits make sure even to remote when local copy exists.
- if com.IsExist(localPath) {
- // No need to check if nothing in the repository.
- if git.IsBranchExist(localPath, "master") {
- if err = git.ResetHEAD(localPath, true, "origin/master"); err != nil {
- return fmt.Errorf("Reset: %v", err)
- }
- }
- }
-
- if err = repo.UpdateLocalWiki(); err != nil {
+ if err = discardLocalWikiChanges(localPath); err != nil {
+ return fmt.Errorf("discardLocalWikiChanges: %v", err)
+ } else if err = repo.UpdateLocalWiki(); err != nil {
return fmt.Errorf("UpdateLocalWiki: %v", err)
}
@@ -178,3 +186,31 @@ func (repo *Repository) AddWikiPage(doer *User, title, content, message string)
func (repo *Repository) EditWikiPage(doer *User, oldTitle, title, content, message string) error {
return repo.updateWikiPage(doer, oldTitle, title, content, message, false)
}
+
+func (repo *Repository) DeleteWikiPage(doer *User, title string) (err error) {
+ wikiWorkingPool.CheckIn(com.ToStr(repo.ID))
+ defer wikiWorkingPool.CheckOut(com.ToStr(repo.ID))
+
+ localPath := repo.LocalWikiPath()
+ if err = discardLocalWikiChanges(localPath); err != nil {
+ return fmt.Errorf("discardLocalWikiChanges: %v", err)
+ } else if err = repo.UpdateLocalWiki(); err != nil {
+ return fmt.Errorf("UpdateLocalWiki: %v", err)
+ }
+
+ title = ToWikiPageName(strings.Replace(title, "/", " ", -1))
+ filename := path.Join(localPath, title+".md")
+ os.Remove(filename)
+
+ message := "Delete page '" + title + "'"
+
+ if err = git.AddChanges(localPath, true); err != nil {
+ return fmt.Errorf("AddChanges: %v", err)
+ } else if err = git.CommitChanges(localPath, message, doer.NewGitSig()); err != nil {
+ return fmt.Errorf("CommitChanges: %v", err)
+ } else if err = git.Push(localPath, "origin", "master"); err != nil {
+ return fmt.Errorf("Push: %v", err)
+ }
+
+ return nil
+}