mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 16:01:32 +01:00 
			
		
		
		
	merge
This commit is contained in:
		
						commit
						a30e72323d
					
				| @ -5,7 +5,7 @@ Gogs(Go Git Service) is a GitHub-like clone in the Go Programming Language. | ||||
| 
 | ||||
| Since we choose to use pure Go implmentation of Git manipulation, Gogs certainly supports **ALL platforms**  that Go supports, including Linux, Max OS X, and Windows with **ZERO** dependency. | ||||
| 
 | ||||
| ##### Current version: 0.0.8 Alpha | ||||
| ##### Current version: 0.0.9 Alpha | ||||
| 
 | ||||
| ## Purpose | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										3
									
								
								bee.json
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								bee.json
									
									
									
									
									
								
							| @ -12,7 +12,8 @@ | ||||
| 		"models": "", | ||||
| 		"others": [ | ||||
| 			"modules", | ||||
| 			"$GOPATH/src/github.com/gogits/binding" | ||||
| 			"$GOPATH/src/github.com/gogits/binding", | ||||
| 			"$GOPATH/src/github.com/gogits/git" | ||||
| 		] | ||||
| 	}, | ||||
| 	"cmd_args": [ | ||||
|  | ||||
| @ -7,6 +7,7 @@ LANG_IGNS=Google Go|C|Python|Ruby | ||||
| LICENSES=Apache v2 License|GPL v2|MIT License|BSD (3-Clause) License | ||||
| 
 | ||||
| [server] | ||||
| DOMAIN = gogits.org | ||||
| HTTP_ADDR =  | ||||
| HTTP_PORT = 3000 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							| @ -20,7 +20,7 @@ import ( | ||||
| // Test that go1.1 tag above is included in builds. main.go refers to this definition. | ||||
| const go11tag = true | ||||
| 
 | ||||
| const APP_VER = "0.0.8.0316.1" | ||||
| const APP_VER = "0.0.9.0317.1" | ||||
| 
 | ||||
| func init() { | ||||
| 	base.AppVer = APP_VER | ||||
|  | ||||
| @ -44,6 +44,10 @@ func (a Action) GetRepoName() string { | ||||
| 	return a.RepoName | ||||
| } | ||||
| 
 | ||||
| func (a Action) GetContent() string { | ||||
| 	return a.Content | ||||
| } | ||||
| 
 | ||||
| // CommitRepoAction records action for commit repository. | ||||
| func CommitRepoAction(userId int64, userName string, | ||||
| 	repoId int64, repoName string, commits [][]string) error { | ||||
|  | ||||
| @ -307,6 +307,9 @@ func DeleteRepository(userId, repoId int64, userName string) (err error) { | ||||
| 	} | ||||
| 
 | ||||
| 	session := orm.NewSession() | ||||
| 	if err = session.Begin(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if _, err = session.Delete(&Repository{Id: repoId}); err != nil { | ||||
| 		session.Rollback() | ||||
| 		return err | ||||
|  | ||||
| @ -5,11 +5,26 @@ | ||||
| package models | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"path" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| 	git "github.com/gogits/git" | ||||
| 	"github.com/Unknwon/com" | ||||
| 
 | ||||
| 	"github.com/gogits/git" | ||||
| ) | ||||
| 
 | ||||
| type Commit struct { | ||||
| 	Author  string | ||||
| 	Email   string | ||||
| 	Date    time.Time | ||||
| 	SHA     string | ||||
| 	Message string | ||||
| } | ||||
| 
 | ||||
| var ( | ||||
| 	ErrRepoFileNotLoaded = fmt.Errorf("repo file not loaded") | ||||
| ) | ||||
| 
 | ||||
| type RepoFile struct { | ||||
| @ -18,6 +33,7 @@ type RepoFile struct { | ||||
| 	Message    string | ||||
| 	Created    time.Time | ||||
| 	Size       int64 | ||||
| 	Repo       *git.Repository | ||||
| 	LastCommit string | ||||
| } | ||||
| 
 | ||||
| @ -43,10 +59,34 @@ func findTree(repo *git.Repository, tree *git.Tree, rpath string) *git.Tree { | ||||
| 	return g | ||||
| } | ||||
| 
 | ||||
| func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, error) { | ||||
| 	f := RepoPath(userName, reposName) | ||||
| func (file *RepoFile) LookupBlob() (*git.Blob, error) { | ||||
| 	if file.Repo == nil { | ||||
| 		return nil, ErrRepoFileNotLoaded | ||||
| 	} | ||||
| 
 | ||||
| 	repo, err := git.OpenRepository(f) | ||||
| 	return file.Repo.LookupBlob(file.Id) | ||||
| } | ||||
| 
 | ||||
| func GetBranches(userName, reposName string) ([]string, error) { | ||||
| 	repo, err := git.OpenRepository(RepoPath(userName, reposName)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	refs, err := repo.AllReferences() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	brs := make([]string, len(refs)) | ||||
| 	for i, ref := range refs { | ||||
| 		brs[i] = ref.Name | ||||
| 	} | ||||
| 	return brs, nil | ||||
| } | ||||
| 
 | ||||
| func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, error) { | ||||
| 	repo, err := git.OpenRepository(RepoPath(userName, reposName)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @ -128,6 +168,7 @@ func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, | ||||
| 				cm.Message(), | ||||
| 				cm.Committer.When, | ||||
| 				size, | ||||
| 				repo, | ||||
| 				cm.Id().String(), | ||||
| 			} | ||||
| 
 | ||||
| @ -142,3 +183,33 @@ func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, | ||||
| 
 | ||||
| 	return append(repodirs, repofiles...), nil | ||||
| } | ||||
| 
 | ||||
| func GetLastestCommit(userName, repoName string) (*Commit, error) { | ||||
| 	stdout, _, err := com.ExecCmd("git", "--git-dir="+RepoPath(userName, repoName), "log", "-1") | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	commit := new(Commit) | ||||
| 	for _, line := range strings.Split(stdout, "\n") { | ||||
| 		if len(line) == 0 { | ||||
| 			continue | ||||
| 		} | ||||
| 		switch { | ||||
| 		case line[0] == 'c': | ||||
| 			commit.SHA = line[7:] | ||||
| 		case line[0] == 'A': | ||||
| 			infos := strings.SplitN(line, " ", 3) | ||||
| 			commit.Author = infos[1] | ||||
| 			commit.Email = infos[2][1 : len(infos[2])-1] | ||||
| 		case line[0] == 'D': | ||||
| 			commit.Date, err = time.Parse("Mon Jan 02 15:04:05 2006 -0700", line[8:]) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 		case line[:4] == "    ": | ||||
| 			commit.Message = line[4:] | ||||
| 		} | ||||
| 	} | ||||
| 	return commit, nil | ||||
| } | ||||
|  | ||||
| @ -17,7 +17,6 @@ import ( | ||||
| ) | ||||
| 
 | ||||
| type CreateRepoForm struct { | ||||
| 	UserId      int64  `form:"userId"` | ||||
| 	RepoName    string `form:"repo" binding:"Required;AlphaDash"` | ||||
| 	Visibility  string `form:"visibility"` | ||||
| 	Description string `form:"desc" binding:"MaxSize(100)"` | ||||
| @ -52,9 +51,3 @@ func (f *CreateRepoForm) Validate(errors *binding.Errors, req *http.Request, con | ||||
| 
 | ||||
| 	validate(errors, data, f) | ||||
| } | ||||
| 
 | ||||
| type DeleteRepoForm struct { | ||||
| 	UserId   int64  `form:"userId" binding:"Required"` | ||||
| 	UserName string `form:"userName" binding:"Required"` | ||||
| 	RepoId   int64  `form:"repoId" binding:"Required"` | ||||
| } | ||||
|  | ||||
| @ -18,6 +18,7 @@ import ( | ||||
| var ( | ||||
| 	AppVer  string | ||||
| 	AppName string | ||||
| 	Domain  string | ||||
| 	Cfg     *goconfig.ConfigFile | ||||
| ) | ||||
| 
 | ||||
| @ -58,4 +59,5 @@ func init() { | ||||
| 	Cfg.BlockMode = false | ||||
| 
 | ||||
| 	AppName = Cfg.MustValue("", "APP_NAME") | ||||
| 	Domain = Cfg.MustValue("server", "DOMAIN") | ||||
| } | ||||
|  | ||||
							
								
								
									
										39
									
								
								modules/base/markdown.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								modules/base/markdown.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | ||||
| // Copyright 2014 The Gogs Authors. All rights reserved. | ||||
| // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package base | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/slene/blackfriday" | ||||
| ) | ||||
| 
 | ||||
| func RenderMarkdown(rawBytes []byte) []byte { | ||||
| 	htmlFlags := 0 | ||||
| 	htmlFlags |= blackfriday.HTML_USE_XHTML | ||||
| 	// htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS | ||||
| 	// htmlFlags |= blackfriday.HTML_SMARTYPANTS_FRACTIONS | ||||
| 	// htmlFlags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES | ||||
| 	htmlFlags |= blackfriday.HTML_SKIP_HTML | ||||
| 	htmlFlags |= blackfriday.HTML_SKIP_STYLE | ||||
| 	htmlFlags |= blackfriday.HTML_SKIP_SCRIPT | ||||
| 	htmlFlags |= blackfriday.HTML_GITHUB_BLOCKCODE | ||||
| 	htmlFlags |= blackfriday.HTML_OMIT_CONTENTS | ||||
| 	htmlFlags |= blackfriday.HTML_COMPLETE_PAGE | ||||
| 	renderer := blackfriday.HtmlRenderer(htmlFlags, "", "") | ||||
| 
 | ||||
| 	// set up the parser | ||||
| 	extensions := 0 | ||||
| 	extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS | ||||
| 	extensions |= blackfriday.EXTENSION_TABLES | ||||
| 	extensions |= blackfriday.EXTENSION_FENCED_CODE | ||||
| 	extensions |= blackfriday.EXTENSION_AUTOLINK | ||||
| 	extensions |= blackfriday.EXTENSION_STRIKETHROUGH | ||||
| 	extensions |= blackfriday.EXTENSION_HARD_LINE_BREAK | ||||
| 	extensions |= blackfriday.EXTENSION_SPACE_HEADERS | ||||
| 	extensions |= blackfriday.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK | ||||
| 
 | ||||
| 	body := blackfriday.Markdown(rawBytes, renderer, extensions) | ||||
| 
 | ||||
| 	return body | ||||
| } | ||||
| @ -19,6 +19,10 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{ | ||||
| 	"AppVer": func() string { | ||||
| 		return AppVer | ||||
| 	}, | ||||
| 	"AppDomain": func() string { | ||||
| 		return Domain | ||||
| 	}, | ||||
| 	"AvatarLink": AvatarLink, | ||||
| 	"str2html":   Str2html, | ||||
| 	"TimeSince":  TimeSince, | ||||
| 	"FileSize":   FileSize, | ||||
|  | ||||
| @ -5,8 +5,10 @@ | ||||
| package base | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"crypto/md5" | ||||
| 	"encoding/hex" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"math" | ||||
| 	"strings" | ||||
| @ -20,6 +22,11 @@ func EncodeMd5(str string) string { | ||||
| 	return hex.EncodeToString(m.Sum(nil)) | ||||
| } | ||||
| 
 | ||||
| // AvatarLink returns avatar link by given e-mail. | ||||
| func AvatarLink(email string) string { | ||||
| 	return "http://1.gravatar.com/avatar/" + EncodeMd5(email) | ||||
| } | ||||
| 
 | ||||
| // Seconds-based time units | ||||
| const ( | ||||
| 	Minute = 60 | ||||
| @ -235,6 +242,7 @@ type Actioner interface { | ||||
| 	GetOpType() int | ||||
| 	GetActUserName() string | ||||
| 	GetRepoName() string | ||||
| 	GetContent() string | ||||
| } | ||||
| 
 | ||||
| // ActionIcon accepts a int that represents action operation type | ||||
| @ -243,23 +251,39 @@ func ActionIcon(opType int) string { | ||||
| 	switch opType { | ||||
| 	case 1: // Create repository. | ||||
| 		return "plus-circle" | ||||
| 	case 5: // Commit repository. | ||||
| 		return "arrow-circle-o-right" | ||||
| 	default: | ||||
| 		return "invalid type" | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| const ( | ||||
| 	CreateRepoTpl = `<a href="/user/%s">%s</a> created repository <a href="/%s/%s">%s</a>` | ||||
| 	TPL_CREATE_REPO    = `<a href="/user/%s">%s</a> created repository <a href="/%s/%s">%s</a>` | ||||
| 	TPL_COMMIT_REPO    = `<a href="/user/%s">%s</a> pushed to <a href="/%s/%s/tree/%s">%s</a> at <a href="/%s/%s">%s/%s</a>%s` | ||||
| 	TPL_COMMIT_REPO_LI = `<div><img id="gogs-user-avatar-commit" src="%s?s=16" alt="user-avatar" title="username"/> <a href="/%s/%s/commit/%s">%s</a> %s</div>` | ||||
| ) | ||||
| 
 | ||||
| // ActionDesc accepts int that represents action operation type | ||||
| // and returns the description. | ||||
| func ActionDesc(act Actioner) string { | ||||
| func ActionDesc(act Actioner, avatarLink string) string { | ||||
| 	actUserName := act.GetActUserName() | ||||
| 	repoName := act.GetRepoName() | ||||
| 	content := act.GetContent() | ||||
| 	switch act.GetOpType() { | ||||
| 	case 1: // Create repository. | ||||
| 		return fmt.Sprintf(CreateRepoTpl, actUserName, actUserName, actUserName, repoName, repoName) | ||||
| 		return fmt.Sprintf(TPL_CREATE_REPO, actUserName, actUserName, actUserName, repoName, repoName) | ||||
| 	case 5: // Commit repository. | ||||
| 		var commits [][]string | ||||
| 		if err := json.Unmarshal([]byte(content), &commits); err != nil { | ||||
| 			return err.Error() | ||||
| 		} | ||||
| 		buf := bytes.NewBuffer([]byte("\n")) | ||||
| 		for _, commit := range commits { | ||||
| 			buf.WriteString(fmt.Sprintf(TPL_COMMIT_REPO_LI, avatarLink, actUserName, repoName, commit[0], commit[0][:7], commit[1]) + "\n") | ||||
| 		} | ||||
| 		return fmt.Sprintf(TPL_COMMIT_REPO, actUserName, actUserName, actUserName, repoName, "master", "master", actUserName, repoName, actUserName, repoName, | ||||
| 			buf.String()) | ||||
| 	default: | ||||
| 		return "invalid type" | ||||
| 	} | ||||
|  | ||||
| @ -6,6 +6,7 @@ package middleware | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/codegangsta/martini" | ||||
| 
 | ||||
| @ -23,8 +24,7 @@ func RepoAssignment(redirect bool) martini.Handler { | ||||
| 		) | ||||
| 
 | ||||
| 		// get repository owner | ||||
| 		ctx.Repo.IsOwner = ctx.IsSigned && ctx.User.LowerName == params["username"] | ||||
| 		ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner | ||||
| 		ctx.Repo.IsOwner = ctx.IsSigned && ctx.User.LowerName == strings.ToLower(params["username"]) | ||||
| 
 | ||||
| 		if !ctx.Repo.IsOwner { | ||||
| 			user, err = models.GetUserByName(params["username"]) | ||||
| @ -70,5 +70,6 @@ func RepoAssignment(redirect bool) martini.Handler { | ||||
| 		ctx.Data["Owner"] = user | ||||
| 		ctx.Data["Title"] = user.Name + "/" + repo.Name | ||||
| 		ctx.Data["RepositoryLink"] = ctx.Data["Title"] | ||||
| 		ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -10,6 +10,7 @@ body { | ||||
| 
 | ||||
| html, body { | ||||
|     height: 100%; | ||||
|     font-family: Helvetica, Arial, sans-serif; | ||||
| } | ||||
| 
 | ||||
| /* override bs3 */ | ||||
| @ -50,7 +51,6 @@ html, body { | ||||
| .gogs-masthead { | ||||
|     background-color: #428bca; | ||||
|     box-shadow: inset 0 -2px 5px rgba(0, 0, 0, .1); | ||||
|     padding: 0 16px; | ||||
|     margin: 0; | ||||
| } | ||||
| 
 | ||||
| @ -65,6 +65,12 @@ html, body { | ||||
|     height: 46px; | ||||
| } | ||||
| 
 | ||||
| #gogs-nav-logo{ | ||||
|     padding-left: 0; | ||||
|     padding-right: 0; | ||||
|     margin-right: 10px; | ||||
| } | ||||
| 
 | ||||
| .gogs-nav-item:hover, | ||||
| .gogs-nav-item:focus { | ||||
|     color: #fff; | ||||
| @ -128,6 +134,11 @@ html, body { | ||||
|     padding: 5px 0; | ||||
|     margin-left: 10px; | ||||
|     height: 28px; | ||||
|     float: right; | ||||
| } | ||||
| 
 | ||||
| #gogs-nav-signin{ | ||||
|     float: right; | ||||
| } | ||||
| 
 | ||||
| #gogs-nav-out .fa { | ||||
| @ -228,6 +239,12 @@ html, body { | ||||
|     border-radius: 6px; | ||||
| } | ||||
| 
 | ||||
| #gogs-user-avatar-commit { | ||||
|     width: 16px; | ||||
|     height: 16px; | ||||
|     border-radius: 2px; | ||||
| } | ||||
| 
 | ||||
| #gogs-user-name { | ||||
|     margin-top: 20px; | ||||
|     font-size: 1.6em; | ||||
| @ -338,10 +355,6 @@ html, body { | ||||
| 
 | ||||
| /* #gogs-feed */ | ||||
| 
 | ||||
| #gogs-feed-left { | ||||
|     padding-left: 0; | ||||
| } | ||||
| 
 | ||||
| #gogs-feed-right .repo-panel .panel-heading .btn { | ||||
|     margin-top: -4px; | ||||
| } | ||||
| @ -399,18 +412,11 @@ html, body { | ||||
| 
 | ||||
| .gogs-repo-nav h3 .fa { | ||||
|     color: #BBB; | ||||
|     margin-left: 0; | ||||
| } | ||||
| 
 | ||||
| .gogs-repo-btns { | ||||
|     margin-top: 18px; | ||||
| } | ||||
| 
 | ||||
| .gogs-repo-btns .btn-group { | ||||
|     margin-left: 1em; | ||||
| } | ||||
| 
 | ||||
| .gogs-repo-btns .btn-group .btn { | ||||
|     padding-left: 6px; | ||||
| .gogs-repo-nav .actions { | ||||
|     padding-top: 20px; | ||||
| } | ||||
| 
 | ||||
| #gogs-repo-watching .dropdown-menu { | ||||
| @ -525,6 +531,10 @@ html, body { | ||||
| } | ||||
| 
 | ||||
| /* #gogs-source */ | ||||
| #gogs-source { | ||||
|     margin-top: -20px; | ||||
| } | ||||
| 
 | ||||
| #gogs-source .source-toolbar:after { | ||||
|     clear: both; | ||||
| } | ||||
| @ -560,7 +570,9 @@ html, body { | ||||
| .file-list .icon { | ||||
|     font-size: 17px; | ||||
|     padding: 5px 0 4px 10px; | ||||
|     width: 40px; | ||||
|     width: 50px; | ||||
|     color: #999; | ||||
|     text-align: right; | ||||
| } | ||||
| 
 | ||||
| .file-list .wrap { | ||||
| @ -588,6 +600,80 @@ html, body { | ||||
|     text-align: right; | ||||
| } | ||||
| 
 | ||||
| .file-content .file-head { | ||||
|     font-size: 18px; | ||||
| } | ||||
| 
 | ||||
| .file-content .file-head .icon { | ||||
|     color: #666; | ||||
|     margin: 0 .5em 0 0; | ||||
| } | ||||
| 
 | ||||
| .file-content .file-body { | ||||
|     padding: 30px 30px 50px; | ||||
| } | ||||
| 
 | ||||
| .branch-list th{ | ||||
|     background-color: #FFF; | ||||
|     line-height: 28px !important; | ||||
| } | ||||
| 
 | ||||
| .branch-list td{ | ||||
|     line-height: 36px !important; | ||||
| } | ||||
| 
 | ||||
| .branch-box tr:hover td{ | ||||
|     background-color: rgba(19, 95, 215, 0.06) !important; | ||||
| } | ||||
| 
 | ||||
| .branch-box .name{ | ||||
|     padding-left: 20px; | ||||
|     font-size: 15px; | ||||
| } | ||||
| 
 | ||||
| .branch-box .action{ | ||||
|     width: 150px; | ||||
| } | ||||
| 
 | ||||
| .branch-box td.date,.branch-box td.behind,.branch-box td.ahead{ | ||||
|     width: 120px; | ||||
|     font-family: Verdana, Arial, sans-serif; | ||||
| } | ||||
| 
 | ||||
| .branch-box .graph{ | ||||
|     display: block; | ||||
|     height: 3px; | ||||
| } | ||||
| 
 | ||||
| .branch-box .behind{ | ||||
|     text-align: right; | ||||
|     direction: rtl; | ||||
| } | ||||
| 
 | ||||
| .branch-box .behind .graph{ | ||||
|     background-color: #888; | ||||
| } | ||||
| 
 | ||||
| .branch-box .ahead .graph{ | ||||
|     background-color: #0093c4; | ||||
| } | ||||
| 
 | ||||
| .branch-box .branch-main{ | ||||
|     background-color: #444; | ||||
|     color: #FFF; | ||||
|     border-color: #444; | ||||
| } | ||||
| 
 | ||||
| .branch-box .branch-main a{ | ||||
|     color: #FFF; | ||||
| } | ||||
| 
 | ||||
| .branch-box .branch-main .name .btn{ | ||||
|     margin-left: .5em; | ||||
| } | ||||
| 
 | ||||
| /* wrapper and footer */ | ||||
| 
 | ||||
| #wrapper { | ||||
|     min-height: 100%; | ||||
|     height: auto !important; | ||||
| @ -604,7 +690,7 @@ html, body { | ||||
| } | ||||
| 
 | ||||
| #footer .footer-wrap { | ||||
|     padding: 20px 0; | ||||
|     padding: 20px 15px; | ||||
| } | ||||
| 
 | ||||
| #footer a { | ||||
|  | ||||
							
								
								
									
										317
									
								
								public/css/markdown.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										317
									
								
								public/css/markdown.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,317 @@ | ||||
| .markdown { | ||||
|   font-size: 14px; | ||||
| } | ||||
| 
 | ||||
| .markdown a { | ||||
|   color: #4183C4; | ||||
| } | ||||
| 
 | ||||
| .markdown h1, | ||||
| .markdown h2, | ||||
| .markdown h3, | ||||
| .markdown h4, | ||||
| .markdown h5, | ||||
| .markdown h6 { | ||||
|   line-height: 1.7; | ||||
|   padding: 15px 0 0; | ||||
|   margin: 0 0 15px; | ||||
|   color: #666; | ||||
| } | ||||
| 
 | ||||
| .markdown h1, | ||||
| .markdown h2 { | ||||
|   border-bottom: 1px solid #EEE; | ||||
| } | ||||
| 
 | ||||
| .markdown h2 { | ||||
|   border-bottom: 1px solid #EEE; | ||||
| } | ||||
| 
 | ||||
| .markdown h1 { | ||||
|   color: #000; | ||||
|   font-size: 33px | ||||
| } | ||||
| 
 | ||||
| .markdown h2 { | ||||
|   color: #333; | ||||
|   font-size: 28px | ||||
| } | ||||
| 
 | ||||
| .markdown h3 { | ||||
|   font-size: 22px | ||||
| } | ||||
| 
 | ||||
| .markdown h4 { | ||||
|   font-size: 18px | ||||
| } | ||||
| 
 | ||||
| .markdown h5 { | ||||
|   font-size: 14px | ||||
| } | ||||
| 
 | ||||
| .markdown h6 { | ||||
|   font-size: 14px | ||||
| } | ||||
| 
 | ||||
| .markdown table { | ||||
|   border-collapse: collapse; | ||||
|   border-spacing: 0; | ||||
|   display: block; | ||||
|   overflow: auto; | ||||
|   width: 100%; | ||||
|   margin: 0 0 9px; | ||||
| } | ||||
| 
 | ||||
| .markdown table th { | ||||
|   font-weight: 700 | ||||
| } | ||||
| 
 | ||||
| .markdown table th, | ||||
| .markdown table td { | ||||
|   border: 1px solid #DDD; | ||||
|   padding: 6px 13px; | ||||
| } | ||||
| 
 | ||||
| .markdown table tr { | ||||
|   background-color: #FFF; | ||||
|   border-top: 1px solid #CCC; | ||||
| } | ||||
| 
 | ||||
| .markdown table tr:nth-child(2n) { | ||||
|   background-color: #F8F8F8 | ||||
| } | ||||
| 
 | ||||
| .markdown li { | ||||
|   line-height: 1.6; | ||||
|   margin-top: 6px; | ||||
| } | ||||
| 
 | ||||
| .markdown dl dt { | ||||
|   font-style: italic; | ||||
|   margin-top: 9px; | ||||
| } | ||||
| 
 | ||||
| .markdown dl dd { | ||||
|   margin: 0 0 9px; | ||||
|   padding: 0 9px; | ||||
| } | ||||
| 
 | ||||
| .markdown blockquote, | ||||
| .markdown blockquote p { | ||||
|   font-size: 14px; | ||||
|   background-color: #f5f5f5; | ||||
| } | ||||
| 
 | ||||
| .markdown > pre { | ||||
|   line-height: 1.6; | ||||
|   overflow: auto; | ||||
|   background: #fff; | ||||
|   padding: 6px 10px; | ||||
|   border: 1px solid #ddd; | ||||
| } | ||||
| 
 | ||||
| .markdown > pre.linenums { | ||||
|   padding: 0; | ||||
| } | ||||
| 
 | ||||
| .markdown > pre > ol.linenums { | ||||
|   -webkit-box-shadow: inset 40px 0 0 #f5f5f5, inset 41px 0 0 #ccc; | ||||
|   box-shadow: inset 40px 0 0 #f5f5f5, inset 41px 0 0 #ccc; | ||||
| } | ||||
| 
 | ||||
| .markdown > pre > code, | ||||
| .markdown > pre > ol.linenums > li > code { | ||||
|   white-space: pre; | ||||
|   word-wrap: normal; | ||||
| } | ||||
| 
 | ||||
| .markdown > pre > ol.linenums > li > code { | ||||
|   padding: 0 10px; | ||||
| } | ||||
| 
 | ||||
| .markdown > pre > ol.linenums > li:first-child { | ||||
|   padding-top: 6px; | ||||
| } | ||||
| 
 | ||||
| .markdown > pre > ol.linenums > li:last-child { | ||||
|   padding-bottom: 6px; | ||||
| } | ||||
| 
 | ||||
| .markdown > pre > ol.linenums > li { | ||||
|   border-left: 1px solid #ddd; | ||||
| } | ||||
| 
 | ||||
| .markdown hr { | ||||
|   border: none; | ||||
|   color: #ccc; | ||||
|   height: 4px; | ||||
|   padding: 0; | ||||
|   margin: 15px 0; | ||||
|   border-bottom: 2px solid #EEE; | ||||
| } | ||||
| 
 | ||||
| .markdown blockquote:last-child, | ||||
| .markdown ul:last-child, | ||||
| .markdown ol:last-child, | ||||
| .markdown > pre:last-child, | ||||
| .markdown > pre:last-child, | ||||
| .markdown p:last-child { | ||||
|   margin-bottom: 0; | ||||
| } | ||||
| 
 | ||||
| .markdown .btn { | ||||
|   color: #fff; | ||||
| } | ||||
| 
 | ||||
| /* Author: jmblog */ | ||||
| /* Project: https://github.com/jmblog/color-themes-for-google-code-prettify */ | ||||
| /* GitHub Theme */ | ||||
| /* Pretty printing styles. Used with prettify.js. */ | ||||
| /* SPAN elements with the classes below are added by prettyprint. */ | ||||
| /* plain text */ | ||||
| .pln { | ||||
|   color: #333333; | ||||
| } | ||||
| 
 | ||||
| @media screen { | ||||
|   /* string content */ | ||||
|   .str { | ||||
|     color: #dd1144; | ||||
|   } | ||||
| 
 | ||||
|   /* a keyword */ | ||||
|   .kwd { | ||||
|     color: #333333; | ||||
|   } | ||||
| 
 | ||||
|   /* a comment */ | ||||
|   .com { | ||||
|     color: #999988; | ||||
|   } | ||||
| 
 | ||||
|   /* a type name */ | ||||
|   .typ { | ||||
|     color: #445588; | ||||
|   } | ||||
| 
 | ||||
|   /* a literal value */ | ||||
|   .lit { | ||||
|     color: #445588; | ||||
|   } | ||||
| 
 | ||||
|   /* punctuation */ | ||||
|   .pun { | ||||
|     color: #333333; | ||||
|   } | ||||
| 
 | ||||
|   /* lisp open bracket */ | ||||
|   .opn { | ||||
|     color: #333333; | ||||
|   } | ||||
| 
 | ||||
|   /* lisp close bracket */ | ||||
|   .clo { | ||||
|     color: #333333; | ||||
|   } | ||||
| 
 | ||||
|   /* a markup tag name */ | ||||
|   .tag { | ||||
|     color: navy; | ||||
|   } | ||||
| 
 | ||||
|   /* a markup attribute name */ | ||||
|   .atn { | ||||
|     color: teal; | ||||
|   } | ||||
| 
 | ||||
|   /* a markup attribute value */ | ||||
|   .atv { | ||||
|     color: #dd1144; | ||||
|   } | ||||
| 
 | ||||
|   /* a declaration */ | ||||
|   .dec { | ||||
|     color: #333333; | ||||
|   } | ||||
| 
 | ||||
|   /* a variable name */ | ||||
|   .var { | ||||
|     color: teal; | ||||
|   } | ||||
| 
 | ||||
|   /* a function name */ | ||||
|   .fun { | ||||
|     color: #990000; | ||||
|   } | ||||
| } | ||||
| /* Use higher contrast and text-weight for printable form. */ | ||||
| @media print, projection { | ||||
|   .str { | ||||
|     color: #006600; | ||||
|   } | ||||
| 
 | ||||
|   .kwd { | ||||
|     color: #006; | ||||
|     font-weight: bold; | ||||
|   } | ||||
| 
 | ||||
|   .com { | ||||
|     color: #600; | ||||
|     font-style: italic; | ||||
|   } | ||||
| 
 | ||||
|   .typ { | ||||
|     color: #404; | ||||
|     font-weight: bold; | ||||
|   } | ||||
| 
 | ||||
|   .lit { | ||||
|     color: #004444; | ||||
|   } | ||||
| 
 | ||||
|   .pun, .opn, .clo { | ||||
|     color: #444400; | ||||
|   } | ||||
| 
 | ||||
|   .tag { | ||||
|     color: #006; | ||||
|     font-weight: bold; | ||||
|   } | ||||
| 
 | ||||
|   .atn { | ||||
|     color: #440044; | ||||
|   } | ||||
| 
 | ||||
|   .atv { | ||||
|     color: #006600; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /* Specify class=linenums on a pre to get line numbering */ | ||||
| ol.linenums { | ||||
|   margin-top: 0; | ||||
|   margin-bottom: 0; | ||||
| } | ||||
| 
 | ||||
| /* IE indents via margin-left */ | ||||
| li.L0, | ||||
| li.L1, | ||||
| li.L2, | ||||
| li.L3, | ||||
| li.L4, | ||||
| li.L5, | ||||
| li.L6, | ||||
| li.L7, | ||||
| li.L8, | ||||
| li.L9 { | ||||
|   /* */ | ||||
| } | ||||
| 
 | ||||
| /* Alternate shading for lines */ | ||||
| li.L1, | ||||
| li.L3, | ||||
| li.L5, | ||||
| li.L7, | ||||
| li.L9 { | ||||
|   /* */ | ||||
| } | ||||
| @ -40,10 +40,37 @@ var Gogits = { | ||||
|             //container: "body"
 | ||||
|         }); | ||||
|     }; | ||||
|     Gogits.initPopovers = function () { | ||||
|         var hideAllPopovers = function() { | ||||
|            $('[data-toggle=popover]').each(function() { | ||||
|                 $(this).popover('hide'); | ||||
|             });   | ||||
|         }; | ||||
| 
 | ||||
|         $(document).on('click', function(e) { | ||||
|             var $e = $(e.target); | ||||
|             if($e.data('toggle') == 'popover'||$e.parents("[data-toggle=popover], .popover").length > 0){ | ||||
|                 return; | ||||
|             } | ||||
|             hideAllPopovers(); | ||||
|         }); | ||||
| 
 | ||||
|         $("body").popover({ | ||||
|             selector: "[data-toggle=popover]" | ||||
|         }); | ||||
|     }; | ||||
|     Gogits.initTabs = function () { | ||||
|         var $tabs = $('[data-init=tabs]'); | ||||
|         $tabs.find("li:eq(0) a").tab("show"); | ||||
|     }; | ||||
| 
 | ||||
|     // render markdown
 | ||||
|     Gogits.renderMarkdown = function () { | ||||
|         var $pre = $('.markdown').find('pre > code').parent(); | ||||
|         $pre.addClass("prettyprint"); | ||||
|         prettyPrint(); | ||||
|     } | ||||
| 
 | ||||
| })(jQuery); | ||||
| 
 | ||||
| // ajax utils
 | ||||
| @ -68,8 +95,10 @@ var Gogits = { | ||||
| 
 | ||||
| function initCore() { | ||||
|     Gogits.initTooltips(); | ||||
|     Gogits.initPopovers(); | ||||
|     Gogits.initTabs(); | ||||
|     Gogits.initModals(); | ||||
|     Gogits.renderMarkdown(); | ||||
| } | ||||
| 
 | ||||
| function initRegister() { | ||||
| @ -112,3 +141,16 @@ function initUserSetting(){ | ||||
|         } | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| (function ($) { | ||||
|     $(function () { | ||||
|         initCore(); | ||||
|         var body = $("#gogs-body"); | ||||
|         if (body.data("page") == "user-signup") { | ||||
|             initRegister(); | ||||
|         } | ||||
|         if (body.data("page") == "user") { | ||||
|             initUserSetting(); | ||||
|         } | ||||
|     }); | ||||
| })(jQuery); | ||||
|  | ||||
							
								
								
									
										259
									
								
								public/js/bootstrap.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										259
									
								
								public/js/bootstrap.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										482
									
								
								public/js/lib.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										482
									
								
								public/js/lib.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -20,50 +20,36 @@ func Create(ctx *middleware.Context, form auth.CreateRepoForm) { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if ctx.HasError() { | ||||
| 		ctx.Render.HTML(200, "repo/create", ctx.Data) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO: access check | ||||
| 
 | ||||
| 	user, err := models.GetUserById(form.UserId) | ||||
| 	if err != nil { | ||||
| 		if err.Error() == models.ErrUserNotExist.Error() { | ||||
| 			ctx.RenderWithErr("User does not exist", "repo/create", &form) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if err == nil { | ||||
| 		if _, err = models.CreateRepository(user, | ||||
| 	if _, err := models.CreateRepository(ctx.User, | ||||
| 		form.RepoName, form.Description, form.Language, form.License, | ||||
| 		form.Visibility == "private", form.InitReadme == "on"); err == nil { | ||||
| 			ctx.Render.Redirect("/"+user.Name+"/"+form.RepoName, 302) | ||||
| 		ctx.Render.Redirect("/"+ctx.User.Name+"/"+form.RepoName, 302) | ||||
| 		return | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if err.Error() == models.ErrRepoAlreadyExist.Error() { | ||||
| 	} else if err == models.ErrRepoAlreadyExist { | ||||
| 		ctx.RenderWithErr("Repository name has already been used", "repo/create", &form) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.Handle(200, "repo.Create", err) | ||||
| } | ||||
| 
 | ||||
| func Delete(ctx *middleware.Context, form auth.DeleteRepoForm) { | ||||
| 	ctx.Data["Title"] = "Delete repository" | ||||
| 
 | ||||
| 	if ctx.Req.Method == "GET" { | ||||
| 		ctx.Render.HTML(200, "repo/delete", ctx.Data) | ||||
| func SettingPost(ctx *middleware.Context) { | ||||
| 	if !ctx.Repo.IsOwner { | ||||
| 		ctx.Render.Error(404) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if err := models.DeleteRepository(form.UserId, form.RepoId, form.UserName); err != nil { | ||||
| 	switch ctx.Query("action") { | ||||
| 	case "delete": | ||||
| 		if len(ctx.Repo.Repository.Name) == 0 || ctx.Repo.Repository.Name != ctx.Query("repository") { | ||||
| 			ctx.Data["ErrorMsg"] = "Please make sure you entered repository name is correct." | ||||
| 			ctx.Render.HTML(200, "repo/setting", ctx.Data) | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		if err := models.DeleteRepository(ctx.User.Id, ctx.Repo.Repository.Id, ctx.User.LowerName); err != nil { | ||||
| 			ctx.Handle(200, "repo.Delete", err) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.Render.Redirect("/", 302) | ||||
| } | ||||
|  | ||||
| @ -9,10 +9,33 @@ import ( | ||||
| 
 | ||||
| 	"github.com/codegangsta/martini" | ||||
| 
 | ||||
| 	"github.com/gogits/git" | ||||
| 
 | ||||
| 	"github.com/gogits/gogs/models" | ||||
| 	"github.com/gogits/gogs/modules/base" | ||||
| 	"github.com/gogits/gogs/modules/middleware" | ||||
| ) | ||||
| 
 | ||||
| func Branches(ctx *middleware.Context, params martini.Params) { | ||||
| 	if !ctx.Repo.IsValid { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.Data["Username"] = params["username"] | ||||
| 	ctx.Data["Reponame"] = params["reponame"] | ||||
| 
 | ||||
| 	brs, err := models.GetBranches(params["username"], params["reponame"]) | ||||
| 	if err != nil { | ||||
| 		ctx.Handle(200, "repo.Branches", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.Data["Branches"] = brs | ||||
| 	ctx.Data["IsRepoToolbarBranches"] = true | ||||
| 
 | ||||
| 	ctx.Render.HTML(200, "repo/branches", ctx.Data) | ||||
| } | ||||
| 
 | ||||
| func Single(ctx *middleware.Context, params martini.Params) { | ||||
| 	if !ctx.Repo.IsValid { | ||||
| 		return | ||||
| @ -22,17 +45,28 @@ func Single(ctx *middleware.Context, params martini.Params) { | ||||
| 		params["branchname"] = "master" | ||||
| 	} | ||||
| 
 | ||||
| 	// Get tree path | ||||
| 	treename := params["_1"] | ||||
| 
 | ||||
| 	// Directory and file list. | ||||
| 	files, err := models.GetReposFiles(params["username"], params["reponame"], | ||||
| 		params["branchname"], treename) | ||||
| 	if err != nil { | ||||
| 		ctx.Handle(200, "repo.Single", err) | ||||
| 		ctx.Render.Error(404) | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.Data["Username"] = params["username"] | ||||
| 	ctx.Data["Reponame"] = params["reponame"] | ||||
| 	ctx.Data["Branchname"] = params["branchname"] | ||||
| 
 | ||||
| 	// Branches. | ||||
| 	brs, err := models.GetBranches(params["username"], params["reponame"]) | ||||
| 	if err != nil { | ||||
| 		ctx.Render.Error(404) | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.Data["Branches"] = brs | ||||
| 
 | ||||
| 	var treenames []string | ||||
| 	Paths := make([]string, 0) | ||||
| 
 | ||||
| @ -43,16 +77,52 @@ func Single(ctx *middleware.Context, params martini.Params) { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Get latest commit according username and repo name | ||||
| 	commit, err := models.GetLastestCommit(params["username"], params["reponame"]) | ||||
| 	if err != nil { | ||||
| 		ctx.Render.Error(404) | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.Data["LatestCommit"] = commit | ||||
| 
 | ||||
| 	var readmeFile *models.RepoFile | ||||
| 
 | ||||
| 	for _, f := range files { | ||||
| 		if !f.IsFile() { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		if len(f.Name) < 6 { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		if strings.ToLower(f.Name[:6]) == "readme" { | ||||
| 			readmeFile = f | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if readmeFile != nil { | ||||
| 		// if file large than 1M not show it | ||||
| 		if readmeFile.Size > 1024*1024 || readmeFile.Filemode != git.FileModeBlob { | ||||
| 			ctx.Data["FileIsLarge"] = true | ||||
| 		} else if blob, err := readmeFile.LookupBlob(); err != nil { | ||||
| 			ctx.Data["FileIsLarge"] = true | ||||
| 		} else { | ||||
| 			ctx.Data["ReadmeContent"] = string(base.RenderMarkdown(blob.Contents())) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.Data["Paths"] = Paths | ||||
| 	ctx.Data["Treenames"] = treenames | ||||
| 	ctx.Data["IsRepoToolbarSource"] = true | ||||
| 	ctx.Data["IsRepositoryOwner"] = strings.ToLower(params["username"]) == ctx.User.LowerName | ||||
| 	ctx.Data["Files"] = files | ||||
| 	ctx.Render.HTML(200, "repo/single", ctx.Data) | ||||
| } | ||||
| 
 | ||||
| func Setting(ctx *middleware.Context, params martini.Params) { | ||||
| 	if !ctx.Repo.IsValid { | ||||
| 	if !ctx.Repo.IsOwner { | ||||
| 		ctx.Render.Error(404) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -63,7 +133,6 @@ func Setting(ctx *middleware.Context, params martini.Params) { | ||||
| 
 | ||||
| 	ctx.Data["Title"] = title + " - settings" | ||||
| 	ctx.Data["IsRepoToolbarSetting"] = true | ||||
| 	ctx.Data["IsRepositoryOwner"] = strings.ToLower(params["username"]) == ctx.User.LowerName | ||||
| 	ctx.Render.HTML(200, "repo/setting", ctx.Data) | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -195,7 +195,7 @@ func Feeds(ctx *middleware.Context, form auth.FeedsForm) { | ||||
| 	feeds := make([]string, len(actions)) | ||||
| 	for i := range actions { | ||||
| 		feeds[i] = fmt.Sprintf(feedTpl, base.ActionIcon(actions[i].OpType), | ||||
| 			base.TimeSince(actions[i].Created), base.ActionDesc(actions[i])) | ||||
| 			base.TimeSince(actions[i].Created), base.ActionDesc(actions[i], ctx.User.AvatarLink())) | ||||
| 	} | ||||
| 	ctx.Render.JSON(200, &feeds) | ||||
| } | ||||
|  | ||||
| @ -1,16 +1,9 @@ | ||||
| <script> | ||||
|     $(function(){ | ||||
|         initCore();{{if .PageIsSignUp}} | ||||
|         initRegister();{{end}}{{if .PageIsUserSetting}} | ||||
|         initUserSetting();{{end}} | ||||
|     }); | ||||
| </script> | ||||
| <div class="wrapper-push"></div> | ||||
| </div> | ||||
| <footer id="footer"> | ||||
|     <div class="container footer-wrap"> | ||||
| 		<p> | ||||
| 			© 2014 Gogs · ver {{AppVer}} · <i class="fa fa-github"></i><a target="_blank" href="https://github.com/gogits/gogs">GitHub</a> | ||||
|         <p>© 2014 Gogs · ver {{AppVer}} · | ||||
|             <i class="fa fa-github"></i><a target="_blank" href="https://github.com/gogits/gogs">GitHub</a> | ||||
|         </p> | ||||
|         <p class="desc"></p> | ||||
|     </div> | ||||
|  | ||||
| @ -3,6 +3,8 @@ | ||||
| 	<head> | ||||
| 		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | ||||
| 		<link rel="shortcut icon" href="/img/favicon.png" /> | ||||
|         <meta http-equiv="X-UA-Compatible" content="IE=edge"/> | ||||
|         <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/> | ||||
|         <meta name="author" content="Gogs - Go Git Service" /> | ||||
| 		<meta name="description" content="Gogs(Go Git Service) is a GitHub-like clone in the Go Programming Language" /> | ||||
| 		<meta name="keywords" content="go, git"> | ||||
| @ -11,10 +13,12 @@ | ||||
| 		<link href="/css/bootstrap.min.css" rel="stylesheet" /> | ||||
| 		<link href="/css/todc-bootstrap.min.css" rel="stylesheet" /> | ||||
| 		<link href="/css/font-awesome.min.css" rel="stylesheet" /> | ||||
| 		<link href="/css/markdown.css" rel="stylesheet" /> | ||||
| 		<link href="/css/gogs.css" rel="stylesheet" /> | ||||
| 
 | ||||
| 		<script src="/js/jquery-1.10.1.min.js"></script> | ||||
| 		<script src="/js/bootstrap.min.js"></script> | ||||
|         <script src="/js/lib.js"></script> | ||||
|         <script src="/js/app.js"></script> | ||||
| 		<title>{{if .Title}}{{.Title}} - {{end}}{{AppName}}</title> | ||||
| 	</head> | ||||
|  | ||||
							
								
								
									
										42
									
								
								templates/repo/branches.tmpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								templates/repo/branches.tmpl
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| {{template "base/head" .}} | ||||
| {{template "base/navbar" .}} | ||||
| {{template "repo/nav" .}} | ||||
| {{template "repo/toolbar" .}} | ||||
| <div id="gogs-body" class="container"> | ||||
|     <div id="gogs-source"> | ||||
|         <div class="panel panel-default branch-box info-box"> | ||||
|             <div class="panel-heading info-head"> | ||||
|                 <h4>Branches</h4> | ||||
|             </div> | ||||
|             <table class="panel-footer table branch-list table table-hover"> | ||||
|                 <thead> | ||||
|                 <tr> | ||||
|                     <th class="name"></th> | ||||
|                     <th class="behind">Behind</th> | ||||
|                     <th class="ahead">Ahead</th> | ||||
|                     <th class="date">Last Commit</th> | ||||
|                     <th class="action"></th> | ||||
|                 </tr> | ||||
|                 </thead> | ||||
|                 <tbody> | ||||
|                 <tr class="branch-main"> | ||||
|                     <td class="name" colspan="3"> | ||||
|                         <a href="#"><strong>BranchName</strong></a> | ||||
|                         <button class="btn btn-primary btn-sm">base branch</button> | ||||
|                     </td> | ||||
|                     <td class="date">3 years ago</td> | ||||
|                     <td class="action"></td> | ||||
|                 </tr> | ||||
|                 <tr> | ||||
|                     <td class="name"><a href="#"><strong>BranchName</strong></a></td> | ||||
|                     <td class="behind">102 <span class="graph" style="width: 100%"></span></td> | ||||
|                     <td class="ahead"><span class="graph" style="width: 4%"></span>4</td> | ||||
|                     <td class="date">3 years ago</td> | ||||
|                     <td class="action"><a class="btn btn-info btn-sm" href="#">compare</a></td> | ||||
|                 </tr> | ||||
|                 </tbody> | ||||
|             </table> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| {{template "base/footer" .}} | ||||
| @ -1,12 +0,0 @@ | ||||
| {{template "base/head" .}} | ||||
| {{template "base/navbar" .}} | ||||
| <div class="container"> | ||||
| 	<form action="/repo/delete" method="post" class="form-horizontal"> | ||||
| 		<div class="form-group"> | ||||
| 		    <div class="col-md-offset-4 col-md-3"> | ||||
| 		    	<button type="submit" class="btn btn-danger">Delete repository</button> | ||||
| 		    </div> | ||||
| 		</div> | ||||
| 	</form> | ||||
| </div> | ||||
| {{template "base/footer" .}} | ||||
| @ -1,16 +1,15 @@ | ||||
| <div id="gogs-body-nav" class="gogs-repo-nav"> | ||||
|     <div class="container"> | ||||
|         <div class="gogs-repo-btns pull-right"> | ||||
|         <div class="row"> | ||||
|             <div class="col-md-6"> | ||||
|                 <h3><i class="fa fa-book fa-lg"></i><a href="{{.Owner.HomeLink}}">{{.Owner.Name}}</a> / {{.Repository.Name}}</h3> | ||||
|             </div> | ||||
|             <div class="col-md-6 actions text-right"> | ||||
|                 <div class="btn-group" id="gogs-repo-clone"> | ||||
|                     <button type="button" class="btn btn-default"><i class="fa fa-download"></i>Clone</button> | ||||
|                 <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> | ||||
|                     <button type="button" class="btn btn-default dropdown-toggle" data-container="body" data-toggle="popover" data-placement="bottom" data-content="<label>SSH:</label><div class='input-group'><input type='text' class='form-control' value='git@{{AppDomain}}:{{.Owner.Name}}/{{.Repository.Name}}.git'></div>" data-html="1"> | ||||
|                         <span class="caret"></span> | ||||
|                     <span class="sr-only">Toggle Dropdown</span> | ||||
|                     </button> | ||||
|                 <div class="dropdown-menu" role="menu"> | ||||
|                     <div data-val="down-http">http link</div> | ||||
|                     <div data-val="down-git">git link</div> | ||||
|                 </div> | ||||
|                 </div> | ||||
|                 <div class="btn-group" id="gogs-repo-watching"> | ||||
|                     <button type="button" class="btn btn-default"><i class="fa fa-eye"></i>Watch {x}</button> | ||||
| @ -37,6 +36,6 @@ | ||||
|                     <button type="button" class="btn btn-default"><i class="fa fa-code-fork"></i>Fork  {{.Repository.NumForks}}</button> | ||||
|                 </div> | ||||
|             </div> | ||||
|         <h3><i class="fa fa-book fa-lg"></i><a href="{{.Owner.HomeLink}}">{{.Owner.Name}}</a> / {{.Repository.Name}}</h3> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| @ -4,31 +4,61 @@ | ||||
| {{template "repo/toolbar" .}} | ||||
| <div id="gogs-body" class="container"> | ||||
|     <div id="gogs-user-setting-nav" class="col-md-3"> | ||||
|         <h4>Repository Settings</h4> | ||||
|         <ul class="list-group" data-init="tabs"> | ||||
|             <li class="list-group-item"><a href="#options" data-toggle="tab">Options</a></li> | ||||
|             <!--<li class="list-group-item" data-toggle="tab"><a href="#">Collaborators</a></li> | ||||
|             <li class="list-group-item" data-toggle="tab"><a href="#">Notifications</a></li>--> | ||||
|             <li class="list-group-item"><a href="#delete" data-toggle="tab">Delete</a></li> | ||||
|             <li class="list-group-item active"><a href="/{{.Owner.Name}}/{{.Repository.Name}}/settings">Options</a></li> | ||||
|             <!--<li class="list-group-item"><a href="#">Collaborators</a></li> | ||||
|             <li class="list-group-item"><a href="#">Notifications</a></li>--> | ||||
|         </ul> | ||||
|     </div> | ||||
|     <div id="gogs-repo-setting-container" class="col-md-9 tab-content"> | ||||
|         <div id="options" class="tab-pane"> | ||||
|             <h4>Repository Options</h4> | ||||
|     <div id="gogs-repo-setting-container" class="col-md-9"> | ||||
|         {{if .ErrorMsg}}<p class="alert alert-danger">{{.ErrorMsg}}</p>{{end}} | ||||
|         <div class="panel panel-default"> | ||||
|             <div class="panel-heading"> | ||||
|                 Repository Options | ||||
|             </div> | ||||
|         <div id="delete" class="tab-pane"> | ||||
|             <h4>Delete Repository</h4> | ||||
|             <p class="alert alert-warning">Unexpected bad things will happen if you don't read this!</p> | ||||
|             <p>This action <strong>CANNOT</strong> be undone. This will delete the repository, wiki, issues, and comments permanently. </p> | ||||
|             <div class="panel-body"> | ||||
|                  | ||||
|             <form action="/repo/delete" method="post"> | ||||
|                 <input type="hidden" name="userId" value="{{.Owner.Id}}"/> | ||||
|                 <input type="hidden" name="userName" value="{{.Owner.Name}}"/> | ||||
|                 <input type="hidden" name="repoId" value="{{.Repository.Id}}"/> | ||||
|                 <hr/> | ||||
|             </div> | ||||
|         </div> | ||||
|         <div class="panel panel-warning"> | ||||
|             <div class="panel-heading"> | ||||
|                 Danger Zone | ||||
|             </div> | ||||
|             <div class="panel-body"> | ||||
|                 <button type="button" class="btn btn-default pull-right" href="#delete-repository-modal" data-toggle="modal"> | ||||
|                     Delete this repository | ||||
|                 </button> | ||||
|                 <dd> | ||||
|                     <dt>Delete this repository.</dt> | ||||
|                     <dl>Once you delete a repository, there is no going back. Please be certain.</dl> | ||||
|                 </dd> | ||||
| 
 | ||||
|                 <div class="modal fade" id="delete-repository-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> | ||||
|                     <div class="modal-dialog"> | ||||
|                         <form action="/{{.Owner.Name}}/{{.Repository.Name}}/settings" method="post" class="modal-content"> | ||||
|                             <input type="hidden" name="action" value="delete"> | ||||
| 
 | ||||
|                             <div class="modal-header"> | ||||
|                                 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | ||||
|                                 <h4 class="modal-title" id="myModalLabel">Delete repository</h4> | ||||
|                             </div> | ||||
| 
 | ||||
|                             <div class="modal-body"> | ||||
|                                 <div class="form-group"> | ||||
|                                     <label>Please enter your repository name "<strong class="text-danger">{{.Repository.Name}}</strong>"</label> | ||||
|                                     <input name="repository" class="form-control" type="text" placeholder="Type your repository name" required="required"> | ||||
|                                 </div> | ||||
|                             </div> | ||||
| 
 | ||||
|                             <div class="modal-footer"> | ||||
|                                 <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> | ||||
|                                 <button class="btn btn-danger btn-lg">I understand the consequences, delete this repository</button> | ||||
|                             </div> | ||||
|                         </form> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| {{template "base/footer" .}} | ||||
| @ -5,39 +5,43 @@ | ||||
| <div id="gogs-body" class="container"> | ||||
|     <div id="gogs-source"> | ||||
|         <div class="source-toolbar"> | ||||
|             <button class="btn btn-default pull-right"><i class="fa fa-plus-square"></i>Add File</button> | ||||
|             <div class="dropdown branch-switch"> | ||||
|                 <a href="#" class="btn btn-success dropdown-toggle" data-toggle="dropdown"><i class="fa fa-chain"></i>master   | ||||
|                     <b class="caret"></b></a> | ||||
|                 <ul class="dropdown-menu"> | ||||
|                     <li><a class="current" href="/{{.RepositoryLink}}/tree/master">master</a></li> | ||||
|                     <li><a href="/{{.RepositoryLink}}/tree/develop">develop</a></li> | ||||
|                 </ul> | ||||
|             </div> | ||||
|             {{$paths := .Paths}} | ||||
|             {{ $username := .Username}} | ||||
|             {{ $reponame := .Reponame}} | ||||
|             {{ $branchname := .Branchname}} | ||||
|             {{ $treenames := .Treenames}} | ||||
|             {{ $repoLink := .RepositoryLink}} | ||||
|             {{ $n := len $treenames}} | ||||
|             <button class="btn btn-default pull-right"><i class="fa fa-plus-square"></i>Add File</button> | ||||
|             <div class="dropdown branch-switch"> | ||||
|                 <a href="#" class="btn btn-success dropdown-toggle" data-toggle="dropdown"><i class="fa fa-chain"></i>{{$branchname}}   | ||||
|                     <b class="caret"></b></a> | ||||
|                 <ul class="dropdown-menu"> | ||||
|                     {{range .Branches}} | ||||
|                     <li><a {{if eq . $branchname}}class="current" {{end}}href="/{{$repoLink}}/tree/{{.}}">{{.}}</a></li> | ||||
|                     {{end}} | ||||
|                 </ul> | ||||
|             </div> | ||||
|             {{$paths := .Paths}} | ||||
|             {{ $l := Subtract $n 1}} | ||||
|             <ol class="breadcrumb"> | ||||
|                 <li class="root dir"><a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}">{{.Repository.Name}}</a></li> | ||||
|                 <li class="root dir"> | ||||
|                     <a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}">{{.Repository.Name}}</a></li> | ||||
|                 {{range $i, $v := $treenames}} | ||||
|                 <li class="dir"> | ||||
|                     {{if eq $i $l}}{{$v}} | ||||
|                     {{else}} | ||||
|                     <a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}/{{index $paths $i}}">{{$v}}</a>  | ||||
|                 {{end}}</li> | ||||
|                     {{end}} | ||||
|                 </li> | ||||
|                 {{end}} | ||||
|             </ol> | ||||
|         </div> | ||||
|         <div class="panel panel-default info-box"> | ||||
|             <div class="panel-heading info-head"> | ||||
|                 Merge branch 'release/1.1.1' | ||||
|                 <a href="/{{$username}}/{{$reponame}}/commit/{{.LatestCommit.SHA}}">{{.LatestCommit.Message}}</a> | ||||
|             </div> | ||||
|             <div class="panel-body info-content"> | ||||
|                 slene authored 4 days ago | ||||
|                 <a href="/user/{{.LatestCommit.Author}}">{{.LatestCommit.Author}}</a> <span class="text-muted">{{TimeSince .LatestCommit.Date}}</span> | ||||
|             </div> | ||||
|             <table class="panel-footer table file-list"> | ||||
|                 <thead class="hidden"> | ||||
| @ -50,7 +54,8 @@ | ||||
|                 </thead> | ||||
|                 <tbody> | ||||
|                 {{range .Files}} | ||||
|     				<tr {{if .IsDir}}class="is-dir"{{end}}> | ||||
|                 <tr | ||||
|                 {{if .IsDir}}class="is-dir"{{end}}> | ||||
|                 <td class="icon"> | ||||
|                     <i class="fa {{if .IsDir}}fa-folder{{else}}fa-file-text-o{{end}}"></i> | ||||
|                 </td> | ||||
| @ -79,12 +84,18 @@ | ||||
|             </table> | ||||
|         </div> | ||||
|         <div class="panel panel-default file-content"> | ||||
|             <div class="panel-heading"> | ||||
|                 README.md | ||||
|             <div class="panel-heading file-head"> | ||||
|                 <i class="icon fa fa-book"></i> README.md | ||||
|             </div> | ||||
|             <div class="panel-body markdown"> | ||||
|                  httplib | ||||
|             {{if .FileIsLarge}} | ||||
|                 <div class="panel-footer"> | ||||
|                     Large file size 1000kb | ||||
|                 </div> | ||||
|             {{else}} | ||||
|                 <div class="panel-body file-body markdown"> | ||||
|                     {{.ReadmeContent|str2html}} | ||||
|                 </div> | ||||
|             {{end}} | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
|  | ||||
| @ -4,9 +4,10 @@ | ||||
|             <div class="collapse navbar-collapse"> | ||||
|                 <ul class="nav navbar-nav"> | ||||
|                     <li class="{{if .IsRepoToolbarSource}}active{{end}}"><a href="/{{.RepositoryLink}}">Source</a></li> | ||||
|                     <li><a href="/{{.RepositoryLink}}/commits">Commits</a></li> | ||||
|                     <li><a href="/{{.RepositoryLink}}/issues">Issues <!--<span class="badge">42</span>--></a></li> | ||||
|                     <li><a href="/{{.RepositoryLink}}/pulls">Pull Requests</a></li> | ||||
|                     <li class="{{if .IsRepoToolbarCommits}}active{{end}}"><a href="/{{.RepositoryLink}}/commits">Commits</a></li> | ||||
|                     <li class="{{if .IsRepoToolbarBranches}}active{{end}}"><a href="/{{.RepositoryLink}}/branches">Branches</a></li> | ||||
|                     <li class="{{if .IsRepoToolbarPulls}}active{{end}}"><a href="/{{.RepositoryLink}}/pulls">Pull Requests</a></li> | ||||
|                     <li class="{{if .IsRepoToolbarIssues}}active{{end}}"><a href="/{{.RepositoryLink}}/issues">Issues <!--<span class="badge">42</span>--></a></li> | ||||
|                     <li class="dropdown"> | ||||
|                         <a href="#" class="dropdown-toggle" data-toggle="dropdown">More <b class="caret"></b></a> | ||||
|                         <ul class="dropdown-menu"> | ||||
|  | ||||
| @ -11,7 +11,7 @@ | ||||
|         <h3>News Feed</h3> | ||||
|     </div> | ||||
| </div> | ||||
| <div id="gogs-body" class="container"> | ||||
| <div id="gogs-body" class="container" data-page="user"> | ||||
|     {{if .HasInfo}}<div class="alert alert-info">{{.InfoMsg}}</div>{{end}} | ||||
|     <div id="gogs-feed-left" class="col-md-8"> | ||||
|         <ul class="list-unstyled activity-list"> | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| {{template "base/head" .}} | ||||
| {{template "base/navbar" .}} | ||||
| <div id="gogs-body" class="container"> | ||||
| <div id="gogs-body" class="container" data-page="user"> | ||||
|     <div id="gogs-user-setting-nav" class="col-md-3"> | ||||
|         <h4>Account Setting</h4> | ||||
|         <ul class="list-group"> | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| {{template "base/head" .}} | ||||
| {{template "base/navbar" .}} | ||||
| <div id="gogs-body" class="container"> | ||||
| <div id="gogs-body" class="container" data-page="user"> | ||||
|     <div id="gogs-user-setting-nav" class="col-md-3"> | ||||
|         <h4>Account Setting</h4> | ||||
|         <ul class="list-group"> | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| {{template "base/head" .}} | ||||
| {{template "base/navbar" .}} | ||||
| <div id="gogs-body" class="container"> | ||||
| <div id="gogs-body" class="container" data-page="user"> | ||||
|     <div id="gogs-user-setting-nav" class="col-md-3"> | ||||
|         <h4>Account Setting</h4> | ||||
|         <ul class="list-group"> | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| {{template "base/head" .}} | ||||
| {{template "base/navbar" .}} | ||||
| <div id="gogs-body" class="container"> | ||||
| <div id="gogs-body" class="container" data-page="user"> | ||||
|     <div id="gogs-user-profile" class="col-md-3"> | ||||
|         <div class="profile-avatar text-center"> | ||||
|             <a href="{{.Owner.HomeLink}}" class="center-block" data-toggle="tooltip" data-placement="bottom" title="Change Avatar"> | ||||
| @ -32,10 +32,11 @@ | ||||
|             {{if eq .TabName "activity"}} | ||||
|             <div class="tab-pane active"> | ||||
|                 <ul class="list-unstyled activity-list"> | ||||
|                 {{$avatarLink := .Owner.AvatarLink}} | ||||
|                 {{range .Feeds}} | ||||
|                     <li> | ||||
|                         <i class="icon fa fa-{{ActionIcon .OpType}}"></i> | ||||
|                         <div class="info"><span class="meta">{{TimeSince .Created}}</span><br>{{ActionDesc . | str2html}}</div> | ||||
|                         <div class="info"><span class="meta">{{TimeSince .Created}}</span><br>{{ActionDesc . $avatarLink | str2html}}</div> | ||||
|                         <span class="clearfix"></span> | ||||
|                     </li> | ||||
|                 {{else}} | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| {{template "base/head" .}} | ||||
| {{template "base/navbar" .}} | ||||
| <div id="gogs-body" class="container"> | ||||
| <div id="gogs-body" class="container" data-page="user"> | ||||
|     <div id="gogs-user-setting-nav" class="col-md-3"> | ||||
|         <h4>Account Setting</h4> | ||||
|         <ul class="list-group"> | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| {{template "base/head" .}} | ||||
| {{template "base/navbar" .}} | ||||
| <div id="gogs-body" class="container"> | ||||
| <div id="gogs-body" class="container" data-page="user"> | ||||
|     <div id="gogs-user-setting-nav" class="col-md-3"> | ||||
|         <h4>Account Setting</h4> | ||||
|         <ul class="list-group"> | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| {{template "base/head" .}} | ||||
| {{template "base/navbar" .}} | ||||
| <div id="gogs-body" class="container"> | ||||
| <div id="gogs-body" class="container" data-page="user"> | ||||
|     <div id="gogs-user-setting-nav" class="col-md-3"> | ||||
|         <h4>Account Setting</h4> | ||||
|         <ul class="list-group"> | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| {{template "base/head" .}} | ||||
| {{template "base/navbar" .}} | ||||
| <div class="container" id="gogs-body"> | ||||
| <div class="container" id="gogs-body" data-page="user-signin"> | ||||
|     <form action="/user/login" method="post" class="form-horizontal gogs-card" id="gogs-login-card"> | ||||
|         <h3>Log in</h3> | ||||
|         <div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div> | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| {{template "base/head" .}} | ||||
| {{template "base/navbar" .}} | ||||
| <div class="container" id="gogs-body"> | ||||
| <div class="container" id="gogs-body" data-page="user-signup"> | ||||
| 	<form action="/user/sign_up" method="post" class="form-horizontal gogs-card" id="gogs-login-card"> | ||||
|         <h3>Sign Up</h3> | ||||
| 	    <div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div> | ||||
|  | ||||
							
								
								
									
										6
									
								
								web.go
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								web.go
									
									
									
									
									
								
							| @ -68,14 +68,16 @@ func runWeb(*cli.Context) { | ||||
| 	m.Get("/user/:username", middleware.SignInRequire(false), user.Profile) | ||||
| 
 | ||||
| 	m.Any("/repo/create", middleware.SignInRequire(true), binding.BindIgnErr(auth.CreateRepoForm{}), repo.Create) | ||||
| 	m.Any("/repo/delete", middleware.SignInRequire(true), binding.Bind(auth.DeleteRepoForm{}), repo.Delete) | ||||
| 
 | ||||
| 	m.Get("/help", routers.Help) | ||||
| 
 | ||||
| 	m.Get("/:username/:reponame/settings", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Setting) | ||||
| 	m.Post("/:username/:reponame/settings", middleware.SignInRequire(true), middleware.RepoAssignment(true), repo.SettingPost) | ||||
| 	m.Get("/:username/:reponame/settings", middleware.SignInRequire(true), middleware.RepoAssignment(true), repo.Setting) | ||||
| 
 | ||||
| 	m.Get("/:username/:reponame/commits", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Commits) | ||||
| 	m.Get("/:username/:reponame/issues", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Issues) | ||||
| 	m.Get("/:username/:reponame/pulls", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Pulls) | ||||
| 	m.Get("/:username/:reponame/branches", middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Branches) | ||||
| 	m.Get("/:username/:reponame/tree/:branchname/**", | ||||
| 		middleware.SignInRequire(false), middleware.RepoAssignment(true), repo.Single) | ||||
| 	m.Get("/:username/:reponame/tree/:branchname", | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user