aboutsummaryrefslogtreecommitdiff
path: root/models/repo.go
diff options
context:
space:
mode:
Diffstat (limited to 'models/repo.go')
-rw-r--r--models/repo.go161
1 files changed, 106 insertions, 55 deletions
diff --git a/models/repo.go b/models/repo.go
index 75e1cd3a..174fbd9d 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -23,6 +23,7 @@ import (
"github.com/Unknwon/cae/zip"
"github.com/Unknwon/com"
"github.com/go-xorm/xorm"
+ "gopkg.in/ini.v1"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/bindata"
@@ -48,7 +49,7 @@ var (
Gitignores, Licenses, Readmes []string
// Maximum items per page in forks, watchers and stars of a repo
- ItemsPerPage = 54
+ ItemsPerPage = 40
)
func LoadRepoConfig() {
@@ -105,6 +106,7 @@ func NewRepoContext() {
if ver.LessThan(reqVer) {
log.Fatal(4, "Gogs requires Git version greater or equal to 1.7.1")
}
+ log.Info("Git Version: %s", ver.String())
// Git requires setting user.name and user.email in order to commit changes.
for configKey, defaultValue := range map[string]string{"user.name": "Gogs", "user.email": "gogs@fake.local"} {
@@ -182,9 +184,11 @@ func (repo *Repository) AfterSet(colName string, _ xorm.Cell) {
}
func (repo *Repository) getOwner(e Engine) (err error) {
- if repo.Owner == nil {
- repo.Owner, err = getUserByID(e, repo.OwnerID)
+ if repo.Owner != nil {
+ return nil
}
+
+ repo.Owner, err = getUserByID(e, repo.OwnerID)
return err
}
@@ -297,7 +301,7 @@ func (repo *Repository) DescriptionHtml() template.HTML {
}
func (repo *Repository) LocalCopyPath() string {
- return path.Join(setting.RepoRootPath, "local", com.ToStr(repo.ID))
+ return path.Join(setting.AppDataPath, "tmp/local", com.ToStr(repo.ID))
}
// UpdateLocalCopy makes sure the local copy of repository is up-to-date.
@@ -316,7 +320,7 @@ func (repo *Repository) UpdateLocalCopy() error {
}
} else {
_, stderr, err := process.ExecDir(-1, localPath,
- fmt.Sprintf("UpdateLocalCopy(git pull): %s", repoPath), "git", "pull")
+ fmt.Sprintf("UpdateLocalCopy(git pull --all): %s", repoPath), "git", "pull", "--all")
if err != nil {
return fmt.Errorf("git pull: %v - %s", err, stderr)
}
@@ -325,6 +329,30 @@ func (repo *Repository) UpdateLocalCopy() error {
return nil
}
+// PatchPath returns corresponding patch file path of repository by given issue ID.
+func (repo *Repository) PatchPath(index int64) (string, error) {
+ if err := repo.GetOwner(); err != nil {
+ return "", err
+ }
+
+ return filepath.Join(RepoPath(repo.Owner.Name, repo.Name), "pulls", com.ToStr(index)+".patch"), nil
+}
+
+// SavePatch saves patch data to corresponding location by given issue ID.
+func (repo *Repository) SavePatch(index int64, patch []byte) error {
+ patchPath, err := repo.PatchPath(index)
+ if err != nil {
+ return fmt.Errorf("PatchPath: %v", err)
+ }
+
+ os.MkdirAll(path.Dir(patchPath), os.ModePerm)
+ if err = ioutil.WriteFile(patchPath, patch, 0644); err != nil {
+ return fmt.Errorf("WriteFile: %v", err)
+ }
+
+ return nil
+}
+
func isRepositoryExist(e Engine, u *User, repoName string) (bool, error) {
has, err := e.Get(&Repository{
OwnerID: u.Id,
@@ -352,11 +380,11 @@ func (repo *Repository) CloneLink() (cl CloneLink, err error) {
}
if setting.SSHPort != 22 {
- cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.SSHDomain, setting.SSHPort, repo.Owner.LowerName, repo.LowerName)
+ cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.SSHDomain, setting.SSHPort, repo.Owner.Name, repo.Name)
} else {
- cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.SSHDomain, repo.Owner.LowerName, repo.LowerName)
+ cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.SSHDomain, repo.Owner.Name, repo.Name)
}
- cl.HTTPS = fmt.Sprintf("%s%s/%s.git", setting.AppUrl, repo.Owner.LowerName, repo.LowerName)
+ cl.HTTPS = fmt.Sprintf("%s%s/%s.git", setting.AppUrl, repo.Owner.Name, repo.Name)
return cl, nil
}
@@ -453,13 +481,21 @@ func MirrorRepository(repoId int64, userName, repoName, repoPath, url string) er
return nil
}
+type MigrateRepoOptions struct {
+ Name string
+ Description string
+ IsPrivate bool
+ IsMirror bool
+ RemoteAddr string
+}
+
// MigrateRepository migrates a existing repository from other project hosting.
-func MigrateRepository(u *User, name, desc string, private, mirror bool, url string) (*Repository, error) {
+func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) {
repo, err := CreateRepository(u, CreateRepoOptions{
- Name: name,
- Description: desc,
- IsPrivate: private,
- IsMirror: mirror,
+ Name: opts.Name,
+ Description: opts.Description,
+ IsPrivate: opts.IsPrivate,
+ IsMirror: opts.IsMirror,
})
if err != nil {
return nil, err
@@ -469,7 +505,7 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()))
os.MkdirAll(tmpDir, os.ModePerm)
- repoPath := RepoPath(u.Name, name)
+ repoPath := RepoPath(u.Name, opts.Name)
if u.IsOrganization() {
t, err := u.GetOwnerTeam()
@@ -482,8 +518,8 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
}
repo.IsBare = false
- if mirror {
- if err = MirrorRepository(repo.ID, u.Name, repo.Name, repoPath, url); err != nil {
+ if opts.IsMirror {
+ if err = MirrorRepository(repo.ID, u.Name, repo.Name, repoPath, opts.RemoteAddr); err != nil {
return repo, err
}
repo.IsMirror = true
@@ -495,13 +531,24 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
// FIXME: this command could for both migrate and mirror
_, stderr, err := process.ExecTimeout(10*time.Minute,
fmt.Sprintf("MigrateRepository: %s", repoPath),
- "git", "clone", "--mirror", "--bare", "--quiet", url, repoPath)
+ "git", "clone", "--mirror", "--bare", "--quiet", opts.RemoteAddr, repoPath)
if err != nil {
return repo, fmt.Errorf("git clone --mirror --bare --quiet: %v", stderr)
} else if err = createUpdateHook(repoPath); err != nil {
return repo, fmt.Errorf("create update hook: %v", err)
}
+ // Clean up mirror info which prevents "push --all".
+ configPath := filepath.Join(repoPath, "/config")
+ cfg, err := ini.Load(configPath)
+ if err != nil {
+ return repo, fmt.Errorf("open config file: %v", err)
+ }
+ cfg.DeleteSection("remote \"origin\"")
+ if err = cfg.SaveToIndent(configPath, "\t"); err != nil {
+ return repo, fmt.Errorf("save config file: %v", err)
+ }
+
// Check if repository is empty.
_, stderr, err = com.ExecCmdDir(repoPath, "git", "log", "-1")
if err != nil {
@@ -552,7 +599,7 @@ func createUpdateHook(repoPath string) error {
hookPath := path.Join(repoPath, "hooks/update")
os.MkdirAll(path.Dir(hookPath), os.ModePerm)
return ioutil.WriteFile(hookPath,
- []byte(fmt.Sprintf(_TPL_UPDATE_HOOK, setting.ScriptType, "\""+appPath+"\"", setting.CustomConf)), 0777)
+ []byte(fmt.Sprintf(_TPL_UPDATE_HOOK, setting.ScriptType, "\""+setting.AppPath+"\"", setting.CustomConf)), 0777)
}
type CreateRepoOptions struct {
@@ -863,9 +910,9 @@ func TransferOwnership(u *User, newOwnerName string, repo *Repository) error {
}
// Remove redundant collaborators.
- collaborators, err := repo.GetCollaborators()
+ collaborators, err := repo.getCollaborators(sess)
if err != nil {
- return fmt.Errorf("GetCollaborators: %v", err)
+ return fmt.Errorf("getCollaborators: %v", err)
}
// Dummy object.
@@ -901,9 +948,9 @@ func TransferOwnership(u *User, newOwnerName string, repo *Repository) error {
}
if newOwner.IsOrganization() {
- t, err := newOwner.GetOwnerTeam()
+ t, err := newOwner.getOwnerTeam(sess)
if err != nil {
- return fmt.Errorf("GetOwnerTeam: %v", err)
+ return fmt.Errorf("getOwnerTeam: %v", err)
} else if err = t.addRepository(sess, repo); err != nil {
return fmt.Errorf("add to owner team: %v", err)
}
@@ -1069,7 +1116,7 @@ func DeleteRepository(uid, repoID int64) error {
return err
} else if _, err = sess.Delete(&Milestone{RepoID: repoID}); err != nil {
return err
- } else if _, err = sess.Delete(&Release{RepoId: repoID}); err != nil {
+ } else if _, err = sess.Delete(&Release{RepoID: repoID}); err != nil {
return err
} else if _, err = sess.Delete(&Collaboration{RepoID: repoID}); err != nil {
return err
@@ -1124,7 +1171,7 @@ func DeleteRepository(uid, repoID int64) error {
desc := fmt.Sprintf("delete repository files[%s]: %v", repoPath, err)
log.Warn(desc)
if err = CreateRepositoryNotice(desc); err != nil {
- log.Error(4, "add notice: %v", err)
+ log.Error(4, "CreateRepositoryNotice: %v", err)
}
}
@@ -1267,10 +1314,14 @@ func DeleteRepositoryArchives() error {
return x.Where("id > 0").Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
- if err := repo.GetOwner(); err != nil {
- return err
+ repoPath, err := repo.RepoPath()
+ if err != nil {
+ if err2 := CreateRepositoryNotice(fmt.Sprintf("DeleteRepositoryArchives[%d]: %v", repo.ID, err)); err2 != nil {
+ log.Error(4, "CreateRepositoryNotice: %v", err2)
+ }
+ return nil
}
- return os.RemoveAll(filepath.Join(RepoPath(repo.Owner.Name, repo.Name), "archives"))
+ return os.RemoveAll(filepath.Join(repoPath, "archives"))
})
}
@@ -1279,10 +1330,14 @@ func RewriteRepositoryUpdateHook() error {
return x.Where("id > 0").Iterate(new(Repository),
func(idx int, bean interface{}) error {
repo := bean.(*Repository)
- if err := repo.GetOwner(); err != nil {
- return err
+ repoPath, err := repo.RepoPath()
+ if err != nil {
+ if err2 := CreateRepositoryNotice(fmt.Sprintf("RewriteRepositoryUpdateHook[%d]: %v", repo.ID, err)); err2 != nil {
+ log.Error(4, "CreateRepositoryNotice: %v", err2)
+ }
+ return nil
}
- return createUpdateHook(RepoPath(repo.Owner.Name, repo.Name))
+ return createUpdateHook(repoPath)
})
}
@@ -1449,6 +1504,12 @@ func CheckRepoStats() {
"UPDATE `user` SET num_repos=(SELECT COUNT(*) FROM `repository` WHERE owner_id=?) WHERE id=?",
"user count 'num_repos'",
},
+ // Issue.NumComments
+ {
+ "SELECT `issue`.id FROM `issue` WHERE `issue`.num_comments!=(SELECT COUNT(*) FROM `comment` WHERE issue_id=`issue`.id AND type=0)",
+ "UPDATE `issue` SET num_comments=(SELECT COUNT(*) FROM `comment` WHERE issue_id=? AND type=0) WHERE id=?",
+ "issue count 'num_comments'",
+ },
}
for i := range checkers {
repoStatsCheck(checkers[i])
@@ -1635,25 +1696,21 @@ func WatchRepo(uid, repoId int64, watch bool) (err error) {
return watchRepo(x, uid, repoId, watch)
}
-func getWatchers(e Engine, rid int64) ([]*Watch, error) {
+func getWatchers(e Engine, repoID int64) ([]*Watch, error) {
watches := make([]*Watch, 0, 10)
- err := e.Find(&watches, &Watch{RepoID: rid})
- return watches, err
+ return watches, e.Find(&watches, &Watch{RepoID: repoID})
}
// GetWatchers returns all watchers of given repository.
-func GetWatchers(rid int64) ([]*Watch, error) {
- return getWatchers(x, rid)
+func GetWatchers(repoID int64) ([]*Watch, error) {
+ return getWatchers(x, repoID)
}
-// Repository.GetWatchers returns all users watching given repository.
-func (repo *Repository) GetWatchers(offset int) ([]*User, error) {
- users := make([]*User, 0, 10)
- offset = (offset - 1) * ItemsPerPage
-
- err := x.Limit(ItemsPerPage, offset).Where("repo_id=?", repo.ID).Join("LEFT", "watch", "user.id=watch.user_id").Find(&users)
-
- return users, err
+// Repository.GetWatchers returns range of users watching given repository.
+func (repo *Repository) GetWatchers(page int) ([]*User, error) {
+ users := make([]*User, 0, ItemsPerPage)
+ return users, x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).
+ Where("repo_id=?", repo.ID).Join("LEFT", "watch", "user.id=watch.user_id").Find(&users)
}
func notifyWatchers(e Engine, act *Action) error {
@@ -1733,13 +1790,10 @@ func IsStaring(uid, repoId int64) bool {
return has
}
-func (repo *Repository) GetStars(offset int) ([]*User, error) {
- users := make([]*User, 0, 10)
- offset = (offset - 1) * ItemsPerPage
-
- err := x.Limit(ItemsPerPage, offset).Where("repo_id=?", repo.ID).Join("LEFT", "star", "user.id=star.uid").Find(&users)
-
- return users, err
+func (repo *Repository) GetStargazers(page int) ([]*User, error) {
+ users := make([]*User, 0, ItemsPerPage)
+ return users, x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).
+ Where("repo_id=?", repo.ID).Join("LEFT", "star", "user.id=star.uid").Find(&users)
}
// ___________ __
@@ -1811,9 +1865,6 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Reposit
}
func (repo *Repository) GetForks() ([]*Repository, error) {
- forks := make([]*Repository, 0, 10)
-
- err := x.Find(&forks, &Repository{ForkID: repo.ID})
-
- return forks, err
+ forks := make([]*Repository, 0, repo.NumForks)
+ return forks, x.Find(&forks, &Repository{ForkID: repo.ID})
}