aboutsummaryrefslogtreecommitdiff
path: root/models/repo.go
diff options
context:
space:
mode:
Diffstat (limited to 'models/repo.go')
-rw-r--r--models/repo.go140
1 files changed, 102 insertions, 38 deletions
diff --git a/models/repo.go b/models/repo.go
index bcd6c0e8..0254e8f0 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -37,10 +37,10 @@ const (
var (
ErrRepoAlreadyExist = errors.New("Repository already exist")
ErrRepoFileNotExist = errors.New("Repository file does not exist")
- ErrRepoNameIllegal = errors.New("Repository name contains illegal characters")
ErrRepoFileNotLoaded = errors.New("Repository file not loaded")
ErrMirrorNotExist = errors.New("Mirror does not exist")
ErrInvalidReference = errors.New("Invalid reference specified")
+ ErrNameEmpty = errors.New("Name is empty")
)
var (
@@ -104,8 +104,8 @@ func NewRepoContext() {
log.Fatal(4, "Gogs requires Git version greater or equal to 1.7.1")
}
- // Check if server has user.email and user.name set correctly and set if they're not.
- for configKey, defaultValue := range map[string]string{"user.name": "Gogs", "user.email": "gogitservice@gmail.com"} {
+ // 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"} {
if stdout, stderr, err := process.Exec("NewRepoContext(get setting)", "git", "config", "--get", configKey); err != nil || strings.TrimSpace(stdout) == "" {
// ExitError indicates this config is not set
if _, ok := err.(*exec.ExitError); ok || strings.TrimSpace(stdout) == "" {
@@ -223,12 +223,12 @@ func (repo *Repository) DescriptionHtml() template.HTML {
}
// IsRepositoryExist returns true if the repository with given name under user has already existed.
-func IsRepositoryExist(u *User, repoName string) bool {
- has, _ := x.Get(&Repository{
+func IsRepositoryExist(u *User, repoName string) (bool, error) {
+ has, err := x.Get(&Repository{
OwnerId: u.Id,
LowerName: strings.ToLower(repoName),
})
- return has && com.IsDir(RepoPath(u.Name, repoName))
+ return has && com.IsDir(RepoPath(u.Name, repoName)), err
}
// CloneLink represents different types of clone URLs of repository.
@@ -243,34 +243,42 @@ func (repo *Repository) CloneLink() (cl CloneLink, err error) {
if err = repo.GetOwner(); err != nil {
return cl, err
}
+
if setting.SSHPort != 22 {
- cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.Domain, 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.LowerName, repo.LowerName)
} else {
- cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.Domain, repo.Owner.LowerName, repo.LowerName)
+ cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.SSHDomain, repo.Owner.LowerName, repo.LowerName)
}
cl.HTTPS = fmt.Sprintf("%s%s/%s.git", setting.AppUrl, repo.Owner.LowerName, repo.LowerName)
return cl, nil
}
var (
- illegalEquals = []string{"debug", "raw", "install", "api", "avatar", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin", "new"}
- illegalSuffixs = []string{".git", ".keys"}
+ reservedNames = []string{"debug", "raw", "install", "api", "avatar", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin", "new"}
+ reservedPatterns = []string{"*.git", "*.keys"}
)
-// IsLegalName returns false if name contains illegal characters.
-func IsLegalName(repoName string) bool {
- repoName = strings.ToLower(repoName)
- for _, char := range illegalEquals {
- if repoName == char {
- return false
+// IsUsableName checks if name is reserved or pattern of name is not allowed.
+func IsUsableName(name string) error {
+ name = strings.TrimSpace(strings.ToLower(name))
+ if utf8.RuneCountInString(name) == 0 {
+ return ErrNameEmpty
+ }
+
+ for i := range reservedNames {
+ if name == reservedNames[i] {
+ return ErrNameReserved{name}
}
}
- for _, char := range illegalSuffixs {
- if strings.HasSuffix(repoName, char) {
- return false
+
+ for _, pat := range reservedPatterns {
+ if pat[0] == '*' && strings.HasSuffix(name, pat[1:]) ||
+ (pat[len(pat)-1] == '*' && strings.HasPrefix(name, pat[:len(pat)-1])) {
+ return ErrNamePatternNotAllowed{pat}
}
}
- return true
+
+ return nil
}
// Mirror represents a mirror information of repository.
@@ -283,9 +291,9 @@ type Mirror struct {
NextUpdate time.Time
}
-func GetMirror(repoId int64) (*Mirror, error) {
+func getMirror(e Engine, repoId int64) (*Mirror, error) {
m := &Mirror{RepoId: repoId}
- has, err := x.Get(m)
+ has, err := e.Get(m)
if err != nil {
return nil, err
} else if !has {
@@ -294,11 +302,20 @@ func GetMirror(repoId int64) (*Mirror, error) {
return m, nil
}
-func UpdateMirror(m *Mirror) error {
- _, err := x.Id(m.Id).Update(m)
+// GetMirror returns mirror object by given repository ID.
+func GetMirror(repoId int64) (*Mirror, error) {
+ return getMirror(x, repoId)
+}
+
+func updateMirror(e Engine, m *Mirror) error {
+ _, err := e.Id(m.Id).Update(m)
return err
}
+func UpdateMirror(m *Mirror) error {
+ return updateMirror(x, m)
+}
+
// MirrorRepository creates a mirror repository from source.
func MirrorRepository(repoId int64, userName, repoName, repoPath, url string) error {
_, stderr, err := process.ExecTimeout(10*time.Minute,
@@ -363,6 +380,15 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
return repo, fmt.Errorf("create update hook: %v", err)
}
+ // Check if repository has master branch, if so set it to default branch.
+ gitRepo, err := git.OpenRepository(repoPath)
+ if err != nil {
+ return repo, fmt.Errorf("open git repository: %v", err)
+ }
+ if gitRepo.IsBranchExist("master") {
+ repo.DefaultBranch = "master"
+ }
+
return repo, UpdateRepository(repo, false)
}
@@ -495,11 +521,14 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, initRe
// 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) {
- if !IsLegalName(name) {
- return nil, ErrRepoNameIllegal
+ if err = IsUsableName(name); err != nil {
+ return nil, err
}
- if IsRepositoryExist(u, name) {
+ has, err := IsRepositoryExist(u, name)
+ if err != nil {
+ return nil, fmt.Errorf("IsRepositoryExist: %v", err)
+ } else if has {
return nil, ErrRepoAlreadyExist
}
@@ -610,7 +639,10 @@ func TransferOwnership(u *User, newOwnerName string, repo *Repository) error {
}
// Check if new owner has repository with same name.
- if IsRepositoryExist(newOwner, repo.Name) {
+ has, err := IsRepositoryExist(newOwner, repo.Name)
+ if err != nil {
+ return fmt.Errorf("IsRepositoryExist: %v", err)
+ } else if has {
return ErrRepoAlreadyExist
}
@@ -697,6 +729,18 @@ func TransferOwnership(u *User, newOwnerName string, repo *Repository) error {
return fmt.Errorf("transferRepoAction: %v", err)
}
+ // Update mirror information.
+ if repo.IsMirror {
+ mirror, err := getMirror(sess, repo.Id)
+ if err != nil {
+ return fmt.Errorf("getMirror: %v", err)
+ }
+ mirror.RepoName = newOwner.LowerName + "/" + repo.LowerName
+ if err = updateMirror(sess, mirror); err != nil {
+ return fmt.Errorf("updateMirror: %v", err)
+ }
+ }
+
// Change repository directory name.
if err = os.Rename(RepoPath(owner.Name, repo.Name), RepoPath(newOwner.Name, repo.Name)); err != nil {
return fmt.Errorf("rename directory: %v", err)
@@ -706,16 +750,22 @@ func TransferOwnership(u *User, newOwnerName string, repo *Repository) error {
}
// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
-func ChangeRepositoryName(userName, oldRepoName, newRepoName string) (err error) {
- userName = strings.ToLower(userName)
+func ChangeRepositoryName(u *User, oldRepoName, newRepoName string) (err error) {
oldRepoName = strings.ToLower(oldRepoName)
newRepoName = strings.ToLower(newRepoName)
- if !IsLegalName(newRepoName) {
- return ErrRepoNameIllegal
+ if err = IsUsableName(newRepoName); err != nil {
+ return err
+ }
+
+ has, err := IsRepositoryExist(u, newRepoName)
+ if err != nil {
+ return fmt.Errorf("IsRepositoryExist: %v", err)
+ } else if has {
+ return ErrRepoAlreadyExist
}
// Change repository directory name.
- return os.Rename(RepoPath(userName, oldRepoName), RepoPath(userName, newRepoName))
+ return os.Rename(RepoPath(u.LowerName, oldRepoName), RepoPath(u.LowerName, newRepoName))
}
func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err error) {
@@ -826,7 +876,7 @@ func DeleteRepository(uid, repoID int64, userName string) error {
return err
}
for i := range issues {
- if _, err = sess.Delete(&Comment{IssueId: issues[i].Id}); err != nil {
+ if _, err = sess.Delete(&Comment{IssueId: issues[i].ID}); err != nil {
return err
}
}
@@ -1009,7 +1059,7 @@ func MirrorUpdate() {
repoPath := filepath.Join(setting.RepoRootPath, m.RepoName+".git")
if _, stderr, err := process.ExecDir(10*time.Minute,
repoPath, fmt.Sprintf("MirrorUpdate: %s", repoPath),
- "git", "remote", "update"); err != nil {
+ "git", "remote", "update", "--prune"); err != nil {
desc := fmt.Sprintf("Fail to update mirror repository(%s): %s", repoPath, stderr)
log.Error(4, desc)
if err = CreateRepositoryNotice(desc); err != nil {
@@ -1144,6 +1194,10 @@ func (repo *Repository) AddCollaborator(u *User) error {
return nil
}
+ if err = repo.GetOwner(); err != nil {
+ return fmt.Errorf("GetOwner: %v", err)
+ }
+
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
@@ -1152,8 +1206,15 @@ func (repo *Repository) AddCollaborator(u *User) error {
if _, err = sess.InsertOne(collaboration); err != nil {
return err
- } else if err = repo.recalculateAccesses(sess); err != nil {
- return err
+ }
+
+ if repo.Owner.IsOrganization() {
+ err = repo.recalculateTeamAccesses(sess, 0)
+ } else {
+ err = repo.recalculateAccesses(sess)
+ }
+ if err != nil {
+ return fmt.Errorf("recalculateAccesses 'team=%v': %v", repo.Owner.IsOrganization(), err)
}
return sess.Commit()
@@ -1345,7 +1406,10 @@ func IsStaring(uid, repoId int64) bool {
// \/ \/
func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) {
- if IsRepositoryExist(u, name) {
+ has, err := IsRepositoryExist(u, name)
+ if err != nil {
+ return nil, fmt.Errorf("IsRepositoryExist: %v", err)
+ } else if has {
return nil, ErrRepoAlreadyExist
}