Browse Source

WIP: create PR - choose branch

tags/v0.9.99
Unknwon 8 years ago
parent
commit
dea3a8c6a4

+ 3
- 3
cmd/serve.go View File

fail("Key permission denied", "Cannot push with deployment key: %d", key.ID) fail("Key permission denied", "Cannot push with deployment key: %d", key.ID)
} }
// Check if this deploy key belongs to current repository. // Check if this deploy key belongs to current repository.
if !models.HasDeployKey(key.ID, repo.Id) {
fail("Key access denied", "Key access denied: %d-%d", key.ID, repo.Id)
if !models.HasDeployKey(key.ID, repo.ID) {
fail("Key access denied", "Key access denied: %d-%d", key.ID, repo.ID)
} }


// Update deploy key activity. // Update deploy key activity.
deployKey, err := models.GetDeployKeyByRepo(key.ID, repo.Id)
deployKey, err := models.GetDeployKeyByRepo(key.ID, repo.ID)
if err != nil { if err != nil {
fail("Internal error", "GetDeployKey: %v", err) fail("Internal error", "GetDeployKey: %v", err)
} }

+ 3
- 1
cmd/web.go View File

m.Get("/edit/:tagname", repo.EditRelease) m.Get("/edit/:tagname", repo.EditRelease)
m.Post("/edit/:tagname", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost) m.Post("/edit/:tagname", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
}, reqRepoAdmin, middleware.RepoRef()) }, reqRepoAdmin, middleware.RepoRef())

m.Combo("/compare/*").Get(repo.CompareAndPullRequest)
}, reqSignIn, middleware.RepoAssignment(true)) }, reqSignIn, middleware.RepoAssignment(true))


m.Group("/:username/:reponame", func() { m.Group("/:username/:reponame", func() {
m.Get("/commit/*", repo.Diff) m.Get("/commit/*", repo.Diff)
}, middleware.RepoRef()) }, middleware.RepoRef())


m.Get("/compare/:before([a-z0-9]+)...:after([a-z0-9]+)", repo.CompareDiff)
m.Get("/compare/:before([a-z0-9]{40})...:after([a-z0-9]{40})", repo.CompareDiff)
}, ignSignIn, middleware.RepoAssignment(true)) }, ignSignIn, middleware.RepoAssignment(true))


m.Group("/:username", func() { m.Group("/:username", func() {

+ 3
- 0
conf/locale/locale_en-US.ini View File

issues.label_deletion_desc = Delete this label will remove its information in all related issues. Do you want to continue? issues.label_deletion_desc = Delete this label will remove its information in all related issues. Do you want to continue?
issues.label_deletion_success = Label has been deleted successfully! issues.label_deletion_success = Label has been deleted successfully!


pulls.compare_changes = Compare Changes
pulls.compare_changes_desc = Compare two branches and make a pull request for changes.

milestones.new = New Milestone milestones.new = New Milestone
milestones.open_tab = %d Open milestones.open_tab = %d Open
milestones.close_tab = %d Closed milestones.close_tab = %d Closed

+ 7
- 7
models/access.go View File

} }


if u != nil { if u != nil {
if u.Id == repo.OwnerId {
if u.Id == repo.OwnerID {
return ACCESS_MODE_OWNER, nil return ACCESS_MODE_OWNER, nil
} }


a := &Access{UserID: u.Id, RepoID: repo.Id}
a := &Access{UserID: u.Id, RepoID: repo.ID}
if has, err := e.Get(a); !has || err != nil { if has, err := e.Get(a); !has || err != nil {
return mode, err return mode, err
} }


repos := make(map[*Repository]AccessMode, len(accesses)) repos := make(map[*Repository]AccessMode, len(accesses))
for _, access := range accesses { for _, access := range accesses {
repo, err := GetRepositoryById(access.RepoID)
repo, err := GetRepositoryByID(access.RepoID)
if err != nil { if err != nil {
if IsErrRepoNotExist(err) { if IsErrRepoNotExist(err) {
log.Error(4, "%v", err) log.Error(4, "%v", err)
} }
if err = repo.GetOwner(); err != nil { if err = repo.GetOwner(); err != nil {
return nil, err return nil, err
} else if repo.OwnerId == u.Id {
} else if repo.OwnerID == u.Id {
continue continue
} }
repos[repo] = access.Mode repos[repo] = access.Mode
} }
newAccesses = append(newAccesses, Access{ newAccesses = append(newAccesses, Access{
UserID: userID, UserID: userID,
RepoID: repo.Id,
RepoID: repo.ID,
Mode: mode, Mode: mode,
}) })
} }


// Delete old accesses and insert new ones for repository. // Delete old accesses and insert new ones for repository.
if _, err = e.Delete(&Access{RepoID: repo.Id}); err != nil {
if _, err = e.Delete(&Access{RepoID: repo.ID}); err != nil {
return fmt.Errorf("delete old accesses: %v", err) return fmt.Errorf("delete old accesses: %v", err)
} else if _, err = e.Insert(newAccesses); err != nil { } else if _, err = e.Insert(newAccesses); err != nil {
return fmt.Errorf("insert new accesses: %v", err) return fmt.Errorf("insert new accesses: %v", err)
// have relations with repository. // have relations with repository.
if t.IsOwnerTeam() { if t.IsOwnerTeam() {
t.Authorize = ACCESS_MODE_OWNER t.Authorize = ACCESS_MODE_OWNER
} else if !t.hasRepository(e, repo.Id) {
} else if !t.hasRepository(e, repo.ID) {
continue continue
} }



+ 8
- 8
models/action.go View File

// check if repo belongs to org and append additional webhooks // check if repo belongs to org and append additional webhooks
if repo.Owner.IsOrganization() { if repo.Owner.IsOrganization() {
// get hooks for org // get hooks for org
orgws, err := GetActiveWebhooksByOrgId(repo.OwnerId)
orgws, err := GetActiveWebhooksByOrgId(repo.OwnerID)
if err != nil { if err != nil {
return errors.New("GetActiveWebhooksByOrgId: " + err.Error()) return errors.New("GetActiveWebhooksByOrgId: " + err.Error())
} }
Ref: refFullName, Ref: refFullName,
Commits: commits, Commits: commits,
Repo: &PayloadRepo{ Repo: &PayloadRepo{
Id: repo.Id,
Id: repo.ID,
Name: repo.LowerName, Name: repo.LowerName,
Url: repoLink, Url: repoLink,
Description: repo.Description, Description: repo.Description,
} }


if err = CreateHookTask(&HookTask{ if err = CreateHookTask(&HookTask{
RepoID: repo.Id,
RepoID: repo.ID,
HookID: w.Id, HookID: w.Id,
Type: w.HookTaskType, Type: w.HookTaskType,
Url: w.Url, Url: w.Url,
ActUserName: u.Name, ActUserName: u.Name,
ActEmail: u.Email, ActEmail: u.Email,
OpType: CREATE_REPO, OpType: CREATE_REPO,
RepoID: repo.Id,
RepoID: repo.ID,
RepoUserName: repo.Owner.Name, RepoUserName: repo.Owner.Name,
RepoName: repo.Name, RepoName: repo.Name,
IsPrivate: repo.IsPrivate, IsPrivate: repo.IsPrivate,
}); err != nil { }); err != nil {
return fmt.Errorf("notify watchers '%d/%s'", u.Id, repo.Id)
return fmt.Errorf("notify watchers '%d/%s'", u.Id, repo.ID)
} }


log.Trace("action.NewRepoAction: %s/%s", u.Name, repo.Name) log.Trace("action.NewRepoAction: %s/%s", u.Name, repo.Name)
ActUserName: actUser.Name, ActUserName: actUser.Name,
ActEmail: actUser.Email, ActEmail: actUser.Email,
OpType: TRANSFER_REPO, OpType: TRANSFER_REPO,
RepoID: repo.Id,
RepoID: repo.ID,
RepoUserName: newOwner.Name, RepoUserName: newOwner.Name,
RepoName: repo.Name, RepoName: repo.Name,
IsPrivate: repo.IsPrivate, IsPrivate: repo.IsPrivate,
Content: path.Join(oldOwner.LowerName, repo.LowerName), Content: path.Join(oldOwner.LowerName, repo.LowerName),
} }
if err = notifyWatchers(e, action); err != nil { if err = notifyWatchers(e, action); err != nil {
return fmt.Errorf("notify watchers '%d/%s'", actUser.Id, repo.Id)
return fmt.Errorf("notify watchers '%d/%s'", actUser.Id, repo.ID)
} }


// Remove watch for organization. // Remove watch for organization.
if repo.Owner.IsOrganization() { if repo.Owner.IsOrganization() {
if err = watchRepo(e, repo.Owner.Id, repo.Id, false); err != nil {
if err = watchRepo(e, repo.Owner.Id, repo.ID, false); err != nil {
return fmt.Errorf("watch repository: %v", err) return fmt.Errorf("watch repository: %v", err)
} }
} }

+ 14
- 14
models/issue.go View File

} }


func (i *Issue) GetPoster() (err error) { func (i *Issue) GetPoster() (err error) {
i.Poster, err = GetUserById(i.PosterID)
i.Poster, err = GetUserByID(i.PosterID)
if IsErrUserNotExist(err) { if IsErrUserNotExist(err) {
i.Poster = &User{Name: "FakeUser"} i.Poster = &User{Name: "FakeUser"}
return nil return nil
return nil return nil
} }


i.Assignee, err = GetUserById(i.AssigneeID)
i.Assignee, err = GetUserByID(i.AssigneeID)
if IsErrUserNotExist(err) { if IsErrUserNotExist(err) {
return nil return nil
} }
return return
} }


return GetIssueByIndex(repo.Id, issueNumber)
return GetIssueByIndex(repo.ID, issueNumber)
} }


// GetIssueByIndex returns issue by given index in repository. // GetIssueByIndex returns issue by given index in repository.


iu := &IssueUser{ iu := &IssueUser{
IssueId: issueID, IssueId: issueID,
RepoId: repo.Id,
RepoId: repo.ID,
} }


isNeedAddPoster := true isNeedAddPoster := true
} }


// Add owner's as well. // Add owner's as well.
if repo.OwnerId != posterID {
if repo.OwnerID != posterID {
iu.Id = 0 iu.Id = 0
iu.Uid = repo.OwnerId
iu.Uid = repo.OwnerID
iu.IsAssigned = iu.Uid == assigneeID iu.IsAssigned = iu.Uid == assigneeID
if _, err = x.Insert(iu); err != nil { if _, err = x.Insert(iu); err != nil {
return err return err


// ChangeMilestoneStatus changes the milestone open/closed status. // ChangeMilestoneStatus changes the milestone open/closed status.
func ChangeMilestoneStatus(m *Milestone, isClosed bool) (err error) { func ChangeMilestoneStatus(m *Milestone, isClosed bool) (err error) {
repo, err := GetRepositoryById(m.RepoID)
repo, err := GetRepositoryByID(m.RepoID)
if err != nil { if err != nil {
return err return err
} }
return err return err
} }


repo.NumMilestones = int(countRepoMilestones(sess, repo.Id))
repo.NumClosedMilestones = int(countRepoClosedMilestones(sess, repo.Id))
if _, err = sess.Id(repo.Id).AllCols().Update(repo); err != nil {
repo.NumMilestones = int(countRepoMilestones(sess, repo.ID))
repo.NumClosedMilestones = int(countRepoClosedMilestones(sess, repo.ID))
if _, err = sess.Id(repo.ID).AllCols().Update(repo); err != nil {
return err return err
} }
return sess.Commit() return sess.Commit()
return err return err
} }


repo, err := GetRepositoryById(m.RepoID)
repo, err := GetRepositoryByID(m.RepoID)
if err != nil { if err != nil {
return err return err
} }
return err return err
} }


repo.NumMilestones = int(countRepoMilestones(sess, repo.Id))
repo.NumClosedMilestones = int(countRepoClosedMilestones(sess, repo.Id))
if _, err = sess.Id(repo.Id).AllCols().Update(repo); err != nil {
repo.NumMilestones = int(countRepoMilestones(sess, repo.ID))
repo.NumClosedMilestones = int(countRepoClosedMilestones(sess, repo.ID))
if _, err = sess.Id(repo.ID).AllCols().Update(repo); err != nil {
return err return err
} }



+ 1
- 1
models/oauth2.go View File

} else if oa.Uid == -1 { } else if oa.Uid == -1 {
return oa, ErrOauth2NotAssociated return oa, ErrOauth2NotAssociated
} }
oa.User, err = GetUserById(oa.Uid)
oa.User, err = GetUserByID(oa.Uid)
return oa, err return oa, err
} }



+ 15
- 15
models/org.go View File



org.Members = make([]*User, len(ous)) org.Members = make([]*User, len(ous))
for i, ou := range ous { for i, ou := range ous {
org.Members[i], err = GetUserById(ou.Uid)
org.Members[i], err = GetUserByID(ou.Uid)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }


u, err := GetUserById(uid)
u, err := GetUserByID(uid)
if err != nil { if err != nil {
return fmt.Errorf("GetUserById: %v", err) return fmt.Errorf("GetUserById: %v", err)
} }
org, err := GetUserById(orgId)
org, err := GetUserByID(orgId)
if err != nil { if err != nil {
return fmt.Errorf("get organization: %v", err) return fmt.Errorf("get organization: %v", err)
} else if err = org.GetRepositories(); err != nil { } else if err = org.GetRepositories(); err != nil {
// Delete all repository accesses. // Delete all repository accesses.
access := &Access{UserID: u.Id} access := &Access{UserID: u.Id}
for _, repo := range org.Repos { for _, repo := range org.Repos {
access.RepoID = repo.Id
access.RepoID = repo.ID
if _, err = sess.Delete(access); err != nil { if _, err = sess.Delete(access); err != nil {
return err return err
} else if err = watchRepo(sess, u.Id, repo.Id, false); err != nil {
} else if err = watchRepo(sess, u.Id, repo.ID, false); err != nil {
return err return err
} }
} }


t.Repos = make([]*Repository, 0, len(teamRepos)) t.Repos = make([]*Repository, 0, len(teamRepos))
for i := range teamRepos { for i := range teamRepos {
repo, err := getRepositoryById(e, teamRepos[i].RepoID)
repo, err := getRepositoryByID(e, teamRepos[i].RepoID)
if err != nil { if err != nil {
return fmt.Errorf("getRepositoryById(%d): %v", teamRepos[i].RepoID, err) return fmt.Errorf("getRepositoryById(%d): %v", teamRepos[i].RepoID, err)
} }
} }


func (t *Team) addRepository(e Engine, repo *Repository) (err error) { func (t *Team) addRepository(e Engine, repo *Repository) (err error) {
if err = addTeamRepo(e, t.OrgID, t.ID, repo.Id); err != nil {
if err = addTeamRepo(e, t.OrgID, t.ID, repo.ID); err != nil {
return err return err
} }


return fmt.Errorf("getMembers: %v", err) return fmt.Errorf("getMembers: %v", err)
} }
for _, u := range t.Members { for _, u := range t.Members {
if err = watchRepo(e, u.Id, repo.Id, true); err != nil {
if err = watchRepo(e, u.Id, repo.ID, true); err != nil {
return fmt.Errorf("watchRepo: %v", err) return fmt.Errorf("watchRepo: %v", err)
} }
} }


// AddRepository adds new repository to team of organization. // AddRepository adds new repository to team of organization.
func (t *Team) AddRepository(repo *Repository) (err error) { func (t *Team) AddRepository(repo *Repository) (err error) {
if repo.OwnerId != t.OrgID {
if repo.OwnerID != t.OrgID {
return errors.New("Repository does not belong to organization") return errors.New("Repository does not belong to organization")
} else if t.HasRepository(repo.Id) {
} else if t.HasRepository(repo.ID) {
return nil return nil
} }


} }


func (t *Team) removeRepository(e Engine, repo *Repository, recalculate bool) (err error) { func (t *Team) removeRepository(e Engine, repo *Repository, recalculate bool) (err error) {
if err = removeTeamRepo(e, t.ID, repo.Id); err != nil {
if err = removeTeamRepo(e, t.ID, repo.ID); err != nil {
return err return err
} }


continue continue
} }


if err = watchRepo(e, u.Id, repo.Id, false); err != nil {
if err = watchRepo(e, u.Id, repo.ID, false); err != nil {
return err return err
} }
} }
return nil return nil
} }


repo, err := GetRepositoryById(repoID)
repo, err := GetRepositoryByID(repoID)
if err != nil { if err != nil {
return err return err
} }
} }


// Get organization. // Get organization.
org, err := GetUserById(t.OrgID)
org, err := GetUserByID(t.OrgID)
if err != nil { if err != nil {
return err return err
} }
} }


// Get organization. // Get organization.
org, err := getUserById(e, orgId)
org, err := getUserByID(e, orgId)
if err != nil { if err != nil {
return err return err
} }

+ 51
- 52
models/repo.go View File



// Repository represents a git repository. // Repository represents a git repository.
type Repository struct { type Repository struct {
Id int64
OwnerId int64 `xorm:"UNIQUE(s)"`
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"UNIQUE(s)"`
Owner *User `xorm:"-"` Owner *User `xorm:"-"`
LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"` LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
Name string `xorm:"INDEX NOT NULL"` Name string `xorm:"INDEX NOT NULL"`
*Mirror `xorm:"-"` *Mirror `xorm:"-"`


IsFork bool `xorm:"NOT NULL DEFAULT false"` IsFork bool `xorm:"NOT NULL DEFAULT false"`
ForkId int64
ForkRepo *Repository `xorm:"-"`
ForkID int64
BaseRepo *Repository `xorm:"-"`


Created time.Time `xorm:"CREATED"` Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"` Updated time.Time `xorm:"UPDATED"`


func (repo *Repository) getOwner(e Engine) (err error) { func (repo *Repository) getOwner(e Engine) (err error) {
if repo.Owner == nil { if repo.Owner == nil {
repo.Owner, err = getUserById(e, repo.OwnerId)
repo.Owner, err = getUserByID(e, repo.OwnerID)
} }
return err return err
} }
} }


func (repo *Repository) GetMirror() (err error) { func (repo *Repository) GetMirror() (err error) {
repo.Mirror, err = GetMirror(repo.Id)
repo.Mirror, err = GetMirror(repo.ID)
return err return err
} }


func (repo *Repository) GetForkRepo() (err error) {
func (repo *Repository) GetBaseRepo() (err error) {
if !repo.IsFork { if !repo.IsFork {
return nil return nil
} }


repo.ForkRepo, err = GetRepositoryById(repo.ForkId)
repo.BaseRepo, err = GetRepositoryByID(repo.ForkID)
return err return err
} }


} }


func (repo *Repository) IsOwnedBy(u *User) bool { func (repo *Repository) IsOwnedBy(u *User) bool {
return repo.OwnerId == u.Id
return repo.OwnerID == u.Id
} }


// DescriptionHtml does special handles to description and return HTML string. // DescriptionHtml does special handles to description and return HTML string.


func isRepositoryExist(e Engine, u *User, repoName string) (bool, error) { func isRepositoryExist(e Engine, u *User, repoName string) (bool, error) {
has, err := e.Get(&Repository{ has, err := e.Get(&Repository{
OwnerId: u.Id,
OwnerID: u.Id,
LowerName: strings.ToLower(repoName), LowerName: strings.ToLower(repoName),
}) })
return has && com.IsDir(RepoPath(u.Name, repoName)), err return has && com.IsDir(RepoPath(u.Name, repoName)), err


// Mirror represents a mirror information of repository. // Mirror represents a mirror information of repository.
type Mirror struct { type Mirror struct {
Id int64
RepoId int64
ID int64 `xorm:"pk autoincr"`
RepoID int64
RepoName string // <user name>/<repo name> RepoName string // <user name>/<repo name>
Interval int // Hour. Interval int // Hour.
Updated time.Time `xorm:"UPDATED"` Updated time.Time `xorm:"UPDATED"`
} }


func getMirror(e Engine, repoId int64) (*Mirror, error) { func getMirror(e Engine, repoId int64) (*Mirror, error) {
m := &Mirror{RepoId: repoId}
m := &Mirror{RepoID: repoId}
has, err := e.Get(m) has, err := e.Get(m)
if err != nil { if err != nil {
return nil, err return nil, err
} }


func updateMirror(e Engine, m *Mirror) error { func updateMirror(e Engine, m *Mirror) error {
_, err := e.Id(m.Id).Update(m)
_, err := e.Id(m.ID).Update(m)
return err return err
} }


} }


if _, err = x.InsertOne(&Mirror{ if _, err = x.InsertOne(&Mirror{
RepoId: repoId,
RepoID: repoId,
RepoName: strings.ToLower(userName + "/" + repoName), RepoName: strings.ToLower(userName + "/" + repoName),
Interval: 24, Interval: 24,
NextUpdate: time.Now().Add(24 * time.Hour), NextUpdate: time.Now().Add(24 * time.Hour),


repo.IsBare = false repo.IsBare = false
if mirror { if mirror {
if err = MirrorRepository(repo.Id, u.Name, repo.Name, repoPath, url); err != nil {
if err = MirrorRepository(repo.ID, u.Name, repo.Name, repoPath, url); err != nil {
return repo, err return repo, err
} }
repo.IsMirror = true repo.IsMirror = true
if len(fileName) == 0 { if len(fileName) == 0 {
// Re-fetch the repository from database before updating it (else it would // Re-fetch the repository from database before updating it (else it would
// override changes that were done earlier with sql) // override changes that were done earlier with sql)
if repo, err = getRepositoryById(e, repo.Id); err != nil {
if repo, err = getRepositoryByID(e, repo.ID); err != nil {
return err return err
} }
repo.IsBare = true repo.IsBare = true
} }
} }


if err = watchRepo(e, u.Id, repo.Id, true); err != nil {
if err = watchRepo(e, u.Id, repo.ID, true); err != nil {
return fmt.Errorf("watchRepo: %v", err) return fmt.Errorf("watchRepo: %v", err)
} else if err = newRepoAction(e, u, repo); err != nil { } else if err = newRepoAction(e, u, repo); err != nil {
return fmt.Errorf("newRepoAction: %v", err) return fmt.Errorf("newRepoAction: %v", err)
// CreateRepository creates a repository for given user or organization. // CreateRepository creates a repository for given user or organization.
func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMirror, initReadme bool) (_ *Repository, err error) { func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMirror, initReadme bool) (_ *Repository, err error) {
repo := &Repository{ repo := &Repository{
OwnerId: u.Id,
OwnerID: u.Id,
Owner: u, Owner: u,
Name: name, Name: name,
LowerName: strings.ToLower(name), LowerName: strings.ToLower(name),
} }


for _, repo := range repos { for _, repo := range repos {
repo.Owner = &User{Id: repo.OwnerId}
repo.Owner = &User{Id: repo.OwnerID}
has, err := x.Get(repo.Owner) has, err := x.Get(repo.Owner)
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
return nil, ErrUserNotExist{repo.OwnerId, ""}
return nil, ErrUserNotExist{repo.OwnerID, ""}
} }
} }




// Note: we have to set value here to make sure recalculate accesses is based on // Note: we have to set value here to make sure recalculate accesses is based on
// new owner. // new owner.
repo.OwnerId = newOwner.Id
repo.OwnerID = newOwner.Id
repo.Owner = newOwner repo.Owner = newOwner


// Update repository. // Update repository.
if _, err := sess.Id(repo.Id).Update(repo); err != nil {
if _, err := sess.Id(repo.ID).Update(repo); err != nil {
return fmt.Errorf("update owner: %v", err) return fmt.Errorf("update owner: %v", err)
} }


} }


// Dummy object. // Dummy object.
collaboration := &Collaboration{RepoID: repo.Id}
collaboration := &Collaboration{RepoID: repo.ID}
for _, c := range collaborators { for _, c := range collaborators {
collaboration.UserID = c.Id collaboration.UserID = c.Id
if c.Id == newOwner.Id || newOwner.IsOrgMember(c.Id) { if c.Id == newOwner.Id || newOwner.IsOrgMember(c.Id) {
return fmt.Errorf("getTeams: %v", err) return fmt.Errorf("getTeams: %v", err)
} }
for _, t := range owner.Teams { for _, t := range owner.Teams {
if !t.hasRepository(sess, repo.Id) {
if !t.hasRepository(sess, repo.ID) {
continue continue
} }


} }
} }


if err = owner.removeOrgRepo(sess, repo.Id); err != nil {
if err = owner.removeOrgRepo(sess, repo.ID); err != nil {
return fmt.Errorf("removeOrgRepo: %v", err) return fmt.Errorf("removeOrgRepo: %v", err)
} }
} }
return fmt.Errorf("decrease old owner repository count: %v", err) return fmt.Errorf("decrease old owner repository count: %v", err)
} }


if err = watchRepo(sess, newOwner.Id, repo.Id, true); err != nil {
if err = watchRepo(sess, newOwner.Id, repo.ID, true); err != nil {
return fmt.Errorf("watchRepo: %v", err) return fmt.Errorf("watchRepo: %v", err)
} else if err = transferRepoAction(sess, u, owner, newOwner, repo); err != nil { } else if err = transferRepoAction(sess, u, owner, newOwner, repo); err != nil {
return fmt.Errorf("transferRepoAction: %v", err) return fmt.Errorf("transferRepoAction: %v", err)


// Update mirror information. // Update mirror information.
if repo.IsMirror { if repo.IsMirror {
mirror, err := getMirror(sess, repo.Id)
mirror, err := getMirror(sess, repo.ID)
if err != nil { if err != nil {
return fmt.Errorf("getMirror: %v", err) return fmt.Errorf("getMirror: %v", err)
} }
repo.Website = repo.Website[:255] repo.Website = repo.Website[:255]
} }


if _, err = e.Id(repo.Id).AllCols().Update(repo); err != nil {
if _, err = e.Id(repo.ID).AllCols().Update(repo); err != nil {
return fmt.Errorf("update: %v", err) return fmt.Errorf("update: %v", err)
} }




// DeleteRepository deletes a repository for a user or organization. // DeleteRepository deletes a repository for a user or organization.
func DeleteRepository(uid, repoID int64, userName string) error { func DeleteRepository(uid, repoID int64, userName string) error {
repo := &Repository{Id: repoID, OwnerId: uid}
repo := &Repository{ID: repoID, OwnerID: uid}
has, err := x.Get(repo) has, err := x.Get(repo)
if err != nil { if err != nil {
return err return err
} }


// In case is a organization. // In case is a organization.
org, err := GetUserById(uid)
org, err := GetUserByID(uid)
if err != nil { if err != nil {
return err return err
} }
} }
} }


if _, err = sess.Delete(&Repository{Id: repoID}); err != nil {
if _, err = sess.Delete(&Repository{ID: repoID}); err != nil {
return err return err
} else if _, err = sess.Delete(&Access{RepoID: repo.Id}); err != nil {
} else if _, err = sess.Delete(&Access{RepoID: repo.ID}); err != nil {
return err return err
} else if _, err = sess.Delete(&Action{RepoID: repo.Id}); err != nil {
} else if _, err = sess.Delete(&Action{RepoID: repo.ID}); err != nil {
return err return err
} else if _, err = sess.Delete(&Watch{RepoID: repoID}); err != nil { } else if _, err = sess.Delete(&Watch{RepoID: repoID}); err != nil {
return err return err
} else if _, err = sess.Delete(&Mirror{RepoId: repoID}); err != nil {
} else if _, err = sess.Delete(&Mirror{RepoID: repoID}); err != nil {
return err return err
} else if _, err = sess.Delete(&IssueUser{RepoId: repoID}); err != nil { } else if _, err = sess.Delete(&IssueUser{RepoId: repoID}); err != nil {
return err return err
} }


if repo.IsFork { if repo.IsFork {
if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks-1 WHERE id=?", repo.ForkId); err != nil {
if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks-1 WHERE id=?", repo.ForkID); err != nil {
return err return err
} }
} }
// GetRepositoryByName returns the repository by given name under user if exists. // GetRepositoryByName returns the repository by given name under user if exists.
func GetRepositoryByName(uid int64, repoName string) (*Repository, error) { func GetRepositoryByName(uid int64, repoName string) (*Repository, error) {
repo := &Repository{ repo := &Repository{
OwnerId: uid,
OwnerID: uid,
LowerName: strings.ToLower(repoName), LowerName: strings.ToLower(repoName),
} }
has, err := x.Get(repo) has, err := x.Get(repo)
return repo, err return repo, err
} }


func getRepositoryById(e Engine, id int64) (*Repository, error) {
func getRepositoryByID(e Engine, id int64) (*Repository, error) {
repo := new(Repository) repo := new(Repository)
has, err := e.Id(id).Get(repo) has, err := e.Id(id).Get(repo)
if err != nil { if err != nil {
return repo, nil return repo, nil
} }


// GetRepositoryById returns the repository by given id if exists.
func GetRepositoryById(id int64) (*Repository, error) {
return getRepositoryById(x, id)
// GetRepositoryByID returns the repository by given id if exists.
func GetRepositoryByID(id int64) (*Repository, error) {
return getRepositoryByID(x, id)
} }


// GetRepositories returns a list of repositories of given user. // GetRepositories returns a list of repositories of given user.
sess.Where("is_private=?", false) sess.Where("is_private=?", false)
} }


err := sess.Find(&repos, &Repository{OwnerId: uid})
return repos, err
return repos, sess.Find(&repos, &Repository{OwnerID: uid})
} }


// GetRecentUpdatedRepositories returns the list of repositories that are recently updated. // GetRecentUpdatedRepositories returns the list of repositories that are recently updated.
} }


// GetRepositoryCount returns the total number of repositories of user. // GetRepositoryCount returns the total number of repositories of user.
func GetRepositoryCount(user *User) (int64, error) {
return x.Count(&Repository{OwnerId: user.Id})
func GetRepositoryCount(u *User) (int64, error) {
return x.Count(&Repository{OwnerID: u.Id})
} }


type SearchOption struct { type SearchOption struct {
// Add collaborator and accompanying access // Add collaborator and accompanying access
func (repo *Repository) AddCollaborator(u *User) error { func (repo *Repository) AddCollaborator(u *User) error {
collaboration := &Collaboration{ collaboration := &Collaboration{
RepoID: repo.Id,
RepoID: repo.ID,
UserID: u.Id, UserID: u.Id,
} }




func (repo *Repository) getCollaborators(e Engine) ([]*User, error) { func (repo *Repository) getCollaborators(e Engine) ([]*User, error) {
collaborations := make([]*Collaboration, 0) collaborations := make([]*Collaboration, 0)
if err := e.Find(&collaborations, &Collaboration{RepoID: repo.Id}); err != nil {
if err := e.Find(&collaborations, &Collaboration{RepoID: repo.ID}); err != nil {
return nil, err return nil, err
} }


users := make([]*User, len(collaborations)) users := make([]*User, len(collaborations))
for i, c := range collaborations { for i, c := range collaborations {
user, err := getUserById(e, c.UserID)
user, err := getUserByID(e, c.UserID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Delete collaborator and accompanying access // Delete collaborator and accompanying access
func (repo *Repository) DeleteCollaborator(u *User) (err error) { func (repo *Repository) DeleteCollaborator(u *User) (err error) {
collaboration := &Collaboration{ collaboration := &Collaboration{
RepoID: repo.Id,
RepoID: repo.ID,
UserID: u.Id, UserID: u.Id,
} }




func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) { func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) {
repo := &Repository{ repo := &Repository{
OwnerId: u.Id,
OwnerID: u.Id,
Owner: u, Owner: u,
Name: name, Name: name,
LowerName: strings.ToLower(name), LowerName: strings.ToLower(name),
Description: desc, Description: desc,
IsPrivate: oldRepo.IsPrivate, IsPrivate: oldRepo.IsPrivate,
IsFork: true, IsFork: true,
ForkId: oldRepo.Id,
ForkID: oldRepo.ID,
} }


sess := x.NewSession() sess := x.NewSession()
return nil, err return nil, err
} }


if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks+1 WHERE id=?", oldRepo.Id); err != nil {
if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks+1 WHERE id=?", oldRepo.ID); err != nil {
return nil, err return nil, err
} }



+ 2
- 2
models/update.go View File

commit := &base.PushCommits{} commit := &base.PushCommits{}


if err = CommitRepoAction(userId, ru.Id, userName, actEmail, if err = CommitRepoAction(userId, ru.Id, userName, actEmail,
repos.Id, repoUserName, repoName, refName, commit, oldCommitId, newCommitId); err != nil {
repos.ID, repoUserName, repoName, refName, commit, oldCommitId, newCommitId); err != nil {
log.GitLogger.Fatal(4, "CommitRepoAction: %s/%s:%v", repoUserName, repoName, err) log.GitLogger.Fatal(4, "CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
} }
return err return err
} }


if err = CommitRepoAction(userId, ru.Id, userName, actEmail, if err = CommitRepoAction(userId, ru.Id, userName, actEmail,
repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits, ""}, oldCommitId, newCommitId); err != nil {
repos.ID, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits, ""}, 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

+ 8
- 8
models/user.go View File



u.Orgs = make([]*User, len(ous)) u.Orgs = make([]*User, len(ous))
for i, ou := range ous { for i, ou := range ous {
u.Orgs[i], err = GetUserById(ou.OrgID)
u.Orgs[i], err = GetUserByID(ou.OrgID)
if err != nil { if err != nil {
return err return err
} }
return user, nil return user, nil
} }


func getUserById(e Engine, id int64) (*User, error) {
func getUserByID(e Engine, id int64) (*User, error) {
u := new(User) u := new(User)
has, err := e.Id(id).Get(u) has, err := e.Id(id).Get(u)
if err != nil { if err != nil {
return u, nil return u, nil
} }


// GetUserById returns the user object by given ID if exists.
func GetUserById(id int64) (*User, error) {
return getUserById(x, id)
// GetUserByID returns the user object by given ID if exists.
func GetUserByID(id int64) (*User, error) {
return getUserByID(x, id)
} }


// GetUserByName returns user by given name. // GetUserByName returns user by given name.
return nil, err return nil, err
} }


u, err := GetUserById(uid)
u, err := GetUserByID(uid)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return err return err
} }


if user, err := GetUserById(email.Uid); err != nil {
if user, err := GetUserByID(email.Uid); err != nil {
return err return err
} else { } else {
user.Rands = GetUserSalt() user.Rands = GetUserSalt()
return nil, err return nil, err
} }
if has { if has {
return GetUserById(emailAddress.Uid)
return GetUserByID(emailAddress.Uid)
} }


return nil, ErrUserNotExist{0, "email"} return nil, ErrUserNotExist{0, "email"}

+ 2
- 2
modules/auth/auth.go View File

return 0 return 0
} }
if id, ok := uid.(int64); ok { if id, ok := uid.(int64); ok {
if _, err := models.GetUserById(id); err != nil {
if _, err := models.GetUserByID(id); err != nil {
if !models.IsErrUserNotExist(err) { if !models.IsErrUserNotExist(err) {
log.Error(4, "GetUserById: %v", err) log.Error(4, "GetUserById: %v", err)
} }
return nil, false return nil, false
} }


u, err := models.GetUserById(uid)
u, err := models.GetUserByID(uid)
if err != nil { if err != nil {
log.Error(4, "GetUserById: %v", err) log.Error(4, "GetUserById: %v", err)
return nil, false return nil, false

+ 2
- 2
modules/bindata/bindata.go
File diff suppressed because it is too large
View File


+ 2
- 2
modules/mailer/mail.go View File



// SendIssueNotifyMail sends mail notification of all watchers of repository. // SendIssueNotifyMail sends mail notification of all watchers of repository.
func SendIssueNotifyMail(u, owner *models.User, repo *models.Repository, issue *models.Issue) ([]string, error) { func SendIssueNotifyMail(u, owner *models.User, repo *models.Repository, issue *models.Issue) ([]string, error) {
ws, err := models.GetWatchers(repo.Id)
ws, err := models.GetWatchers(repo.ID)
if err != nil { if err != nil {
return nil, errors.New("mail.NotifyWatchers(GetWatchers): " + err.Error()) return nil, errors.New("mail.NotifyWatchers(GetWatchers): " + err.Error())
} }
if u.Id == uid { if u.Id == uid {
continue continue
} }
u, err := models.GetUserById(uid)
u, err := models.GetUserByID(uid)
if err != nil { if err != nil {
return nil, errors.New("mail.NotifyWatchers(GetUserById): " + err.Error()) return nil, errors.New("mail.NotifyWatchers(GetUserById): " + err.Error())
} }

+ 33
- 9
modules/middleware/repo.go View File

ctx.Data["HasAccess"] = true ctx.Data["HasAccess"] = true


if repo.IsMirror { if repo.IsMirror {
ctx.Repo.Mirror, err = models.GetMirror(repo.Id)
ctx.Repo.Mirror, err = models.GetMirror(repo.ID)
if err != nil { if err != nil {
ctx.Handle(500, "GetMirror", err) ctx.Handle(500, "GetMirror", err)
return return
ctx.Data["Tags"] = tags ctx.Data["Tags"] = tags
ctx.Repo.Repository.NumTags = len(tags) ctx.Repo.Repository.NumTags = len(tags)


// Non-fork repository will not return error in this method.
if err = repo.GetForkRepo(); err != nil {
ctx.Handle(500, "GetForkRepo", err)
return
if repo.IsFork {
// Non-fork repository will not return error in this method.
if err = repo.GetBaseRepo(); err != nil {
ctx.Handle(500, "GetBaseRepo", err)
return
} else if repo.BaseRepo.GetOwner(); err != nil {
ctx.Handle(500, "BaseRepo.GetOwner", err)
return
}

bsaeRepo := repo.BaseRepo
baseGitRepo, err := git.OpenRepository(models.RepoPath(bsaeRepo.Owner.Name, bsaeRepo.Name))
if err != nil {
ctx.Handle(500, "OpenRepository", err)
return
}
if len(bsaeRepo.DefaultBranch) > 0 && baseGitRepo.IsBranchExist(bsaeRepo.DefaultBranch) {
ctx.Data["BaseDefaultBranch"] = bsaeRepo.DefaultBranch
} else {
baseBranches, err := baseGitRepo.GetBranches()
if err != nil {
ctx.Handle(500, "GetBranches", err)
return
}
if len(baseBranches) > 0 {
ctx.Data["BaseDefaultBranch"] = baseBranches[0]
}
}
} }


ctx.Data["Title"] = u.Name + "/" + repo.Name ctx.Data["Title"] = u.Name + "/" + repo.Name
} }


if ctx.IsSigned { if ctx.IsSigned {
ctx.Data["IsWatchingRepo"] = models.IsWatching(ctx.User.Id, repo.Id)
ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.Id, repo.Id)
ctx.Data["IsWatchingRepo"] = models.IsWatching(ctx.User.Id, repo.ID)
ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.Id, repo.ID)
} }


ctx.Data["TagName"] = ctx.Repo.TagName ctx.Data["TagName"] = ctx.Repo.TagName


// If not branch selected, try default one. // If not branch selected, try default one.
// If default branch doesn't exists, fall back to some other branch. // If default branch doesn't exists, fall back to some other branch.
if ctx.Repo.BranchName == "" {
if ctx.Repo.Repository.DefaultBranch != "" && gitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) {
if len(ctx.Repo.BranchName) == 0 {
if len(ctx.Repo.Repository.DefaultBranch) > 0 && gitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) {
ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch
} else if len(brs) > 0 { } else if len(brs) > 0 {
ctx.Repo.BranchName = brs[0] ctx.Repo.BranchName = brs[0]

+ 1
- 1
public/css/gogs.min.css
File diff suppressed because it is too large
View File


+ 11
- 0
public/js/gogs.js View File

$('#add-deploy-key-panel').show(); $('#add-deploy-key-panel').show();
}); });
} }

// Pull request
if ($('.repository.compare.pull').length > 0) {
$('.choose.branch .dropdown').dropdown({
action: 'hide',
fullTextSearch: true,
onNoResults: function () {
$('.choose.branch .dropdown .active').addClass('selected');
}
});
}
}; };


$(document).ready(function () { $(document).ready(function () {

+ 40
- 0
public/less/_repository.less View File

padding-left: 20px!important; padding-left: 20px!important;
} }
} }

&.compare.pull {
.choose.branch {
.octicon {
padding-right: 10px;
}
}
}

.filter.dropdown .menu {
margin-top: 1px!important;
.items {
max-height: 300px;
overflow-y: auto;
.item {
position: relative;
cursor: pointer;
display: block;
border: none;
height: auto;
border-top: none;
line-height: 1em;
color: rgba(0,0,0,.8);
padding: .71428571em 1.14285714em!important;
font-size: 1rem;
text-transform: none;
font-weight: 400;
box-shadow: none;
-webkit-touch-callout: none;
&.active {
font-weight: 700;
}
&:hover {
background: rgba(0,0,0,.05);
color: rgba(0,0,0,.8);
z-index: 13;
}
}
}
}
} }


.settings .key.list { .settings .key.list {

+ 5
- 5
routers/admin/users.go View File

return return
} }


u, err := models.GetUserById(uid)
u, err := models.GetUserByID(uid)
if err != nil { if err != nil {
ctx.Handle(500, "GetUserById", err)
ctx.Handle(500, "GetUserByID", err)
return return
} }


return return
} }


u, err := models.GetUserById(uid)
u, err := models.GetUserByID(uid)
if err != nil { if err != nil {
ctx.Handle(500, "GetUserById", err) ctx.Handle(500, "GetUserById", err)
return return
return return
} }


u, err := models.GetUserById(uid)
u, err := models.GetUserByID(uid)
if err != nil { if err != nil {
ctx.Handle(500, "GetUserById", err)
ctx.Handle(500, "GetUserByID", err)
return return
} }



+ 6
- 6
routers/api/v1/repo.go View File

log.Error(4, "CloneLink: %v", err) log.Error(4, "CloneLink: %v", err)
} }
return &api.Repository{ return &api.Repository{
Id: repo.Id,
Id: repo.ID,
Owner: *ToApiUser(owner), Owner: *ToApiUser(owner),
FullName: owner.Name + "/" + repo.Name, FullName: owner.Name + "/" + repo.Name,
Private: repo.IsPrivate, Private: repo.IsPrivate,
if ctx.User.Id == opt.Uid { if ctx.User.Id == opt.Uid {
opt.Private = true opt.Private = true
} else { } else {
u, err := models.GetUserById(opt.Uid)
u, err := models.GetUserByID(opt.Uid)
if err != nil { if err != nil {
ctx.JSON(500, map[string]interface{}{ ctx.JSON(500, map[string]interface{}{
"ok": false, "ok": false,
return return
} }
results[i] = &api.Repository{ results[i] = &api.Repository{
Id: repos[i].Id,
Id: repos[i].ID,
FullName: path.Join(repos[i].Owner.Name, repos[i].Name), FullName: path.Join(repos[i].Owner.Name, repos[i].Name),
} }
} }
} else { } else {
log.Error(4, "CreateRepository: %v", err) log.Error(4, "CreateRepository: %v", err)
if repo != nil { if repo != nil {
if err = models.DeleteRepository(ctx.User.Id, repo.Id, ctx.User.Name); err != nil {
if err = models.DeleteRepository(ctx.User.Id, repo.ID, ctx.User.Name); err != nil {
log.Error(4, "DeleteRepository: %v", err) log.Error(4, "DeleteRepository: %v", err)
} }
} }
ctxUser := u ctxUser := u
// Not equal means current user is an organization. // Not equal means current user is an organization.
if form.Uid != u.Id { if form.Uid != u.Id {
org, err := models.GetUserById(form.Uid)
org, err := models.GetUserByID(form.Uid)
if err != nil { if err != nil {
if models.IsErrUserNotExist(err) { if models.IsErrUserNotExist(err) {
ctx.HandleAPI(422, err) ctx.HandleAPI(422, err)
repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private, form.Mirror, remoteAddr) repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private, form.Mirror, remoteAddr)
if err != nil { if err != nil {
if repo != nil { if repo != nil {
if errDelete := models.DeleteRepository(ctxUser.Id, repo.Id, ctxUser.Name); errDelete != nil {
if errDelete := models.DeleteRepository(ctxUser.Id, repo.ID, ctxUser.Name); errDelete != nil {
log.Error(4, "DeleteRepository: %v", errDelete) log.Error(4, "DeleteRepository: %v", errDelete)
} }
} }

+ 2
- 2
routers/api/v1/repo_hooks.go View File

// GET /repos/:username/:reponame/hooks // GET /repos/:username/:reponame/hooks
// https://developer.github.com/v3/repos/hooks/#list-hooks // https://developer.github.com/v3/repos/hooks/#list-hooks
func ListRepoHooks(ctx *middleware.Context) { func ListRepoHooks(ctx *middleware.Context) {
hooks, err := models.GetWebhooksByRepoId(ctx.Repo.Repository.Id)
hooks, err := models.GetWebhooksByRepoId(ctx.Repo.Repository.ID)
if err != nil { if err != nil {
ctx.JSON(500, &base.ApiJsonErr{"GetWebhooksByRepoId: " + err.Error(), base.DOC_URL}) ctx.JSON(500, &base.ApiJsonErr{"GetWebhooksByRepoId: " + err.Error(), base.DOC_URL})
return return
} }


w := &models.Webhook{ w := &models.Webhook{
RepoId: ctx.Repo.Repository.Id,
RepoId: ctx.Repo.Repository.ID,
Url: form.Config["url"], Url: form.Config["url"],
ContentType: models.ToHookContentType(form.Config["content_type"]), ContentType: models.ToHookContentType(form.Config["content_type"]),
Secret: form.Config["secret"], Secret: form.Config["secret"],

+ 1
- 1
routers/home.go View File

} }
for _, repo := range repos { for _, repo := range repos {
if err = repo.GetOwner(); err != nil { if err = repo.GetOwner(); err != nil {
ctx.Handle(500, "GetOwner", fmt.Errorf("%d: %v", repo.Id, err))
ctx.Handle(500, "GetOwner", fmt.Errorf("%d: %v", repo.ID, err))
return return
} }
} }

+ 2
- 2
routers/repo/http.go View File

} }
return return
} }
authUser, err = models.GetUserById(token.Uid)
authUser, err = models.GetUserByID(token.Uid)
if err != nil { if err != nil {
ctx.Handle(500, "GetUserById", err) ctx.Handle(500, "GetUserById", err)
return return


// FIXME: handle error. // FIXME: handle error.
if err = models.Update(refName, oldCommitId, newCommitId, authUsername, username, reponame, authUser.Id); err == nil { if err = models.Update(refName, oldCommitId, newCommitId, authUsername, username, reponame, authUser.Id); err == nil {
models.HookQueue.AddRepoID(repo.Id)
models.HookQueue.AddRepoID(repo.ID)
} }


} }

+ 28
- 28
routers/repo/issue.go View File

) )


func RetrieveLabels(ctx *middleware.Context) { func RetrieveLabels(ctx *middleware.Context) {
labels, err := models.GetLabels(ctx.Repo.Repository.Id)
labels, err := models.GetLabels(ctx.Repo.Repository.ID)
if err != nil { if err != nil {
ctx.Handle(500, "RetrieveLabels.GetLabels: %v", err) ctx.Handle(500, "RetrieveLabels.GetLabels: %v", err)
return return
selectLabels := ctx.Query("labels") selectLabels := ctx.Query("labels")
milestoneID := ctx.QueryInt64("milestone") milestoneID := ctx.QueryInt64("milestone")
isShowClosed := ctx.Query("state") == "closed" isShowClosed := ctx.Query("state") == "closed"
issueStats := models.GetIssueStats(repo.Id, uid, com.StrTo(selectLabels).MustInt64(), milestoneID, isShowClosed, filterMode)
issueStats := models.GetIssueStats(repo.ID, uid, com.StrTo(selectLabels).MustInt64(), milestoneID, isShowClosed, filterMode)


page := ctx.QueryInt("page") page := ctx.QueryInt("page")
if page <= 1 { if page <= 1 {
ctx.Data["Page"] = paginater.New(total, setting.IssuePagingNum, page, 5) ctx.Data["Page"] = paginater.New(total, setting.IssuePagingNum, page, 5)


// Get issues. // Get issues.
issues, err := models.Issues(uid, assigneeID, repo.Id, posterID, milestoneID,
issues, err := models.Issues(uid, assigneeID, repo.ID, posterID, milestoneID,
page, isShowClosed, filterMode == models.FM_MENTION, selectLabels, ctx.Query("sortType")) page, isShowClosed, filterMode == models.FM_MENTION, selectLabels, ctx.Query("sortType"))
if err != nil { if err != nil {
ctx.Handle(500, "GetIssues: %v", err) ctx.Handle(500, "GetIssues: %v", err)
} }


// Get issue-user pairs. // Get issue-user pairs.
pairs, err := models.GetIssueUserPairs(repo.Id, posterID, isShowClosed)
pairs, err := models.GetIssueUserPairs(repo.ID, posterID, isShowClosed)
if err != nil { if err != nil {
ctx.Handle(500, "GetIssueUserPairs: %v", err) ctx.Handle(500, "GetIssueUserPairs: %v", err)
return return
ctx.Data["Issues"] = issues ctx.Data["Issues"] = issues


// Get milestones. // Get milestones.
miles, err := models.GetAllRepoMilestones(repo.Id)
miles, err := models.GetAllRepoMilestones(repo.ID)
if err != nil { if err != nil {
ctx.Handle(500, "GetAllRepoMilestones: %v", err) ctx.Handle(500, "GetAllRepoMilestones: %v", err)
return return
err error err error
) )
// Get all milestones. // Get all milestones.
ctx.Data["OpenMilestones"], err = models.GetMilestones(repo.Id, -1, false)
ctx.Data["OpenMilestones"], err = models.GetMilestones(repo.ID, -1, false)
if err != nil { if err != nil {
ctx.Handle(500, "GetMilestones.1: %v", err) ctx.Handle(500, "GetMilestones.1: %v", err)
return return
} }
ctx.Data["ClosedMilestones"], err = models.GetMilestones(repo.Id, -1, true)
ctx.Data["ClosedMilestones"], err = models.GetMilestones(repo.ID, -1, true)
if err != nil { if err != nil {
ctx.Handle(500, "GetMilestones.2: %v", err) ctx.Handle(500, "GetMilestones.2: %v", err)
return return


var err error var err error
// Get all milestones. // Get all milestones.
_, err = models.GetMilestones(ctx.Repo.Repository.Id, -1, false)
_, err = models.GetMilestones(ctx.Repo.Repository.ID, -1, false)
if err != nil { if err != nil {
send(500, nil, err) send(500, nil, err)
return return
} }
_, err = models.GetMilestones(ctx.Repo.Repository.Id, -1, true)
_, err = models.GetMilestones(ctx.Repo.Repository.ID, -1, true)
if err != nil { if err != nil {
send(500, nil, err) send(500, nil, err)
return return
form.AssigneeId = 0 form.AssigneeId = 0
} }
issue := &models.Issue{ issue := &models.Issue{
RepoID: ctx.Repo.Repository.Id,
RepoID: ctx.Repo.Repository.ID,
Index: int64(ctx.Repo.Repository.NumIssues) + 1, Index: int64(ctx.Repo.Repository.NumIssues) + 1,
Name: form.IssueName, Name: form.IssueName,
PosterID: ctx.User.Id, PosterID: ctx.User.Id,
ActEmail: ctx.User.Email, ActEmail: ctx.User.Email,
OpType: models.CREATE_ISSUE, OpType: models.CREATE_ISSUE,
Content: fmt.Sprintf("%d|%s", issue.Index, issue.Name), Content: fmt.Sprintf("%d|%s", issue.Index, issue.Name),
RepoID: ctx.Repo.Repository.Id,
RepoID: ctx.Repo.Repository.ID,
RepoUserName: ctx.Repo.Owner.Name, RepoUserName: ctx.Repo.Owner.Name,
RepoName: ctx.Repo.Repository.Name, RepoName: ctx.Repo.Repository.Name,
RefName: ctx.Repo.BranchName, RefName: ctx.Repo.BranchName,
return return
} }
} }
log.Trace("%d Issue created: %d", ctx.Repo.Repository.Id, issue.ID)
log.Trace("%d Issue created: %d", ctx.Repo.Repository.ID, issue.ID)


send(200, fmt.Sprintf("%s/%s/%s/issues/%d", setting.AppSubUrl, ctx.Params(":username"), ctx.Params(":reponame"), issue.Index), nil) send(200, fmt.Sprintf("%s/%s/%s/issues/%d", setting.AppSubUrl, ctx.Params(":username"), ctx.Params(":reponame"), issue.Index), nil)
} }
return return
} }


issue, err := models.GetIssueByIndex(ctx.Repo.Repository.Id, idx)
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, idx)
if err != nil { if err != nil {
if err == models.ErrIssueNotExist { if err == models.ErrIssueNotExist {
ctx.Handle(404, "GetIssueByIndex", err) ctx.Handle(404, "GetIssueByIndex", err)
ctx.Handle(500, "GetLabels", err) ctx.Handle(500, "GetLabels", err)
return return
} }
labels, err := models.GetLabels(ctx.Repo.Repository.Id)
labels, err := models.GetLabels(ctx.Repo.Repository.ID)
if err != nil { if err != nil {
ctx.Handle(500, "GetLabels.2", err) ctx.Handle(500, "GetLabels.2", err)
return return
} }


// Get all milestones. // Get all milestones.
ctx.Data["OpenMilestones"], err = models.GetMilestones(ctx.Repo.Repository.Id, -1, false)
ctx.Data["OpenMilestones"], err = models.GetMilestones(ctx.Repo.Repository.ID, -1, false)
if err != nil { if err != nil {
ctx.Handle(500, "GetMilestones.1: %v", err) ctx.Handle(500, "GetMilestones.1: %v", err)
return return
} }
ctx.Data["ClosedMilestones"], err = models.GetMilestones(ctx.Repo.Repository.Id, -1, true)
ctx.Data["ClosedMilestones"], err = models.GetMilestones(ctx.Repo.Repository.ID, -1, true)
if err != nil { if err != nil {
ctx.Handle(500, "GetMilestones.2: %v", err) ctx.Handle(500, "GetMilestones.2: %v", err)
return return


// Get posters. // Get posters.
for i := range comments { for i := range comments {
u, err := models.GetUserById(comments[i].PosterId)
u, err := models.GetUserByID(comments[i].PosterId)
if err != nil { if err != nil {
ctx.Handle(500, "GetUserById.2: %v", err) ctx.Handle(500, "GetUserById.2: %v", err)
return return
return return
} }


issue, err := models.GetIssueByIndex(ctx.Repo.Repository.Id, idx)
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, idx)
if err != nil { if err != nil {
if err == models.ErrIssueNotExist { if err == models.ErrIssueNotExist {
ctx.Handle(404, "issue.UpdateIssue", err) ctx.Handle(404, "issue.UpdateIssue", err)
return return
} }


issue, err := models.GetIssueByIndex(ctx.Repo.Repository.Id, idx)
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, idx)
if err != nil { if err != nil {
if err == models.ErrIssueNotExist { if err == models.ErrIssueNotExist {
ctx.Handle(404, "issue.UpdateIssueLabel(GetIssueByIndex)", err) ctx.Handle(404, "issue.UpdateIssueLabel(GetIssueByIndex)", err)
return return
} }


issue, err := models.GetIssueByIndex(ctx.Repo.Repository.Id, index)
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, index)
if err != nil { if err != nil {
if err == models.ErrIssueNotExist { if err == models.ErrIssueNotExist {
send(404, nil, err) send(404, nil, err)
cmtType = models.COMMENT_TYPE_REOPEN cmtType = models.COMMENT_TYPE_REOPEN
} }


if _, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.Id, issue.ID, 0, 0, cmtType, "", nil); err != nil {
if _, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.ID, issue.ID, 0, 0, cmtType, "", nil); err != nil {
send(200, nil, err) send(200, nil, err)
return return
} }
if len(content) > 0 || len(ctx.Req.MultipartForm.File["attachments"]) > 0 { if len(content) > 0 || len(ctx.Req.MultipartForm.File["attachments"]) > 0 {
switch ctx.Params(":action") { switch ctx.Params(":action") {
case "new": case "new":
if comment, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.Id, issue.ID, 0, 0, models.COMMENT_TYPE_COMMENT, content, nil); err != nil {
if comment, err = models.CreateComment(ctx.User.Id, ctx.Repo.Repository.ID, issue.ID, 0, 0, models.COMMENT_TYPE_COMMENT, content, nil); err != nil {
send(500, nil, err) send(500, nil, err)
return return
} }
ActEmail: ctx.User.Email, ActEmail: ctx.User.Email,
OpType: models.COMMENT_ISSUE, OpType: models.COMMENT_ISSUE,
Content: fmt.Sprintf("%d|%s", issue.Index, strings.Split(content, "\n")[0]), Content: fmt.Sprintf("%d|%s", issue.Index, strings.Split(content, "\n")[0]),
RepoID: ctx.Repo.Repository.Id,
RepoID: ctx.Repo.Repository.ID,
RepoUserName: ctx.Repo.Owner.LowerName, RepoUserName: ctx.Repo.Owner.LowerName,
RepoName: ctx.Repo.Repository.LowerName, RepoName: ctx.Repo.Repository.LowerName,
IsPrivate: ctx.Repo.Repository.IsPrivate, IsPrivate: ctx.Repo.Repository.IsPrivate,
} }


l := &models.Label{ l := &models.Label{
RepoId: ctx.Repo.Repository.Id,
RepoId: ctx.Repo.Repository.ID,
Name: form.Title, Name: form.Title,
Color: form.Color, Color: form.Color,
} }
} }


func DeleteLabel(ctx *middleware.Context) { func DeleteLabel(ctx *middleware.Context) {
if err := models.DeleteLabel(ctx.Repo.Repository.Id, ctx.QueryInt64("id")); err != nil {
if err := models.DeleteLabel(ctx.Repo.Repository.ID, ctx.QueryInt64("id")); err != nil {
ctx.Flash.Error("DeleteLabel: " + err.Error()) ctx.Flash.Error("DeleteLabel: " + err.Error())
} else { } else {
ctx.Flash.Success(ctx.Tr("repo.issues.label_deletion_success")) ctx.Flash.Success(ctx.Tr("repo.issues.label_deletion_success"))
ctx.Data["PageIsMilestones"] = true ctx.Data["PageIsMilestones"] = true


isShowClosed := ctx.Query("state") == "closed" isShowClosed := ctx.Query("state") == "closed"
openCount, closedCount := models.MilestoneStats(ctx.Repo.Repository.Id)
openCount, closedCount := models.MilestoneStats(ctx.Repo.Repository.ID)
ctx.Data["OpenCount"] = openCount ctx.Data["OpenCount"] = openCount
ctx.Data["ClosedCount"] = closedCount ctx.Data["ClosedCount"] = closedCount


} }
ctx.Data["Page"] = paginater.New(total, setting.IssuePagingNum, page, 5) ctx.Data["Page"] = paginater.New(total, setting.IssuePagingNum, page, 5)


miles, err := models.GetMilestones(ctx.Repo.Repository.Id, page, isShowClosed)
miles, err := models.GetMilestones(ctx.Repo.Repository.ID, page, isShowClosed)
if err != nil { if err != nil {
ctx.Handle(500, "GetMilestones", err) ctx.Handle(500, "GetMilestones", err)
return return
} }


if err = models.NewMilestone(&models.Milestone{ if err = models.NewMilestone(&models.Milestone{
RepoID: ctx.Repo.Repository.Id,
RepoID: ctx.Repo.Repository.ID,
Name: form.Title, Name: form.Title,
Content: form.Content, Content: form.Content,
Deadline: deadline, Deadline: deadline,

+ 58
- 7
routers/repo/pull.go View File

package repo package repo


import ( import (
"fmt"
"strings"

"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"
) )


const ( const (
FORK base.TplName = "repo/pulls/fork"
PULLS base.TplName = "repo/pulls"
FORK base.TplName = "repo/pulls/fork"
COMPARE_PULL base.TplName = "repo/pulls/compare"
PULLS base.TplName = "repo/pulls"
) )


func getForkRepository(ctx *middleware.Context) *models.Repository { func getForkRepository(ctx *middleware.Context) *models.Repository {
forkRepo, err := models.GetRepositoryById(ctx.ParamsInt64(":repoid"))
forkRepo, err := models.GetRepositoryByID(ctx.ParamsInt64(":repoid"))
if err != nil { if err != nil {
if models.IsErrRepoNotExist(err) { if models.IsErrRepoNotExist(err) {
ctx.Handle(404, "GetRepositoryById", nil)
ctx.Handle(404, "GetRepositoryByID", nil)
} else { } else {
ctx.Handle(500, "GetRepositoryById", err)
ctx.Handle(500, "GetRepositoryByID", err)
} }
return nil return nil
} }
return return
} }


repo, has := models.HasForkedRepo(ctxUser.Id, forkRepo.Id)
repo, has := models.HasForkedRepo(ctxUser.Id, forkRepo.ID)
if has { if has {
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name) ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name)
return return
return return
} }


log.Trace("Repository forked[%d]: %s/%s", forkRepo.Id, ctxUser.Name, repo.Name)
log.Trace("Repository forked[%d]: %s/%s", forkRepo.ID, ctxUser.Name, repo.Name)
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name) ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name)
} }


func CompareAndPullRequest(ctx *middleware.Context) {
// Get compare information.
infos := strings.Split(ctx.Params("*"), "...")
if len(infos) != 2 {
ctx.Handle(404, "CompareAndPullRequest", nil)
return
}

baseBranch := infos[0]
ctx.Data["BaseBranch"] = baseBranch

headInfos := strings.Split(infos[1], ":")
if len(headInfos) != 2 {
ctx.Handle(404, "CompareAndPullRequest", nil)
return
}
headUser := headInfos[0]
headBranch := headInfos[1]
ctx.Data["HeadBranch"] = headBranch

// TODO: check if branches are valid.
fmt.Println(baseBranch, headUser, headBranch)

// TODO: add organization support
// Check if current user has fork of repository.
headRepo, has := models.HasForkedRepo(ctx.User.Id, ctx.Repo.Repository.ID)
if !has {
ctx.Handle(404, "HasForkedRepo", nil)
return
}

headGitRepo, err := git.OpenRepository(models.RepoPath(ctx.User.Name, headRepo.Name))
if err != nil {
ctx.Handle(500, "OpenRepository", err)
return
}
headBranches, err := headGitRepo.GetBranches()
if err != nil {
ctx.Handle(500, "GetBranches", err)
return
}
ctx.Data["HeadBranches"] = headBranches

ctx.HTML(200, COMPARE_PULL)
}

func Pulls(ctx *middleware.Context) { func Pulls(ctx *middleware.Context) {
ctx.Data["IsRepoToolbarPulls"] = true ctx.Data["IsRepoToolbarPulls"] = true
ctx.HTML(200, PULLS) ctx.HTML(200, PULLS)

+ 6
- 6
routers/repo/release.go View File

return return
} }


rels, err := models.GetReleasesByRepoId(ctx.Repo.Repository.Id)
rels, err := models.GetReleasesByRepoId(ctx.Repo.Repository.ID)
if err != nil { if err != nil {
ctx.Handle(500, "GetReleasesByRepoId", err) ctx.Handle(500, "GetReleasesByRepoId", err)
return return
continue continue
} }
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
continue continue
} }


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
} }


rel := &models.Release{ rel := &models.Release{
RepoId: ctx.Repo.Repository.Id,
RepoId: ctx.Repo.Repository.ID,
PublisherId: ctx.User.Id, PublisherId: ctx.User.Id,
Title: form.Title, Title: form.Title,
TagName: form.TagName, TagName: form.TagName,
} }


tagName := ctx.Params(":tagname") tagName := ctx.Params(":tagname")
rel, err := models.GetRelease(ctx.Repo.Repository.Id, tagName)
rel, err := models.GetRelease(ctx.Repo.Repository.ID, tagName)
if err != nil { if err != nil {
if err == models.ErrReleaseNotExist { if err == models.ErrReleaseNotExist {
ctx.Handle(404, "GetRelease", err) ctx.Handle(404, "GetRelease", err)
} }


tagName := ctx.Params(":tagname") tagName := ctx.Params(":tagname")
rel, err := models.GetRelease(ctx.Repo.Repository.Id, tagName)
rel, err := models.GetRelease(ctx.Repo.Repository.ID, tagName)
if err != nil { if err != nil {
if err == models.ErrReleaseNotExist { if err == models.ErrReleaseNotExist {
ctx.Handle(404, "GetRelease", err) ctx.Handle(404, "GetRelease", err)

+ 7
- 7
routers/repo/repo.go View File

return ctx.User return ctx.User
} }


org, err := models.GetUserById(uid)
org, err := models.GetUserByID(uid)
if models.IsErrUserNotExist(err) { if models.IsErrUserNotExist(err) {
return ctx.User return ctx.User
} }
} }


if repo != nil { if repo != nil {
if errDelete := models.DeleteRepository(ctxUser.Id, repo.Id, ctxUser.Name); errDelete != nil {
if errDelete := models.DeleteRepository(ctxUser.Id, repo.ID, ctxUser.Name); errDelete != nil {
log.Error(4, "DeleteRepository: %v", errDelete) log.Error(4, "DeleteRepository: %v", errDelete)
} }
} }
} }


if repo != nil { if repo != nil {
if errDelete := models.DeleteRepository(ctxUser.Id, repo.Id, ctxUser.Name); errDelete != nil {
if errDelete := models.DeleteRepository(ctxUser.Id, repo.ID, ctxUser.Name); errDelete != nil {
log.Error(4, "DeleteRepository: %v", errDelete) log.Error(4, "DeleteRepository: %v", errDelete)
} }
} }
var err error var err error
switch ctx.Params(":action") { switch ctx.Params(":action") {
case "watch": case "watch":
err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, true)
err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.ID, true)
case "unwatch": case "unwatch":
err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, false)
err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.ID, false)
case "star": case "star":
err = models.StarRepo(ctx.User.Id, ctx.Repo.Repository.Id, true)
err = models.StarRepo(ctx.User.Id, ctx.Repo.Repository.ID, true)
case "unstar": case "unstar":
err = models.StarRepo(ctx.User.Id, ctx.Repo.Repository.Id, false)
err = models.StarRepo(ctx.User.Id, ctx.Repo.Repository.ID, false)
case "desc": case "desc":
if !ctx.Repo.IsOwner() { if !ctx.Repo.IsOwner() {
ctx.Error(404) ctx.Error(404)

+ 7
- 7
routers/repo/setting.go View File

return return
} }


if err := models.DeleteRepository(ctx.Repo.Owner.Id, ctx.Repo.Repository.Id, ctx.Repo.Owner.Name); err != nil {
if err := models.DeleteRepository(ctx.Repo.Owner.Id, ctx.Repo.Repository.ID, ctx.Repo.Owner.Name); err != nil {
ctx.Handle(500, "DeleteRepository", err) ctx.Handle(500, "DeleteRepository", err)
return return
} }
return return
} }


ws, err := models.GetWebhooksByRepoId(ctx.Repo.Repository.Id)
ws, err := models.GetWebhooksByRepoId(ctx.Repo.Repository.ID)
if err != nil { if err != nil {
ctx.Handle(500, "GetWebhooksByRepoId", err) ctx.Handle(500, "GetWebhooksByRepoId", err)
return return
if _, ok := ctx.Data["RepoLink"]; ok { if _, ok := ctx.Data["RepoLink"]; ok {
return &OrgRepoCtx{ return &OrgRepoCtx{
OrgId: int64(0), OrgId: int64(0),
RepoId: ctx.Repo.Repository.Id,
RepoId: ctx.Repo.Repository.ID,
Link: ctx.Repo.RepoLink, Link: ctx.Repo.RepoLink,
NewTemplate: HOOK_NEW, NewTemplate: HOOK_NEW,
}, nil }, nil
} }
return return
} }
models.HookQueue.AddRepoID(repo.Id)
models.HookQueue.AddRepoID(repo.ID)
} }


func GitHooks(ctx *middleware.Context) { func GitHooks(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("repo.settings") ctx.Data["Title"] = ctx.Tr("repo.settings")
ctx.Data["PageIsSettingsKeys"] = true ctx.Data["PageIsSettingsKeys"] = true


keys, err := models.ListDeployKeys(ctx.Repo.Repository.Id)
keys, err := models.ListDeployKeys(ctx.Repo.Repository.ID)
if err != nil { if err != nil {
ctx.Handle(500, "ListDeployKeys", err) ctx.Handle(500, "ListDeployKeys", err)
return return
} }
} }


if err = models.AddDeployKey(ctx.Repo.Repository.Id, form.Title, content); err != nil {
if err = models.AddDeployKey(ctx.Repo.Repository.ID, form.Title, content); err != nil {
ctx.Data["HasError"] = true ctx.Data["HasError"] = true
switch { switch {
case models.IsErrKeyAlreadyExist(err): case models.IsErrKeyAlreadyExist(err):
return return
} }


log.Trace("Deploy key added: %d", ctx.Repo.Repository.Id)
log.Trace("Deploy key added: %d", ctx.Repo.Repository.ID)
ctx.Flash.Success(ctx.Tr("repo.settings.add_key_success", form.Title)) ctx.Flash.Success(ctx.Tr("repo.settings.add_key_success", form.Title))
ctx.Redirect(ctx.Repo.RepoLink + "/settings/keys") ctx.Redirect(ctx.Repo.RepoLink + "/settings/keys")
} }

+ 6
- 6
routers/user/home.go View File

for _, act := range actions { for _, act := range actions {
if act.IsPrivate { if act.IsPrivate {
// This prevents having to retrieve the repository for each action // This prevents having to retrieve the repository for each action
repo := &models.Repository{Id: act.RepoID, IsPrivate: true}
repo := &models.Repository{ID: act.RepoID, IsPrivate: true}
if act.RepoUserName != ctx.User.LowerName { if act.RepoUserName != ctx.User.LowerName {
if has, _ := models.HasAccess(ctx.User, repo, models.ACCESS_MODE_READ); !has { if has, _ := models.HasAccess(ctx.User, repo, models.ACCESS_MODE_READ); !has {
continue continue
continue continue
} }
// This prevents having to retrieve the repository for each action // This prevents having to retrieve the repository for each action
repo := &models.Repository{Id: act.RepoID, IsPrivate: true}
repo := &models.Repository{ID: act.RepoID, IsPrivate: true}
if act.RepoUserName != ctx.User.LowerName { if act.RepoUserName != ctx.User.LowerName {
if has, _ := models.HasAccess(ctx.User, repo, models.ACCESS_MODE_READ); !has { if has, _ := models.HasAccess(ctx.User, repo, models.ACCESS_MODE_READ); !has {
continue continue
continue continue
} }


repoIds = append(repoIds, repo.Id)
repoIds = append(repoIds, repo.ID)
repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
issueStats.AllCount += int64(repo.NumOpenIssues) issueStats.AllCount += int64(repo.NumOpenIssues)


if isShowClosed { if isShowClosed {
if repo.NumClosedIssues > 0 { if repo.NumClosedIssues > 0 {
if filterMode == models.FM_CREATE { if filterMode == models.FM_CREATE {
repo.NumClosedIssues = int(models.GetIssueCountByPoster(ctx.User.Id, repo.Id, isShowClosed))
repo.NumClosedIssues = int(models.GetIssueCountByPoster(ctx.User.Id, repo.ID, isShowClosed))
} }
showRepos = append(showRepos, repo) showRepos = append(showRepos, repo)
} }
} else { } else {
if repo.NumOpenIssues > 0 { if repo.NumOpenIssues > 0 {
if filterMode == models.FM_CREATE { if filterMode == models.FM_CREATE {
repo.NumOpenIssues = int(models.GetIssueCountByPoster(ctx.User.Id, repo.Id, isShowClosed))
repo.NumOpenIssues = int(models.GetIssueCountByPoster(ctx.User.Id, repo.ID, isShowClosed))
} }
showRepos = append(showRepos, repo) showRepos = append(showRepos, repo)
} }
} }
} }


issues[i].Repo, err = models.GetRepositoryById(issues[i].RepoID)
issues[i].Repo, err = models.GetRepositoryByID(issues[i].RepoID)
if err != nil { if err != nil {
if models.IsErrRepoNotExist(err) { if models.IsErrRepoNotExist(err) {
log.Warn("GetRepositoryById[%d]: repository not exist", issues[i].RepoID) log.Warn("GetRepositoryById[%d]: repository not exist", issues[i].RepoID)

+ 2
- 2
templates/admin/repo/list.tmpl View File

<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr> <tr>
<th>Id</th>
<th>ID</th>
<th>{{.i18n.Tr "admin.repos.owner"}}</th> <th>{{.i18n.Tr "admin.repos.owner"}}</th>
<th>{{.i18n.Tr "admin.repos.name"}}</th> <th>{{.i18n.Tr "admin.repos.name"}}</th>
<th>{{.i18n.Tr "admin.repos.private"}}</th> <th>{{.i18n.Tr "admin.repos.private"}}</th>
<tbody> <tbody>
{{range .Repos}} {{range .Repos}}
<tr> <tr>
<td>{{.Id}}</td>
<td>{{.ID}}</td>
<td><a href="{{AppSubUrl}}/{{.Owner.Name}}">{{.Owner.Name}}</a></td> <td><a href="{{AppSubUrl}}/{{.Owner.Name}}">{{.Owner.Name}}</a></td>
<td><a href="{{AppSubUrl}}/{{.Owner.Name}}/{{.Name}}">{{.Name}}</a></td> <td><a href="{{AppSubUrl}}/{{.Owner.Name}}/{{.Name}}">{{.Name}}</a></td>
<td><i class="fa fa{{if .IsPrivate}}-check{{end}}-square-o"></i></td> <td><i class="fa fa{{if .IsPrivate}}-check{{end}}-square-o"></i></td>

+ 1
- 1
templates/repo/header.tmpl View File

<div class="divider"> / </div> <div class="divider"> / </div>
<a href="{{$.RepoLink}}">{{.Name}}</a> <a href="{{$.RepoLink}}">{{.Name}}</a>
{{if .IsMirror}}<div class="ui label">{{$.i18n.Tr "mirror"}}</div>{{end}} {{if .IsMirror}}<div class="ui label">{{$.i18n.Tr "mirror"}}</div>{{end}}
{{if .IsFork}}<div class="fork-flag">{{$.i18n.Tr "repo.forked_from"}} <a href="{{.ForkRepo.RepoLink}}">{{SubStr .ForkRepo.RepoLink 1 -1}}</a></div>{{end}}
{{if .IsFork}}<div class="fork-flag">{{$.i18n.Tr "repo.forked_from"}} <a href="{{.BaseRepo.RepoLink}}">{{SubStr .BaseRepo.RepoLink 1 -1}}</a></div>{{end}}
</div> </div>
</h2> </h2>
<div class="ui right floated secondary menu"> <div class="ui right floated secondary menu">

+ 2
- 2
templates/repo/header_old.tmpl View File

<span class="divider">/</span> <span class="divider">/</span>
<a class="repo text-bold" href="{{$.RepoLink}}">{{.Name}}</a> <a class="repo text-bold" href="{{$.RepoLink}}">{{.Name}}</a>
{{if .IsMirror}}<span class="label label-gray">{{$.i18n.Tr "mirror"}}</span>{{end}} {{if .IsMirror}}<span class="label label-gray">{{$.i18n.Tr "mirror"}}</span>{{end}}
{{if .IsFork}}<span class="fork-flag">forked from <a href="{{.ForkRepo.RepoLink}}">{{SubStr .ForkRepo.RepoLink 1 -1}}</a></span>{{end}}
{{if .IsFork}}<span class="fork-flag">forked from <a href="{{.BaseRepo.RepoLink}}">{{SubStr .BaseRepo.RepoLink 1 -1}}</a></span>{{end}}
</h1> </h1>
<ul id="repo-header-meta" class="right menu menu-line"> <ul id="repo-header-meta" class="right menu menu-line">
<li id="repo-header-download" class="drop"> <li id="repo-header-download" class="drop">
</a> </a>
</li> </li>
<li id="repo-header-fork"> <li id="repo-header-fork">
<a id="repo-header-fork-btn" {{if or (not $.IsRepositoryAdmin) $.Owner.IsOrganization}}href="{{AppSubUrl}}/repo/fork/{{.Id}}"{{end}}>
<a id="repo-header-fork-btn" {{if or (not $.IsRepositoryAdmin) $.Owner.IsOrganization}}href="{{AppSubUrl}}/repo/fork/{{.ID}}"{{end}}>
<button class="btn btn-gray text-bold btn-radius"> <button class="btn btn-gray text-bold btn-radius">
<i class="octicon octicon-repo-forked"></i>{{$.i18n.Tr "repo.fork"}} <i class="octicon octicon-repo-forked"></i>{{$.i18n.Tr "repo.fork"}}
<span class="num">{{.NumForks}}</span> <span class="num">{{.NumForks}}</span>

+ 6
- 3
templates/repo/home.tmpl View File

<a class="link" href="{{.Repository.Website}}">{{.Repository.Website}}</a> <a class="link" href="{{.Repository.Website}}">{{.Repository.Website}}</a>
</p> </p>
<ul id="repo-file-nav" class="clear menu menu-line"> <ul id="repo-file-nav" class="clear menu menu-line">
<!-- <li>
<a href="#">
{{if and .IsRepositoryAdmin .Repository.BaseRepo}}
{{ $baseRepo := .Repository.BaseRepo}}
<li>
<a href="{{AppSubUrl}}/{{$baseRepo.Owner.Name}}/{{$baseRepo.Name}}/compare/{{$.BaseDefaultBranch}}...{{$.Owner.Name}}:{{$.BranchName}}">
<button class="btn btn-green btn-small btn-radius" id="repo-compare-btn"><i class="octicon octicon-git-compare"></i></button> <button class="btn btn-green btn-small btn-radius" id="repo-compare-btn"><i class="octicon octicon-git-compare"></i></button>
</a> </a>
</li> -->
</li>
{{end}}
<li id="repo-branch-switch" class="down drop"> <li id="repo-branch-switch" class="down drop">
<a> <a>
<button class="btn btn-gray btn-medium btn-radius"> <button class="btn btn-gray btn-medium btn-radius">

+ 51
- 0
templates/repo/pulls/compare.tmpl View File

{{template "base/head" .}}
<div class="repository compare pull">
{{template "repo/header" .}}
<div class="ui middle page grid body">
<div class="sixteen wide column page grid">
<h2 class="ui header">
{{.i18n.Tr "repo.pulls.compare_changes"}}
<div class="sub header">{{.i18n.Tr "repo.pulls.compare_changes_desc"}}</div>
</h2>
<div class="ui segment choose branch">
<span class="octicon octicon-git-compare"></span>
<div class="ui floating filter dropdown">
<div class="ui basic small button">
<span class="text">base: {{$.BaseBranch}}</span>
<i class="dropdown icon"></i>
</div>
<div class="menu">
<div class="ui icon search input">
<i class="filter icon"></i>
<input name="search" placeholder="Filter branch...">
</div>
<div class="items">
{{range .Branches}}
<a class="{{if eq $.BaseBranch .}}active selected{{end}} item" href="{{$.RepoLink}}/compare/{{.}}...{{$.SignedUser.Name}}:{{$.HeadBranch}}">{{.}}</a>
{{end}}
</div>
</div>
</div>
...
<div class="ui floating filter dropdown">
<div class="ui basic small button">
<span class="text">compare: {{$.HeadBranch}}</span>
<i class="dropdown icon"></i>
</div>
<div class="menu">
<div class="ui icon search input">
<i class="filter icon"></i>
<input name="search" placeholder="Filter branch...">
</div>
<div class="items">
{{range .HeadBranches}}
<a class="{{if eq $.HeadBranch .}}active selected{{end}} item" href="{{$.RepoLink}}/compare/{{$.BaseBranch}}...{{$.SignedUser.Name}}:{{.}}">{{.}}</a>
{{end}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{{template "base/footer" .}}

Loading…
Cancel
Save