improve fork process

This commit is contained in:
Unknwon committed 2015-08-08 17:10:34 +08:00
1 parent e6862e9cec
commit 9db4acc62e
17 files changed
+292 -272

No files matched your search

+2 -2
View File
@@ -383,8 +383,8 @@ func runWeb(ctx *cli.Context) {
m.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost)
m.Get("/migrate", repo.Migrate)
m.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost)
m.Get("/fork", repo.Fork)
m.Post("/fork", bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost)
m.Combo("/fork/:repoid").Get(repo.Fork).
Post(bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost)
}, reqSignIn)
m.Group("/:username/:reponame", func() {
+1 -1
View File
@@ -300,7 +300,7 @@ owner = Owner
repo_name = Repository Name
repo_name_helper = A good repository name is usually composed of short, memorable and unique keywords.
visibility = Visibility
visiblity_helper = This repository is <span class="label label-red label-radius">Private</span>
visiblity_helper = This repository is <span class="ui red text">Private</span>
fork_repo = Fork Repository
fork_from = Fork From
fork_visiblity_helper = You cannot alter the visibility of a forked repository.
+14
View File
@@ -225,6 +225,20 @@ func (err ErrRepoNotExist) Error() string {
return fmt.Sprintf("repository does not exist [id: %d, uid: %d, name: %s]", err.ID, err.UID, err.Name)
}
type ErrRepoAlreadyExist struct {
Uname string
Name string
}
func IsErrRepoAlreadyExist(err error) bool {
_, ok := err.(ErrRepoAlreadyExist)
return ok
}
func (err ErrRepoAlreadyExist) Error() string {
return fmt.Sprintf("repository already exists [uname: %d, name: %s]", err.Uname, err.Name)
}
// _____ .__.__ __
// / \ |__| | ____ _______/ |_ ____ ____ ____
// / \ / \| | | _/ __ \ / ___/\ __\/ _ \ / \_/ __ \
+54 -83
View File
@@ -21,6 +21,7 @@ import (
"github.com/Unknwon/cae/zip"
"github.com/Unknwon/com"
"github.com/go-xorm/xorm"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/bindata"
@@ -35,7 +36,6 @@ const (
)
var (
ErrRepoAlreadyExist = errors.New("Repository already exist")
ErrRepoFileNotExist = errors.New("Repository file does not exist")
ErrRepoFileNotLoaded = errors.New("Repository file not loaded")
ErrMirrorNotExist = errors.New("Mirror does not exist")
@@ -222,15 +222,19 @@ func (repo *Repository) DescriptionHtml() template.HTML {
return template.HTML(DescPattern.ReplaceAllStringFunc(base.Sanitizer.Sanitize(repo.Description), sanitize))
}
// IsRepositoryExist returns true if the repository with given name under user has already existed.
func IsRepositoryExist(u *User, repoName string) (bool, error) {
has, err := x.Get(&Repository{
func isRepositoryExist(e Engine, u *User, repoName string) (bool, error) {
has, err := e.Get(&Repository{
OwnerId: u.Id,
LowerName: strings.ToLower(repoName),
})
return has && com.IsDir(RepoPath(u.Name, repoName)), err
}
// IsRepositoryExist returns true if the repository with given name under user has already existed.
func IsRepositoryExist(u *User, repoName string) (bool, error) {
return isRepositoryExist(x, u, repoName)
}
// CloneLink represents different types of clone URLs of repository.
type CloneLink struct {
SSH string
@@ -525,19 +529,50 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, initRe
return initRepoCommit(tmpDir, u.NewGitSig())
}
func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) {
if err = IsUsableName(repo.Name); err != nil {
return err
}
has, err := isRepositoryExist(e, u, repo.Name)
if err != nil {
return fmt.Errorf("IsRepositoryExist: %v", err)
} else if has {
return ErrRepoAlreadyExist{u.Name, repo.Name}
}
if _, err = e.Insert(repo); err != nil {
return err
} else if _, err = e.Exec("UPDATE `user` SET num_repos=num_repos+1 WHERE id=?", u.Id); err != nil {
return err
}
// Give access to all members in owner team.
if u.IsOrganization() {
t, err := u.getOwnerTeam(e)
if err != nil {
return fmt.Errorf("getOwnerTeam: %v", err)
} else if err = t.addRepository(e, repo); err != nil {
return fmt.Errorf("addRepository: %v", err)
}
} else {
// Organization automatically called this in addRepository method.
if err = repo.recalculateAccesses(e); err != nil {
return fmt.Errorf("recalculateAccesses: %v", err)
}
}
if err = watchRepo(e, u.Id, repo.Id, true); err != nil {
return fmt.Errorf("watchRepo: %v", err)
} else if err = newRepoAction(e, u, repo); err != nil {
return fmt.Errorf("newRepoAction: %v", err)
}
return nil
}
// 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 err = IsUsableName(name); err != nil {
return nil, err
}
has, err := IsRepositoryExist(u, name)
if err != nil {
return nil, fmt.Errorf("IsRepositoryExist: %v", err)
} else if has {
return nil, ErrRepoAlreadyExist
}
repo := &Repository{
OwnerId: u.Id,
Owner: u,
@@ -553,33 +588,8 @@ func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMi
return nil, err
}
if _, err = sess.Insert(repo); err != nil {
if err = createRepository(sess, u, repo); err != nil {
return nil, err
} else if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?", u.Id); err != nil {
return nil, err
}
// TODO fix code for mirrors?
// Give access to all members in owner team.
if u.IsOrganization() {
t, err := u.getOwnerTeam(sess)
if err != nil {
return nil, fmt.Errorf("getOwnerTeam: %v", err)
} else if err = t.addRepository(sess, repo); err != nil {
return nil, fmt.Errorf("addRepository: %v", err)
}
} else {
// Organization called this in addRepository method.
if err = repo.recalculateAccesses(sess); err != nil {
return nil, fmt.Errorf("recalculateAccesses: %v", err)
}
}
if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
return nil, fmt.Errorf("watchRepo: %v", err)
} else if err = newRepoAction(sess, u, repo); err != nil {
return nil, fmt.Errorf("newRepoAction: %v", err)
}
// No need for init mirror.
@@ -649,7 +659,7 @@ func TransferOwnership(u *User, newOwnerName string, repo *Repository) error {
if err != nil {
return fmt.Errorf("IsRepositoryExist: %v", err)
} else if has {
return ErrRepoAlreadyExist
return ErrRepoAlreadyExist{newOwnerName, repo.Name}
}
sess := x.NewSession()
@@ -767,7 +777,7 @@ func ChangeRepositoryName(u *User, oldRepoName, newRepoName string) (err error)
if err != nil {
return fmt.Errorf("IsRepositoryExist: %v", err)
} else if has {
return ErrRepoAlreadyExist
return ErrRepoAlreadyExist{u.Name, newRepoName}
}
// Change repository directory name.
@@ -1412,21 +1422,6 @@ func IsStaring(uid, repoId int64) bool {
// \/ \/
func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) {
has, err := IsRepositoryExist(u, name)
if err != nil {
return nil, fmt.Errorf("IsRepositoryExist: %v", err)
} else if has {
return nil, ErrRepoAlreadyExist
}
// In case the old repository is a fork.
if oldRepo.IsFork {
oldRepo, err = GetRepositoryById(oldRepo.ForkId)
if err != nil {
return nil, err
}
}
repo := &Repository{
OwnerId: u.Id,
Owner: u,
@@ -1444,34 +1439,10 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Reposit
return nil, err
}
if _, err = sess.Insert(repo); err != nil {
if err = createRepository(sess, u, repo); err != nil {
return nil, err
}
if err = repo.recalculateAccesses(sess); err != nil {
return nil, err
} else if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?", u.Id); err != nil {
return nil, err
}
if u.IsOrganization() {
// Update owner team info and count.
t, err := u.getOwnerTeam(sess)
if err != nil {
return nil, fmt.Errorf("getOwnerTeam: %v", err)
} else if err = t.addRepository(sess, repo); err != nil {
return nil, fmt.Errorf("addRepository: %v", err)
}
} else {
if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
return nil, fmt.Errorf("watchRepo: %v", err)
}
}
if err = newRepoAction(sess, u, repo); err != nil {
return nil, fmt.Errorf("newRepoAction: %v", err)
}
if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks+1 WHERE id=?", oldRepo.Id); err != nil {
return nil, err
}
+5
View File
@@ -20,6 +20,10 @@ import (
"github.com/gogits/gogs/modules/setting"
)
func Safe(raw string) template.HTML {
return template.HTML(raw)
}
func Str2html(raw string) template.HTML {
return template.HTML(Sanitizer.Sanitize(raw))
}
@@ -128,6 +132,7 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
},
"AvatarLink": AvatarLink,
"Safe": Safe,
"Str2html": Str2html,
"TimeSince": TimeSince,
"FileSize": FileSize,
+4 -4
View File
@@ -127,7 +127,7 @@ func confAppIni() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "conf/app.ini", size: 9185, mode: os.FileMode(420), modTime: time.Unix(1438834795, 0)}
info := bindataFileInfo{name: "conf/app.ini", size: 9185, mode: os.FileMode(420), modTime: time.Unix(1438976559, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -772,7 +772,7 @@ func confLocaleLocale_deDeIni() (*asset, error) {
return a, nil
}
var _confLocaleLocale_enUsIni = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xc4\x7d\xeb\x72\xdc\x46\xb2\xe6\x7f\x3c\x05\xec\x0d\xad\xec\x08\xaa\x15\xb6\x63\x2f\xe1\x90\xe4\xa5\x49\xeb\x32\x47\x24\x75\x44\x6a\x66\x67\x15\x0a\x0c\xba\x01\x76\x63\xd8\x0d\xb4\x01\x34\xdb\x3d\xbf\xf6\x35\xf6\xf5\xf6\x49\x36\xf3\xcb\xcc\xba\x00\x68\x4a\x9a\x73\x62\xcf\x1f\xb2\xba\x2a\xeb\x96\x95\x95\x95\xb7\x2a\xe4\xdb\x6d\x56\x94\xdd\x22\x7d\x9e\x9e\xa6\xdb\xbc\xaa\xd7\x65\xd7\xa5\x5d\xb9\xbe\x7d\xb2\x6a\xba\xbe\x2c\xd2\x57\x55\x4f\xbf\xdb\xfb\x6a\x51\x26\xc9\xaa\xd9\x94\x04\xfa\x9a\xfe\x25\x45\xde\xad\xe6\x4d\xde\x16\x94\x71\x6e\xe9\xa4\xfc\x63\xbb\x6e\x5a\x06\xfa\x4d\x52\xc9\xaa\x5c\x6f\xb9\x0e\xfd\x4b\xba\x6a\x59\x67\x55\x4d\x3f\xaf\x29\x95\xbe\xa9\x93\xae\x59\x54\xf9\x3a\x0b\x0a\x90\x61\xe5\x3f\xa7\x3f\xd6\x45\x7a\xdd\x97\xdb\xf4\x59\xb7\xc9\xd7\xeb\x17\x79\x87\x2a\x7d\x99\xe6\x8b\x45\xb3\xab\xfb\x67\x4f\xa5\x40\x1a\x6f\x76\xbd\xb5\x7e\xb5\xeb\x25\x6f\xb7\xb5\xac\x0f\xdb\xa4\x2d\x97\x15\x4d\xac\xa5\xac\xf7\x9a\x4c\xf6\xe5\xbc\xab\x7a\x1e\xf4\x5f\x24\x95\xdc\x97\x6d\x57\x35\x3c\x9e\x3f\x4b\x2a\xd9\xe6\x4b\x06\x78\x47\xff\x92\xbe\xdc\x6c\xd7\x39\x2a\xdc\x68\x32\x59\xe7\xf5\x72\x27\x30\x6f\x35\x99\x24\x3b\xc2\x5c\x9d\x03\x67\x1f\x34\x99\x94\x9b\xbc\x5a\x33\x7e\x9e\x70\x82\xda\xed\xba\x7d\x03\x2c\xbe\xd3\x24\x8d\x31\xeb\x0f\xdb\x12\x43\x7c\x72\x43\xa9\x64\x91\x6f\xfb\xc5\x2a\xa7\x9c\x33\x49\x25\x04\xb4\x6d\x68\xac\x4d\x7b\x00\x9c\xfd\x48\x9a\x76\x99\xd7\xd5\x3f\xf2\x5e\xc6\x7f\x15\xfc\x4c\x36\x55\xdb\x36\x3c\xf5\x0b\x24\x92\xba\xdc\x67\xdc\x0e\xe5\x5c\x96\xfb\xb0\x15\x2e\xd9\x54\xcb\x56\x66\xc9\x85\x17\xf8\xc5\xad\x70\xd9\x6d\xd3\xde\x69\xc1\x4b\x4e\x0e\xaa\xd2\x20\xb4\x34\xee\x3f\xaf\x09\x2f\x5a\x7a\x81\x1f\x11\x40\x97\xe4\xc5\xa6\xaa\xb3\x6d\x5e\x97\x8c\xa3\x53\xfe\x45\x78\xa1\x5f\x89\x2e\x77\xd6\x95\x7d\x5f\xd5\xcb\x8e\x8b\x25\x2b\xbd\xd6\xac\x24\x28\x73\x79\x3c\x9e\x2e\xbb\x2d\xcb\x42\x46\xd4\xa5\x2f\x29\x9d\x6c\x77\xeb\x35\xcd\xfd\xf7\x5d\xd9\xf5\x0c\xff\x8e\x7e\xd3\x2c\xe4\x77\x52\x75\x1d\x25\x28\xfb\x0d\x12\x09\x2d\x40\xbd\xc0\x90\xce\x90\x48\x92\x8f\x5d\x99\xb7\x8b\xd5\xa7\x44\xfe\xa3\x47\x4e\xcc\x66\xb3\xa3\x4b\xc3\xe4\xa0\xa4\x20\x3d\x58\x07\xc9\xa2\x29\xf8\xc7\x19\xfd\xa3\xa6\xab\xba\xeb\x89\xa4\x3f\x25\x9a\x60\x30\x49\x09\x1a\xfb\xaa\x5f\x97\x3e\x13\xfb\xa3\xe3\x75\x48\x5f\x56\x6d\xd7\x3f\xe9\x2b\x22\xb9\xf7\xbb\x3a\xe1\xf9\x11\x39\x67\xc5\xdc\x76\xf9\xab\x86\xb0\x83\xec\x96\xe6\x77\x71\xb8\xfe\xd7\xb7\x27\xe9\x3b\xda\xea\xcb\xb6\xa4\x74\x4a\x6d\xd0\x3f\xaa\xf3\xd3\x2c\xa1\x5a\xd6\xd3\x79\xde\xe7\xf3\xbc\x2b\x3d\x5a\xb9\x50\x68\xd4\x95\x81\x52\x99\x6d\x80\x45\x74\x7d\x34\xdf\x29\x3a\xa7\x36\x74\x77\xb8\x36\x2e\x79\x8b\x50\x3e\x73\x0d\x54\x7e\xb7\x2e\x39\x9f\x9a\x4a\xdf\x5c\x5e\x5e\x9d\xff\x9a\x96\xf5\xb2\xaa\xcb\x74\x5f\xf5\xab\x74\xd7\xdf\xfe\xf7\x6c\x59\xd6\x65\x4b\x4c\x64\x51\xa5\xb4\x33\x5a\x22\x82\x94\xc8\x53\x26\x37\x4b\xba\x6e\x9d\x6d\x04\xbd\xd7\xd7\x6f\xd3\x0b\x46\xf1\x36\xef\x57\x18\x48\xbf\x4a\xba\xdf\xd7\x8c\x22\xd7\xe1\xcd\xaa\x4c\x6f\x2b\x9a\x35\x80\x9a\x5b\xc3\x47\x5a\xe8\x18\x67\x49\xd9\xb6\x19\xed\xfb\xfe\x90\x69\x65\x6d\x6f\x08\x29\x4d\x10\xe9\xd4\x4d\x9f\xce\xcb\x14\x75\x66\x49\x62\x03\x36\xec\x9e\x6e\xb7\xeb\x6a\x21\x3b\xf6\x95\x94\x79\x44\x33\x8b\x56\x2c\x85\x70\x40\x94\x95\x05\xe8\x22\xfe\x77\x68\x76\x6d\x1a\xb1\x01\xd4\x5f\x95\xc4\x97\x57\x3b\xda\x72\x39\xf1\xd4\x75\xb3\x2b\xbe\x01\xa5\xda\xe8\x3d\xa1\xa6\xef\x1b\x1a\x30\xb0\xe3\x00\x7c\x17\xa7\x44\x71\x7c\x2a\xb4\xe5\xa6\x21\xee\xe0\x88\xbd\x22\x82\xda\x57\x54\x48\x33\xed\xf2\x7b\xda\x6f\x7d\x93\xf6\xab\xaa\x4b\x0b\x22\xb6\x05\x37\x4c\x5b\x63\x47\xfc\x58\xc8\x82\x08\x54\x48\xc3\xf2\xe2\x35\x00\xd4\x66\x47\xd4\xb4\xa2\xc6\x98\xdb\xf3\xd1\x44\x4d\x4e\x8d\x13\x53\xa2\x76\x40\xdf\x44\xb9\x0d\xf1\x56\xe6\x7e\xe7\x48\xe8\xef\xb0\x7d\x1a\x55\x7e\x7b\x4b\xa3\xea\x88\x2a\x5e\xa7\x8b\x75\x43\x24\xf5\xe1\xfd\x5b\xaa\xbc\xea\xfb\x6d\xb6\x6d\x5a\x90\xf1\xcd\xcd\x3b\xda\x1e\x6d\xef\x73\x03\x5c\x33\x4c\xbd\xdb\xcc\xe9\xd7\x7e\x55\x11\x13\xc8\x83\x05\x02\x2a\xd6\x7c\xc0\xd4\x69\x53\xcf\xb0\x56\xbb\x76\x3d\x58\x46\xea\xd2\x4a\x8e\x0c\x8f\x87\xf0\x94\xff\x5c\xfb\x51\x62\xba\x1d\x9d\xc2\x7b\x2c\x2a\x4d\xb5\xc4\x69\x42\xb4\xd5\x6c\xb9\xdd\x80\xb8\xae\x34\xc3\x53\x14\x4e\x20\x57\x2e\xe7\x10\x95\xe2\x8c\x0f\x78\xe9\x86\x26\xac\xbb\xf9\xfa\x82\xd0\x80\x2d\x8d\xdc\xdb\xb6\xd9\x50\xee\x4b\xfa\xe7\x33\xfc\xf0\x2f\xb8\x3d\xc0\xe4\x45\x41\x6c\xa6\x3b\x49\xdf\xbf\x3c\x4b\xff\xcb\x4f\x3f\xfe\x38\x4b\xdf\xf4\xbc\x21\x98\x46\xfe\xce\x6b\x4b\x49\x39\x10\x1d\x28\xed\xdc\x9e\x96\xff\x5b\x26\xf0\x6f\xd3\x67\x28\xfd\x1f\xe5\x1f\x39\x9d\xb3\xe5\x6c\xd1\x6c\x5e\xf0\xe6\xde\xe4\xfd\x2c\xe1\x12\xa2\x1a\x25\xa7\xeb\xb2\x2e\x28\xa1\xc7\xaa\x96\x05\x5c\x47\xcb\x83\x43\x56\x4e\xff\x6c\xd1\xd4\xb7\x55\xcb\x13\xfa\xad\xce\xe7\x84\x13\x93\x0b\x88\x1d\xa3\xc4\xce\x2e\x42\x1a\x6d\xe4\xea\xf6\xe0\x41\x31\xd5\x4b\xce\xd4\x05\x4d\x58\x56\xa2\x46\x55\x64\x72\x58\xbe\x46\x36\xd6\xed\x8a\xa6\xd7\x1a\xbe\x3b\x8f\xf0\xe6\xf6\x76\x4d\x8c\xcd\x98\x95\xf6\x70\x25\xb9\xc2\xb7\x42\x10\x22\xc6\x2d\x2Line truncated
var _confLocaleLocale_enUsIni = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xc4\x7d\xeb\x72\xdc\x46\xb2\xe6\x7f\x3c\x05\xac\x0d\xad\xec\x08\xaa\x15\xb6\x63\x2f\xe1\x90\xe4\xa5\x49\xeb\x32\x47\x14\x75\x44\x6a\x66\x67\x15\x0a\x0c\xba\x01\x76\x63\xd4\x0d\xb4\x71\x61\x9b\xf3\x6b\x5f\x63\x5f\x6f\x9f\x64\x33\xbf\xcc\xac\x0b\x80\xa6\xe4\x39\x27\xf6\xfc\x21\xab\xab\xb2\x6e\x59\x59\x59\x79\xab\x42\xbe\xdf\x67\x45\xd9\xad\xd2\x67\xe9\x69\xba\xcf\xab\x7a\x5b\x76\x5d\xda\x95\xdb\x9b\xc7\x9b\xa6\xeb\xcb\x22\x7d\x59\xf5\xf4\xbb\xbd\xad\x56\x65\x92\x6c\x9a\x5d\x49\xa0\xaf\xe8\x5f\x52\xe4\xdd\x66\xd9\xe4\x6d\x41\x19\xe7\x96\x4e\xca\xdf\xf7\xdb\xa6\x65\xa0\x5f\x25\x95\x6c\xca\xed\x9e\xeb\xd0\xbf\xa4\xab\xd6\x75\x56\xd5\xf4\xf3\x8a\x52\xe9\xeb\x3a\xe9\x9a\x55\x95\x6f\xb3\xa0\x00\x19\x56\xfe\x53\xfa\x43\x5d\xa4\x57\x7d\xb9\x4f\x9f\x76\xbb\x7c\xbb\x7d\x9e\x77\xa8\xd2\x97\x69\xbe\x5a\x35\x43\xdd\x3f\x7d\x22\x05\xd2\x78\x33\xf4\xd6\xfa\xe5\xd0\x4b\xde\xb0\xb7\xac\x0f\xfb\xa4\x2d\xd7\x15\x4d\xac\xa5\xac\xf7\x9a\x4c\x0e\xe5\xb2\xab\x7a\x1e\xf4\x5f\x24\x95\xdc\x96\x6d\x57\x35\x3c\x9e\x3f\x4b\x2a\xd9\xe7\x6b\x06\x78\x47\xff\x92\xbe\xdc\xed\xb7\x39\x2a\x5c\x6b\x32\xd9\xe6\xf5\x7a\x10\x98\x37\x9a\x4c\x92\x81\x30\x57\xe7\xc0\xd9\x07\x4d\x26\xe5\x2e\xaf\xb6\x8c\x9f\xc7\x9c\xa0\x76\xbb\xee\xd0\x00\x8b\xef\x34\x49\x63\xcc\xfa\xbb\x7d\x89\x21\x3e\xbe\xa6\x54\xb2\xca\xf7\xfd\x6a\x93\x53\xce\x99\xa4\x12\x02\xda\x37\x34\xd6\xa6\xbd\x03\x9c\xfd\x48\x9a\x76\x9d\xd7\xd5\x3f\xf2\x5e\xc6\x7f\x19\xfc\x4c\x76\x55\xdb\x36\x3c\xf5\x0b\x24\x92\xba\x3c\x64\xdc\x0e\xe5\xbc\x2d\x0f\x61\x2b\x5c\xb2\xab\xd6\xad\xcc\x92\x0b\x2f\xf0\x8b\x5b\xe1\xb2\x9b\xa6\xfd\xac\x05\x2f\x38\x39\xaa\x4a\x83\xd0\xd2\xb8\xff\xbc\x26\xbc\x68\xe9\x05\x7e\x44\x00\x5d\x92\x17\xbb\xaa\xce\xf6\x79\x5d\x32\x8e\x4e\xf9\x17\xe1\x85\x7e\x25\xba\xdc\x59\x57\xf6\x7d\x55\xaf\x3b\x2e\x96\xac\xf4\x4a\xb3\x92\xa0\xcc\xe5\xf1\x78\xba\xec\xa6\x2c\x0b\x19\x51\x97\xbe\xa0\x74\xb2\x1f\xb6\x5b\x9a\xfb\x6f\x43\xd9\xf5\x0c\xff\x8e\x7e\xd3\x2c\xe4\x77\x52\x75\x1d\x25\x28\xfb\x35\x12\x09\x2d\x40\xbd\xc2\x90\xce\x90\x48\x92\x8f\x5d\x99\xb7\xab\xcd\xa7\x44\xfe\xa3\x47\x4e\x2c\x16\x8b\xa3\x4b\xc3\xe4\xa0\xa4\x20\x3d\x58\x07\xc9\xaa\x29\xf8\xc7\x19\xfd\xa3\xa6\xab\xba\xeb\x89\xa4\x3f\x25\x9a\x60\x30\x49\x09\x1a\xfb\xaa\xdf\x96\x3e\x13\xfb\xa3\xe3\x75\x48\x5f\x54\x6d\xd7\x3f\xee\x2b\x22\xb9\xf7\x43\x9d\xf0\xfc\x88\x9c\xb3\x62\x69\xbb\xfc\x65\x43\xd8\x41\x76\x4b\xf3\xbb\xb8\xbb\xfa\xd7\x37\x27\xe9\x3b\xda\xea\xeb\xb6\xa4\x74\x4a\x6d\xd0\x3f\xaa\xf3\xe3\x22\xa1\x5a\xd6\xd3\x79\xde\xe7\xcb\xbc\x2b\x3d\x5a\xb9\x50\x68\xd4\x95\x81\x52\x99\x6d\x80\x45\x74\x7d\x34\xdf\x39\x3a\xa7\x36\x74\x77\xb8\x36\xde\xf2\x16\xa1\x7c\xe6\x1a\xa8\xfc\x6e\x5b\x72\x3e\x35\x95\xbe\x7e\xfb\xf6\xf2\xfc\x97\xb4\xac\xd7\x55\x5d\xa6\x87\xaa\xdf\xa4\x43\x7f\xf3\xdf\xb3\x75\x59\x97\x2d\x31\x91\x55\x95\xd2\xce\x68\x89\x08\x52\x22\x4f\x99\xdc\x22\xe9\xba\x6d\xb6\x13\xf4\x5e\x5d\xbd\x49\x2f\x18\xc5\xfb\xbc\xdf\x60\x20\xfd\x26\xe9\x7e\xdb\x32\x8a\x5c\x87\xd7\x9b\x32\xbd\xa9\x68\xd6\x00\x6a\x6e\x0c\x1f\x69\xa1\x63\x5c\x24\x65\xdb\x66\xb4\xef\xfb\xbb\x4c\x2b\x6b\x7b\x63\x48\x69\x82\x48\xa7\x6e\xfa\x74\x59\xa6\xa8\xb3\x48\x12\x1b\xb0\x61\xf7\x74\xbf\xdf\x56\x2b\xd9\xb1\x2f\xa5\xcc\x23\x9a\x59\xb4\x62\x29\x84\x03\xa2\xac\x2c\x40\x17\xf1\xbf\xbb\x66\x68\xd3\x88\x0d\xa0\xfe\xa6\x24\xbe\xbc\x19\x68\xcb\xe5\xc4\x53\xb7\xcd\x50\x7c\x03\x4a\xb5\xd1\x7b\x42\x4d\xdf\x37\x34\x60\x60\xc7\x01\xf8\x2e\x4e\x89\xe2\xf8\x54\x68\xcb\x5d\x43\xdc\xc1\x11\x7b\x45\x04\x75\xa8\xa8\x90\x66\xda\xe5\xb7\xb4\xdf\xfa\x26\xed\x37\x55\x97\x16\x44\x6c\x2b\x6e\x98\xb6\xc6\x40\xfc\x58\xc8\x82\x08\x54\x48\xc3\xf2\xe2\x35\x00\xd4\x6e\x20\x6a\xda\x50\x63\xcc\xed\xf9\x68\xa2\x26\xe7\xc6\x89\x29\x51\x3b\xa0\x6f\xa2\xdc\x86\x78\x2b\x73\xbf\x73\x24\xf4\x77\xd8\x3e\x8d\x2a\xbf\xb9\xa1\x51\x75\x44\x15\xaf\xd2\xd5\xb6\x21\x92\xfa\xf0\xfe\x0d\x55\xde\xf4\xfd\x3e\xdb\x37\x2d\xc8\xf8\xfa\xfa\x1d\x6d\x8f\xb6\xf7\xb9\x01\xae\x19\xa6\x1e\x76\x4b\xfa\x75\xd8\x54\xc4\x04\xf2\x60\x81\x80\x8a\x2d\x1f\x30\x75\xda\xd4\x0b\xac\xd5\xd0\x6e\x47\xcb\x48\x5d\x5a\xc9\x91\xe1\xf1\x10\x9e\xf0\x9f\x2b\x3f\x4a\x4c\xb7\xa3\x53\xf8\x80\x45\xa5\xa9\x96\x38\x4d\x88\xb6\x9a\x3d\xb7\x1b\x10\xd7\xa5\x66\x78\x8a\xc2\x09\xe4\xca\xe5\x1c\xa2\x52\x9c\xf1\x01\x2f\xdd\xd1\x84\x75\x37\x5f\x5d\x10\x1a\xb0\xa5\x91\x7b\xd3\x36\x3b\xca\x7d\x41\xff\x7c\x86\x1f\xfe\x05\xb7\x07\x98\xbc\x28\x88\xcd\x74\x27\xe9\xfb\x17\x67\xe9\x7f\xf9\xf1\x87\x1f\x16\xe9\xeb\x9e\x37\x04\xd3\xc8\xdf\x79\x6d\x29\x29\x07\xa2\x03\xa5\x9d\xdb\xd3\xf2\x3f\x60\x02\x7f\x90\x3e\x45\xe9\xff\x28\x7f\xcf\xe9\x9c\x2d\x17\xab\x66\xf7\x9c\x37\xf7\x2e\xef\x17\x09\x97\x10\xd5\x28\x39\x5d\x95\x75\x41\x09\x3d\x56\xb5\x2c\xe0\x3a\x5a\x1e\x1c\xb2\x72\xfa\x67\xab\xa6\xbe\xa9\x5a\x9e\xd0\xaf\x75\xbe\x24\x9c\x98\x5c\x40\xec\x18\x25\x76\x76\x11\xd2\x68\x23\x57\x37\x77\x1e\x14\x53\x7d\xcb\x99\xba\xa0\x09\xcb\x4a\xd4\xa8\x8a\x4c\x0e\xcb\x57\xc8\xc6\xba\x5d\xd2\xf4\x5a\xc3\x77\xe7\x11\xde\xdc\xdc\x6c\x89\xb1\x19\xb3\xd2\x1e\x2e\x25\x57\xf8\x56\x08\x42\xc4\xb8\x87\x64\x7Line truncated
func confLocaleLocale_enUsIniBytes() ([]byte, error) {
return bindataRead(
@@ -787,7 +787,7 @@ func confLocaleLocale_enUsIni() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "conf/locale/locale_en-US.ini", size: 36002, mode: os.FileMode(420), modTime: time.Unix(1438872339, 0)}
info := bindataFileInfo{name: "conf/locale/locale_en-US.ini", size: 35985, mode: os.FileMode(420), modTime: time.Unix(1439021705, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -987,7 +987,7 @@ func confLocaleLocale_zhCnIni() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "conf/locale/locale_zh-CN.ini", size: 35357, mode: os.FileMode(493), modTime: time.Unix(1438846726, 0)}
info := bindataFileInfo{name: "conf/locale/locale_zh-CN.ini", size: 35357, mode: os.FileMode(493), modTime: time.Unix(1439005078, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
+1 -1
View File
@@ -1 +1 @@
@font-face{font-family:octicons;src:url(../fonts/octicons.eot?#iefix&v=345f8bad9c5003db196d08f05e7f030fd2a32ff6)format('embedded-opentype'),url(../fonts/octicons.woff?v=345f8bad9c5003db196d08f05e7f030fd2a32ff6)format('woff'),url(../fonts/octicons.ttf?v=345f8bad9c5003db196d08f05e7f030fd2a32ff6)format('truetype'),url(../fonts/octicons.svg?v=345f8bad9c5003db196d08f05e7f030fd2a32ff6#octicons)format('svg');font-weight:400;font-style:normal}.mega-octicon,.octicon{font:normal normal normal 16px/1 octicons;display:inline-block;text-decoration:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mega-octicon{font-size:32px}.octicon-alert:before{content:'\f02d'}.octicon-alignment-align:before{content:'\f08a'}.octicon-alignment-aligned-to:before{content:'\f08e'}.octicon-alignment-unalign:before{content:'\f08b'}.octicon-arrow-down:before{content:'\f03f'}.octicon-arrow-left:before{content:'\f040'}.octicon-arrow-right:before{content:'\f03e'}.octicon-arrow-small-down:before{content:'\f0a0'}.octicon-arrow-small-left:before{content:'\f0a1'}.octicon-arrow-small-right:before{content:'\f071'}.octicon-arrow-small-up:before{content:'\f09f'}.octicon-arrow-up:before{content:'\f03d'}.octicon-beer:before{content:'\f069'}.octicon-book:before{content:'\f007'}.octicon-bookmark:before{content:'\f07b'}.octicon-briefcase:before{content:'\f0d3'}.octicon-broadcast:before{content:'\f048'}.octicon-browser:before{content:'\f0c5'}.octicon-bug:before{content:'\f091'}.octicon-calendar:before{content:'\f068'}.octicon-check:before{content:'\f03a'}.octicon-checklist:before{content:'\f076'}.octicon-chevron-down:before{content:'\f0a3'}.octicon-chevron-left:before{content:'\f0a4'}.octicon-chevron-right:before{content:'\f078'}.octicon-chevron-up:before{content:'\f0a2'}.octicon-circle-slash:before{content:'\f084'}.octicon-circuit-board:before{content:'\f0d6'}.octicon-clippy:before{content:'\f035'}.octicon-clock:before{content:'\f046'}.octicon-cloud-download:before{content:'\f00b'}.octicon-cloud-upload:before{content:'\f00c'}.octicon-code:before{content:'\f05f'}.octicon-color-mode:before{content:'\f065'}.octicon-comment-add:before,.octicon-comment:before{content:'\f02b'}.octicon-comment-discussion:before{content:'\f04f'}.octicon-credit-card:before{content:'\f045'}.octicon-dash:before{content:'\f0ca'}.octicon-dashboard:before{content:'\f07d'}.octicon-database:before{content:'\f096'}.octicon-device-camera:before{content:'\f056'}.octicon-device-camera-video:before{content:'\f057'}.octicon-device-desktop:before{content:'\f27c'}.octicon-device-mobile:before{content:'\f038'}.octicon-diff:before{content:'\f04d'}.octicon-diff-added:before{content:'\f06b'}.octicon-diff-ignored:before{content:'\f099'}.octicon-diff-modified:before{content:'\f06d'}.octicon-diff-removed:before{content:'\f06c'}.octicon-diff-renamed:before{content:'\f06e'}.octicon-ellipsis:before{content:'\f09a'}.octicon-eye-unwatch:before,.octicon-eye-watch:before,.octicon-eye:before{content:'\f04e'}.octicon-file-binary:before{content:'\f094'}.octicon-file-code:before{content:'\f010'}.octicon-file-directory:before{content:'\f016'}.octicon-file-media:before{content:'\f012'}.octicon-file-pdf:before{content:'\f014'}.octicon-file-submodule:before{content:'\f017'}.octicon-file-symlink-directory:before{content:'\f0b1'}.octicon-file-symlink-file:before{content:'\f0b0'}.octicon-file-text:before{content:'\f011'}.octicon-file-zip:before{content:'\f013'}.octicon-flame:before{content:'\f0d2'}.octicon-fold:before{content:'\f0cc'}.octicon-gear:before{content:'\f02f'}.octicon-gift:before{content:'\f042'}.octicon-gist:before{content:'\f00e'}.octicon-gist-secret:before{content:'\f08c'}.octicon-git-branch-create:before,.octicon-git-branch-delete:before,.octicon-git-branch:before{content:'\f020'}.octicon-git-commit:before{content:'\f01f'}.octicon-git-compare:before{content:'\f0ac'}.octicon-git-merge:before{content:'\f023'}.octicon-git-pull-request-abandoned:before,.octicon-git-pull-request:before{content:'\f009'}.octicon-globe:before{content:'\f0b6'}.octicon-graph:before{content:'\f043'}.octicon-heart:before{content:'\2665'}.octicon-history:before{content:'\f07e'}.octicon-home:before{content:'\f08d'}.octicon-horizontal-rule:before{content:'\f070'}.octicon-hourglass:before{content:'\f09e'}.octicon-hubot:before{content:'\f09d'}.octicon-inbox:before{content:'\f0cf'}.octicon-info:before{content:'\f059'}.octicon-issue-closed:before{content:'\f028'}.octicon-issue-opened:before{content:'\f026'}.octicon-issue-reopened:before{content:'\f027'}.octicon-jersey:before{content:'\f019'}.octicon-jump-down:before{content:'\f072'}.octicon-jump-left:before{content:'\f0a5'}.octicon-jump-right:before{content:'\f0a6'}.octicon-jump-up:before{content:'\f073'}.octicon-key:before{content:'\f049'}.octicon-keyboard:before{content:'\f00d'}.octicon-law:before{content:'\f0d8'}.octicon-light-bulb:before{content:'\f000'}.octicoLine truncated
@font-face{font-family:octicons;src:url(../fonts/octicons.eot?#iefix&v=345f8bad9c5003db196d08f05e7f030fd2a32ff6)format('embedded-opentype'),url(../fonts/octicons.woff?v=345f8bad9c5003db196d08f05e7f030fd2a32ff6)format('woff'),url(../fonts/octicons.ttf?v=345f8bad9c5003db196d08f05e7f030fd2a32ff6)format('truetype'),url(../fonts/octicons.svg?v=345f8bad9c5003db196d08f05e7f030fd2a32ff6#octicons)format('svg');font-weight:400;font-style:normal}.mega-octicon,.octicon{font:normal normal normal 16px/1 octicons;display:inline-block;text-decoration:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mega-octicon{font-size:32px}.octicon-alert:before{content:'\f02d'}.octicon-alignment-align:before{content:'\f08a'}.octicon-alignment-aligned-to:before{content:'\f08e'}.octicon-alignment-unalign:before{content:'\f08b'}.octicon-arrow-down:before{content:'\f03f'}.octicon-arrow-left:before{content:'\f040'}.octicon-arrow-right:before{content:'\f03e'}.octicon-arrow-small-down:before{content:'\f0a0'}.octicon-arrow-small-left:before{content:'\f0a1'}.octicon-arrow-small-right:before{content:'\f071'}.octicon-arrow-small-up:before{content:'\f09f'}.octicon-arrow-up:before{content:'\f03d'}.octicon-beer:before{content:'\f069'}.octicon-book:before{content:'\f007'}.octicon-bookmark:before{content:'\f07b'}.octicon-briefcase:before{content:'\f0d3'}.octicon-broadcast:before{content:'\f048'}.octicon-browser:before{content:'\f0c5'}.octicon-bug:before{content:'\f091'}.octicon-calendar:before{content:'\f068'}.octicon-check:before{content:'\f03a'}.octicon-checklist:before{content:'\f076'}.octicon-chevron-down:before{content:'\f0a3'}.octicon-chevron-left:before{content:'\f0a4'}.octicon-chevron-right:before{content:'\f078'}.octicon-chevron-up:before{content:'\f0a2'}.octicon-circle-slash:before{content:'\f084'}.octicon-circuit-board:before{content:'\f0d6'}.octicon-clippy:before{content:'\f035'}.octicon-clock:before{content:'\f046'}.octicon-cloud-download:before{content:'\f00b'}.octicon-cloud-upload:before{content:'\f00c'}.octicon-code:before{content:'\f05f'}.octicon-color-mode:before{content:'\f065'}.octicon-comment-add:before,.octicon-comment:before{content:'\f02b'}.octicon-comment-discussion:before{content:'\f04f'}.octicon-credit-card:before{content:'\f045'}.octicon-dash:before{content:'\f0ca'}.octicon-dashboard:before{content:'\f07d'}.octicon-database:before{content:'\f096'}.octicon-device-camera:before{content:'\f056'}.octicon-device-camera-video:before{content:'\f057'}.octicon-device-desktop:before{content:'\f27c'}.octicon-device-mobile:before{content:'\f038'}.octicon-diff:before{content:'\f04d'}.octicon-diff-added:before{content:'\f06b'}.octicon-diff-ignored:before{content:'\f099'}.octicon-diff-modified:before{content:'\f06d'}.octicon-diff-removed:before{content:'\f06c'}.octicon-diff-renamed:before{content:'\f06e'}.octicon-ellipsis:before{content:'\f09a'}.octicon-eye-unwatch:before,.octicon-eye-watch:before,.octicon-eye:before{content:'\f04e'}.octicon-file-binary:before{content:'\f094'}.octicon-file-code:before{content:'\f010'}.octicon-file-directory:before{content:'\f016'}.octicon-file-media:before{content:'\f012'}.octicon-file-pdf:before{content:'\f014'}.octicon-file-submodule:before{content:'\f017'}.octicon-file-symlink-directory:before{content:'\f0b1'}.octicon-file-symlink-file:before{content:'\f0b0'}.octicon-file-text:before{content:'\f011'}.octicon-file-zip:before{content:'\f013'}.octicon-flame:before{content:'\f0d2'}.octicon-fold:before{content:'\f0cc'}.octicon-gear:before{content:'\f02f'}.octicon-gift:before{content:'\f042'}.octicon-gist:before{content:'\f00e'}.octicon-gist-secret:before{content:'\f08c'}.octicon-git-branch-create:before,.octicon-git-branch-delete:before,.octicon-git-branch:before{content:'\f020'}.octicon-git-commit:before{content:'\f01f'}.octicon-git-compare:before{content:'\f0ac'}.octicon-git-merge:before{content:'\f023'}.octicon-git-pull-request-abandoned:before,.octicon-git-pull-request:before{content:'\f009'}.octicon-globe:before{content:'\f0b6'}.octicon-graph:before{content:'\f043'}.octicon-heart:before{content:'\2665'}.octicon-history:before{content:'\f07e'}.octicon-home:before{content:'\f08d'}.octicon-horizontal-rule:before{content:'\f070'}.octicon-hourglass:before{content:'\f09e'}.octicon-hubot:before{content:'\f09d'}.octicon-inbox:before{content:'\f0cf'}.octicon-info:before{content:'\f059'}.octicon-issue-closed:before{content:'\f028'}.octicon-issue-opened:before{content:'\f026'}.octicon-issue-reopened:before{content:'\f027'}.octicon-jersey:before{content:'\f019'}.octicon-jump-down:before{content:'\f072'}.octicon-jump-left:before{content:'\f0a5'}.octicon-jump-right:before{content:'\f0a6'}.octicon-jump-up:before{content:'\f073'}.octicon-key:before{content:'\f049'}.octicon-keyboard:before{content:'\f00d'}.octicon-law:before{content:'\f0d8'}.octicon-light-bulb:before{content:'\f000'}.octicoLine truncated
+6
View File
@@ -62,6 +62,12 @@ img {
&.right {
float: right;
}
.text {
&.red {
color: #d95c5c!important;
}
}
}
footer {
margin-top: @footer-margin!important;
+34
View File
@@ -11,4 +11,38 @@
.right {
margin-top: -5px;
}
}
.repository form {
margin: auto;
width: 800px!important;
.ui.message {
text-align: center;
}
@input-padding: 250px !important;
.header {
padding-left: @input-padding+20px;
}
.inline.field > label {
text-align: right;
width: @input-padding;
word-wrap: break-word;
}
.help {
margin-left: @input-padding+10px;
}
.dropdown {
.dropdown.icon {
margin-top: -7px!important;
}
.text {
margin-right: 0!important;
i {
margin-right: 0!important;
}
}
}
input,
textarea {
width: 50%!important;
}
}
+1 -1
View File
@@ -104,7 +104,7 @@ func createRepo(ctx *middleware.Context, owner *models.User, opt api.CreateRepoO
repo, err := models.CreateRepository(owner, opt.Name, opt.Description,
opt.Gitignore, opt.License, opt.Private, false, opt.AutoInit)
if err != nil {
if err == models.ErrRepoAlreadyExist ||
if models.IsErrRepoAlreadyExist(err) ||
models.IsErrNameReserved(err) ||
models.IsErrNamePatternNotAllowed(err) {
ctx.JSON(422, &base.ApiJsonErr{err.Error(), base.DOC_URL})
+95
View File
@@ -5,14 +5,109 @@
package repo
import (
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/auth"
"github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
"github.com/gogits/gogs/modules/setting"
)
const (
FORK base.TplName = "repo/pulls/fork"
PULLS base.TplName = "repo/pulls"
)
func getForkRepository(ctx *middleware.Context) *models.Repository {
forkRepo, err := models.GetRepositoryById(ctx.ParamsInt64(":repoid"))
if err != nil {
if models.IsErrRepoNotExist(err) {
ctx.Handle(404, "GetRepositoryById", nil)
} else {
ctx.Handle(500, "GetRepositoryById", err)
}
return nil
}
ctx.Data["repo_name"] = forkRepo.Name
ctx.Data["desc"] = forkRepo.Description
ctx.Data["IsPrivate"] = forkRepo.IsPrivate
if err = forkRepo.GetOwner(); err != nil {
ctx.Handle(500, "GetOwner", err)
return nil
}
ctx.Data["ForkFrom"] = forkRepo.Owner.Name + "/" + forkRepo.Name
if err := ctx.User.GetOrganizations(); err != nil {
ctx.Handle(500, "GetOrganizations", err)
return nil
}
ctx.Data["Orgs"] = ctx.User.Orgs
return forkRepo
}
func Fork(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("new_fork")
getForkRepository(ctx)
if ctx.Written() {
return
}
ctx.Data["ContextUser"] = ctx.User
ctx.HTML(200, FORK)
}
func ForkPost(ctx *middleware.Context, form auth.CreateRepoForm) {
ctx.Data["Title"] = ctx.Tr("new_fork")
forkRepo := getForkRepository(ctx)
if ctx.Written() {
return
}
ctxUser := checkContextUser(ctx, form.Uid)
if ctx.Written() {
return
}
ctx.Data["ContextUser"] = ctxUser
if ctx.HasError() {
ctx.HTML(200, FORK)
return
}
// Check ownership of organization.
if ctxUser.IsOrganization() {
if !ctxUser.IsOwnedBy(ctx.User.Id) {
ctx.Error(403)
return
}
}
repo, err := models.ForkRepository(ctxUser, forkRepo, form.RepoName, form.Description)
if err != nil {
switch {
case models.IsErrRepoAlreadyExist(err):
ctx.Data["Err_RepoName"] = true
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), FORK, &form)
case models.IsErrNameReserved(err):
ctx.Data["Err_RepoName"] = true
ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), FORK, &form)
case models.IsErrNamePatternNotAllowed(err):
ctx.Data["Err_RepoName"] = true
ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), FORK, &form)
default:
ctx.Handle(500, "ForkPost", err)
}
return
}
log.Trace("Repository forked[%d]: %s/%s", forkRepo.Id, ctxUser.Name, repo.Name)
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name)
}
func Pulls(ctx *middleware.Context) {
ctx.Data["IsRepoToolbarPulls"] = true
ctx.HTML(200, PULLS)
+2 -111
View File
@@ -25,7 +25,6 @@ import (
const (
CREATE base.TplName = "repo/create"
MIGRATE base.TplName = "repo/migrate"
FORK base.TplName = "repo/fork"
)
func checkContextUser(ctx *middleware.Context, uid int64) *models.User {
@@ -119,7 +118,7 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
}
switch {
case err == models.ErrRepoAlreadyExist:
case models.IsErrRepoAlreadyExist(err):
ctx.Data["Err_RepoName"] = true
ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), CREATE, &form)
case models.IsErrNameReserved(err):
@@ -222,7 +221,7 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
}
switch {
case err == models.ErrRepoAlreadyExist:
case models.IsErrRepoAlreadyExist(err):
ctx.Data["Err_RepoName"] = true
ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), MIGRATE, &form)
case models.IsErrNameReserved(err):
@@ -236,114 +235,6 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
}
}
func getForkRepository(ctx *middleware.Context) (*models.Repository, error) {
forkId := ctx.QueryInt64("fork_id")
ctx.Data["ForkId"] = forkId
forkRepo, err := models.GetRepositoryById(forkId)
if err != nil {
return nil, fmt.Errorf("GetRepositoryById: %v", err)
}
ctx.Data["repo_name"] = forkRepo.Name
ctx.Data["desc"] = forkRepo.Description
if err = forkRepo.GetOwner(); err != nil {
return nil, fmt.Errorf("GetOwner: %v", err)
}
ctx.Data["ForkFrom"] = forkRepo.Owner.Name + "/" + forkRepo.Name
return forkRepo, nil
}
func Fork(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("new_fork")
if _, err := getForkRepository(ctx); err != nil {
if models.IsErrRepoNotExist(err) {
ctx.Redirect(setting.AppSubUrl + "/")
} else {
ctx.Handle(500, "getForkRepository", err)
}
return
}
// FIXME: maybe sometime can directly fork to organization?
ctx.Data["ContextUser"] = ctx.User
if err := ctx.User.GetOrganizations(); err != nil {
ctx.Handle(500, "GetOrganizations", err)
return
}
ctx.Data["Orgs"] = ctx.User.Orgs
ctx.HTML(200, FORK)
}
func ForkPost(ctx *middleware.Context, form auth.CreateRepoForm) {
ctx.Data["Title"] = ctx.Tr("new_fork")
forkRepo, err := getForkRepository(ctx)
if err != nil {
if models.IsErrRepoNotExist(err) {
ctx.Redirect(setting.AppSubUrl + "/")
} else {
ctx.Handle(500, "getForkRepository", err)
}
return
}
ctxUser := checkContextUser(ctx, form.Uid)
if ctx.Written() {
return
}
ctx.Data["ContextUser"] = ctxUser
if err := ctx.User.GetOrganizations(); err != nil {
ctx.Handle(500, "GetOrganizations", err)
return
}
ctx.Data["Orgs"] = ctx.User.Orgs
if ctx.HasError() {
ctx.HTML(200, CREATE)
return
}
if ctxUser.IsOrganization() {
// Check ownership of organization.
if !ctxUser.IsOwnedBy(ctx.User.Id) {
ctx.Error(403)
return
}
}
repo, err := models.ForkRepository(ctxUser, forkRepo, form.RepoName, form.Description)
if err == nil {
log.Trace("Repository forked: %s/%s", ctxUser.Name, repo.Name)
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name)
return
}
if repo != nil {
if errDelete := models.DeleteRepository(ctxUser.Id, repo.Id, ctxUser.Name); errDelete != nil {
log.Error(4, "DeleteRepository: %v", errDelete)
}
}
// FIXME: merge this with other 2 error handling in to one.
switch {
case err == models.ErrRepoAlreadyExist:
ctx.Data["Err_RepoName"] = true
ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), FORK, &form)
case models.IsErrNameReserved(err):
ctx.Data["Err_RepoName"] = true
ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), FORK, &form)
case models.IsErrNamePatternNotAllowed(err):
ctx.Data["Err_RepoName"] = true
ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), FORK, &form)
default:
ctx.Handle(500, "ForkPost", err)
}
}
func Action(ctx *middleware.Context) {
var err error
switch ctx.Params(":action") {
+2 -2
View File
@@ -56,7 +56,7 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
if ctx.Repo.Repository.Name != newRepoName {
if err := models.ChangeRepositoryName(ctx.Repo.Owner, ctx.Repo.Repository.Name, newRepoName); err != nil {
switch {
case err == models.ErrRepoAlreadyExist:
case models.IsErrRepoAlreadyExist(err):
ctx.Data["Err_RepoName"] = true
ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), SETTINGS_OPTIONS, &form)
case models.IsErrNameReserved(err):
@@ -128,7 +128,7 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
}
if err = models.TransferOwnership(ctx.User, newOwner, ctx.Repo.Repository); err != nil {
if err == models.ErrRepoAlreadyExist {
if models.IsErrRepoAlreadyExist(err) {
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), SETTINGS_OPTIONS, nil)
} else {
ctx.Handle(500, "TransferOwnership", err)
-65
View File
@@ -1,65 +0,0 @@
{{template "ng/base/head" .}}
{{template "ng/base/header" .}}
<div id="repo-wrapper">
<form id="repo-create-form" class="form form-align panel panel-radius" action="{{AppSubUrl}}/repo/fork?fork_id={{.ForkId}}" method="post">
{{.CsrfTokenHtml}}
<div class="panel-header">
<h2>{{.i18n.Tr "new_fork"}}</h2>
</div>
<div class="panel-content">
{{template "ng/base/alert" .}}
<div class="field">
<label for="owner" class="req">{{.i18n.Tr "repo.owner"}}</label>
<input id="repo-owner-id" type="hidden" name="uid" value="{{.ContextUser.Id}}" />
<div class="inline-block drop">
<a class="drop-bottom">
<img class="avatar" src="{{.ContextUser.AvatarLink}}" id="repo-owner-avatar" alt="user-avatar">
<strong id="repo-owner-name">{{.ContextUser.Name}}</strong>
</a>
<ul class="drop-down menu menu-vertical menu-radius switching-list" id="repo-create-owner-list">
<li {{if eq $.ContextUser.Id .SignedUser.Id}}class="checked"{{end}} data-uid="{{.SignedUser.Id}}">
<a>
<i class="octicon octicon-check"></i>
<img class="avatar" src="{{.SignedUser.AvatarLink}}" alt="user-avatar">
<strong>{{.SignedUser.Name}}</strong>
</a>
</li>
{{range .Orgs}}
<li {{if eq $.ContextUser.Id .Id}}class="checked"{{end}} data-uid="{{.Id}}">
<a>
<i class="octicon octicon-check"></i>
<img class="avatar" src="{{.AvatarLink}}" alt="user-avatar">
<strong>{{.Name}}</strong>
</a>
</li>
{{end}}
</ul>
</div>
</div>
<div class="field">
<label>{{.i18n.Tr "repo.fork_from"}}</label>
<span><a target="_blank" href="{{AppSubUrl}}/{{.ForkFrom}}">{{.ForkFrom}}</a></span>
</div>
<div class="field">
<label class="req" for="repo-name">{{.i18n.Tr "repo.repo_name"}}</label>
<input class="ipt ipt-large ipt-radius {{if .Err_RepoName}}ipt-error{{end}}" id="repo-name" name="repo_name" type="text" value="{{.repo_name}}" required />
<span class="form-label"></span>
<span class="help">{{.i18n.Tr "repo.repo_name_helper" | Str2html}}</span>
</div>
<div class="field">
<label for="visibility">{{.i18n.Tr "repo.visibility"}}</label>
<span>{{.i18n.Tr "repo.fork_visiblity_helper"}}</span>
</div>
<div class="field clear">
<label class="left" for="desc">{{.i18n.Tr "repo.repo_desc"}}</label>
<textarea class="ipt ipt-large ipt-radius {{if .Err_Description}}ipt-error{{end}}" id="desc" name="desc">{{.desc}}</textarea>
</div>
<div class="field">
<label></label>
<button class="btn btn-large btn-blue btn-radius">{{.i18n.Tr "repo.fork_repo"}}</button>
<a class="btn btn-small btn-gray btn-radius" id="repo-create-cancel" href="{{AppSubUrl}}/"><strong>{{.i18n.Tr "cancel"}}</strong></a>
</div>
</div>
</form>
</div>
{{template "ng/base/footer" .}}
+1 -1
View File
@@ -19,7 +19,7 @@
<i class="fa fa-star{{if not $.IsStaringRepo}}-o{{end}}"></i>
{{if $.IsStaringRepo}}{{$.i18n.Tr "repo.unstar"}}{{else}}{{$.i18n.Tr "repo.star"}}{{end}} <span class="num">{{.NumStars}}</span>
</a>
<a class="ui black basic button {{if $.IsRepositoryOwner}}poping up{{end}}" {{if not $.IsRepositoryOwner}}href="{{AppSubUrl}}/repo/fork?fork_id={{.Id}}"{{end}} {{if $.IsRepositoryOwner}}data-content="{{$.i18n.Tr "repo.fork_from_self"}}"{{end}}>
<a class="ui black basic button {{if $.IsRepositoryOwner}}poping up{{end}}" {{if not $.IsRepositoryOwner}}href="{{AppSubUrl}}/repo/fork/{{.Id}}"{{end}} {{if $.IsRepositoryOwner}}data-content="{{$.i18n.Tr "repo.fork_from_self"}}"{{end}}>
<i class="octicon octicon-repo-forked"></i>
{{$.i18n.Tr "repo.fork"}} <span class="num">{{.NumForks}}</span>
</a>
+1 -1
View File
@@ -49,7 +49,7 @@
</a>
</li>
<li id="repo-header-fork">
<a id="repo-header-fork-btn" {{if or (not $.IsRepositoryAdmin) $.Owner.IsOrganization}}href="{{AppSubUrl}}/repo/fork?fork_id={{.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">
<i class="octicon octicon-repo-forked"></i>{{$.i18n.Tr "repo.fork"}}
<span class="num">{{.NumForks}}</span>
+69
View File
@@ -0,0 +1,69 @@
{{template "base/head" .}}
<div class="repository new fork">
<div class="ui middle very relaxed page grid">
<div class="column">
<form class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<h3 class="ui top attached header">
{{.i18n.Tr "new_fork"}}
</h3>
<div class="ui attached segment">
{{template "base/alert" .}}
<div class="inline required field {{if .Err_Owner}}error{{end}}">
<label>{{.i18n.Tr "repo.owner"}}</label>
<div class="ui selection dropdown">
<input type="hidden" id="uid" name="uid" value="{{.ContextUser.Id}}" required>
<span class="text">
<img class="ui mini avatar image" src="{{.ContextUser.AvatarLink}}">
{{.ContextUser.Name}}
</span>
<i class="dropdown icon"></i>
<div class="menu">
<div class="item" data-value="{{.SignedUser.Id}}">
<img class="ui mini avatar image" src="{{.SignedUser.AvatarLink}}">
{{.SignedUser.Name}}
</div>
{{range .Orgs}}
<div class="item" data-value="{{.Id}}">
<img class="ui mini avatar image" src="{{.AvatarLink}}">
{{.Name}}
</div>
{{end}}
</div>
</div>
</div>
<div class="inline field">
<label>{{.i18n.Tr "repo.fork_from"}}</label>
<a href="{{AppSubUrl}}/{{.ForkFrom}}">{{.ForkFrom}}</a>
</div>
<div class="inline required field {{if .Err_RepoName}}error{{end}}">
<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
<input id="repo_name" name="repo_name" value="{{.repo_name}}" required>
</div>
<div class="inline field">
<label>{{.i18n.Tr "repo.visibility"}}</label>
<div class="ui read-only toggle checkbox">
<input type="checkbox" {{if .IsPrivate}}checked{{end}}>
<label>{{.i18n.Tr "repo.visiblity_helper" | Safe}}</label>
</div>
<span class="help">{{.i18n.Tr "repo.fork_visiblity_helper"}}</span>
</div>
<div class="inline field {{if .Err_Description}}error{{end}}">
<label for="desc">{{.i18n.Tr "repo.repo_desc"}}</label>
<textarea id="desc" name="desc">{{.desc}}</textarea>
</div>
<div class="inline field">
<label></label>
<button class="ui green button">
{{.i18n.Tr "repo.fork_repo"}}
</button>
<a class="ui button" href="{{AppSubUrl}}/{{.ForkFrom}}">{{.i18n.Tr "cancel"}}</a>
</div>
</div>
</form>
</div>
</div>
</div>
{{template "base/footer" .}}