mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	@@ -5,7 +5,7 @@ Gogs - Go Git Service [
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##### Current version: 0.7.29 Beta
 | 
					##### Current version: 0.7.30 Beta
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<table>
 | 
					<table>
 | 
				
			||||||
    <tr>
 | 
					    <tr>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -421,7 +421,7 @@ func runWeb(ctx *cli.Context) {
 | 
				
			|||||||
		m.Get("/action/:action", repo.Action)
 | 
							m.Get("/action/:action", repo.Action)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		m.Group("/issues", func() {
 | 
							m.Group("/issues", func() {
 | 
				
			||||||
			m.Combo("/new").Get(middleware.RepoRef(), repo.NewIssue).
 | 
								m.Combo("/new", repo.MustEnableIssues).Get(middleware.RepoRef(), repo.NewIssue).
 | 
				
			||||||
				Post(bindIgnErr(auth.CreateIssueForm{}), repo.NewIssuePost)
 | 
									Post(bindIgnErr(auth.CreateIssueForm{}), repo.NewIssuePost)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			m.Combo("/:index/comments").Post(bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
 | 
								m.Combo("/:index/comments").Post(bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
 | 
				
			||||||
@@ -459,7 +459,7 @@ func runWeb(ctx *cli.Context) {
 | 
				
			|||||||
			m.Post("/delete", repo.DeleteRelease)
 | 
								m.Post("/delete", repo.DeleteRelease)
 | 
				
			||||||
		}, reqRepoAdmin, middleware.RepoRef())
 | 
							}, reqRepoAdmin, middleware.RepoRef())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		m.Combo("/compare/*").Get(repo.CompareAndPullRequest).
 | 
							m.Combo("/compare/*", repo.MustEnablePulls).Get(repo.CompareAndPullRequest).
 | 
				
			||||||
			Post(bindIgnErr(auth.CreateIssueForm{}), repo.CompareAndPullRequestPost)
 | 
								Post(bindIgnErr(auth.CreateIssueForm{}), repo.CompareAndPullRequestPost)
 | 
				
			||||||
	}, reqSignIn, middleware.RepoAssignment())
 | 
						}, reqSignIn, middleware.RepoAssignment())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -484,7 +484,7 @@ func runWeb(ctx *cli.Context) {
 | 
				
			|||||||
				m.Combo("/:page/_edit").Get(repo.EditWiki).
 | 
									m.Combo("/:page/_edit").Get(repo.EditWiki).
 | 
				
			||||||
					Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost)
 | 
										Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost)
 | 
				
			||||||
			}, reqSignIn, reqRepoPusher)
 | 
								}, reqSignIn, reqRepoPusher)
 | 
				
			||||||
		}, middleware.RepoRef())
 | 
							}, repo.MustEnableWiki, middleware.RepoRef())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		m.Get("/archive/*", repo.Download)
 | 
							m.Get("/archive/*", repo.Download)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -492,7 +492,7 @@ func runWeb(ctx *cli.Context) {
 | 
				
			|||||||
			m.Get("/commits", repo.ViewPullCommits)
 | 
								m.Get("/commits", repo.ViewPullCommits)
 | 
				
			||||||
			m.Get("/files", repo.ViewPullFiles)
 | 
								m.Get("/files", repo.ViewPullFiles)
 | 
				
			||||||
			m.Post("/merge", reqRepoAdmin, repo.MergePullRequest)
 | 
								m.Post("/merge", reqRepoAdmin, repo.MergePullRequest)
 | 
				
			||||||
		})
 | 
							}, repo.MustEnablePulls)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		m.Group("", func() {
 | 
							m.Group("", func() {
 | 
				
			||||||
			m.Get("/src/*", repo.Home)
 | 
								m.Get("/src/*", repo.Home)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -558,10 +558,17 @@ settings.collaboration = Collaboration
 | 
				
			|||||||
settings.hooks = Webhooks
 | 
					settings.hooks = Webhooks
 | 
				
			||||||
settings.githooks = Git Hooks
 | 
					settings.githooks = Git Hooks
 | 
				
			||||||
settings.basic_settings = Basic Settings
 | 
					settings.basic_settings = Basic Settings
 | 
				
			||||||
settings.danger_zone = Danger Zone
 | 
					 | 
				
			||||||
settings.site = Official Site
 | 
					settings.site = Official Site
 | 
				
			||||||
settings.update_settings = Update Settings
 | 
					settings.update_settings = Update Settings
 | 
				
			||||||
settings.change_reponame_prompt = This change will affect how links relate to the repository.
 | 
					settings.change_reponame_prompt = This change will affect how links relate to the repository.
 | 
				
			||||||
 | 
					settings.advanced_settings = Advanced Settings
 | 
				
			||||||
 | 
					settings.wiki_desc = Enable wiki to allow people write documents
 | 
				
			||||||
 | 
					settings.issues_desc = Enable builtin lightweight issue tracker 
 | 
				
			||||||
 | 
					settings.use_external_issue_tracker = Use external issue tracker
 | 
				
			||||||
 | 
					settings.tracker_url_format = External Issue Tracker URL Format
 | 
				
			||||||
 | 
					settings.tracker_url_format_desc = You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
 | 
				
			||||||
 | 
					settings.pulls_desc = Enable pull requests to accept public contributions
 | 
				
			||||||
 | 
					settings.danger_zone = Danger Zone
 | 
				
			||||||
settings.transfer = Transfer Ownership
 | 
					settings.transfer = Transfer Ownership
 | 
				
			||||||
settings.transfer_desc = Transfer this repository to another user or to an organization in which you have admin rights.
 | 
					settings.transfer_desc = Transfer this repository to another user or to an organization in which you have admin rights.
 | 
				
			||||||
settings.new_owner_has_same_repo = The new owner already has a repository with same name. Please choose another name.
 | 
					settings.new_owner_has_same_repo = The new owner already has a repository with same name. Please choose another name.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,6 @@ Directory `/var/gogs` keeps Git repositories and Gogs data:
 | 
				
			|||||||
        |-- conf
 | 
					        |-- conf
 | 
				
			||||||
        |-- data
 | 
					        |-- data
 | 
				
			||||||
        |-- log
 | 
					        |-- log
 | 
				
			||||||
        |-- templates
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Volume with data container
 | 
					### Volume with data container
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							@@ -17,7 +17,7 @@ import (
 | 
				
			|||||||
	"github.com/gogits/gogs/modules/setting"
 | 
						"github.com/gogits/gogs/modules/setting"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const APP_VER = "0.7.29.1204 Beta"
 | 
					const APP_VER = "0.7.30.1204 Beta"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	runtime.GOMAXPROCS(runtime.NumCPU())
 | 
						runtime.GOMAXPROCS(runtime.NumCPU())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -161,6 +161,14 @@ type Repository struct {
 | 
				
			|||||||
	IsMirror bool
 | 
						IsMirror bool
 | 
				
			||||||
	*Mirror  `xorm:"-"`
 | 
						*Mirror  `xorm:"-"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Advanced settings
 | 
				
			||||||
 | 
						EnableWiki            bool `xorm:"NOT NULL DEFAULT true"`
 | 
				
			||||||
 | 
						EnableIssues          bool `xorm:"NOT NULL DEFAULT true"`
 | 
				
			||||||
 | 
						EnableExternalTracker bool
 | 
				
			||||||
 | 
						ExternalTrackerFormat string
 | 
				
			||||||
 | 
						ExternalMetas         map[string]string `xorm:"-"`
 | 
				
			||||||
 | 
						EnablePulls           bool              `xorm:"NOT NULL DEFAULT true"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	IsFork   bool `xorm:"NOT NULL DEFAULT false"`
 | 
						IsFork   bool `xorm:"NOT NULL DEFAULT false"`
 | 
				
			||||||
	ForkID   int64
 | 
						ForkID   int64
 | 
				
			||||||
	BaseRepo *Repository `xorm:"-"`
 | 
						BaseRepo *Repository `xorm:"-"`
 | 
				
			||||||
@@ -214,6 +222,20 @@ func (repo *Repository) MustOwner() *User {
 | 
				
			|||||||
	return repo.mustOwner(x)
 | 
						return repo.mustOwner(x)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ComposeMetas composes a map of metas for rendering external issue tracker URL.
 | 
				
			||||||
 | 
					func (repo *Repository) ComposeMetas() map[string]string {
 | 
				
			||||||
 | 
						if !repo.EnableExternalTracker {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						} else if repo.ExternalMetas == nil {
 | 
				
			||||||
 | 
							repo.ExternalMetas = map[string]string{
 | 
				
			||||||
 | 
								"format": repo.ExternalTrackerFormat,
 | 
				
			||||||
 | 
								"user":   repo.MustOwner().Name,
 | 
				
			||||||
 | 
								"repo":   repo.Name,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return repo.ExternalMetas
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetAssignees returns all users that have write access of repository.
 | 
					// GetAssignees returns all users that have write access of repository.
 | 
				
			||||||
func (repo *Repository) GetAssignees() (_ []*User, err error) {
 | 
					func (repo *Repository) GetAssignees() (_ []*User, err error) {
 | 
				
			||||||
	if err = repo.GetOwner(); err != nil {
 | 
						if err = repo.GetOwner(); err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -87,6 +87,13 @@ type RepoSettingForm struct {
 | 
				
			|||||||
	Branch      string
 | 
						Branch      string
 | 
				
			||||||
	Interval    int
 | 
						Interval    int
 | 
				
			||||||
	Private     bool
 | 
						Private     bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Advanced settings
 | 
				
			||||||
 | 
						EnableWiki            bool
 | 
				
			||||||
 | 
						EnableIssues          bool
 | 
				
			||||||
 | 
						EnableExternalTracker bool
 | 
				
			||||||
 | 
						TrackerURLFormat      string
 | 
				
			||||||
 | 
						EnablePulls           bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *RepoSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
 | 
					func (f *RepoSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -137,50 +137,6 @@ var (
 | 
				
			|||||||
	sha1CurrentPattern = regexp.MustCompile(`\b[0-9a-f]{40}\b`)
 | 
						sha1CurrentPattern = regexp.MustCompile(`\b[0-9a-f]{40}\b`)
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte {
 | 
					 | 
				
			||||||
	ms := MentionPattern.FindAll(rawBytes, -1)
 | 
					 | 
				
			||||||
	for _, m := range ms {
 | 
					 | 
				
			||||||
		m = bytes.TrimSpace(m)
 | 
					 | 
				
			||||||
		rawBytes = bytes.Replace(rawBytes, m,
 | 
					 | 
				
			||||||
			[]byte(fmt.Sprintf(`<a href="%s/%s">%s</a>`, setting.AppSubUrl, m[1:], m)), -1)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ms = commitPattern.FindAll(rawBytes, -1)
 | 
					 | 
				
			||||||
	for _, m := range ms {
 | 
					 | 
				
			||||||
		m = bytes.TrimSpace(m)
 | 
					 | 
				
			||||||
		i := strings.Index(string(m), "commit/")
 | 
					 | 
				
			||||||
		j := strings.Index(string(m), "#")
 | 
					 | 
				
			||||||
		if j == -1 {
 | 
					 | 
				
			||||||
			j = len(m)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(
 | 
					 | 
				
			||||||
			` <code><a href="%s">%s</a></code>`, m, ShortSha(string(m[i+7:j])))), -1)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ms = issueFullPattern.FindAll(rawBytes, -1)
 | 
					 | 
				
			||||||
	for _, m := range ms {
 | 
					 | 
				
			||||||
		m = bytes.TrimSpace(m)
 | 
					 | 
				
			||||||
		i := strings.Index(string(m), "issues/")
 | 
					 | 
				
			||||||
		j := strings.Index(string(m), "#")
 | 
					 | 
				
			||||||
		if j == -1 {
 | 
					 | 
				
			||||||
			j = len(m)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(
 | 
					 | 
				
			||||||
			` <a href="%s">#%s</a>`, m, ShortSha(string(m[i+7:j])))), -1)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rawBytes = RenderIssueIndexPattern(rawBytes, urlPrefix)
 | 
					 | 
				
			||||||
	rawBytes = RenderSha1CurrentPattern(rawBytes, urlPrefix)
 | 
					 | 
				
			||||||
	return rawBytes
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func RenderSha1CurrentPattern(rawBytes []byte, urlPrefix string) []byte {
 | 
					 | 
				
			||||||
	ms := sha1CurrentPattern.FindAll(rawBytes, -1)
 | 
					 | 
				
			||||||
	for _, m := range ms {
 | 
					 | 
				
			||||||
		rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(
 | 
					 | 
				
			||||||
			`<a href="%s/commit/%s"><code>%s</code></a>`, urlPrefix, m, ShortSha(string(m)))), -1)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return rawBytes
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func cutoutVerbosePrefix(prefix string) string {
 | 
					func cutoutVerbosePrefix(prefix string) string {
 | 
				
			||||||
	count := 0
 | 
						count := 0
 | 
				
			||||||
	for i := 0; i < len(prefix); i++ {
 | 
						for i := 0; i < len(prefix); i++ {
 | 
				
			||||||
@@ -194,7 +150,7 @@ func cutoutVerbosePrefix(prefix string) string {
 | 
				
			|||||||
	return prefix
 | 
						return prefix
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RenderIssueIndexPattern(rawBytes []byte, urlPrefix string) []byte {
 | 
					func RenderIssueIndexPattern(rawBytes []byte, urlPrefix string, metas map[string]string) []byte {
 | 
				
			||||||
	urlPrefix = cutoutVerbosePrefix(urlPrefix)
 | 
						urlPrefix = cutoutVerbosePrefix(urlPrefix)
 | 
				
			||||||
	ms := issueIndexPattern.FindAll(rawBytes, -1)
 | 
						ms := issueIndexPattern.FindAll(rawBytes, -1)
 | 
				
			||||||
	for _, m := range ms {
 | 
						for _, m := range ms {
 | 
				
			||||||
@@ -204,24 +160,45 @@ func RenderIssueIndexPattern(rawBytes []byte, urlPrefix string) []byte {
 | 
				
			|||||||
			space = " "
 | 
								space = " "
 | 
				
			||||||
			m2 = m2[1:]
 | 
								m2 = m2[1:]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(`%s<a href="%s/issues/%s">%s</a>`,
 | 
							if metas == nil {
 | 
				
			||||||
			space, urlPrefix, m2[1:], m2)), 1)
 | 
								rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(`%s<a href="%s/issues/%s">%s</a>`,
 | 
				
			||||||
 | 
									space, urlPrefix, m2[1:], m2)), 1)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								// Support for external issue tracker
 | 
				
			||||||
 | 
								metas["index"] = string(m2[1:])
 | 
				
			||||||
 | 
								rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(`%s<a href="%s">%s</a>`,
 | 
				
			||||||
 | 
									space, com.Expand(metas["format"], metas), m2)), 1)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return rawBytes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func RenderSpecialLink(rawBytes []byte, urlPrefix string, metas map[string]string) []byte {
 | 
				
			||||||
 | 
						ms := MentionPattern.FindAll(rawBytes, -1)
 | 
				
			||||||
 | 
						for _, m := range ms {
 | 
				
			||||||
 | 
							m = bytes.TrimSpace(m)
 | 
				
			||||||
 | 
							rawBytes = bytes.Replace(rawBytes, m,
 | 
				
			||||||
 | 
								[]byte(fmt.Sprintf(`<a href="%s/%s">%s</a>`, setting.AppSubUrl, m[1:], m)), -1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rawBytes = RenderIssueIndexPattern(rawBytes, urlPrefix, metas)
 | 
				
			||||||
 | 
						rawBytes = RenderSha1CurrentPattern(rawBytes, urlPrefix)
 | 
				
			||||||
 | 
						return rawBytes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func RenderSha1CurrentPattern(rawBytes []byte, urlPrefix string) []byte {
 | 
				
			||||||
 | 
						ms := sha1CurrentPattern.FindAll(rawBytes, -1)
 | 
				
			||||||
 | 
						for _, m := range ms {
 | 
				
			||||||
 | 
							rawBytes = bytes.Replace(rawBytes, m, []byte(fmt.Sprintf(
 | 
				
			||||||
 | 
								`<a href="%s/commit/%s"><code>%s</code></a>`, urlPrefix, m, ShortSha(string(m)))), -1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return rawBytes
 | 
						return rawBytes
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RenderRawMarkdown(body []byte, urlPrefix string) []byte {
 | 
					func RenderRawMarkdown(body []byte, urlPrefix string) []byte {
 | 
				
			||||||
	htmlFlags := 0
 | 
						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_STYLE
 | 
				
			||||||
	// htmlFlags |= blackfriday.HTML_SKIP_SCRIPT
 | 
					 | 
				
			||||||
	// htmlFlags |= blackfriday.HTML_GITHUB_BLOCKCODE
 | 
					 | 
				
			||||||
	htmlFlags |= blackfriday.HTML_OMIT_CONTENTS
 | 
						htmlFlags |= blackfriday.HTML_OMIT_CONTENTS
 | 
				
			||||||
	// htmlFlags |= blackfriday.HTML_COMPLETE_PAGE
 | 
					 | 
				
			||||||
	renderer := &CustomRender{
 | 
						renderer := &CustomRender{
 | 
				
			||||||
		Renderer:  blackfriday.HtmlRenderer(htmlFlags, "", ""),
 | 
							Renderer:  blackfriday.HtmlRenderer(htmlFlags, "", ""),
 | 
				
			||||||
		urlPrefix: urlPrefix,
 | 
							urlPrefix: urlPrefix,
 | 
				
			||||||
@@ -252,9 +229,36 @@ var (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var noEndTags = []string{"img", "input", "br", "hr"}
 | 
					var noEndTags = []string{"img", "input", "br", "hr"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PreProcessMarkdown renders full links of commits, issues and pulls to shorter version.
 | 
				
			||||||
 | 
					func PreProcessMarkdown(rawHTML []byte, urlPrefix string) []byte {
 | 
				
			||||||
 | 
						ms := commitPattern.FindAll(rawHTML, -1)
 | 
				
			||||||
 | 
						for _, m := range ms {
 | 
				
			||||||
 | 
							m = bytes.TrimSpace(m)
 | 
				
			||||||
 | 
							i := strings.Index(string(m), "commit/")
 | 
				
			||||||
 | 
							j := strings.Index(string(m), "#")
 | 
				
			||||||
 | 
							if j == -1 {
 | 
				
			||||||
 | 
								j = len(m)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							rawHTML = bytes.Replace(rawHTML, m, []byte(fmt.Sprintf(
 | 
				
			||||||
 | 
								` <code><a href="%s">%s</a></code>`, m, ShortSha(string(m[i+7:j])))), -1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ms = issueFullPattern.FindAll(rawHTML, -1)
 | 
				
			||||||
 | 
						for _, m := range ms {
 | 
				
			||||||
 | 
							m = bytes.TrimSpace(m)
 | 
				
			||||||
 | 
							i := strings.Index(string(m), "issues/")
 | 
				
			||||||
 | 
							j := strings.Index(string(m), "#")
 | 
				
			||||||
 | 
							if j == -1 {
 | 
				
			||||||
 | 
								j = len(m)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							rawHTML = bytes.Replace(rawHTML, m, []byte(fmt.Sprintf(
 | 
				
			||||||
 | 
								` <a href="%s">#%s</a>`, m, ShortSha(string(m[i+7:j])))), -1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return rawHTML
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PostProcessMarkdown treats different types of HTML differently,
 | 
					// PostProcessMarkdown treats different types of HTML differently,
 | 
				
			||||||
// and only renders special links for plain text blocks.
 | 
					// and only renders special links for plain text blocks.
 | 
				
			||||||
func PostProcessMarkdown(rawHtml []byte, urlPrefix string) []byte {
 | 
					func PostProcessMarkdown(rawHtml []byte, urlPrefix string, metas map[string]string) []byte {
 | 
				
			||||||
	startTags := make([]string, 0, 5)
 | 
						startTags := make([]string, 0, 5)
 | 
				
			||||||
	var buf bytes.Buffer
 | 
						var buf bytes.Buffer
 | 
				
			||||||
	tokenizer := html.NewTokenizer(bytes.NewReader(rawHtml))
 | 
						tokenizer := html.NewTokenizer(bytes.NewReader(rawHtml))
 | 
				
			||||||
@@ -264,7 +268,7 @@ OUTER_LOOP:
 | 
				
			|||||||
		token := tokenizer.Token()
 | 
							token := tokenizer.Token()
 | 
				
			||||||
		switch token.Type {
 | 
							switch token.Type {
 | 
				
			||||||
		case html.TextToken:
 | 
							case html.TextToken:
 | 
				
			||||||
			buf.Write(RenderSpecialLink([]byte(token.String()), urlPrefix))
 | 
								buf.Write(RenderSpecialLink([]byte(token.String()), urlPrefix, metas))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case html.StartTagToken:
 | 
							case html.StartTagToken:
 | 
				
			||||||
			buf.WriteString(token.String())
 | 
								buf.WriteString(token.String())
 | 
				
			||||||
@@ -322,13 +326,14 @@ OUTER_LOOP:
 | 
				
			|||||||
	return rawHtml
 | 
						return rawHtml
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte {
 | 
					func RenderMarkdown(rawBytes []byte, urlPrefix string, metas map[string]string) []byte {
 | 
				
			||||||
	result := RenderRawMarkdown(rawBytes, urlPrefix)
 | 
						result := PreProcessMarkdown(rawBytes, urlPrefix)
 | 
				
			||||||
	result = PostProcessMarkdown(result, urlPrefix)
 | 
						result = RenderRawMarkdown(result, urlPrefix)
 | 
				
			||||||
 | 
						result = PostProcessMarkdown(result, urlPrefix, metas)
 | 
				
			||||||
	result = Sanitizer.SanitizeBytes(result)
 | 
						result = Sanitizer.SanitizeBytes(result)
 | 
				
			||||||
	return result
 | 
						return result
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RenderMarkdownString(raw, urlPrefix string) string {
 | 
					func RenderMarkdownString(raw, urlPrefix string, metas map[string]string) string {
 | 
				
			||||||
	return string(RenderMarkdown([]byte(raw), urlPrefix))
 | 
						return string(RenderMarkdown([]byte(raw), urlPrefix, metas))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -125,7 +125,7 @@ func SendIssueNotifyMail(u, owner *models.User, repo *models.Repository, issue *
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	subject := fmt.Sprintf("[%s] %s (#%d)", repo.Name, issue.Name, issue.Index)
 | 
						subject := fmt.Sprintf("[%s] %s (#%d)", repo.Name, issue.Name, issue.Index)
 | 
				
			||||||
	content := fmt.Sprintf("%s<br>-<br> <a href=\"%s%s/%s/issues/%d\">View it on Gogs</a>.",
 | 
						content := fmt.Sprintf("%s<br>-<br> <a href=\"%s%s/%s/issues/%d\">View it on Gogs</a>.",
 | 
				
			||||||
		base.RenderSpecialLink([]byte(issue.Content), owner.Name+"/"+repo.Name),
 | 
							base.RenderSpecialLink([]byte(issue.Content), owner.Name+"/"+repo.Name, repo.ComposeMetas()),
 | 
				
			||||||
		setting.AppUrl, owner.Name, repo.Name, issue.Index)
 | 
							setting.AppUrl, owner.Name, repo.Name, issue.Index)
 | 
				
			||||||
	msg := NewMessage(tos, subject, content)
 | 
						msg := NewMessage(tos, subject, content)
 | 
				
			||||||
	msg.Info = fmt.Sprintf("Subject: %s, issue notify", subject)
 | 
						msg.Info = fmt.Sprintf("Subject: %s, issue notify", subject)
 | 
				
			||||||
@@ -148,7 +148,7 @@ func SendIssueMentionMail(r macaron.Render, u, owner *models.User,
 | 
				
			|||||||
	data["IssueLink"] = fmt.Sprintf("%s/%s/issues/%d", owner.Name, repo.Name, issue.Index)
 | 
						data["IssueLink"] = fmt.Sprintf("%s/%s/issues/%d", owner.Name, repo.Name, issue.Index)
 | 
				
			||||||
	data["Subject"] = subject
 | 
						data["Subject"] = subject
 | 
				
			||||||
	data["ActUserName"] = u.DisplayName()
 | 
						data["ActUserName"] = u.DisplayName()
 | 
				
			||||||
	data["Content"] = string(base.RenderSpecialLink([]byte(issue.Content), owner.Name+"/"+repo.Name))
 | 
						data["Content"] = string(base.RenderSpecialLink([]byte(issue.Content), owner.Name+"/"+repo.Name, repo.ComposeMetas()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	body, err := r.HTMLString(string(NOTIFY_MENTION), data)
 | 
						body, err := r.HTMLString(string(NOTIFY_MENTION), data)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -165,6 +165,7 @@ func RepoAssignment(args ...bool) macaron.Handler {
 | 
				
			|||||||
		ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner()
 | 
							ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner()
 | 
				
			||||||
		ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin()
 | 
							ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin()
 | 
				
			||||||
		ctx.Data["IsRepositoryPusher"] = ctx.Repo.IsPusher()
 | 
							ctx.Data["IsRepositoryPusher"] = ctx.Repo.IsPusher()
 | 
				
			||||||
 | 
							ctx.Data["CanPullRequest"] = ctx.Repo.IsAdmin() && repo.BaseRepo != nil && repo.BaseRepo.EnablePulls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ctx.Data["DisableSSH"] = setting.DisableSSH
 | 
							ctx.Data["DisableSSH"] = setting.DisableSSH
 | 
				
			||||||
		ctx.Data["CloneLink"] = repo.CloneLink()
 | 
							ctx.Data["CloneLink"] = repo.CloneLink()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -183,9 +183,9 @@ func ReplaceLeft(s, old, new string) string {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RenderCommitMessage renders commit message with XSS-safe and special links.
 | 
					// RenderCommitMessage renders commit message with XSS-safe and special links.
 | 
				
			||||||
func RenderCommitMessage(msg, urlPrefix string) template.HTML {
 | 
					func RenderCommitMessage(msg, urlPrefix string, metas map[string]string) template.HTML {
 | 
				
			||||||
	cleanMsg := template.HTMLEscapeString(msg)
 | 
						cleanMsg := template.HTMLEscapeString(msg)
 | 
				
			||||||
	fullMessage := string(base.RenderIssueIndexPattern([]byte(cleanMsg), urlPrefix))
 | 
						fullMessage := string(base.RenderIssueIndexPattern([]byte(cleanMsg), urlPrefix, metas))
 | 
				
			||||||
	msgLines := strings.Split(strings.TrimSpace(fullMessage), "\n")
 | 
						msgLines := strings.Split(strings.TrimSpace(fullMessage), "\n")
 | 
				
			||||||
	for i := range msgLines {
 | 
						for i := range msgLines {
 | 
				
			||||||
		msgLines[i] = ReplaceLeft(msgLines[i], " ", " ")
 | 
							msgLines[i] = ReplaceLeft(msgLines[i], " ", " ")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -911,6 +911,9 @@ pre.raw {
 | 
				
			|||||||
.ui .form .fake {
 | 
					.ui .form .fake {
 | 
				
			||||||
  display: none !important;
 | 
					  display: none !important;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					.ui .form .sub.field {
 | 
				
			||||||
 | 
					  margin-left: 25px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
.ui .sha.label {
 | 
					.ui .sha.label {
 | 
				
			||||||
  font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace;
 | 
					  font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace;
 | 
				
			||||||
  font-size: 13px;
 | 
					  font-size: 13px;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -217,6 +217,10 @@ pre {
 | 
				
			|||||||
		.fake {
 | 
							.fake {
 | 
				
			||||||
			display: none !important;
 | 
								display: none !important;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							.sub.field {
 | 
				
			||||||
 | 
								margin-left: 25px;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.sha.label {
 | 
						.sha.label {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,7 @@ func Markdown(ctx *middleware.Context, form api.MarkdownOption) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	switch form.Mode {
 | 
						switch form.Mode {
 | 
				
			||||||
	case "gfm":
 | 
						case "gfm":
 | 
				
			||||||
		ctx.Write(base.RenderMarkdown([]byte(form.Text), form.Context))
 | 
							ctx.Write(base.RenderMarkdown([]byte(form.Text), form.Context, nil))
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		ctx.Write(base.RenderRawMarkdown([]byte(form.Text), ""))
 | 
							ctx.Write(base.RenderRawMarkdown([]byte(form.Text), ""))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,6 +41,18 @@ var (
 | 
				
			|||||||
	ErrTooManyFiles      = errors.New("Maximum number of files to upload exceeded")
 | 
						ErrTooManyFiles      = errors.New("Maximum number of files to upload exceeded")
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func MustEnableIssues(ctx *middleware.Context) {
 | 
				
			||||||
 | 
						if !ctx.Repo.Repository.EnableIssues {
 | 
				
			||||||
 | 
							ctx.Handle(404, "MustEnableIssues", nil)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func MustEnablePulls(ctx *middleware.Context) {
 | 
				
			||||||
 | 
						if !ctx.Repo.Repository.EnablePulls {
 | 
				
			||||||
 | 
							ctx.Handle(404, "MustEnablePulls", nil)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RetrieveLabels(ctx *middleware.Context) {
 | 
					func RetrieveLabels(ctx *middleware.Context) {
 | 
				
			||||||
	labels, err := models.GetLabelsByRepoID(ctx.Repo.Repository.ID)
 | 
						labels, err := models.GetLabelsByRepoID(ctx.Repo.Repository.ID)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -60,7 +72,12 @@ func Issues(ctx *middleware.Context) {
 | 
				
			|||||||
		ctx.Data["Title"] = ctx.Tr("repo.pulls")
 | 
							ctx.Data["Title"] = ctx.Tr("repo.pulls")
 | 
				
			||||||
		ctx.Data["PageIsPullList"] = true
 | 
							ctx.Data["PageIsPullList"] = true
 | 
				
			||||||
		ctx.Data["HasForkedRepo"] = ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID)
 | 
							ctx.Data["HasForkedRepo"] = ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
 | 
							MustEnableIssues(ctx)
 | 
				
			||||||
 | 
							if ctx.Written() {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		ctx.Data["Title"] = ctx.Tr("repo.issues")
 | 
							ctx.Data["Title"] = ctx.Tr("repo.issues")
 | 
				
			||||||
		ctx.Data["PageIsIssueList"] = true
 | 
							ctx.Data["PageIsIssueList"] = true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -496,6 +513,10 @@ func ViewIssue(ctx *middleware.Context) {
 | 
				
			|||||||
		ctx.Data["PageIsPullConversation"] = true
 | 
							ctx.Data["PageIsPullConversation"] = true
 | 
				
			||||||
		ctx.Data["HasForkedRepo"] = ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID)
 | 
							ctx.Data["HasForkedRepo"] = ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
 | 
							MustEnableIssues(ctx)
 | 
				
			||||||
 | 
							if ctx.Written() {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		ctx.Data["PageIsIssueList"] = true
 | 
							ctx.Data["PageIsIssueList"] = true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -503,7 +524,8 @@ func ViewIssue(ctx *middleware.Context) {
 | 
				
			|||||||
		ctx.Handle(500, "GetPoster", err)
 | 
							ctx.Handle(500, "GetPoster", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink))
 | 
						issue.RenderedContent = string(base.RenderMarkdown([]byte(issue.Content), ctx.Repo.RepoLink,
 | 
				
			||||||
 | 
							ctx.Repo.Repository.ComposeMetas()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repo := ctx.Repo.Repository
 | 
						repo := ctx.Repo.Repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -570,7 +592,8 @@ func ViewIssue(ctx *middleware.Context) {
 | 
				
			|||||||
	// Render comments.
 | 
						// Render comments.
 | 
				
			||||||
	for _, comment = range issue.Comments {
 | 
						for _, comment = range issue.Comments {
 | 
				
			||||||
		if comment.Type == models.COMMENT_TYPE_COMMENT {
 | 
							if comment.Type == models.COMMENT_TYPE_COMMENT {
 | 
				
			||||||
			comment.RenderedContent = string(base.RenderMarkdown([]byte(comment.Content), ctx.Repo.RepoLink))
 | 
								comment.RenderedContent = string(base.RenderMarkdown([]byte(comment.Content), ctx.Repo.RepoLink,
 | 
				
			||||||
 | 
									ctx.Repo.Repository.ComposeMetas()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Check tag.
 | 
								// Check tag.
 | 
				
			||||||
			tag, ok = marked[comment.PosterID]
 | 
								tag, ok = marked[comment.PosterID]
 | 
				
			||||||
@@ -656,7 +679,7 @@ func UpdateIssueContent(ctx *middleware.Context) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.JSON(200, map[string]interface{}{
 | 
						ctx.JSON(200, map[string]interface{}{
 | 
				
			||||||
		"content": string(base.RenderMarkdown([]byte(issue.Content), ctx.Query("context"))),
 | 
							"content": string(base.RenderMarkdown([]byte(issue.Content), ctx.Query("context"), ctx.Repo.Repository.ComposeMetas())),
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -893,7 +916,7 @@ func UpdateCommentContent(ctx *middleware.Context) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.JSON(200, map[string]interface{}{
 | 
						ctx.JSON(200, map[string]interface{}{
 | 
				
			||||||
		"content": string(base.RenderMarkdown([]byte(comment.Content), ctx.Query("context"))),
 | 
							"content": string(base.RenderMarkdown([]byte(comment.Content), ctx.Query("context"), ctx.Repo.Repository.ComposeMetas())),
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -991,7 +1014,7 @@ func Milestones(ctx *middleware.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, m := range miles {
 | 
						for _, m := range miles {
 | 
				
			||||||
		m.RenderedContent = string(base.RenderMarkdown([]byte(m.Content), ctx.Repo.RepoLink))
 | 
							m.RenderedContent = string(base.RenderMarkdown([]byte(m.Content), ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas()))
 | 
				
			||||||
		m.CalOpenIssues()
 | 
							m.CalOpenIssues()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ctx.Data["Milestones"] = miles
 | 
						ctx.Data["Milestones"] = miles
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -69,7 +69,7 @@ func Releases(ctx *middleware.Context) {
 | 
				
			|||||||
					rel.NumCommitsBehind = ctx.Repo.CommitsCount - rel.NumCommits
 | 
										rel.NumCommitsBehind = ctx.Repo.CommitsCount - rel.NumCommits
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				rel.Note = base.RenderMarkdownString(rel.Note, ctx.Repo.RepoLink)
 | 
									rel.Note = base.RenderMarkdownString(rel.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas())
 | 
				
			||||||
				tags[i] = rel
 | 
									tags[i] = rel
 | 
				
			||||||
				rels[j] = nil // Mark as used.
 | 
									rels[j] = nil // Mark as used.
 | 
				
			||||||
				break
 | 
									break
 | 
				
			||||||
@@ -129,7 +129,7 @@ func Releases(ctx *middleware.Context) {
 | 
				
			|||||||
			rel.NumCommitsBehind = ctx.Repo.CommitsCount - rel.NumCommits
 | 
								rel.NumCommitsBehind = ctx.Repo.CommitsCount - rel.NumCommits
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rel.Note = base.RenderMarkdownString(rel.Note, ctx.Repo.RepoLink)
 | 
							rel.Note = base.RenderMarkdownString(rel.Note, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas())
 | 
				
			||||||
		tags = append(tags, rel)
 | 
							tags = append(tags, rel)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	models.SortReleases(tags)
 | 
						models.SortReleases(tags)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -104,7 +104,7 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
 | 
				
			|||||||
			ctx.Handle(500, "UpdateRepository", err)
 | 
								ctx.Handle(500, "UpdateRepository", err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		log.Trace("Repository updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
 | 
							log.Trace("Repository basic settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if isNameChanged {
 | 
							if isNameChanged {
 | 
				
			||||||
			if err := models.RenameRepoAction(ctx.User, oldRepoName, repo); err != nil {
 | 
								if err := models.RenameRepoAction(ctx.User, oldRepoName, repo); err != nil {
 | 
				
			||||||
@@ -123,7 +123,24 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
 | 
							ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
 | 
				
			||||||
		ctx.Redirect(fmt.Sprintf("%s/%s/%s/settings", setting.AppSubUrl, ctx.Repo.Owner.Name, repo.Name))
 | 
							ctx.Redirect(ctx.Repo.RepoLink + "/settings")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case "advanced":
 | 
				
			||||||
 | 
							repo.EnableWiki = form.EnableWiki
 | 
				
			||||||
 | 
							repo.EnableIssues = form.EnableIssues
 | 
				
			||||||
 | 
							repo.EnableExternalTracker = form.EnableExternalTracker
 | 
				
			||||||
 | 
							repo.ExternalTrackerFormat = form.TrackerURLFormat
 | 
				
			||||||
 | 
							repo.EnablePulls = form.EnablePulls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := models.UpdateRepository(repo, false); err != nil {
 | 
				
			||||||
 | 
								ctx.Handle(500, "UpdateRepository", err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							log.Trace("Repository advanced settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
 | 
				
			||||||
 | 
							ctx.Redirect(ctx.Repo.RepoLink + "/settings")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case "transfer":
 | 
						case "transfer":
 | 
				
			||||||
		if repo.Name != form.RepoName {
 | 
							if repo.Name != form.RepoName {
 | 
				
			||||||
			ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
 | 
								ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_repo_name"), SETTINGS_OPTIONS, nil)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -108,7 +108,7 @@ func Home(ctx *middleware.Context) {
 | 
				
			|||||||
				readmeExist := base.IsMarkdownFile(blob.Name()) || base.IsReadmeFile(blob.Name())
 | 
									readmeExist := base.IsMarkdownFile(blob.Name()) || base.IsReadmeFile(blob.Name())
 | 
				
			||||||
				ctx.Data["ReadmeExist"] = readmeExist
 | 
									ctx.Data["ReadmeExist"] = readmeExist
 | 
				
			||||||
				if readmeExist {
 | 
									if readmeExist {
 | 
				
			||||||
					ctx.Data["FileContent"] = string(base.RenderMarkdown(buf, path.Dir(treeLink)))
 | 
										ctx.Data["FileContent"] = string(base.RenderMarkdown(buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					if err, content := template.ToUtf8WithErr(buf); err != nil {
 | 
										if err, content := template.ToUtf8WithErr(buf); err != nil {
 | 
				
			||||||
						if err != nil {
 | 
											if err != nil {
 | 
				
			||||||
@@ -201,7 +201,7 @@ func Home(ctx *middleware.Context) {
 | 
				
			|||||||
					buf = append(buf, d...)
 | 
										buf = append(buf, d...)
 | 
				
			||||||
					switch {
 | 
										switch {
 | 
				
			||||||
					case base.IsMarkdownFile(readmeFile.Name()):
 | 
										case base.IsMarkdownFile(readmeFile.Name()):
 | 
				
			||||||
						buf = base.RenderMarkdown(buf, treeLink)
 | 
											buf = base.RenderMarkdown(buf, treeLink, ctx.Repo.Repository.ComposeMetas())
 | 
				
			||||||
					default:
 | 
										default:
 | 
				
			||||||
						buf = bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1)
 | 
											buf = bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,12 @@ const (
 | 
				
			|||||||
	WIKI_PAGES base.TplName = "repo/wiki/pages"
 | 
						WIKI_PAGES base.TplName = "repo/wiki/pages"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func MustEnableWiki(ctx *middleware.Context) {
 | 
				
			||||||
 | 
						if !ctx.Repo.Repository.EnableWiki {
 | 
				
			||||||
 | 
							ctx.Handle(404, "MustEnableWiki", nil)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type PageMeta struct {
 | 
					type PageMeta struct {
 | 
				
			||||||
	Name    string
 | 
						Name    string
 | 
				
			||||||
	URL     string
 | 
						URL     string
 | 
				
			||||||
@@ -94,7 +100,7 @@ func renderWikiPage(ctx *middleware.Context, isViewPage bool) (*git.Repository,
 | 
				
			|||||||
		return nil, ""
 | 
							return nil, ""
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if isViewPage {
 | 
						if isViewPage {
 | 
				
			||||||
		ctx.Data["content"] = string(base.RenderMarkdown(data, ctx.Repo.RepoLink))
 | 
							ctx.Data["content"] = string(base.RenderMarkdown(data, ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas()))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		ctx.Data["content"] = string(data)
 | 
							ctx.Data["content"] = string(data)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
0.7.29.1204 Beta
 | 
					0.7.30.1204 Beta
 | 
				
			||||||
@@ -37,7 +37,7 @@
 | 
				
			|||||||
        </td>
 | 
					        </td>
 | 
				
			||||||
        <td class="message collapsing">
 | 
					        <td class="message collapsing">
 | 
				
			||||||
          <a rel="nofollow" class="ui sha label" href="{{AppSubUrl}}/{{$.Username}}/{{$.Reponame}}/commit/{{.ID}}">{{ShortSha .ID.String}}</a>
 | 
					          <a rel="nofollow" class="ui sha label" href="{{AppSubUrl}}/{{$.Username}}/{{$.Reponame}}/commit/{{.ID}}">{{ShortSha .ID.String}}</a>
 | 
				
			||||||
          {{RenderCommitMessage .Summary $.RepoLink}}   
 | 
					          {{RenderCommitMessage .Summary $.RepoLink $.Repository.ComposeMetas}}   
 | 
				
			||||||
        </td>
 | 
					        </td>
 | 
				
			||||||
        <td class="grey text right aligned">{{TimeSince .Author.When $.Lang}}</td>
 | 
					        <td class="grey text right aligned">{{TimeSince .Author.When $.Lang}}</td>
 | 
				
			||||||
      </tr>
 | 
					      </tr>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,21 +51,27 @@
 | 
				
			|||||||
    <a class="{{if .PageIsViewCode}}active{{end}} item" href="{{.RepoLink}}">
 | 
					    <a class="{{if .PageIsViewCode}}active{{end}} item" href="{{.RepoLink}}">
 | 
				
			||||||
      <i class="icon octicon octicon-code"></i> {{.i18n.Tr "repo.code"}}
 | 
					      <i class="icon octicon octicon-code"></i> {{.i18n.Tr "repo.code"}}
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
 | 
					    {{if .Repository.EnableIssues}}
 | 
				
			||||||
    <a class="{{if .PageIsIssueList}}active{{end}} item" href="{{.RepoLink}}/issues">
 | 
					    <a class="{{if .PageIsIssueList}}active{{end}} item" href="{{.RepoLink}}/issues">
 | 
				
			||||||
      <i class="icon octicon octicon-issue-opened"></i> {{.i18n.Tr "repo.issues"}} <span class="ui {{if not .Repository.NumOpenIssues}}gray{{else}}blue{{end}} small label">{{.Repository.NumOpenIssues}}</span>
 | 
					      <i class="icon octicon octicon-issue-opened"></i> {{.i18n.Tr "repo.issues"}} <span class="ui {{if not .Repository.NumOpenIssues}}gray{{else}}blue{{end}} small label">{{.Repository.NumOpenIssues}}</span>
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
 | 
					    {{end}}
 | 
				
			||||||
 | 
					    {{if .Repository.EnablePulls}}
 | 
				
			||||||
    <a class="{{if .PageIsPullList}}active{{end}} item" href="{{.RepoLink}}/pulls">
 | 
					    <a class="{{if .PageIsPullList}}active{{end}} item" href="{{.RepoLink}}/pulls">
 | 
				
			||||||
      <i class="icon octicon octicon-git-pull-request"></i> {{.i18n.Tr "repo.pulls"}} <span class="ui {{if not .Repository.NumOpenPulls}}gray{{else}}blue{{end}} small label">{{.Repository.NumOpenPulls}}</span>
 | 
					      <i class="icon octicon octicon-git-pull-request"></i> {{.i18n.Tr "repo.pulls"}} <span class="ui {{if not .Repository.NumOpenPulls}}gray{{else}}blue{{end}} small label">{{.Repository.NumOpenPulls}}</span>
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
 | 
					    {{end}}
 | 
				
			||||||
    <a class="{{if .PageIsCommits}}active{{end}} item" href="{{.RepoLink}}/commits/{{EscapePound .BranchName}}">
 | 
					    <a class="{{if .PageIsCommits}}active{{end}} item" href="{{.RepoLink}}/commits/{{EscapePound .BranchName}}">
 | 
				
			||||||
      <i class="icon octicon octicon-history"></i> {{.i18n.Tr "repo.commits"}} <span class="ui {{if not .CommitsCount}}gray{{else}}blue{{end}} small label">{{.CommitsCount}}</span>
 | 
					      <i class="icon octicon octicon-history"></i> {{.i18n.Tr "repo.commits"}} <span class="ui {{if not .CommitsCount}}gray{{else}}blue{{end}} small label">{{.CommitsCount}}</span>
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <a class="{{if .PageIsReleaseList}}active{{end}} item" href="{{.RepoLink}}/releases">
 | 
					    <a class="{{if .PageIsReleaseList}}active{{end}} item" href="{{.RepoLink}}/releases">
 | 
				
			||||||
      <i class="icon octicon octicon-tag"></i> {{.i18n.Tr "repo.releases"}} <span class="ui {{if not .Repository.NumTags}}gray{{else}}blue{{end}} small label">{{.Repository.NumTags}}</span>
 | 
					      <i class="icon octicon octicon-tag"></i> {{.i18n.Tr "repo.releases"}} <span class="ui {{if not .Repository.NumTags}}gray{{else}}blue{{end}} small label">{{.Repository.NumTags}}</span>
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
 | 
					    {{if .Repository.EnableWiki}}
 | 
				
			||||||
    <a class="{{if .PageIsWiki}}active{{end}} item" href="{{.RepoLink}}/wiki">
 | 
					    <a class="{{if .PageIsWiki}}active{{end}} item" href="{{.RepoLink}}/wiki">
 | 
				
			||||||
      <i class="icon octicon octicon-book"></i> {{.i18n.Tr "repo.wiki"}}
 | 
					      <i class="icon octicon octicon-book"></i> {{.i18n.Tr "repo.wiki"}}
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
 | 
					    {{end}}
 | 
				
			||||||
    {{if .IsRepositoryAdmin}}
 | 
					    {{if .IsRepositoryAdmin}}
 | 
				
			||||||
    <div class="right menu">
 | 
					    <div class="right menu">
 | 
				
			||||||
      <a class="{{if .PageIsSettings}}active{{end}} item" href="{{.RepoLink}}/settings">
 | 
					      <a class="{{if .PageIsSettings}}active{{end}} item" href="{{.RepoLink}}/settings">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
      <a class="link" href="{{.Repository.Website}}">{{.Repository.Website}}</a>
 | 
					      <a class="link" href="{{.Repository.Website}}">{{.Repository.Website}}</a>
 | 
				
			||||||
    </p>
 | 
					    </p>
 | 
				
			||||||
    <div class="ui secondary menu">
 | 
					    <div class="ui secondary menu">
 | 
				
			||||||
      {{if and .IsRepositoryAdmin .Repository.BaseRepo}}
 | 
					      {{if .CanPullRequest}}
 | 
				
			||||||
      <div class="fitted item">
 | 
					      <div class="fitted item">
 | 
				
			||||||
        {{ $baseRepo := .Repository.BaseRepo}}
 | 
					        {{ $baseRepo := .Repository.BaseRepo}}
 | 
				
			||||||
        <a href="{{AppSubUrl}}/{{$baseRepo.Owner.Name}}/{{$baseRepo.Name}}/compare/{{$.BaseDefaultBranch}}...{{$.Owner.Name}}:{{$.BranchName}}">
 | 
					        <a href="{{AppSubUrl}}/{{$baseRepo.Owner.Name}}/{{$baseRepo.Name}}/compare/{{$.BaseDefaultBranch}}...{{$.Owner.Name}}:{{$.BranchName}}">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,6 @@
 | 
				
			|||||||
					    <input id="website" name="website" type="url" value="{{.Repository.Website}}">
 | 
										    <input id="website" name="website" type="url" value="{{.Repository.Website}}">
 | 
				
			||||||
					  </div>
 | 
										  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					  <div class="ui divider"></div>
 | 
					 | 
				
			||||||
					  {{if not .Repository.IsBare}}
 | 
										  {{if not .Repository.IsBare}}
 | 
				
			||||||
					  <div class="required inline field">
 | 
										  <div class="required inline field">
 | 
				
			||||||
					    <label>{{.i18n.Tr "repo.default_branch"}}</label>
 | 
										    <label>{{.i18n.Tr "repo.default_branch"}}</label>
 | 
				
			||||||
@@ -58,12 +57,67 @@
 | 
				
			|||||||
					  </div>
 | 
										  </div>
 | 
				
			||||||
					  {{end}}
 | 
										  {{end}}
 | 
				
			||||||
					
 | 
										
 | 
				
			||||||
 | 
										  <div class="ui divider"></div>
 | 
				
			||||||
					  <div class="field">
 | 
										  <div class="field">
 | 
				
			||||||
					     <button class="ui green button">{{$.i18n.Tr "repo.settings.update_settings"}}</button>
 | 
										     <button class="ui green button">{{$.i18n.Tr "repo.settings.update_settings"}}</button>
 | 
				
			||||||
					  </div>
 | 
										  </div>
 | 
				
			||||||
					</form>
 | 
										</form>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <h4 class="ui top attached header">
 | 
				
			||||||
 | 
									  {{.i18n.Tr "repo.settings.advanced_settings"}}
 | 
				
			||||||
 | 
					        </h4>
 | 
				
			||||||
 | 
					        <div class="ui attached segment">
 | 
				
			||||||
 | 
					        	<form class="ui form" action="{{.Link}}" method="post">
 | 
				
			||||||
 | 
					        		{{.CsrfTokenHtml}}
 | 
				
			||||||
 | 
					      			<input type="hidden" name="action" value="advanced">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						          <div class="inline field">
 | 
				
			||||||
 | 
						            <label>{{.i18n.Tr "repo.wiki"}}</label>
 | 
				
			||||||
 | 
						            <div class="ui checkbox">
 | 
				
			||||||
 | 
						              <input name="enable_wiki" type="checkbox" {{if .Repository.EnableWiki}}checked{{end}}>
 | 
				
			||||||
 | 
						              <label>{{.i18n.Tr "repo.settings.wiki_desc"}}</label>
 | 
				
			||||||
 | 
						            </div>
 | 
				
			||||||
 | 
						          </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						        	<div class="ui divider"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						          <div class="inline field">
 | 
				
			||||||
 | 
						            <label>{{.i18n.Tr "repo.issues"}}</label>
 | 
				
			||||||
 | 
						            <div class="ui checkbox">
 | 
				
			||||||
 | 
						              <input name="enable_issues" type="checkbox" {{if .Repository.EnableIssues}}checked{{end}}>
 | 
				
			||||||
 | 
						              <label>{{.i18n.Tr "repo.settings.issues_desc"}}</label>
 | 
				
			||||||
 | 
						            </div>
 | 
				
			||||||
 | 
						          </div>
 | 
				
			||||||
 | 
						          <div class="inline field">
 | 
				
			||||||
 | 
						            <div class="ui checkbox">
 | 
				
			||||||
 | 
						              <input name="enable_external_tracker" type="checkbox" {{if .Repository.EnableExternalTracker}}checked{{end}}>
 | 
				
			||||||
 | 
						              <label>{{.i18n.Tr "repo.settings.use_external_issue_tracker"}}</label>
 | 
				
			||||||
 | 
						            </div>
 | 
				
			||||||
 | 
						          </div>
 | 
				
			||||||
 | 
						          <div class="field">
 | 
				
			||||||
 | 
										    <label for="tracker_url_format">{{.i18n.Tr "repo.settings.tracker_url_format"}}</label>
 | 
				
			||||||
 | 
										    <input id="tracker_url_format" name="tracker_url_format" value="{{.Repository.ExternalTrackerFormat}}" placeholder="e.g. https://github.com/{user}/{repo}/issues/{index}">
 | 
				
			||||||
 | 
										    <p class="help">{{.i18n.Tr "repo.settings.tracker_url_format_desc" | Str2html}}</p>
 | 
				
			||||||
 | 
						          </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						        	<div class="ui divider"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						          <div class="inline field">
 | 
				
			||||||
 | 
						          	<label>{{.i18n.Tr "repo.pulls"}}</label>
 | 
				
			||||||
 | 
						            <div class="ui checkbox">
 | 
				
			||||||
 | 
						              <input name="enable_pulls" type="checkbox" {{if .Repository.EnablePulls}}checked{{end}}>
 | 
				
			||||||
 | 
						              <label>{{.i18n.Tr "repo.settings.pulls_desc"}}</label>
 | 
				
			||||||
 | 
						            </div>
 | 
				
			||||||
 | 
						          </div>
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										  <div class="ui divider"></div>
 | 
				
			||||||
 | 
										  <div class="field">
 | 
				
			||||||
 | 
										     <button class="ui green button">{{$.i18n.Tr "repo.settings.update_settings"}}</button>
 | 
				
			||||||
 | 
										  </div>
 | 
				
			||||||
 | 
					        	</form>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <h4 class="ui top attached warning header">
 | 
					        <h4 class="ui top attached warning header">
 | 
				
			||||||
          {{.i18n.Tr "repo.settings.danger_zone"}}
 | 
					          {{.i18n.Tr "repo.settings.danger_zone"}}
 | 
				
			||||||
        </h4>
 | 
					        </h4>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user