mirror of https://github.com/go-gitea/gitea.git
Compare commits
16 Commits
76cb46dfbf
...
e8f902bd6f
| Author | SHA1 | Date |
|---|---|---|
|
|
e8f902bd6f | |
|
|
29b28002aa | |
|
|
618e2d8106 | |
|
|
485d8f1121 | |
|
|
181db69e0c | |
|
|
a46b16f10f | |
|
|
1748045285 | |
|
|
f114c388ff | |
|
|
94c6d46faa | |
|
|
7436c6297d | |
|
|
ddd1e6ca83 | |
|
|
0548c10293 | |
|
|
7de114a332 | |
|
|
9363b591ed | |
|
|
57ba66822a | |
|
|
a68e04c0e0 |
|
|
@ -653,7 +653,7 @@ func (repo *Repository) AllowsPulls(ctx context.Context) bool {
|
|||
|
||||
// CanEnableEditor returns true if repository meets the requirements of web editor.
|
||||
func (repo *Repository) CanEnableEditor() bool {
|
||||
return !repo.IsMirror
|
||||
return !repo.IsMirror && !repo.IsArchived
|
||||
}
|
||||
|
||||
// DescriptionHTML does special handles to description and return HTML string.
|
||||
|
|
|
|||
|
|
@ -831,6 +831,20 @@ type CountUserFilter struct {
|
|||
IsActive optional.Option[bool]
|
||||
}
|
||||
|
||||
// HasUsers checks whether there are any users in the database, or only one user exists.
|
||||
func HasUsers(ctx context.Context) (ret struct {
|
||||
HasAnyUser, HasOnlyOneUser bool
|
||||
}, err error,
|
||||
) {
|
||||
res, err := db.GetEngine(ctx).Table(&User{}).Cols("id").Limit(2).Query()
|
||||
if err != nil {
|
||||
return ret, fmt.Errorf("error checking user existence: %w", err)
|
||||
}
|
||||
ret.HasAnyUser = len(res) != 0
|
||||
ret.HasOnlyOneUser = len(res) == 1
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// CountUsers returns number of users.
|
||||
func CountUsers(ctx context.Context, opts *CountUserFilter) int64 {
|
||||
return countUsers(ctx, opts)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ package languagestats
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"code.gitea.io/gitea/modules/analyze"
|
||||
|
|
@ -20,8 +21,8 @@ import (
|
|||
"github.com/go-git/go-git/v5/plumbing/object"
|
||||
)
|
||||
|
||||
// GetLanguageStats calculates language stats for git repository at specified commit
|
||||
func GetLanguageStats(repo *git_module.Repository, commitID string) (map[string]int64, error) {
|
||||
// CalcLanguageStats calculates language stats for git repository at specified commit
|
||||
func CalcLanguageStats(ctx context.Context, repo *git_module.Repository, commitID string) (map[string]int64, error) {
|
||||
r, err := git.PlainOpen(repo.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -58,6 +59,13 @@ func GetLanguageStats(repo *git_module.Repository, commitID string) (map[string]
|
|||
firstExcludedLanguageSize := int64(0)
|
||||
|
||||
err = tree.Files().ForEach(func(f *object.File) error {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
if f.Size == 0 {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ package languagestats
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"code.gitea.io/gitea/modules/analyze"
|
||||
|
|
@ -18,8 +19,8 @@ import (
|
|||
"github.com/go-enry/go-enry/v2"
|
||||
)
|
||||
|
||||
// GetLanguageStats calculates language stats for git repository at specified commit
|
||||
func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64, error) {
|
||||
// CalcLanguageStats calculates language stats for git repository at specified commit
|
||||
func CalcLanguageStats(ctx context.Context, repo *git.Repository, commitID string) (map[string]int64, error) {
|
||||
// We will feed the commit IDs in order into cat-file --batch, followed by blobs as necessary.
|
||||
// so let's create a batch stdin and stdout
|
||||
batchStdinWriter, batchReader, cancel, err := repo.CatFileBatch(repo.Ctx)
|
||||
|
|
@ -59,11 +60,6 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
|
|||
|
||||
tree := commit.Tree
|
||||
|
||||
entries, err := tree.ListEntriesRecursiveWithSize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
checker, err := attribute.NewBatchChecker(repo, commitID, attribute.LinguistAttributes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -82,18 +78,12 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
|
|||
firstExcludedLanguage := ""
|
||||
firstExcludedLanguageSize := int64(0)
|
||||
|
||||
for _, f := range entries {
|
||||
select {
|
||||
case <-repo.Ctx.Done():
|
||||
return sizes, repo.Ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if err := tree.IterateEntriesRecursive(ctx, func(ctx context.Context, f *git.TreeEntry) error {
|
||||
contentBuf.Reset()
|
||||
content = contentBuf.Bytes()
|
||||
|
||||
if f.Size() == 0 {
|
||||
continue
|
||||
return nil
|
||||
}
|
||||
|
||||
isVendored := optional.None[bool]()
|
||||
|
|
@ -104,19 +94,19 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
|
|||
attrLinguistGenerated := optional.None[bool]()
|
||||
if err == nil {
|
||||
if isVendored = attrs.GetVendored(); isVendored.ValueOrDefault(false) {
|
||||
continue
|
||||
return nil
|
||||
}
|
||||
|
||||
if attrLinguistGenerated = attrs.GetGenerated(); attrLinguistGenerated.ValueOrDefault(false) {
|
||||
continue
|
||||
return nil
|
||||
}
|
||||
|
||||
if isDocumentation = attrs.GetDocumentation(); isDocumentation.ValueOrDefault(false) {
|
||||
continue
|
||||
return nil
|
||||
}
|
||||
|
||||
if isDetectable = attrs.GetDetectable(); !isDetectable.ValueOrDefault(true) {
|
||||
continue
|
||||
return nil
|
||||
}
|
||||
|
||||
if hasLanguage := attrs.GetLanguage(); hasLanguage.Value() != "" {
|
||||
|
|
@ -130,7 +120,7 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
|
|||
|
||||
// this language will always be added to the size
|
||||
sizes[language] += f.Size()
|
||||
continue
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -138,19 +128,19 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
|
|||
enry.IsDotFile(f.Name()) ||
|
||||
(!isDocumentation.Has() && enry.IsDocumentation(f.Name())) ||
|
||||
enry.IsConfiguration(f.Name()) {
|
||||
continue
|
||||
return nil
|
||||
}
|
||||
|
||||
// If content can not be read or file is too big just do detection by filename
|
||||
|
||||
if f.Size() <= bigFileSize {
|
||||
if err := writeID(f.ID.String()); err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
_, _, size, err := git.ReadBatchLine(batchReader)
|
||||
if err != nil {
|
||||
log.Debug("Error reading blob: %s Err: %v", f.ID.String(), err)
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
sizeToRead := size
|
||||
|
|
@ -162,11 +152,11 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
|
|||
|
||||
_, err = contentBuf.ReadFrom(io.LimitReader(batchReader, sizeToRead))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
content = contentBuf.Bytes()
|
||||
if err := git.DiscardFull(batchReader, discard); err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -178,14 +168,14 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
|
|||
isGenerated = enry.IsGenerated(f.Name(), content)
|
||||
}
|
||||
if isGenerated {
|
||||
continue
|
||||
return nil
|
||||
}
|
||||
|
||||
// FIXME: Why can't we split this and the IsGenerated tests to avoid reading the blob unless absolutely necessary?
|
||||
// - eg. do the all the detection tests using filename first before reading content.
|
||||
language := analyze.GetCodeLanguage(f.Name(), content)
|
||||
if language == "" {
|
||||
continue
|
||||
return nil
|
||||
}
|
||||
|
||||
// group languages, such as Pug -> HTML; SCSS -> CSS
|
||||
|
|
@ -206,6 +196,9 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
|
|||
firstExcludedLanguage = language
|
||||
firstExcludedLanguageSize += f.Size()
|
||||
}
|
||||
return nil
|
||||
}, git.TrustedCmdArgs{"--long"}); err != nil {
|
||||
return sizes, err
|
||||
}
|
||||
|
||||
// If there are no included languages add the first excluded language
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ func TestRepository_GetLanguageStats(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
defer gitRepo.Close()
|
||||
|
||||
stats, err := GetLanguageStats(gitRepo, "8fee858da5796dfb37704761701bb8e800ad9ef3")
|
||||
stats, err := CalcLanguageStats(t.Context(), gitRepo, "8fee858da5796dfb37704761701bb8e800ad9ef3")
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, map[string]int64{
|
||||
|
|
|
|||
|
|
@ -22,6 +22,13 @@ func ParseTreeEntries(data []byte) ([]*TreeEntry, error) {
|
|||
// parseTreeEntries FIXME this function's design is not right, it should not make the caller read all data into memory
|
||||
func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) {
|
||||
entries := make([]*TreeEntry, 0, bytes.Count(data, []byte{'\n'})+1)
|
||||
return entries, iterateTreeEntries(data, ptree, func(entry *TreeEntry) error {
|
||||
entries = append(entries, entry)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func iterateTreeEntries(data []byte, ptree *Tree, f func(entry *TreeEntry) error) error {
|
||||
for pos := 0; pos < len(data); {
|
||||
posEnd := bytes.IndexByte(data[pos:], '\n')
|
||||
if posEnd == -1 {
|
||||
|
|
@ -33,7 +40,7 @@ func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) {
|
|||
line := data[pos:posEnd]
|
||||
lsTreeLine, err := parseLsTreeLine(line)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
entry := &TreeEntry{
|
||||
ptree: ptree,
|
||||
|
|
@ -44,9 +51,11 @@ func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) {
|
|||
sized: lsTreeLine.Size.Has(),
|
||||
}
|
||||
pos = posEnd + 1
|
||||
entries = append(entries, entry)
|
||||
if err := f(entry); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return entries, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func catBatchParseTreeEntries(objectFormat ObjectFormat, ptree *Tree, rd *bufio.Reader, sz int64) ([]*TreeEntry, error) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
|
@ -122,3 +124,50 @@ func (t *Tree) ListEntriesRecursiveFast() (Entries, error) {
|
|||
func (t *Tree) ListEntriesRecursiveWithSize() (Entries, error) {
|
||||
return t.listEntriesRecursive(TrustedCmdArgs{"--long"})
|
||||
}
|
||||
|
||||
// IterateEntriesRecursive returns iterate entries of current tree recursively including all subtrees
|
||||
// extraArgs could be "-l" to get the size, which is slower
|
||||
func (t *Tree) IterateEntriesRecursive(ctx context.Context, f func(ctx context.Context, entry *TreeEntry) error, extraArgs TrustedCmdArgs) error {
|
||||
reader, writer := io.Pipe()
|
||||
done := make(chan error)
|
||||
|
||||
go func(t *Tree, done chan error, writer *io.PipeWriter) {
|
||||
runErr := NewCommand("ls-tree", "-t", "-r").
|
||||
AddArguments(extraArgs...).
|
||||
AddDynamicArguments(t.ID.String()).
|
||||
Run(ctx, &RunOpts{
|
||||
Dir: t.repo.Path,
|
||||
Stdout: writer,
|
||||
})
|
||||
|
||||
_ = writer.Close()
|
||||
|
||||
done <- runErr
|
||||
}(t, done, writer)
|
||||
|
||||
scanner := bufio.NewScanner(reader)
|
||||
for scanner.Scan() {
|
||||
if err := scanner.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data := scanner.Bytes()
|
||||
if err := iterateTreeEntries(data, t, func(entry *TreeEntry) error {
|
||||
if err := f(ctx, entry); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case runErr := <-done:
|
||||
return runErr
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ func (db *DBIndexer) Index(id int64) error {
|
|||
}
|
||||
|
||||
// Calculate and save language statistics to database
|
||||
stats, err := languagestats.GetLanguageStats(gitRepo, commitID)
|
||||
stats, err := languagestats.CalcLanguageStats(ctx, gitRepo, commitID)
|
||||
if err != nil {
|
||||
if !setting.IsInTesting {
|
||||
log.Error("Unable to get language stats for ID %s for default branch %s in %s. Error: %v", commitID, repo.DefaultBranch, repo.FullName(), err)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
package markup
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"io"
|
||||
"net/url"
|
||||
"regexp"
|
||||
|
|
@ -92,9 +93,9 @@ func (st *Sanitizer) createDefaultPolicy() *bluemonday.Policy {
|
|||
return policy
|
||||
}
|
||||
|
||||
// Sanitize takes a string that contains a HTML fragment or document and applies policy whitelist.
|
||||
func Sanitize(s string) string {
|
||||
return GetDefaultSanitizer().defaultPolicy.Sanitize(s)
|
||||
// Sanitize use default sanitizer policy to sanitize a string
|
||||
func Sanitize(s string) template.HTML {
|
||||
return template.HTML(GetDefaultSanitizer().defaultPolicy.Sanitize(s))
|
||||
}
|
||||
|
||||
// SanitizeReader sanitizes a Reader
|
||||
|
|
|
|||
|
|
@ -69,6 +69,6 @@ func TestSanitizer(t *testing.T) {
|
|||
}
|
||||
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
assert.Equal(t, testCases[i+1], Sanitize(testCases[i]))
|
||||
assert.Equal(t, testCases[i+1], string(Sanitize(testCases[i])))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,9 +176,9 @@ func safeHTML(s any) template.HTML {
|
|||
panic(fmt.Sprintf("unexpected type %T", s))
|
||||
}
|
||||
|
||||
// SanitizeHTML sanitizes the input by pre-defined markdown rules
|
||||
// SanitizeHTML sanitizes the input by default sanitization rules.
|
||||
func SanitizeHTML(s string) template.HTML {
|
||||
return template.HTML(markup.Sanitize(s))
|
||||
return markup.Sanitize(s)
|
||||
}
|
||||
|
||||
func htmlEscape(s any) template.HTML {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ package web
|
|||
import (
|
||||
"net/http"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
|
|
@ -36,11 +37,21 @@ func (g *RouterPathGroup) ServeHTTP(resp http.ResponseWriter, req *http.Request)
|
|||
g.r.chiRouter.NotFoundHandler().ServeHTTP(resp, req)
|
||||
}
|
||||
|
||||
type RouterPathGroupPattern struct {
|
||||
re *regexp.Regexp
|
||||
params []routerPathParam
|
||||
middlewares []any
|
||||
}
|
||||
|
||||
// MatchPath matches the request method, and uses regexp to match the path.
|
||||
// The pattern uses "<...>" to define path parameters, for example: "/<name>" (different from chi router)
|
||||
// It is only designed to resolve some special cases which chi router can't handle.
|
||||
// The pattern uses "<...>" to define path parameters, for example, "/<name>" (different from chi router)
|
||||
// It is only designed to resolve some special cases that chi router can't handle.
|
||||
// For most cases, it shouldn't be used because it needs to iterate all rules to find the matched one (inefficient).
|
||||
func (g *RouterPathGroup) MatchPath(methods, pattern string, h ...any) {
|
||||
g.MatchPattern(methods, g.PatternRegexp(pattern), h...)
|
||||
}
|
||||
|
||||
func (g *RouterPathGroup) MatchPattern(methods string, pattern *RouterPathGroupPattern, h ...any) {
|
||||
g.matchers = append(g.matchers, newRouterPathMatcher(methods, pattern, h...))
|
||||
}
|
||||
|
||||
|
|
@ -96,8 +107,8 @@ func isValidMethod(name string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func newRouterPathMatcher(methods, pattern string, h ...any) *routerPathMatcher {
|
||||
middlewares, handlerFunc := wrapMiddlewareAndHandler(nil, h)
|
||||
func newRouterPathMatcher(methods string, patternRegexp *RouterPathGroupPattern, h ...any) *routerPathMatcher {
|
||||
middlewares, handlerFunc := wrapMiddlewareAndHandler(patternRegexp.middlewares, h)
|
||||
p := &routerPathMatcher{methods: make(container.Set[string]), middlewares: middlewares, handlerFunc: handlerFunc}
|
||||
for method := range strings.SplitSeq(methods, ",") {
|
||||
method = strings.TrimSpace(method)
|
||||
|
|
@ -106,19 +117,25 @@ func newRouterPathMatcher(methods, pattern string, h ...any) *routerPathMatcher
|
|||
}
|
||||
p.methods.Add(method)
|
||||
}
|
||||
p.re, p.params = patternRegexp.re, patternRegexp.params
|
||||
return p
|
||||
}
|
||||
|
||||
func patternRegexp(pattern string, h ...any) *RouterPathGroupPattern {
|
||||
p := &RouterPathGroupPattern{middlewares: slices.Clone(h)}
|
||||
re := []byte{'^'}
|
||||
lastEnd := 0
|
||||
for lastEnd < len(pattern) {
|
||||
start := strings.IndexByte(pattern[lastEnd:], '<')
|
||||
if start == -1 {
|
||||
re = append(re, pattern[lastEnd:]...)
|
||||
re = append(re, regexp.QuoteMeta(pattern[lastEnd:])...)
|
||||
break
|
||||
}
|
||||
end := strings.IndexByte(pattern[lastEnd+start:], '>')
|
||||
if end == -1 {
|
||||
panic("invalid pattern: " + pattern)
|
||||
}
|
||||
re = append(re, pattern[lastEnd:lastEnd+start]...)
|
||||
re = append(re, regexp.QuoteMeta(pattern[lastEnd:lastEnd+start])...)
|
||||
partName, partExp, _ := strings.Cut(pattern[lastEnd+start+1:lastEnd+start+end], ":")
|
||||
lastEnd += start + end + 1
|
||||
|
||||
|
|
@ -140,7 +157,10 @@ func newRouterPathMatcher(methods, pattern string, h ...any) *routerPathMatcher
|
|||
p.params = append(p.params, param)
|
||||
}
|
||||
re = append(re, '$')
|
||||
reStr := string(re)
|
||||
p.re = regexp.MustCompile(reStr)
|
||||
p.re = regexp.MustCompile(string(re))
|
||||
return p
|
||||
}
|
||||
|
||||
func (g *RouterPathGroup) PatternRegexp(pattern string, h ...any) *RouterPathGroupPattern {
|
||||
return patternRegexp(pattern, h...)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func TestPathProcessor(t *testing.T) {
|
|||
testProcess := func(pattern, uri string, expectedPathParams map[string]string) {
|
||||
chiCtx := chi.NewRouteContext()
|
||||
chiCtx.RouteMethod = "GET"
|
||||
p := newRouterPathMatcher("GET", pattern, http.NotFound)
|
||||
p := newRouterPathMatcher("GET", patternRegexp(pattern), http.NotFound)
|
||||
assert.True(t, p.matchPath(chiCtx, uri), "use pattern %s to process uri %s", pattern, uri)
|
||||
assert.Equal(t, expectedPathParams, chiURLParamsToMap(chiCtx), "use pattern %s to process uri %s", pattern, uri)
|
||||
}
|
||||
|
|
@ -56,18 +56,20 @@ func TestRouter(t *testing.T) {
|
|||
recorder.Body = buff
|
||||
|
||||
type resultStruct struct {
|
||||
method string
|
||||
pathParams map[string]string
|
||||
handlerMark string
|
||||
method string
|
||||
pathParams map[string]string
|
||||
handlerMarks []string
|
||||
}
|
||||
var res resultStruct
|
||||
|
||||
var res resultStruct
|
||||
h := func(optMark ...string) func(resp http.ResponseWriter, req *http.Request) {
|
||||
mark := util.OptionalArg(optMark, "")
|
||||
return func(resp http.ResponseWriter, req *http.Request) {
|
||||
res.method = req.Method
|
||||
res.pathParams = chiURLParamsToMap(chi.RouteContext(req.Context()))
|
||||
res.handlerMark = mark
|
||||
if mark != "" {
|
||||
res.handlerMarks = append(res.handlerMarks, mark)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -77,6 +79,8 @@ func TestRouter(t *testing.T) {
|
|||
if stop := req.FormValue("stop"); stop != "" && (mark == "" || mark == stop) {
|
||||
h(stop)(resp, req)
|
||||
resp.WriteHeader(http.StatusOK)
|
||||
} else if mark != "" {
|
||||
res.handlerMarks = append(res.handlerMarks, mark)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +112,7 @@ func TestRouter(t *testing.T) {
|
|||
m.Delete("", h())
|
||||
})
|
||||
m.PathGroup("/*", func(g *RouterPathGroup) {
|
||||
g.MatchPath("GET", `/<dir:*>/<file:[a-z]{1,2}>`, stopMark("s2"), h("match-path"))
|
||||
g.MatchPattern("GET", g.PatternRegexp(`/<dir:*>/<file:[a-z]{1,2}>`, stopMark("s2")), stopMark("s3"), h("match-path"))
|
||||
}, stopMark("s1"))
|
||||
})
|
||||
})
|
||||
|
|
@ -126,31 +130,31 @@ func TestRouter(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("RootRouter", func(t *testing.T) {
|
||||
testRoute(t, "GET /the-user/the-repo/other", resultStruct{method: "GET", handlerMark: "not-found:/"})
|
||||
testRoute(t, "GET /the-user/the-repo/other", resultStruct{method: "GET", handlerMarks: []string{"not-found:/"}})
|
||||
testRoute(t, "GET /the-user/the-repo/pulls", resultStruct{
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "type": "pulls"},
|
||||
handlerMark: "list-issues-b",
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "type": "pulls"},
|
||||
handlerMarks: []string{"list-issues-b"},
|
||||
})
|
||||
testRoute(t, "GET /the-user/the-repo/issues/123", resultStruct{
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "type": "issues", "index": "123"},
|
||||
handlerMark: "view-issue",
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "type": "issues", "index": "123"},
|
||||
handlerMarks: []string{"view-issue"},
|
||||
})
|
||||
testRoute(t, "GET /the-user/the-repo/issues/123?stop=hijack", resultStruct{
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "type": "issues", "index": "123"},
|
||||
handlerMark: "hijack",
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "type": "issues", "index": "123"},
|
||||
handlerMarks: []string{"hijack"},
|
||||
})
|
||||
testRoute(t, "POST /the-user/the-repo/issues/123/update", resultStruct{
|
||||
method: "POST",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "index": "123"},
|
||||
handlerMark: "update-issue",
|
||||
method: "POST",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "index": "123"},
|
||||
handlerMarks: []string{"update-issue"},
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Sub Router", func(t *testing.T) {
|
||||
testRoute(t, "GET /api/v1/other", resultStruct{method: "GET", handlerMark: "not-found:/api/v1"})
|
||||
testRoute(t, "GET /api/v1/other", resultStruct{method: "GET", handlerMarks: []string{"not-found:/api/v1"}})
|
||||
testRoute(t, "GET /api/v1/repos/the-user/the-repo/branches", resultStruct{
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo"},
|
||||
|
|
@ -179,31 +183,37 @@ func TestRouter(t *testing.T) {
|
|||
|
||||
t.Run("MatchPath", func(t *testing.T) {
|
||||
testRoute(t, "GET /api/v1/repos/the-user/the-repo/branches/d1/d2/fn", resultStruct{
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "*": "d1/d2/fn", "dir": "d1/d2", "file": "fn"},
|
||||
handlerMark: "match-path",
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "*": "d1/d2/fn", "dir": "d1/d2", "file": "fn"},
|
||||
handlerMarks: []string{"s1", "s2", "s3", "match-path"},
|
||||
})
|
||||
testRoute(t, "GET /api/v1/repos/the-user/the-repo/branches/d1%2fd2/fn", resultStruct{
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "*": "d1%2fd2/fn", "dir": "d1%2fd2", "file": "fn"},
|
||||
handlerMark: "match-path",
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "*": "d1%2fd2/fn", "dir": "d1%2fd2", "file": "fn"},
|
||||
handlerMarks: []string{"s1", "s2", "s3", "match-path"},
|
||||
})
|
||||
testRoute(t, "GET /api/v1/repos/the-user/the-repo/branches/d1/d2/000", resultStruct{
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"reponame": "the-repo", "username": "the-user", "*": "d1/d2/000"},
|
||||
handlerMark: "not-found:/api/v1",
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"reponame": "the-repo", "username": "the-user", "*": "d1/d2/000"},
|
||||
handlerMarks: []string{"s1", "not-found:/api/v1"},
|
||||
})
|
||||
|
||||
testRoute(t, "GET /api/v1/repos/the-user/the-repo/branches/d1/d2/fn?stop=s1", resultStruct{
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "*": "d1/d2/fn"},
|
||||
handlerMark: "s1",
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "*": "d1/d2/fn"},
|
||||
handlerMarks: []string{"s1"},
|
||||
})
|
||||
|
||||
testRoute(t, "GET /api/v1/repos/the-user/the-repo/branches/d1/d2/fn?stop=s2", resultStruct{
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "*": "d1/d2/fn", "dir": "d1/d2", "file": "fn"},
|
||||
handlerMark: "s2",
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "*": "d1/d2/fn", "dir": "d1/d2", "file": "fn"},
|
||||
handlerMarks: []string{"s1", "s2"},
|
||||
})
|
||||
|
||||
testRoute(t, "GET /api/v1/repos/the-user/the-repo/branches/d1/d2/fn?stop=s3", resultStruct{
|
||||
method: "GET",
|
||||
pathParams: map[string]string{"username": "the-user", "reponame": "the-repo", "*": "d1/d2/fn", "dir": "d1/d2", "file": "fn"},
|
||||
handlerMarks: []string{"s1", "s2", "s3"},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1330,7 +1330,6 @@ editor.update=Aktualizovat %s
|
|||
editor.delete=Odstranit %s
|
||||
editor.patch=Použít záplatu
|
||||
editor.patching=Záplatování:
|
||||
editor.fail_to_apply_patch=Nelze použít záplatu „%s“
|
||||
editor.new_patch=Nová záplata
|
||||
editor.commit_message_desc=Přidat volitelný rozšířený popis…
|
||||
editor.signoff_desc=Přidat Signed-off-by podpis přispěvatele na konec zprávy o commitu.
|
||||
|
|
@ -1348,8 +1347,6 @@ editor.branch_already_exists=Větev „%s“ již existuje v tomto repozitáři.
|
|||
editor.directory_is_a_file=Jméno adresáře „%s“ je již použito jako jméno souboru v tomto repozitáři.
|
||||
editor.file_is_a_symlink=`„%s“ je symbolický odkaz. Symbolické odkazy nemohou být upravovány ve webovém editoru`
|
||||
editor.filename_is_a_directory=Jméno souboru „%s“ je již použito jako jméno adresáře v tomto repozitáři.
|
||||
editor.file_editing_no_longer_exists=Upravovaný soubor „%s“ již není součástí tohoto repozitáře.
|
||||
editor.file_deleting_no_longer_exists=Odstraňovaný soubor „%s“ již není součástí tohoto repozitáře.
|
||||
editor.file_changed_while_editing=Obsah souboru byl změněn od doby, kdy jste začaly s úpravou. <a target="_blank" rel="noopener noreferrer" href="%s">Klikněte zde</a>, abyste je zobrazili, nebo <strong>potvrďte změny ještě jednou</strong> pro jejich přepsání.
|
||||
editor.file_already_exists=Soubor „%s“ již existuje v tomto repozitáři.
|
||||
editor.commit_id_not_matching=ID commitu se neshoduje s ID, když jsi začal/a s úpravami. Odevzdat do záplatové větve a poté sloučit.
|
||||
|
|
@ -1357,8 +1354,6 @@ editor.push_out_of_date=Nahrání se zdá být zastaralé.
|
|||
editor.commit_empty_file_header=Odevzdat prázdný soubor
|
||||
editor.commit_empty_file_text=Soubor, který se chystáte odevzdat, je prázdný. Pokračovat?
|
||||
editor.no_changes_to_show=Žádné změny k zobrazení.
|
||||
editor.fail_to_update_file=Nepodařilo se aktualizovat/vytvořit soubor „%s“.
|
||||
editor.fail_to_update_file_summary=Chybové hlášení:
|
||||
editor.push_rejected_no_message=Změna byla serverem zamítnuta bez zprávy. Prosím, zkontrolujte háčky Gitu.
|
||||
editor.push_rejected=Změna byla serverem zamítnuta. Prosím, zkontrolujte háčky Gitu.
|
||||
editor.push_rejected_summary=Úplná zpráva o odmítnutí:
|
||||
|
|
@ -1373,6 +1368,7 @@ editor.require_signed_commit=Větev vyžaduje podepsaný commit
|
|||
editor.cherry_pick=Cherry-pick %s na:
|
||||
editor.revert=Vrátit %s na:
|
||||
|
||||
|
||||
commits.desc=Procházet historii změn zdrojového kódu.
|
||||
commits.commits=Commity
|
||||
commits.no_commits=Žádné společné commity. „%s“ a „%s“ mají zcela odlišnou historii.
|
||||
|
|
@ -2780,15 +2776,13 @@ settings.visibility.private_shortname=Soukromý
|
|||
|
||||
settings.update_settings=Upravit nastavení
|
||||
settings.update_setting_success=Nastavení organizace bylo upraveno.
|
||||
settings.change_orgname_prompt=Poznámka: Změna názvu organizace také změní adresu URL vaší organizace a uvolní staré jméno této organizace.
|
||||
settings.change_orgname_redirect_prompt=Staré jméno bude přesměrovávat, dokud nebude znovu obsazeno.
|
||||
|
||||
|
||||
settings.update_avatar_success=Avatar organizace byl aktualizován.
|
||||
settings.delete=Smazat organizaci
|
||||
settings.delete_account=Smazat tuto organizaci
|
||||
settings.delete_prompt=Organizace bude trvale odstraněna. Tato změna <strong>NEMŮŽE</strong> být vrácena!
|
||||
settings.confirm_delete_account=Potvrdit smazání
|
||||
settings.delete_org_title=Smazat organizaci
|
||||
settings.delete_org_desc=Tato organizace bude trvale smazána. Pokračovat?
|
||||
settings.hooks_desc=Přidat webové háčky, které budou spouštěny pro <strong>všechny repozitáře</strong> v této organizaci.
|
||||
|
||||
settings.labels_desc=Přidejte štítky, které mohou být použity pro úkoly <strong>všech repositářů</strong> v rámci této organizace.
|
||||
|
|
|
|||
|
|
@ -1352,7 +1352,6 @@ editor.update=%s aktualisiert
|
|||
editor.delete=%s gelöscht
|
||||
editor.patch=Patch anwenden
|
||||
editor.patching=Patche:
|
||||
editor.fail_to_apply_patch=Patch "%s" nicht anwendbar
|
||||
editor.new_patch=Neuer Patch
|
||||
editor.commit_message_desc=Eine ausführlichere (optionale) Beschreibung hinzufügen…
|
||||
editor.signoff_desc=Am Ende der Commit Nachricht einen Signed-off-by Anhang vom Committer hinzufügen.
|
||||
|
|
@ -1372,8 +1371,6 @@ editor.branch_already_exists=Branch "%s" existiert bereits in diesem Repository.
|
|||
editor.directory_is_a_file=Der Verzeichnisname "%s" wird bereits als Dateiname in diesem Repository verwendet.
|
||||
editor.file_is_a_symlink=`"%s" ist ein symbolischer Link. Symbolische Links können mit dem Web-Editor nicht bearbeitet werden`
|
||||
editor.filename_is_a_directory=Der Dateiname "%s" wird bereits als Verzeichnisname in diesem Repository verwendet.
|
||||
editor.file_editing_no_longer_exists=Die bearbeitete Datei "%s" existiert nicht mehr in diesem Repository.
|
||||
editor.file_deleting_no_longer_exists=Die zu löschende Datei "%s" existiert nicht mehr in diesem Repository.
|
||||
editor.file_changed_while_editing=Der Inhalt der Datei hat sich seit dem Beginn der Bearbeitung geändert. <a target="_blank" rel="noopener noreferrer" href="%s">Hier klicken</a>, um die Änderungen anzusehen, oder <strong>Änderungen erneut comitten</strong>, um sie zu überschreiben.
|
||||
editor.file_already_exists=Eine Datei mit dem Namen '%s' existiert bereits in diesem Repository.
|
||||
editor.commit_id_not_matching=Die Commit-ID stimmt nicht mit der ID überein, bei welcher du mit der Bearbeitung begonnen hast. Commite in einen Patch-Branch und merge daraufhin.
|
||||
|
|
@ -1381,8 +1378,6 @@ editor.push_out_of_date=Der Push scheint veraltet zu sein.
|
|||
editor.commit_empty_file_header=Leere Datei committen
|
||||
editor.commit_empty_file_text=Die Datei, die du commiten willst, ist leer. Fortfahren?
|
||||
editor.no_changes_to_show=Keine Änderungen vorhanden.
|
||||
editor.fail_to_update_file=Fehler beim Aktualisieren/Erstellen der Datei "%s".
|
||||
editor.fail_to_update_file_summary=Fehlermeldung:
|
||||
editor.push_rejected_no_message=Die Änderung wurde vom Server ohne Nachricht abgelehnt. Bitte überprüfe die Git Hooks.
|
||||
editor.push_rejected=Die Änderung wurde vom Server abgelehnt. Bitte überprüfe die Git Hooks.
|
||||
editor.push_rejected_summary=Vollständige Ablehnungsmeldung:
|
||||
|
|
@ -1397,6 +1392,7 @@ editor.require_signed_commit=Branch erfordert einen signierten Commit
|
|||
editor.cherry_pick=Cherry-Picke %s von:
|
||||
editor.revert=%s zurücksetzen auf:
|
||||
|
||||
|
||||
commits.desc=Durchsuche die Quellcode-Änderungshistorie.
|
||||
commits.commits=Commits
|
||||
commits.no_commits=Keine gemeinsamen Commits. "%s" und "%s" haben vollständig unterschiedliche Historien.
|
||||
|
|
@ -2829,15 +2825,13 @@ settings.visibility.private_shortname=Privat
|
|||
|
||||
settings.update_settings=Einstellungen speichern
|
||||
settings.update_setting_success=Organisationseinstellungen wurden aktualisiert.
|
||||
settings.change_orgname_prompt=Hinweis: Das Ändern des Organisationsnamens wird auch die URL deiner Organisation ändern und den alten Namen freigeben.
|
||||
settings.change_orgname_redirect_prompt=Der alte Name wird weiterleiten, bis er wieder beansprucht wird.
|
||||
|
||||
|
||||
settings.update_avatar_success=Der Organisationsavatar wurde aktualisiert.
|
||||
settings.delete=Organisation löschen
|
||||
settings.delete_account=Diese Organisation löschen
|
||||
settings.delete_prompt=Die Organisation wird dauerhaft gelöscht. Dies <strong>KANN NICHT</strong> rückgängig gemacht werden!
|
||||
settings.confirm_delete_account=Löschen bestätigen
|
||||
settings.delete_org_title=Organisation löschen
|
||||
settings.delete_org_desc=Diese Organisation wird dauerhaft gelöscht. Fortfahren?
|
||||
settings.hooks_desc=Webhooks hinzufügen, die für <strong>alle</strong> Repositories dieser Organisation ausgelöst werden.
|
||||
|
||||
settings.labels_desc=Labels hinzufügen, die für <strong>alle Repositories</strong> dieser Organisation genutzt werden können.
|
||||
|
|
|
|||
|
|
@ -1190,7 +1190,6 @@ editor.update=Ενημέρωση %s
|
|||
editor.delete=Διαγραφή %s
|
||||
editor.patch=Εφαρμογή Διόρθωσης
|
||||
editor.patching=Επιδιόρθωση:
|
||||
editor.fail_to_apply_patch=`Αδυναμία εφαρμογής της επιδιόρθωσης "%s"`
|
||||
editor.new_patch=Νέα Διόρθωση
|
||||
editor.commit_message_desc=Προσθήκη προαιρετικής εκτενούς περιγραφής…
|
||||
editor.signoff_desc=Προσθέστε ένα πρόσθετο Signed-off-by στο τέλος του μηνύματος καταγραφής της υποβολής.
|
||||
|
|
@ -1208,15 +1207,11 @@ editor.branch_already_exists=Ο κλάδος "%s" υπάρχει ήδη σε α
|
|||
editor.directory_is_a_file=Το όνομα φακέλου "%s" χρησιμοποιείται ήδη ως όνομα αρχείου σε αυτό το αποθετήριο.
|
||||
editor.file_is_a_symlink=`Το "%s" είναι συμβολικός σύνδεσμος. Οι συμβολικοί σύνδεσμοι δεν μπορούν να επεξεργαστούν στην ενσωματωμένη εφαρμογή`
|
||||
editor.filename_is_a_directory=Το όνομα αρχείου "%s" χρησιμοποιείται ήδη ως όνομα φακέλου σε αυτό το αποθετήριο.
|
||||
editor.file_editing_no_longer_exists=Το αρχείο "%s" που επεξεργάζεται, δεν υπάρχει πλέον σε αυτό το αποθετήριο.
|
||||
editor.file_deleting_no_longer_exists=Το αρχείο "%s" που διαγράφεται, δεν υπάρχει πλέον σε αυτό το αποθετήριο.
|
||||
editor.file_changed_while_editing=Τα περιεχόμενα του αρχείου άλλαξαν από τότε που ξεκίνησε η επεξεργασία. <a target="_blank" rel="noopener noreferrer" href="%s">Κάντε κλικ εδώ</a> για να τα δείτε ή <strong>Υποβολή Αλλαγών ξανά</strong> για να τα αντικαταστήσετε.
|
||||
editor.file_already_exists=Ένα αρχείο με το όνομα "%s" υπάρχει ήδη σε αυτό το αποθετήριο.
|
||||
editor.commit_empty_file_header=Υποβολή ενός κενού αρχείου
|
||||
editor.commit_empty_file_text=Το αρχείο που πρόκειται να υποβληθεί είναι κενό. Συνέχεια;
|
||||
editor.no_changes_to_show=Δεν υπάρχουν αλλαγές για εμφάνιση.
|
||||
editor.fail_to_update_file=Αποτυχία ενημέρωσης/δημιουργίας του αρχείου "%s".
|
||||
editor.fail_to_update_file_summary=Μήνυμα Σφάλματος:
|
||||
editor.push_rejected_no_message=Η αλλαγή απορρίφθηκε από το διακομιστή χωρίς κάποιο μήνυμα. Παρακαλώ ελέγξτε τα Άγκιστρα Git.
|
||||
editor.push_rejected=Η αλλαγή απορρίφθηκε από τον διακομιστή. Παρακαλώ ελέγξτε τα Άγκιστρα Git.
|
||||
editor.push_rejected_summary=Μήνυμα Πλήρους Απόρριψης:
|
||||
|
|
@ -1231,6 +1226,7 @@ editor.require_signed_commit=Ο κλάδος απαιτεί υπογεγραμμ
|
|||
editor.cherry_pick=Ανθολόγηση (cherry-pic) του %s στο:
|
||||
editor.revert=Απόσυρση του %s στο:
|
||||
|
||||
|
||||
commits.desc=Δείτε το ιστορικό αλλαγών του πηγαίου κώδικα.
|
||||
commits.commits=Υποβολές
|
||||
commits.no_commits=Δεν υπάρχουν κοινές υποβολές. Τα "%s" και "%s" έχουν εντελώς διαφορετικές ιστορίες.
|
||||
|
|
@ -2505,15 +2501,13 @@ settings.visibility.private_shortname=Ιδιωτικός
|
|||
|
||||
settings.update_settings=Ενημέρωση Ρυθμίσεων
|
||||
settings.update_setting_success=Οι ρυθμίσεις του οργανισμού έχουν ενημερωθεί.
|
||||
settings.change_orgname_prompt=Σημείωση: Η αλλαγή του ονόματος του οργανισμού θα αλλάξει επίσης τη διεύθυνση URL του οργανισμού σας και θα απελευθερώσει το παλιό όνομα.
|
||||
settings.change_orgname_redirect_prompt=Το παλιό όνομα θα ανακατευθύνει μέχρι να διεκδικηθεί.
|
||||
|
||||
|
||||
settings.update_avatar_success=Η εικόνα του οργανισμού έχει ενημερωθεί.
|
||||
settings.delete=Διαγραφή Οργανισμού
|
||||
settings.delete_account=Διαγραφή Αυτού Του Οργανισμού
|
||||
settings.delete_prompt=Ο οργανισμός θα αφαιρεθεί οριστικά. Αυτό το <strong>ΔΕΝ ΜΠΟΡΕΙ</strong> να αναιρεθεί!
|
||||
settings.confirm_delete_account=Επιβεβαίωση Διαγραφής
|
||||
settings.delete_org_title=Διαγραφή Οργανισμού
|
||||
settings.delete_org_desc=Αυτός ο οργανισμός θα διαγραφεί οριστικά. Συνέχεια;
|
||||
settings.hooks_desc=Προσθήκη webhooks που θα ενεργοποιούνται για <strong>όλα τα αποθετήρια</strong> κάτω από αυτό τον οργανισμό.
|
||||
|
||||
settings.labels_desc=Προσθήκη σημάτων που μπορούν να χρησιμοποιηθούν σε ζητήματα για <strong>όλα τα αποθετήρια</strong> κάτω από αυτό τον οργανισμό.
|
||||
|
|
|
|||
|
|
@ -421,6 +421,7 @@ remember_me.compromised = The login token is not valid anymore which may indicat
|
|||
forgot_password_title= Forgot Password
|
||||
forgot_password = Forgot password?
|
||||
need_account = Need an account?
|
||||
sign_up_tip = You are registering the first account in the system, which has administrator privileges. Please carefully remember your username and password. If you forget the username or password, please refer to the Gitea documentation to recover the account.
|
||||
sign_up_now = Register now.
|
||||
sign_up_successful = Account was successfully created. Welcome!
|
||||
confirmation_mail_sent_prompt_ex = A new confirmation email has been sent to <b>%s</b>. Please check your inbox within the next %s to complete the registration process. If your registration email address is incorrect, you can sign in again and change it.
|
||||
|
|
@ -1398,6 +1399,13 @@ editor.revert = Revert %s onto:
|
|||
editor.failed_to_commit = Failed to commit changes.
|
||||
editor.failed_to_commit_summary = Error Message:
|
||||
|
||||
editor.fork_create = Fork Repository to Propose Changes
|
||||
editor.fork_create_description = You can not edit this repository directly. Instead you can create a fork, make edits and create a pull request.
|
||||
editor.fork_edit_description = You can not edit this repository directly. The changes will be written to your fork <b>%s</b>, so you can create a pull request.
|
||||
editor.fork_not_editable = You have forked this repository but your fork is not editable.
|
||||
editor.fork_failed_to_push_branch = Failed to push branch %s to your repository.
|
||||
editor.fork_branch_exists = Branch "%s" already exists in your fork, please choose a new branch name.
|
||||
|
||||
commits.desc = Browse source code change history.
|
||||
commits.commits = Commits
|
||||
commits.no_commits = No commits in common. "%s" and "%s" have entirely different histories.
|
||||
|
|
@ -2811,6 +2819,7 @@ team_permission_desc = Permission
|
|||
team_unit_desc = Allow Access to Repository Sections
|
||||
team_unit_disabled = (Disabled)
|
||||
|
||||
form.name_been_taken = The organisation name "%s" has already been taken.
|
||||
form.name_reserved = The organization name "%s" is reserved.
|
||||
form.name_pattern_not_allowed = The pattern "%s" is not allowed in an organization name.
|
||||
form.create_org_not_allowed = You are not allowed to create an organization.
|
||||
|
|
@ -2832,15 +2841,28 @@ settings.visibility.private_shortname = Private
|
|||
|
||||
settings.update_settings = Update Settings
|
||||
settings.update_setting_success = Organization settings have been updated.
|
||||
settings.change_orgname_prompt = Note: Changing the organization name will also change your organization's URL and free the old name.
|
||||
settings.change_orgname_redirect_prompt = The old name will redirect until it is claimed.
|
||||
|
||||
settings.rename = Rename Organization
|
||||
settings.rename_desc = Changing the organization name will also change your organization's URL and free the old name.
|
||||
settings.rename_success = Organization %[1]s have been renamed to %[2]s successfully.
|
||||
settings.rename_no_change = Organization name is no change.
|
||||
settings.rename_new_org_name = New Organization Name
|
||||
settings.rename_failed = Rename Organization failed because of internal error
|
||||
settings.rename_notices_1 = This operation <strong>CANNOT</strong> be undone.
|
||||
settings.rename_notices_2 = The old name will redirect until it is claimed.
|
||||
|
||||
settings.update_avatar_success = The organization's avatar has been updated.
|
||||
settings.delete = Delete Organization
|
||||
settings.delete_account = Delete This Organization
|
||||
settings.delete_prompt = The organization will be permanently removed. This <strong>CANNOT</strong> be undone!
|
||||
settings.name_confirm = Enter the organization name as confirmation:
|
||||
settings.delete_notices_1 = This operation <strong>CANNOT</strong> be undone.
|
||||
settings.delete_notices_2 = This operation will permanently delete all the <strong>repositories</strong> of <strong>%s</strong> including code, issues, comments, wiki data and collaborator settings.
|
||||
settings.delete_notices_3 = This operation will permanently delete all the <strong>packages</strong> of <strong>%s</strong>.
|
||||
settings.delete_notices_4 = This operation will permanently delete all the <strong>projects</strong> of <strong>%s</strong>.
|
||||
settings.confirm_delete_account = Confirm Deletion
|
||||
settings.delete_org_title = Delete Organization
|
||||
settings.delete_org_desc = This organization will be deleted permanently. Continue?
|
||||
settings.delete_failed = Delete Organization failed because of internal error
|
||||
settings.delete_successful = Organization <b>%s</b> has been deleted successfully.
|
||||
settings.hooks_desc = Add webhooks which will be triggered for <strong>all repositories</strong> under this organization.
|
||||
|
||||
settings.labels_desc = Add labels which can be used on issues for <strong>all repositories</strong> under this organization.
|
||||
|
|
@ -3817,6 +3839,7 @@ runs.no_runs = The workflow has no runs yet.
|
|||
runs.empty_commit_message = (empty commit message)
|
||||
runs.expire_log_message = Logs have been purged because they were too old.
|
||||
runs.delete = Delete workflow run
|
||||
runs.cancel = Cancel workflow run
|
||||
runs.delete.description = Are you sure you want to permanently delete this workflow run? This action cannot be undone.
|
||||
runs.not_done = This workflow run is not done.
|
||||
runs.view_workflow_file = View workflow file
|
||||
|
|
|
|||
|
|
@ -1180,7 +1180,6 @@ editor.update=Actualizar %s
|
|||
editor.delete=Eliminar %s
|
||||
editor.patch=Aplicar parche
|
||||
editor.patching=Parcheando:
|
||||
editor.fail_to_apply_patch=`No se puede aplicar el parche "%s"`
|
||||
editor.new_patch=Nuevo parche
|
||||
editor.commit_message_desc=Añadir una descripción extendida opcional…
|
||||
editor.signoff_desc=Añadir un trailer firmado por el committer al final del mensaje de registro de confirmación.
|
||||
|
|
@ -1198,15 +1197,11 @@ editor.branch_already_exists=La rama "%s" ya existe en este repositorio.
|
|||
editor.directory_is_a_file=Nombre del directorio "%s" ya se utiliza como nombre de archivo en este repositorio.
|
||||
editor.file_is_a_symlink=`"%s" es un enlace simbólico. Los enlaces simbólicos no se pueden editar en el editor web`
|
||||
editor.filename_is_a_directory=Nombre de archivo "%s" ya se utiliza como nombre de directorio en este repositorio.
|
||||
editor.file_editing_no_longer_exists=El archivo que se está editando, "%s", ya no existe en este repositorio.
|
||||
editor.file_deleting_no_longer_exists=El archivo que se está eliminando, "%s", ya no existe en este repositorio.
|
||||
editor.file_changed_while_editing=Desde que comenzó a editar, el contenido del archivo ha sido cambiado. <a target="_blank" rel="noopener noreferrer" href="%s">Haga clic aquí</a> para ver qué ha cambiado o <strong>presione confirmar de nuevo</strong> para sobrescribir los cambios.
|
||||
editor.file_already_exists=Ya existe un archivo llamado "%s" en este repositorio.
|
||||
editor.commit_empty_file_header=Commit un archivo vacío
|
||||
editor.commit_empty_file_text=El archivo que estás tratando de commit está vacío. ¿Proceder?
|
||||
editor.no_changes_to_show=No existen cambios para mostrar.
|
||||
editor.fail_to_update_file=Error al actualizar/crear el archivo "%s".
|
||||
editor.fail_to_update_file_summary=Mensaje de error
|
||||
editor.push_rejected_no_message=El cambio fue rechazado por el servidor sin un mensaje. Por favor, compruebe Git Hooks.
|
||||
editor.push_rejected=El cambio fue rechazado por el servidor. Por favor, comprueba los Git Hooks.
|
||||
editor.push_rejected_summary=Mensaje completo de rechazo
|
||||
|
|
@ -1221,6 +1216,7 @@ editor.require_signed_commit=Esta rama requiere un commit firmado
|
|||
editor.cherry_pick=Hacer Cherry-pick %s en:
|
||||
editor.revert=Revertir %s en:
|
||||
|
||||
|
||||
commits.desc=Ver el historial de cambios de código fuente.
|
||||
commits.commits=Commits
|
||||
commits.no_commits=No hay commits en común. "%s" y "%s" tienen historias totalmente diferentes.
|
||||
|
|
@ -2487,15 +2483,13 @@ settings.visibility.private_shortname=Privado
|
|||
|
||||
settings.update_settings=Actualizar configuración
|
||||
settings.update_setting_success=Configuración de la organización se han actualizado.
|
||||
settings.change_orgname_prompt=Nota: Cambiar el nombre de la organización también cambiará la URL de su organización y liberará el nombre antiguo.
|
||||
settings.change_orgname_redirect_prompt=El nombre antiguo se redirigirá hasta que se reclame.
|
||||
|
||||
|
||||
settings.update_avatar_success=Se ha actualizado el avatar de la organización.
|
||||
settings.delete=Eliminar organización
|
||||
settings.delete_account=Eliminar esta organización
|
||||
settings.delete_prompt=La organización será eliminada permanentemente. ¡Esta acción <strong>NO PUEDE</strong> deshacerse!
|
||||
settings.confirm_delete_account=Confirmar eliminación
|
||||
settings.delete_org_title=Eliminar organización
|
||||
settings.delete_org_desc=Esta organización se eliminará permanentemente. ¿Continuar?
|
||||
settings.hooks_desc=Añadir webhooks que serán ejecutados para <strong>todos los repositorios</strong> de esta organización.
|
||||
|
||||
settings.labels_desc=Añadir etiquetas que pueden ser utilizadas en problemas para <strong>todos los repositorios</strong> bajo esta organización.
|
||||
|
|
|
|||
|
|
@ -943,13 +943,13 @@ editor.file_changed_while_editing=محتوای پرونده تغییر میکن
|
|||
editor.commit_empty_file_header=کامیت کردن یک پرونده خالی
|
||||
editor.commit_empty_file_text=فایلی که درخواست ارسال دارید خالی است. ادامه بدم?
|
||||
editor.no_changes_to_show=تغییری برای نمایش وجود ندارد.
|
||||
editor.fail_to_update_file_summary=متن خطا:
|
||||
editor.push_rejected_summary=متن کامل پیام دلیل رد شدن:
|
||||
editor.add_subdir=افزودن پوشه…
|
||||
editor.no_commit_to_branch=نمیتوان به طور مستقیم درمورد شاخه نطر داد زیرا:
|
||||
editor.user_no_push_to_branch=کاربر نمیتواند به شاخه ارسال کند
|
||||
editor.require_signed_commit=شاخه یک کامیت امضا شده لازم دارد
|
||||
|
||||
|
||||
commits.desc=تاریخچه تغییرات کد منبع را مرور کنید.
|
||||
commits.commits=کامیتها
|
||||
commits.nothing_to_compare=این شاخه ها برابرند.
|
||||
|
|
@ -1920,14 +1920,13 @@ settings.visibility.private_shortname=پوشیده
|
|||
|
||||
settings.update_settings=به روزرسانی تنظیمات
|
||||
settings.update_setting_success=تنظیمات این سازمان بهروز شد.
|
||||
settings.change_orgname_redirect_prompt=نام قدیمی تا زمانی که ادعا شود تغییر مسیر می دهد.
|
||||
|
||||
|
||||
settings.update_avatar_success=آواتار این سازمان بهروز شد.
|
||||
settings.delete=حذف سازمان
|
||||
settings.delete_account=حذف این سازمان
|
||||
settings.delete_prompt=سازمان برای همیشه حذف خواهد شد. این قابل برگشت <strong>نخواهد بود</strong>!
|
||||
settings.confirm_delete_account=تاییدیه حذف
|
||||
settings.delete_org_title=حذف سازمان
|
||||
settings.delete_org_desc=سازمان برای همیشه حذف خواهد شد. آیا همچنان ادامه میدهید؟
|
||||
settings.hooks_desc=افزودن webhook های که برای<strong> تمام مخازن</strong> این سازمان اجرا میشود.
|
||||
|
||||
settings.labels_desc=تگ هایی را اضافه کنید که میتوانند برای مشکلات <strong>همه مخازن</strong> تحت این سازمان استفاده شوند.
|
||||
|
|
|
|||
|
|
@ -764,6 +764,7 @@ editor.no_changes_to_show=Ei muutoksia näytettäväksi.
|
|||
editor.add_subdir=Lisää hakemisto…
|
||||
editor.require_signed_commit=Haara vaatii vahvistetun commitin
|
||||
|
||||
|
||||
commits.commits=Commitit
|
||||
commits.nothing_to_compare=Nämä haarat vastaavat toisiaan.
|
||||
commits.search_all=Kaikki haarat
|
||||
|
|
@ -1318,11 +1319,12 @@ settings.visibility.private=Yksityinen (näkyvä vain organisaation jäsenille)
|
|||
settings.visibility.private_shortname=Yksityinen
|
||||
|
||||
settings.update_settings=Päivitä asetukset
|
||||
|
||||
|
||||
settings.delete=Poista organisaatio
|
||||
settings.delete_account=Poista tämä organisaatio
|
||||
settings.delete_prompt=Organisaatio poistetaan pysyvästi, ja tätä <strong>EI VOI</strong> peruuttaa myöhemmin!
|
||||
settings.confirm_delete_account=Vahvista poisto
|
||||
settings.delete_org_title=Poista organisaatio
|
||||
settings.hooks_desc=Lisää webkoukkuja, jotka suoritetaan <strong>kaikissa repoissa</strong> tässä organisaatiossa.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1354,7 +1354,6 @@ editor.update=Actualiser %s
|
|||
editor.delete=Supprimer %s
|
||||
editor.patch=Appliquer le correctif
|
||||
editor.patching=Correction:
|
||||
editor.fail_to_apply_patch=`Impossible d'appliquer le correctif "%s"`
|
||||
editor.new_patch=Nouveau correctif
|
||||
editor.commit_message_desc=Ajouter une description détaillée facultative…
|
||||
editor.signoff_desc=Créditer l'auteur "Signed-off-by:" en pied de révision.
|
||||
|
|
@ -1374,8 +1373,6 @@ editor.branch_already_exists=La branche "%s" existe déjà dans ce dépôt.
|
|||
editor.directory_is_a_file=Le nom de dossier "%s" est déjà utilisé comme nom de fichier dans ce dépôt.
|
||||
editor.file_is_a_symlink=`« %s » est un lien symbolique. Ce type de fichiers ne peut être modifié dans l'éditeur web.`
|
||||
editor.filename_is_a_directory=« %s » est déjà utilisé comme nom de dossier dans ce dépôt.
|
||||
editor.file_editing_no_longer_exists=Impossible de modifier le fichier « %s » car il n’existe plus dans ce dépôt.
|
||||
editor.file_deleting_no_longer_exists=Impossible de supprimer le fichier « %s » car il n’existe plus dans ce dépôt.
|
||||
editor.file_changed_while_editing=Le contenu du fichier a changé depuis que vous avez commencé à éditer. <a target="_blank" rel="noopener noreferrer" href="%s">Cliquez ici</a> pour voir les changements ou <strong>soumettez de nouveau</strong> pour les écraser.
|
||||
editor.file_already_exists=Un fichier nommé "%s" existe déjà dans ce dépôt.
|
||||
editor.commit_id_not_matching=L’ID de la révision ne correspond pas à l’ID lorsque vous avez commencé à éditer. Faites une révision dans une branche de correctif puis fusionnez.
|
||||
|
|
@ -1383,8 +1380,6 @@ editor.push_out_of_date=Cet envoi semble être obsolète.
|
|||
editor.commit_empty_file_header=Réviser un fichier vide
|
||||
editor.commit_empty_file_text=Le fichier que vous allez réviser est vide. Continuer ?
|
||||
editor.no_changes_to_show=Il n’y a aucune modification à afficher.
|
||||
editor.fail_to_update_file=Impossible de mettre à jour/créer le fichier "%s".
|
||||
editor.fail_to_update_file_summary=Message d'erreur :
|
||||
editor.push_rejected_no_message=La modification a été rejetée par le serveur sans message. Veuillez vérifier les Git Hooks.
|
||||
editor.push_rejected=La modification a été rejetée par le serveur. Veuillez vérifier vos Git Hooks.
|
||||
editor.push_rejected_summary=Message de rejet complet :
|
||||
|
|
@ -1399,6 +1394,7 @@ editor.require_signed_commit=Cette branche nécessite une révision signée
|
|||
editor.cherry_pick=Picorer %s vers:
|
||||
editor.revert=Rétablir %s sur:
|
||||
|
||||
|
||||
commits.desc=Naviguer dans l'historique des modifications.
|
||||
commits.commits=Révisions
|
||||
commits.no_commits=Pas de révisions en commun. "%s" et "%s" ont des historiques entièrement différents.
|
||||
|
|
@ -1654,6 +1650,7 @@ issues.save=Enregistrer
|
|||
issues.label_title=Nom du label
|
||||
issues.label_description=Description du label
|
||||
issues.label_color=Couleur du label
|
||||
issues.label_color_invalid=Couleur invalide
|
||||
issues.label_exclusive=Exclusif
|
||||
issues.label_archive=Archivé
|
||||
issues.label_archived_filter=Afficher les labels archivés
|
||||
|
|
@ -2830,15 +2827,13 @@ settings.visibility.private_shortname=Privé
|
|||
|
||||
settings.update_settings=Appliquer les paramètres
|
||||
settings.update_setting_success=Les paramètres de l'organisation ont été mis à jour.
|
||||
settings.change_orgname_prompt=Remarque : Changer le nom de l'organisation changera également l'URL de votre organisation et libèrera l'ancien nom.
|
||||
settings.change_orgname_redirect_prompt=L'ancien nom d'utilisateur redirigera jusqu'à ce qu'il soit réclamé.
|
||||
|
||||
|
||||
settings.update_avatar_success=L'avatar de l'organisation a été mis à jour.
|
||||
settings.delete=Supprimer l'organisation
|
||||
settings.delete_account=Supprimer cette organisation
|
||||
settings.delete_prompt=Cette organisation sera supprimée définitivement. Cette action est <strong>IRRÉVERSIBLE</strong> !
|
||||
settings.confirm_delete_account=Confirmer la suppression
|
||||
settings.delete_org_title=Supprimer l'organisation
|
||||
settings.delete_org_desc=Cette organisation sera supprimée définitivement. Voulez-vous continuer ?
|
||||
settings.hooks_desc=Vous pouvez ajouter des webhooks qui seront activés pour <strong>tous les dépôts</strong> de cette organisation.
|
||||
|
||||
settings.labels_desc=Ajoute des labels qui peuvent être utilisés sur les tickets pour <strong>tous les dépôts</strong> de cette organisation.
|
||||
|
|
|
|||
|
|
@ -421,6 +421,7 @@ remember_me.compromised=Níl an comhartha logála isteach bailí níos mó a d'f
|
|||
forgot_password_title=Dearmad ar an bPasfhocal
|
||||
forgot_password=Dearmad ar an bPasfhocal?
|
||||
need_account=An bhfuil cuntas ag teastáil uait?
|
||||
sign_up_tip=Tá tú ag clárú an chéad chuntais sa chóras, a bhfuil pribhléidí riarthóra aige. Cuimhnigh go cúramach ar d’ainm úsáideora agus do phasfhocal. Má dhéanann tú dearmad ar an ainm úsáideora nó ar an pasfhocal, féach ar dhoiciméadacht Gitea le do thoil chun an cuntas a aisghabháil.
|
||||
sign_up_now=Cláraigh anois.
|
||||
sign_up_successful=Cruthaíodh cuntas go rathúil. Fáilte romhat!
|
||||
confirmation_mail_sent_prompt_ex=Tá ríomhphost dearbhaithe nua seolta chuig <b>%s</b>. Seiceáil do bhosca isteach laistigh den chéad %s eile chun an próiseas clárúcháin a chur i gcrích. Má tá do sheoladh ríomhphoist clárúcháin mícheart, is féidir leat síniú isteach arís agus é a athrú.
|
||||
|
|
@ -1354,7 +1355,6 @@ editor.update=Nuashonraigh %s
|
|||
editor.delete=Scrios %s
|
||||
editor.patch=Cuir paiste i bhfeidh
|
||||
editor.patching=Paisteáil:
|
||||
editor.fail_to_apply_patch=Ní féidir paiste "%s" a chur i bhfeidhm
|
||||
editor.new_patch=Paiste Nua
|
||||
editor.commit_message_desc=Cuir cur síos leathnaithe roghnach leis…
|
||||
editor.signoff_desc=Cuir leantóir sínithe ag an gcoiteoir ag deireadh na teachtaireachta logála tiomanta.
|
||||
|
|
@ -1374,8 +1374,7 @@ editor.branch_already_exists=Tá brainse "%s" ann cheana féin sa stóras seo.
|
|||
editor.directory_is_a_file=Úsáidtear ainm eolaire "%s" cheana féin mar ainm comhaid sa stóras seo.
|
||||
editor.file_is_a_symlink=Is nasc siombalach é "%s". Ní féidir naisc shiombalacha a chur in eagar san eagarthóir gréasáin
|
||||
editor.filename_is_a_directory=Úsáidtear ainm comhaid "%s" cheana féin mar ainm eolaire sa stóras seo.
|
||||
editor.file_editing_no_longer_exists=Níl an comhad atá á chur in eagar, "%s", ann sa stóras seo a thuilleadh.
|
||||
editor.file_deleting_no_longer_exists=Níl an comhad atá á scriosadh, "%s", ann sa stóras seo a thuilleadh.
|
||||
editor.file_modifying_no_longer_exists=Níl an comhad atá á mhodhnú, "%s", sa stóras seo a thuilleadh.
|
||||
editor.file_changed_while_editing=Tá athrú tagtha ar ábhar an chomhad ó thosaigh tú ag eagarthóireacht <a target="_blank" rel="noopener noreferrer" href="%s">Cliceáil anseo</a> chun iad a fheiceáil nó Athru <strong>ithe a Tiomantas arís</strong> chun iad a fhorscríobh.
|
||||
editor.file_already_exists=Tá comhad darb ainm "%s" ann cheana féin sa stóras seo.
|
||||
editor.commit_id_not_matching=Ní mheaitseálann an ID Tiomanta leis an ID nuair a thosaigh tú ag eagarthóireacht. Tiomanta isteach i mbrainse paiste agus ansin cumaisc.
|
||||
|
|
@ -1383,8 +1382,6 @@ editor.push_out_of_date=Is cosúil go bhfuil an brú as dáta.
|
|||
editor.commit_empty_file_header=Tiomantas comhad folamh
|
||||
editor.commit_empty_file_text=Tá an comhad atá tú ar tí tiomantas folamh. Ar aghaidh?
|
||||
editor.no_changes_to_show=Níl aon athruithe le taispeáint.
|
||||
editor.fail_to_update_file=Theip ar nuashonrú/cruthú comhad "%s".
|
||||
editor.fail_to_update_file_summary=Teachtaireacht Earráide:
|
||||
editor.push_rejected_no_message=Dhiúltaigh an freastalaí an t-athrú gan teachtaireacht. Seiceáil Git Hooks le do thoil.
|
||||
editor.push_rejected=Dhiúltaigh an freastalaí an t-athrú. Seiceáil Git Hooks le do thoil.
|
||||
editor.push_rejected_summary=Teachtaireacht Diúltaithe Iomlán:
|
||||
|
|
@ -1398,6 +1395,9 @@ editor.user_no_push_to_branch=Ní féidir leis an úsáideoir brúigh go dtí an
|
|||
editor.require_signed_commit=Éilíonn an Brainse tiomantas sínithe
|
||||
editor.cherry_pick=Roghnaigh silíní %s ar:
|
||||
editor.revert=Fill %s ar:
|
||||
editor.failed_to_commit=Theip ar athruithe a chur i bhfeidhm.
|
||||
editor.failed_to_commit_summary=Teachtaireacht Earráide:
|
||||
|
||||
|
||||
commits.desc=Brabhsáil stair athraithe cód foinse.
|
||||
commits.commits=Tiomáintí
|
||||
|
|
@ -2403,6 +2403,8 @@ settings.event_pull_request_review_request_desc=Tarraing athbhreithniú iarratai
|
|||
settings.event_pull_request_approvals=Ceaduithe Iarratais Tarraing
|
||||
settings.event_pull_request_merge=Cumaisc Iarratas Tarraing
|
||||
settings.event_header_workflow=Imeachtaí Sreabhadh Oibre
|
||||
settings.event_workflow_run=Rith Sreabhadh Oibre
|
||||
settings.event_workflow_run_desc=Tá rith Sreabhadh Oibre Gníomhartha Gitea sa scuaine, ag fanacht, ar siúl, nó críochnaithe.
|
||||
settings.event_workflow_job=Poist Sreabhadh Oibre
|
||||
settings.event_workflow_job_desc=Gitea Actions Sreabhadh oibre post ciúáilte, ag fanacht, ar siúl, nó críochnaithe.
|
||||
settings.event_package=Pacáiste
|
||||
|
|
@ -2810,6 +2812,7 @@ team_permission_desc=Cead
|
|||
team_unit_desc=Ceadaigh Rochtain ar Rannóga Stóras
|
||||
team_unit_disabled=(Díchumasaithe)
|
||||
|
||||
form.name_been_taken=Tá ainm na heagraíochta "%s" tógtha cheana féin.
|
||||
form.name_reserved=Tá an t-ainm eagraíochta "%s" curtha in áirithe.
|
||||
form.name_pattern_not_allowed=Ní cheadaítear an patrún "%s" in ainm eagraíochta.
|
||||
form.create_org_not_allowed=Níl cead agat eagraíocht a chruthú.
|
||||
|
|
@ -2831,15 +2834,28 @@ settings.visibility.private_shortname=Príobháideach
|
|||
|
||||
settings.update_settings=Nuashonrú Socruithe
|
||||
settings.update_setting_success=Nuashonraíodh socruithe eagraíochta.
|
||||
settings.change_orgname_prompt=Nóta: Athróidh ainm na heagraíochta ag athrú URL d'eagraíochta agus saorfar an sean-ainm.
|
||||
settings.change_orgname_redirect_prompt=Déanfaidh an sean-ainm a atreorú go dtí go n-éilítear é.
|
||||
|
||||
settings.rename=Athainmnigh an Eagraíocht
|
||||
settings.rename_desc=Má athraíonn tú ainm na heagraíochta, athrófar URL d’eagraíochta freisin agus saorfar an seanainm.
|
||||
settings.rename_success=Athainmníodh an eagraíocht %[1]s go %[2]s go rathúil.
|
||||
settings.rename_no_change=Níl aon athrú ar ainm na heagraíochta.
|
||||
settings.rename_new_org_name=Ainm Nua na hEagraíochta
|
||||
settings.rename_failed=Theip ar athainmniú na hEagraíochta mar gheall ar earráid inmheánach
|
||||
settings.rename_notices_1=NÍ <strong>FÉIDIR</strong> an oibríocht seo a chealú.
|
||||
settings.rename_notices_2=Déanfar an seanainm a atreorú go dtí go n-éileofar é.
|
||||
|
||||
settings.update_avatar_success=Nuashonraíodh avatar na heagraíochta.
|
||||
settings.delete=Scrios Eagraíocht
|
||||
settings.delete_account=Scrios an Eagraíocht seo
|
||||
settings.delete_prompt=Bainfear an eagraíocht go buan. <strong>NÍ FÉIDIR</strong> é seo a chealú!
|
||||
settings.name_confirm=Cuir isteach ainm na heagraíochta mar dheimhniú:
|
||||
settings.delete_notices_1=NÍ <strong>FÉIDIR</strong> an oibríocht seo a chealú.
|
||||
settings.delete_notices_2=Scriosfaidh an oibríocht seo go buan gach <strong>stórais</strong> de chuid <strong>%s</strong>, lena n-áirítear cód, saincheisteanna, tuairimí, sonraí vicí agus socruithe comhoibritheora.
|
||||
settings.delete_notices_3=Scriosfaidh an oibríocht seo gach <strong>pacáiste</strong> de chuid <strong>%s</strong> go buan.
|
||||
settings.delete_notices_4=Scriosfaidh an oibríocht seo gach <strong>tionscadal</strong> de chuid <strong>%s</strong> go buan.
|
||||
settings.confirm_delete_account=Deimhnigh scriosadh
|
||||
settings.delete_org_title=Scrios Eagraíocht
|
||||
settings.delete_org_desc=Scriosfar an eagraíocht seo go buan. Lean ar aghaidh?
|
||||
settings.delete_failed=Theip ar Scriosadh na hEagraíochta mar gheall ar earráid inmheánach
|
||||
settings.delete_successful=Scriosadh an eagraíocht <b>%s</b> go rathúil.
|
||||
settings.hooks_desc=Cuir crúcaí gréasán in leis a spreagfar do <strong>gach stóras</strong> faoin eagraíocht seo.
|
||||
|
||||
settings.labels_desc=Cuir lipéid leis ar féidir iad a úsáid ar shaincheisteanna do <strong>gach stóras</strong> faoin eagraíocht seo.
|
||||
|
|
|
|||
|
|
@ -711,6 +711,7 @@ editor.commit_empty_file_header=Egy üres fájl commitolása
|
|||
editor.no_changes_to_show=Nincsen megjeleníthető változás.
|
||||
editor.add_subdir=Mappa hozzáadása…
|
||||
|
||||
|
||||
commits.commits=Commit-ok
|
||||
commits.search_all=Minden ág
|
||||
commits.author=Szerző
|
||||
|
|
@ -1174,13 +1175,13 @@ settings.visibility.private_shortname=Privát
|
|||
|
||||
settings.update_settings=Beállítások frissítése
|
||||
settings.update_setting_success=A szervezet beállításai frissültek.
|
||||
|
||||
|
||||
settings.update_avatar_success=A szervezet avatarja frissítve.
|
||||
settings.delete=Szervezet törlése
|
||||
settings.delete_account=A szervezet törlése
|
||||
settings.delete_prompt=A szervezet véglegesen el lesz távolítva. <strong>NEM</strong> vonható vissza!
|
||||
settings.confirm_delete_account=Törlés megerősítése
|
||||
settings.delete_org_title=Szervezet törlése
|
||||
settings.delete_org_desc=Ez a szervezet véglegesen törölve lesz. Folytatható?
|
||||
settings.hooks_desc=Webhook hozzáadása a szervezet <strong>összes tárolójához</strong>.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -717,6 +717,7 @@ editor.new_branch_name_desc=Nama branch baru…
|
|||
editor.cancel=Membatalkan
|
||||
editor.no_changes_to_show=Tidak ada perubahan untuk ditampilkan.
|
||||
|
||||
|
||||
commits.commits=Melakukan
|
||||
commits.author=Penulis
|
||||
commits.message=Pesan
|
||||
|
|
@ -1055,10 +1056,11 @@ settings.visibility.private_shortname=Pribadi
|
|||
|
||||
settings.update_settings=Perbarui Setelan
|
||||
settings.update_setting_success=Pengaturan organisasi telah diperbarui.
|
||||
|
||||
|
||||
settings.delete=Menghapus Organisasi
|
||||
settings.delete_account=Menghapus Organisasi Ini
|
||||
settings.confirm_delete_account=Konfirmasi Penghapusan
|
||||
settings.delete_org_title=Menghapus Organisasi
|
||||
settings.hooks_desc=Tambahkan webhooks yang akan dipicu untuk <strong>semua repositori</strong> di bawah organisasi ini.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -689,7 +689,7 @@ editor.create_new_branch=Búðu til <strong>nýja grein</strong> og sameiningarb
|
|||
editor.create_new_branch_np=Búðu til <strong>nýja grein</strong> fyrir þetta framlag.
|
||||
editor.new_branch_name_desc=Heiti nýjar greinar…
|
||||
editor.cancel=Hætta við
|
||||
editor.fail_to_update_file_summary=Villuskilaboð:
|
||||
|
||||
|
||||
commits.commits=Framlög
|
||||
commits.author=Höfundur
|
||||
|
|
@ -1118,6 +1118,8 @@ settings.visibility.private_shortname=Einka
|
|||
settings.update_settings=Uppfæra Stillingar
|
||||
|
||||
|
||||
|
||||
|
||||
members.private=Faldir
|
||||
members.owner=Eigandi
|
||||
members.member=Meðlimur
|
||||
|
|
|
|||
|
|
@ -1014,7 +1014,6 @@ editor.file_changed_while_editing=I contenuti di questo file hanno subito dei ca
|
|||
editor.commit_empty_file_header=Commit di un file vuoto
|
||||
editor.commit_empty_file_text=Il file che stai per effettuare il commit è vuoto. Procedere?
|
||||
editor.no_changes_to_show=Non ci sono cambiamenti da mostrare.
|
||||
editor.fail_to_update_file_summary=Messaggio d'errore:
|
||||
editor.push_rejected_no_message=La modifica è stata rifiutata dal server senza un messaggio. Controlla Git Hooks.
|
||||
editor.push_rejected=La modifica è stata rifiutata dal server. Controlla Git Hooks.
|
||||
editor.push_rejected_summary=Messaggio Di Rifiuto Completo:
|
||||
|
|
@ -1025,6 +1024,7 @@ editor.require_signed_commit=Il branch richiede un commit firmato
|
|||
editor.cherry_pick=Cherry-pick %s suto:
|
||||
editor.revert=Ripristina %s su:
|
||||
|
||||
|
||||
commits.desc=Sfoglia la cronologia di modifiche del codice rogente.
|
||||
commits.commits=Commit
|
||||
commits.nothing_to_compare=Questi rami sono uguali.
|
||||
|
|
@ -2078,14 +2078,13 @@ settings.visibility.private_shortname=Privato
|
|||
|
||||
settings.update_settings=Aggiorna Impostazioni
|
||||
settings.update_setting_success=Le impostazioni dell'organizzazione sono state aggiornate.
|
||||
settings.change_orgname_redirect_prompt=Il vecchio nome reindirizzerà fino a quando non sarà richiesto.
|
||||
|
||||
|
||||
settings.update_avatar_success=L'avatar dell'organizzazione è stato aggiornato.
|
||||
settings.delete=Elimina organizzazione
|
||||
settings.delete_account=Elimina questa organizzazione
|
||||
settings.delete_prompt=L'organizzazione verrà rimossa definitivamente. Questa operazione <strong>NON PUÒ</strong> essere annullata!
|
||||
settings.confirm_delete_account=Conferma Eliminazione
|
||||
settings.delete_org_title=Elimina organizzazione
|
||||
settings.delete_org_desc=Questa organizzazione verrà eliminata definitivamente. Continuare?
|
||||
settings.hooks_desc=Aggiungi i webhooks che verranno attivati per <strong>tutti i repository</strong> sotto questa organizzazione.
|
||||
|
||||
settings.labels_desc=Aggiungi i webhooks che verranno attivati per <strong>tutti i repository</strong> sotto questa organizzazione.
|
||||
|
|
|
|||
|
|
@ -421,6 +421,7 @@ remember_me.compromised=ログイントークンはもう有効ではなく、
|
|||
forgot_password_title=パスワードを忘れた
|
||||
forgot_password=パスワードをお忘れですか?
|
||||
need_account=アカウントが必要ですか?
|
||||
sign_up_tip=管理者権限を持つ、このシステムの最初のアカウントを登録しようとしています。 ユーザー名とパスワードをよく覚えておいてください。 ユーザー名またはパスワードを忘れた場合は、Giteaのドキュメントを参照してアカウントを復元してください。
|
||||
sign_up_now=登録はこちら。
|
||||
sign_up_successful=アカウントは無事に作成されました。ようこそ!
|
||||
confirmation_mail_sent_prompt_ex=新しい確認メールを <b>%s</b> に送信しました。 %s以内にメールボックスを確認し、登録手続きを完了してください。 登録メールアドレスが間違っている場合は、もういちどサインインすると変更することができます。
|
||||
|
|
@ -1332,7 +1333,9 @@ editor.upload_file=ファイルをアップロード
|
|||
editor.edit_file=ファイルを編集
|
||||
editor.preview_changes=変更をプレビュー
|
||||
editor.cannot_edit_lfs_files=LFSのファイルはWebインターフェースで編集できません。
|
||||
editor.cannot_edit_too_large_file=このファイルは大きすぎるため、編集できません。
|
||||
editor.cannot_edit_non_text_files=バイナリファイルはWebインターフェースで編集できません。
|
||||
editor.file_not_editable_hint=名前の変更や移動は可能です。
|
||||
editor.edit_this_file=ファイルを編集
|
||||
editor.this_file_locked=ファイルはロックされています
|
||||
editor.must_be_on_a_branch=このファイルを変更したり変更の提案をするには、ブランチ上にいる必要があります。
|
||||
|
|
@ -1352,7 +1355,7 @@ editor.update=%s を更新
|
|||
editor.delete=%s を削除
|
||||
editor.patch=パッチの適用
|
||||
editor.patching=パッチ:
|
||||
editor.fail_to_apply_patch=`パッチを適用できません "%s"`
|
||||
editor.fail_to_apply_patch=パッチを適用できません
|
||||
editor.new_patch=新しいパッチ
|
||||
editor.commit_message_desc=詳細な説明を追加…
|
||||
editor.signoff_desc=コミットログメッセージの最後にコミッターの Signed-off-by 行を追加
|
||||
|
|
@ -1372,8 +1375,7 @@ editor.branch_already_exists=ブランチ "%s" は、このリポジトリに既
|
|||
editor.directory_is_a_file=ディレクトリ名 "%s" はすでにリポジトリ内のファイルで使用されています。
|
||||
editor.file_is_a_symlink=`"%s" はシンボリックリンクです。 シンボリックリンクはWebエディターで編集できません。`
|
||||
editor.filename_is_a_directory=ファイル名 "%s" は、このリポジトリ上でディレクトリ名としてすでに使用されています。
|
||||
editor.file_editing_no_longer_exists=編集中のファイル "%s" が、もうリポジトリ内にありません。
|
||||
editor.file_deleting_no_longer_exists=削除しようとしたファイル "%s" が、すでにリポジトリ内にありません。
|
||||
editor.file_modifying_no_longer_exists=修正中のファイル "%s" が、すでにリポジトリ内にありません。
|
||||
editor.file_changed_while_editing=あなたが編集を開始したあと、ファイルの内容が変更されました。 <a target="_blank" rel="noopener noreferrer" href="%s">ここをクリック</a>して何が変更されたか確認するか、<strong>もう一度"変更をコミット"をクリック</strong>して上書きします。
|
||||
editor.file_already_exists=ファイル "%s" は、このリポジトリに既に存在します。
|
||||
editor.commit_id_not_matching=コミットIDが編集を開始したときのIDと一致しません。 パッチ用のブランチにコミットしたあとマージしてください。
|
||||
|
|
@ -1381,8 +1383,6 @@ editor.push_out_of_date=このプッシュは最新ではないようです。
|
|||
editor.commit_empty_file_header=空ファイルのコミット
|
||||
editor.commit_empty_file_text=コミットしようとしているファイルは空です。 続行しますか?
|
||||
editor.no_changes_to_show=表示する変更箇所はありません。
|
||||
editor.fail_to_update_file=ファイル "%s" を作成または変更できませんでした。
|
||||
editor.fail_to_update_file_summary=エラーメッセージ:
|
||||
editor.push_rejected_no_message=サーバーがメッセージを出さずに変更を拒否しました。 Git フックを確認してください。
|
||||
editor.push_rejected=サーバーが変更を拒否しました。 Gitフックを確認してください。
|
||||
editor.push_rejected_summary=拒否メッセージ全体:
|
||||
|
|
@ -1396,6 +1396,9 @@ editor.user_no_push_to_branch=ユーザーはブランチにプッシュでき
|
|||
editor.require_signed_commit=ブランチでは署名されたコミットが必須です
|
||||
editor.cherry_pick=チェリーピック %s:
|
||||
editor.revert=リバート %s:
|
||||
editor.failed_to_commit=変更のコミットに失敗しました。
|
||||
editor.failed_to_commit_summary=エラーメッセージ:
|
||||
|
||||
|
||||
commits.desc=ソースコードの変更履歴を参照します。
|
||||
commits.commits=コミット
|
||||
|
|
@ -1560,6 +1563,7 @@ issues.filter_user_placeholder=ユーザーを検索
|
|||
issues.filter_user_no_select=すべてのユーザー
|
||||
issues.filter_type=タイプ
|
||||
issues.filter_type.all_issues=すべてのイシュー
|
||||
issues.filter_type.all_pull_requests=すべてのプルリクエスト
|
||||
issues.filter_type.assigned_to_you=自分が担当
|
||||
issues.filter_type.created_by_you=自分が作成
|
||||
issues.filter_type.mentioning_you=自分が関係
|
||||
|
|
@ -1651,6 +1655,7 @@ issues.save=保存
|
|||
issues.label_title=名前
|
||||
issues.label_description=説明
|
||||
issues.label_color=カラー
|
||||
issues.label_color_invalid=無効な色です
|
||||
issues.label_exclusive=排他
|
||||
issues.label_archive=アーカイブ ラベル
|
||||
issues.label_archived_filter=アーカイブされたラベルを表示
|
||||
|
|
@ -2399,6 +2404,8 @@ settings.event_pull_request_review_request_desc=プルリクエストのレビ
|
|||
settings.event_pull_request_approvals=プルリクエストの承認
|
||||
settings.event_pull_request_merge=プルリクエストのマージ
|
||||
settings.event_header_workflow=ワークフローイベント
|
||||
settings.event_workflow_run=ワークフロー実行
|
||||
settings.event_workflow_run_desc=Gitea Actions のワークフロー実行が、キューに追加、待機中、実行中、完了になったとき。
|
||||
settings.event_workflow_job=ワークフロージョブ
|
||||
settings.event_workflow_job_desc=Gitea Actions のワークフロージョブが、キューに追加、待機中、実行中、完了になったとき。
|
||||
settings.event_package=パッケージ
|
||||
|
|
@ -2806,6 +2813,7 @@ team_permission_desc=権限
|
|||
team_unit_desc=リポジトリのセクションへのアクセスを許可
|
||||
team_unit_disabled=(無効)
|
||||
|
||||
form.name_been_taken=組織名 "%s" は既に使用されています。
|
||||
form.name_reserved=組織名 "%s" は予約されています。
|
||||
form.name_pattern_not_allowed=`"%s" の形式は組織名に使用できません。`
|
||||
form.create_org_not_allowed=組織を作成する権限がありません。
|
||||
|
|
@ -2827,15 +2835,28 @@ settings.visibility.private_shortname=プライベート
|
|||
|
||||
settings.update_settings=設定の更新
|
||||
settings.update_setting_success=組織の設定を更新しました。
|
||||
settings.change_orgname_prompt=注意: 組織名を変更すると組織のURLも変更され、古い名前は解放されます。
|
||||
settings.change_orgname_redirect_prompt=古い名前は、再使用されていない限りリダイレクトします。
|
||||
|
||||
settings.rename=組織名の変更
|
||||
settings.rename_desc=組織名を変更すると組織のURLも変更され、古い名前は解放されます。
|
||||
settings.rename_success=組織 %[1]s の %[2]s への改名に成功しました。
|
||||
settings.rename_no_change=組織名の変更はありません。
|
||||
settings.rename_new_org_name=新しい組織名
|
||||
settings.rename_failed=内部エラーのため組織名を変更できませんでした
|
||||
settings.rename_notices_1=この操作は<strong>元に戻せません</strong> 。
|
||||
settings.rename_notices_2=古い名前は、再使用されるまではリダイレクトします。
|
||||
|
||||
settings.update_avatar_success=組織のアバターを更新しました。
|
||||
settings.delete=組織を削除
|
||||
settings.delete_account=この組織を削除
|
||||
settings.delete_prompt=組織は恒久的に削除されます。 元に戻すことは<strong>できません</strong>!
|
||||
settings.name_confirm=確認のため組織名を入力:
|
||||
settings.delete_notices_1=この操作は<strong>元に戻せません</strong> 。
|
||||
settings.delete_notices_2=この操作により、<strong>%s</strong>のすべての<strong>リポジトリ</strong>が恒久的に削除されます。 コード、イシュー、コメント、Wikiデータ、共同作業者の設定も含まれます。
|
||||
settings.delete_notices_3=この操作により、<strong>%s</strong>のすべての<strong>パッケージ</strong>が恒久的に削除されます。
|
||||
settings.delete_notices_4=この操作により、<strong>%s</strong>のすべての<strong>プロジェクト</strong>が恒久的に削除されます。
|
||||
settings.confirm_delete_account=削除を確認
|
||||
settings.delete_org_title=組織の削除
|
||||
settings.delete_org_desc=組織を恒久的に削除します。 続行しますか?
|
||||
settings.delete_failed=内部エラーのため組織を削除できませんでした
|
||||
settings.delete_successful=組織の<b>%s</b>の削除に成功しました。
|
||||
settings.hooks_desc=この組織の<strong>すべてのリポジトリ</strong>でトリガーされるWebhookを追加します。
|
||||
|
||||
settings.labels_desc=この組織の<strong>すべてのリポジトリ</strong>で使用可能なイシューラベルを追加します。
|
||||
|
|
|
|||
|
|
@ -648,6 +648,7 @@ editor.filename_cannot_be_empty=파일명이 빈칸입니다.
|
|||
editor.no_changes_to_show=표시할 변경사항이 없습니다.
|
||||
editor.add_subdir=경로 추가...
|
||||
|
||||
|
||||
commits.desc=소스 코드 변경 내역 탐색
|
||||
commits.commits=커밋
|
||||
commits.search_all=모든 브랜치
|
||||
|
|
@ -1151,12 +1152,12 @@ settings.visibility.private_shortname=비공개
|
|||
|
||||
settings.update_settings=설정 업데이트
|
||||
settings.update_setting_success=조직 설정이 변경되었습니다.
|
||||
|
||||
|
||||
settings.update_avatar_success=조직의 아바타가 갱신되었습니다.
|
||||
settings.delete=조직 삭제
|
||||
settings.delete_account=이 조직을 삭제합니다.
|
||||
settings.confirm_delete_account=삭제 승인
|
||||
settings.delete_org_title=조직 삭제
|
||||
settings.delete_org_desc=이 조직이 영구히 삭제됩니다. 계속 하시겠습니까?
|
||||
|
||||
|
||||
members.membership_visibility=회원 표시:
|
||||
|
|
|
|||
|
|
@ -1196,7 +1196,6 @@ editor.update=Atjaunot %s
|
|||
editor.delete=Dzēst %s
|
||||
editor.patch=Pielietot ielāpu
|
||||
editor.patching=Pielieto ielāpu:
|
||||
editor.fail_to_apply_patch=`Neizdevās pielietot ielāpu "%s"`
|
||||
editor.new_patch=Jauns ielāps
|
||||
editor.commit_message_desc=Pievienot neobligātu paplašinātu aprakstu…
|
||||
editor.signoff_desc=Pievienot revīzijas žurnāla ziņojuma beigās Signed-off-by ar revīzijas autoru.
|
||||
|
|
@ -1214,15 +1213,11 @@ editor.branch_already_exists=Atzars "%s" šajā repozitorijā jau eksistē.
|
|||
editor.directory_is_a_file=Direktorijas nosaukums "%s" vecāka ceļā ir fails nevis direktorija šajā repozitorijā.
|
||||
editor.file_is_a_symlink=Fails "%s" ir norāde, kuru nav iespējams labot no tīmekļa redaktora
|
||||
editor.filename_is_a_directory=Faila nosaukums "%s" sakrīt ar direktorijas nosaukumu šajā repozitorijā.
|
||||
editor.file_editing_no_longer_exists=Fails "%s", ko labojat, vairs neeksistē šajā repozitorijā.
|
||||
editor.file_deleting_no_longer_exists=Fails "%s", ko dzēšat, vairs neeksistē šajā repozitorijā.
|
||||
editor.file_changed_while_editing=Faila saturs ir mainījies kopš sākāt to labot. Noklikšķiniet <a target="_blank" rel="noopener noreferrer" href="%s">šeit</a>, lai apskatītu, vai <strong>Nosūtiet izmaiņas atkārtoti</strong>, lai pārrakstītu.
|
||||
editor.file_already_exists=Fails ar nosaukumu "%s" šajā repozitorijā jau eksistē.
|
||||
editor.commit_empty_file_header=Iesūtīt tukšu failu
|
||||
editor.commit_empty_file_text=Fails, ko vēlaties iesūtīt, ir tukšs. Vai turpināt?
|
||||
editor.no_changes_to_show=Nav izmaiņu, ko rādīt.
|
||||
editor.fail_to_update_file=Neizdevās atjaunot/izveidot failu "%s".
|
||||
editor.fail_to_update_file_summary=Kļūdas ziņojums:
|
||||
editor.push_rejected_no_message=Izmaiņu iesūtīšana tika noraidīta, bet serveris neatgrieza paziņojumu. Pārbaudiet git āķus šim repozitorijam.
|
||||
editor.push_rejected=Serveris noraidīja šo izmaiņu. Pārbaudiet git āķus.
|
||||
editor.push_rejected_summary=Pilns noraidīšanas ziņojums:
|
||||
|
|
@ -1237,6 +1232,7 @@ editor.require_signed_commit=Atzarā var iesūtīt tikai parakstītas revīzijas
|
|||
editor.cherry_pick=Izlasīt %s uz:
|
||||
editor.revert=Atgriezt %s uz:
|
||||
|
||||
|
||||
commits.desc=Pārlūkot pirmkoda izmaiņu vēsturi.
|
||||
commits.commits=Revīzijas
|
||||
commits.no_commits=Nav kopīgu revīziju. Atzariem "%s" un "%s" ir pilnībā atšķirīga izmaiņu vēsture.
|
||||
|
|
@ -2509,15 +2505,13 @@ settings.visibility.private_shortname=Privāta
|
|||
|
||||
settings.update_settings=Mainīt iestatījumus
|
||||
settings.update_setting_success=Organizācijas iestatījumi tika saglabāti.
|
||||
settings.change_orgname_prompt=Piezīme: organizācijas nosaukuma maiņa izmainīs arī organizācijas URL un atbrīvos veco nosaukumu.
|
||||
settings.change_orgname_redirect_prompt=Vecais vārds pārsūtīs uz jauno, kamēr vien tas nebūs izmantots.
|
||||
|
||||
|
||||
settings.update_avatar_success=Organizācijas attēls tika saglabāts.
|
||||
settings.delete=Dzēst organizāciju
|
||||
settings.delete_account=Dzēst šo organizāciju
|
||||
settings.delete_prompt=Šī darbība pilnībā dzēsīs šo organizāciju, kā arī tā ir <strong>NEATGRIEZENISKA</strong>!
|
||||
settings.confirm_delete_account=Apstiprināt dzēšanu
|
||||
settings.delete_org_title=Dzēst organizāciju
|
||||
settings.delete_org_desc=Organizācija tiks dzēsta neatgriezeniski. Vai turpināt?
|
||||
|
||||
settings.labels_desc=Pievienojiet iezīmes, kas var tikt izmantotas <strong>visos</strong> šīs organizācijas repozitorijos.
|
||||
|
||||
|
|
|
|||
|
|
@ -1012,7 +1012,6 @@ editor.file_changed_while_editing=De bestandsinhoud is veranderd sinds je bent b
|
|||
editor.commit_empty_file_header=Commit een leeg bestand
|
||||
editor.commit_empty_file_text=Het bestand dat u wilt committen is leeg. Doorgaan?
|
||||
editor.no_changes_to_show=Er zijn geen wijzigingen om weer te geven.
|
||||
editor.fail_to_update_file_summary=Foutmelding:
|
||||
editor.push_rejected_no_message=De wijziging is afgewezen door de server zonder bericht. Controleer de Git Hooks alsjeblieft.
|
||||
editor.push_rejected=De wijziging is afgewezen door de server. Controleer Controleer de Git Hooks alsjeblieft.
|
||||
editor.push_rejected_summary=Volledig afwijzingsbericht:
|
||||
|
|
@ -1023,6 +1022,7 @@ editor.require_signed_commit=Branch vereist een ondertekende commit
|
|||
editor.cherry_pick=Cherry-pick %s op:
|
||||
editor.revert=%s ongedaan maken op:
|
||||
|
||||
|
||||
commits.desc=Bekijk de broncode-wijzigingsgeschiedenis.
|
||||
commits.commits=Commits
|
||||
commits.nothing_to_compare=Deze branches zijn gelijk.
|
||||
|
|
@ -1989,13 +1989,13 @@ settings.visibility.private=Privé (alleen zichtbaar voor organisatieleden)
|
|||
settings.visibility.private_shortname=Privé
|
||||
|
||||
settings.update_settings=Instellingen bijwerken
|
||||
|
||||
|
||||
settings.update_avatar_success=De avatar van de organisatie is aangepast.
|
||||
settings.delete=Verwijder organisatie
|
||||
settings.delete_account=Verwijder deze organisatie
|
||||
settings.delete_prompt=Deze organisatie zal permanent worden verwijderd. U kunt dit <strong>NIET</strong> ongedaan maken!
|
||||
settings.confirm_delete_account=Bevestig verwijdering
|
||||
settings.delete_org_title=Verwijder organisatie
|
||||
settings.delete_org_desc=Deze organisatie zal permanent verwijderd worden. Doorgaan?
|
||||
settings.hooks_desc=Een webhook toevoegen die door <strong>alle repositories</strong> in deze organisatie getriggerd kan worden.
|
||||
|
||||
settings.labels_desc=Voeg labels toe die kunnen worden gebruikt bij problemen voor <strong>alle repositories</strong> in deze organisatie.
|
||||
|
|
|
|||
|
|
@ -942,13 +942,13 @@ editor.file_changed_while_editing=Zawartość pliku zmieniła się, odkąd rozpo
|
|||
editor.commit_empty_file_header=Commituj pusty plik
|
||||
editor.commit_empty_file_text=Plik, który zamierzasz commitować, jest pusty. Kontynuować?
|
||||
editor.no_changes_to_show=Brak zmian do pokazania.
|
||||
editor.fail_to_update_file_summary=Komunikat błędu:
|
||||
editor.push_rejected_summary=Pełny komunikat odrzucenia:
|
||||
editor.add_subdir=Dodaj katalog…
|
||||
editor.no_commit_to_branch=Zatwierdzanie bezpośrednio do tej gałęzi nie jest możliwe, ponieważ:
|
||||
editor.user_no_push_to_branch=Użytkownik nie może wypychać do gałęzi
|
||||
editor.require_signed_commit=Gałąź wymaga podpisanych commitów
|
||||
|
||||
|
||||
commits.desc=Przeglądaj historię zmian kodu źródłowego.
|
||||
commits.commits=Commity
|
||||
commits.search_all=Wszystkie gałęzie
|
||||
|
|
@ -1862,14 +1862,13 @@ settings.visibility.private_shortname=Prywatny
|
|||
|
||||
settings.update_settings=Aktualizuj ustawienia
|
||||
settings.update_setting_success=Ustawienia organizacji zostały zaktualizowane.
|
||||
settings.change_orgname_redirect_prompt=Stara nazwa będzie przekierowywała dopóki ktoś jej nie zajmie.
|
||||
|
||||
|
||||
settings.update_avatar_success=Awatar organizacji został zaktualizowany.
|
||||
settings.delete=Usuń organizację
|
||||
settings.delete_account=Usuń tą organizację
|
||||
settings.delete_prompt=Organizacja zostanie trwale usunięta. Tej akcji <strong>NIE MOŻNA</strong> cofnąć!
|
||||
settings.confirm_delete_account=Potwierdź usunięcie
|
||||
settings.delete_org_title=Usuń organizację
|
||||
settings.delete_org_desc=Ta organizacja zostanie trwale usunięta. Kontynuować?
|
||||
settings.hooks_desc=Dodaj webhooki, uruchamiane dla <strong>wszystkich repozytoriów</strong> w tej organizacji.
|
||||
|
||||
settings.labels_desc=Dodaj etykiety, które mogą być używane w zgłoszeniach dla <strong>wszystkich repozytoriów</strong> w tej organizacji.
|
||||
|
|
|
|||
|
|
@ -1191,7 +1191,6 @@ editor.update=Atualizar %s
|
|||
editor.delete=Excluir %s
|
||||
editor.patch=Aplicar Correção
|
||||
editor.patching=Corrigindo:
|
||||
editor.fail_to_apply_patch=`Não foi possível aplicar a correção "%s"`
|
||||
editor.new_patch=Nova correção
|
||||
editor.commit_message_desc=Adicione uma descrição detalhada (opcional)...
|
||||
editor.signoff_desc=Adicione um assinado-por-committer no final do log do commit.
|
||||
|
|
@ -1209,15 +1208,11 @@ editor.branch_already_exists=Branch "%s" já existe neste repositório.
|
|||
editor.directory_is_a_file=O nome do diretório "%s" já é usado como um nome de arquivo neste repositório.
|
||||
editor.file_is_a_symlink=`"%s" é um link simbólico. Links simbólicos não podem ser editados no editor da web`
|
||||
editor.filename_is_a_directory=O nome do arquivo "%s" já é usado como um nome de diretório neste repositório.
|
||||
editor.file_editing_no_longer_exists=O arquivo que está sendo editado, "%s", não existe mais neste repositório.
|
||||
editor.file_deleting_no_longer_exists=O arquivo a ser excluído, "%s", não existe mais neste repositório.
|
||||
editor.file_changed_while_editing=O conteúdo do arquivo mudou desde que você começou a editar. <a target="_blank" rel="noopener noreferrer" href="%s">Clique aqui</a> para ver o que foi editado ou <strong>clique em Aplicar commit das alterações novamemente</strong> para sobreescrever estas alterações.
|
||||
editor.file_already_exists=Um arquivo com nome "%s" já existe neste repositório.
|
||||
editor.commit_empty_file_header=Fazer commit de um arquivo vazio
|
||||
editor.commit_empty_file_text=O arquivo que você está prestes fazer commit está vazio. Continuar?
|
||||
editor.no_changes_to_show=Nenhuma alteração a mostrar.
|
||||
editor.fail_to_update_file=Falha ao atualizar/criar arquivo "%s".
|
||||
editor.fail_to_update_file_summary=Mensagem de erro:
|
||||
editor.push_rejected_no_message=A alteração foi rejeitada pelo servidor sem uma mensagem. Por favor, verifique os Hooks Git.
|
||||
editor.push_rejected=A alteração foi rejeitada pelo servidor. Por favor, verifique os Hooks Git.
|
||||
editor.push_rejected_summary=Mensagem completa de rejeição:
|
||||
|
|
@ -1232,6 +1227,7 @@ editor.require_signed_commit=Branch requer um commit assinado
|
|||
editor.cherry_pick=Cherry-pick %s para:
|
||||
editor.revert=Reverter %s para:
|
||||
|
||||
|
||||
commits.desc=Veja o histórico de alterações do código de fonte.
|
||||
commits.commits=Commits
|
||||
commits.no_commits=Nenhum commit em comum. "%s" e "%s" tem históricos completamente diferentes.
|
||||
|
|
@ -2468,14 +2464,13 @@ settings.visibility.private_shortname=Privado
|
|||
|
||||
settings.update_settings=Atualizar Configurações
|
||||
settings.update_setting_success=Configurações da organização foram atualizadas.
|
||||
settings.change_orgname_redirect_prompt=O nome antigo irá redirecionar até que seja reivindicado.
|
||||
|
||||
|
||||
settings.update_avatar_success=O avatar da organização foi atualizado.
|
||||
settings.delete=Excluir organização
|
||||
settings.delete_account=Excluir esta organização
|
||||
settings.delete_prompt=A organização será excluída permanentemente. Isto <strong>NÃO PODERÁ</strong> ser desfeito!
|
||||
settings.confirm_delete_account=Confirmar exclusão
|
||||
settings.delete_org_title=Excluir organização
|
||||
settings.delete_org_desc=Essa organização será excluída permanentemente. Continuar?
|
||||
settings.hooks_desc=Adicionar Webhooks que serão acionados para <strong>todos os repositórios</strong> desta organização.
|
||||
|
||||
settings.labels_desc=Adicionar rótulos que possam ser usadas em issues para <strong>todos os repositórios</strong> desta organização.
|
||||
|
|
|
|||
|
|
@ -1353,7 +1353,6 @@ editor.update=Modificar %s
|
|||
editor.delete=Eliminar %s
|
||||
editor.patch=Aplicar remendo (patch)
|
||||
editor.patching=Remendando (patching):
|
||||
editor.fail_to_apply_patch=`Não foi possível aplicar o remendo (patch) "%s"`
|
||||
editor.new_patch=Novo remendo (patch)
|
||||
editor.commit_message_desc=Adicionar uma descrição alargada opcional…
|
||||
editor.signoff_desc=Adicionar "Assinado-por" seguido do autor do cometimento no fim da mensagem do registo de cometimentos.
|
||||
|
|
@ -1373,8 +1372,6 @@ editor.branch_already_exists=O ramo "%s" já existe neste repositório.
|
|||
editor.directory_is_a_file=O nome da pasta "%s" já é usado como um nome de ficheiro neste repositório.
|
||||
editor.file_is_a_symlink=`"%s" é uma ligação simbólica. Ligações simbólicas não podem ser editadas no editor web`
|
||||
editor.filename_is_a_directory=O nome de ficheiro "%s" já está a ser usado como um nome de pasta neste repositório.
|
||||
editor.file_editing_no_longer_exists=O ficheiro que está a ser editado, "%s", já não existe neste repositório.
|
||||
editor.file_deleting_no_longer_exists=O ficheiro que está a ser eliminado, "%s", já não existe neste repositório.
|
||||
editor.file_changed_while_editing=O conteúdo do ficheiro mudou desde que começou a editar. <a target="_blank" rel="noopener noreferrer" href="%s">Clique aqui</a> para ver as modificações ou clique em <strong>Cometer novamente</strong> para escrever por cima.
|
||||
editor.file_already_exists=Já existe um ficheiro com o nome "%s" neste repositório.
|
||||
editor.commit_id_not_matching=O ID do cometimento não corresponde ao ID de quando começou a editar. Faça o cometimento para um ramo de remendo (patch) e depois faça a integração.
|
||||
|
|
@ -1382,8 +1379,6 @@ editor.push_out_of_date=O envio parece estar obsoleto.
|
|||
editor.commit_empty_file_header=Cometer um ficheiro vazio
|
||||
editor.commit_empty_file_text=O ficheiro que está prestes a cometer está vazio. Quer continuar?
|
||||
editor.no_changes_to_show=Não existem modificações para mostrar.
|
||||
editor.fail_to_update_file=Falhou ao modificar/criar o ficheiro "%s".
|
||||
editor.fail_to_update_file_summary=Mensagem de erro:
|
||||
editor.push_rejected_no_message=A modificação foi rejeitada pelo servidor sem qualquer mensagem. Verifique os Automatismos do Git.
|
||||
editor.push_rejected=A modificação foi rejeitada pelo servidor. Verifique os Automatismos do Git.
|
||||
editor.push_rejected_summary=Mensagem completa de rejeição:
|
||||
|
|
@ -1398,6 +1393,7 @@ editor.require_signed_commit=O ramo requer um cometimento assinado
|
|||
editor.cherry_pick=Escolher a dedo %s para:
|
||||
editor.revert=Reverter %s para:
|
||||
|
||||
|
||||
commits.desc=Navegar pelo histórico de modificações no código fonte.
|
||||
commits.commits=Cometimentos
|
||||
commits.no_commits=Não há cometimentos em comum. "%s" e "%s" têm históricos completamente diferentes.
|
||||
|
|
@ -2402,8 +2398,10 @@ settings.event_pull_request_review_request_desc=A revisão do pedido de integra
|
|||
settings.event_pull_request_approvals=Aprovações do pedido de integração
|
||||
settings.event_pull_request_merge=Integração constante no pedido
|
||||
settings.event_header_workflow=Eventos da sequência de trabalho
|
||||
settings.event_workflow_run=Execução da sequência de trabalho
|
||||
settings.event_workflow_run_desc=A execução da sequência de trabalho das operações do Gitea foi colocada em fila, está em espera, em andamento ou concluída.
|
||||
settings.event_workflow_job=Trabalhos da sequência de trabalho
|
||||
settings.event_workflow_job_desc=O trabalho da sequência de trabalho das operações do Gitea foi colocado em fila, está em espera, em andamento ou concluída.
|
||||
settings.event_workflow_job_desc=O trabalho da sequência de trabalho das operações do Gitea foi colocado em fila, está em espera, em andamento ou concluído.
|
||||
settings.event_package=Pacote
|
||||
settings.event_package_desc=Pacote criado ou eliminado num repositório.
|
||||
settings.branch_filter=Filtro de ramos
|
||||
|
|
@ -2830,15 +2828,13 @@ settings.visibility.private_shortname=Privado
|
|||
|
||||
settings.update_settings=Modificar configurações
|
||||
settings.update_setting_success=As configurações da organização foram modificadas.
|
||||
settings.change_orgname_prompt=Nota: Mudar o nome da organização também irá mudar o URL da organização e libertar o nome antigo.
|
||||
settings.change_orgname_redirect_prompt=O nome antigo, enquanto não for reivindicado, irá reencaminhar para o novo.
|
||||
|
||||
|
||||
settings.update_avatar_success=O avatar da organização foi modificado.
|
||||
settings.delete=Eliminar organização
|
||||
settings.delete_account=Eliminar esta organização
|
||||
settings.delete_prompt=A organização será removida permanentemente. Essa operação <strong>NÃO PODERÁ</strong> ser revertida!
|
||||
settings.confirm_delete_account=Confirme a eliminação
|
||||
settings.delete_org_title=Eliminar organização
|
||||
settings.delete_org_desc=Esta organização será eliminada permanentemente. Quer continuar?
|
||||
settings.hooks_desc=Adicionar automatismos web que serão despoletados para <strong>todos os repositórios</strong> desta organização.
|
||||
|
||||
settings.labels_desc=Adicionar rótulos que possam ser usados em questões para <strong>todos os repositórios</strong> desta organização.
|
||||
|
|
|
|||
|
|
@ -1169,7 +1169,6 @@ editor.update=Обновить %s
|
|||
editor.delete=Удалить %s
|
||||
editor.patch=Применить патч
|
||||
editor.patching=Исправление:
|
||||
editor.fail_to_apply_patch=Невозможно применить патч «%s»
|
||||
editor.new_patch=Новый патч
|
||||
editor.commit_message_desc=Добавьте необязательное расширенное описание…
|
||||
editor.signoff_desc=Добавить трейлер Signed-off-by с автором коммита в конце сообщения коммита.
|
||||
|
|
@ -1187,15 +1186,11 @@ editor.branch_already_exists=Ветка «%s» уже существует в э
|
|||
editor.directory_is_a_file=Имя каталога «%s» уже используется в качестве имени файла в этом репозитории.
|
||||
editor.file_is_a_symlink=`«%s» является символической ссылкой. Символические ссылки невозможно отредактировать в веб-редакторе`
|
||||
editor.filename_is_a_directory=Имя файла «%s» уже используется в качестве каталога в этом репозитории.
|
||||
editor.file_editing_no_longer_exists=Редактируемый файл «%s» больше не существует в этом репозитории.
|
||||
editor.file_deleting_no_longer_exists=Удаляемый файл «%s» больше не существует в этом репозитории.
|
||||
editor.file_changed_while_editing=Содержимое файла изменилось с момента начала редактирования. <a target="_blank" rel="noopener noreferrer" href="%s">Нажмите здесь</a>, чтобы увидеть, что было изменено, или <strong>Зафиксировать изменения снова</strong>, чтобы заменить их.
|
||||
editor.file_already_exists=Файл с именем «%s» уже существует в репозитории.
|
||||
editor.commit_empty_file_header=Закоммитить пустой файл
|
||||
editor.commit_empty_file_text=Файл, который вы собираетесь зафиксировать, пуст. Продолжить?
|
||||
editor.no_changes_to_show=Нет изменений.
|
||||
editor.fail_to_update_file=Не удалось обновить/создать файл «%s».
|
||||
editor.fail_to_update_file_summary=Ошибка:
|
||||
editor.push_rejected_no_message=Изменение отклонено сервером без сообщения. Пожалуйста, проверьте хуки Git.
|
||||
editor.push_rejected=Изменение отклонено сервером. Пожалуйста, проверьте хуки Git.
|
||||
editor.push_rejected_summary=Полное сообщение об отклонении:
|
||||
|
|
@ -1210,6 +1205,7 @@ editor.require_signed_commit=Ветка ожидает подписанный к
|
|||
editor.cherry_pick=Перенести изменения %s в:
|
||||
editor.revert=Откатить %s к:
|
||||
|
||||
|
||||
commits.desc=Просмотр истории изменений исходного кода.
|
||||
commits.commits=Коммитов
|
||||
commits.no_commits=Нет общих коммитов. «%s» и «%s» имеют совершенно разные истории.
|
||||
|
|
@ -2455,15 +2451,13 @@ settings.visibility.private_shortname=Приватный
|
|||
|
||||
settings.update_settings=Обновить настройки
|
||||
settings.update_setting_success=Настройки организации обновлены.
|
||||
settings.change_orgname_prompt=Обратите внимание: изменение названия организации также изменит URL вашей организации и освободит старое имя.
|
||||
settings.change_orgname_redirect_prompt=Старое имя будет перенаправлено до тех пор, пока оно не будет введено.
|
||||
|
||||
|
||||
settings.update_avatar_success=Аватар организации обновлён.
|
||||
settings.delete=Удалить организацию
|
||||
settings.delete_account=Удалить эту организацию
|
||||
settings.delete_prompt=Это действие <strong>БЕЗВОЗВРАТНО</strong> удалит эту организацию навсегда!
|
||||
settings.confirm_delete_account=Подтвердить удаление
|
||||
settings.delete_org_title=Удалить организацию
|
||||
settings.delete_org_desc=Эта организация будет безвозвратно удалена. Продолжить?
|
||||
settings.hooks_desc=Добавьте веб-хуки, которые будет вызываться для <strong>всех репозиториев</strong> под этой организации.
|
||||
|
||||
settings.labels_desc=Добавьте метки, которые могут быть использованы в задачах для <strong>всех репозиториев</strong> этой организации.
|
||||
|
|
|
|||
|
|
@ -917,13 +917,13 @@ editor.file_changed_while_editing=ඔබ සංස්කරණය කිරී
|
|||
editor.commit_empty_file_header=හිස් ගොනුවක් කැප කරන්න
|
||||
editor.commit_empty_file_text=ඔබ කැප කිරීමට යන ගොනුව හිස් ය. ඉදිරියට?
|
||||
editor.no_changes_to_show=පෙන්වීමට කිසිදු වෙනසක් නැත.
|
||||
editor.fail_to_update_file_summary=දෝෂ පණිවිඩය:
|
||||
editor.push_rejected_summary=පූර්ණ ප්රතික්ෂේප පණිවිඩය:
|
||||
editor.add_subdir=ඩිරෙක්ටරියක් එක් කරන්න…
|
||||
editor.no_commit_to_branch=ශාඛාවට කෙලින්ම කැපවිය නොහැකි නිසා:
|
||||
editor.user_no_push_to_branch=පරිශීලකයාට ශාඛාවට තල්ලු කළ නොහැක
|
||||
editor.require_signed_commit=ශාඛාවට අත්සන් කළ කැපවීමක් අවශ්ය වේ
|
||||
|
||||
|
||||
commits.desc=මූලාශ්ර කේත වෙනස් කිරීමේ ඉතිහාසය පිරික්සන්න.
|
||||
commits.commits=විවරයන්
|
||||
commits.nothing_to_compare=මෙම ශාඛා සමාන වේ.
|
||||
|
|
@ -1882,14 +1882,13 @@ settings.visibility.private_shortname=පෞද්ගලික
|
|||
|
||||
settings.update_settings=සැකසුම් යාවත්කාල කරන්න
|
||||
settings.update_setting_success=සංවිධානයේ සැකසුම් යාවත්කාල කර ඇත.
|
||||
settings.change_orgname_redirect_prompt=පැරණි නම ඉල්ලා සිටින තුරු නැවත හරවා යවයි.
|
||||
|
||||
|
||||
settings.update_avatar_success=සංවිධානයේ අවතාරය යාවත්කාලීන කර ඇත.
|
||||
settings.delete=සංවිධානය මකන්න
|
||||
settings.delete_account=මෙම සංවිධානය මකන්න
|
||||
settings.delete_prompt=සංවිධානය ස්ථිරවම ඉවත් කරනු ලැබේ. මෙම <strong></strong> අහෝසි කළ නොහැක!
|
||||
settings.confirm_delete_account=මකාදැමීම තහවුරු කරන්න
|
||||
settings.delete_org_title=සංවිධානය මකන්න
|
||||
settings.delete_org_desc=මෙම සංවිධානය ස්ථිරවම මකා දමනු ඇත. දිගටම?
|
||||
settings.hooks_desc=මෙම සංවිධානය යටතේ <strong>සියලුම ගබඩාවන්</strong> සඳහා මුලපුරනු ලබන වෙබ් කොකු එකතු කරන්න.
|
||||
|
||||
settings.labels_desc=මෙම සංවිධානය යටතේ <strong>සියලුම ගබඩාවලදී</strong> සඳහා ගැටළු සඳහා භාවිතා කළ හැකි ලේබල් එකතු කරන්න.
|
||||
|
|
|
|||
|
|
@ -1007,6 +1007,7 @@ editor.commit_empty_file_text=Súbor, ktorý sa chystáte odoslať, je prázdny.
|
|||
editor.no_commit_to_branch=Nedá sa odoslať priamo do vetvy, pretože:
|
||||
editor.require_signed_commit=Vetva vyžaduje podpísaný commit
|
||||
|
||||
|
||||
commits.commits=Commity
|
||||
commits.search_all=Všetky vetvy
|
||||
commits.author=Autor
|
||||
|
|
@ -1219,6 +1220,8 @@ lower_repositories=repozitáre
|
|||
settings.visibility.private=Súkromná (viditeľné iba pre členov organizácie)
|
||||
settings.visibility.private_shortname=Súkromný
|
||||
|
||||
|
||||
|
||||
settings.hooks_desc=Pridajte webhooky, ktoré sa spustia nad <strong>všetkými repozitármi</strong> v rámci tejto organizácie.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -777,12 +777,12 @@ editor.file_changed_while_editing=Filens innehåll har ändrats sedan du påbör
|
|||
editor.commit_empty_file_header=Committa en tom fil
|
||||
editor.commit_empty_file_text=Filen du vill committa är tom. Vill du fortsätta?
|
||||
editor.no_changes_to_show=Det finns inga ändringar att visa.
|
||||
editor.fail_to_update_file_summary=Felmeddelande:
|
||||
editor.add_subdir=Lägga till en katalog…
|
||||
editor.no_commit_to_branch=Det gick inte att committa direkt till branchen för:
|
||||
editor.user_no_push_to_branch=Användaren kan inte pusha till branchen
|
||||
editor.require_signed_commit=Branchen kräver en signerad commit
|
||||
|
||||
|
||||
commits.desc=Bläddra i källkodens förändringshistorik.
|
||||
commits.commits=Incheckningar
|
||||
commits.search_all=Alla brancher
|
||||
|
|
@ -1524,13 +1524,13 @@ settings.visibility.private=Privat (synlig endast för organisationens medlemmar
|
|||
settings.visibility.private_shortname=Privat
|
||||
|
||||
settings.update_settings=Uppdatera inställningar
|
||||
|
||||
|
||||
settings.update_avatar_success=Organisationens avatar har uppdateras.
|
||||
settings.delete=Tag bort organisation
|
||||
settings.delete_account=Tag bort denna organisation
|
||||
settings.delete_prompt=Organisationen kommer tas bort permanent, och det går <strong>INTE</strong> att ångra detta!
|
||||
settings.confirm_delete_account=Bekräfta borttagning
|
||||
settings.delete_org_title=Ta bort organisation
|
||||
settings.delete_org_desc=Denna organisation kommer tas bort permanent. Vill du fortsätta?
|
||||
settings.hooks_desc=Lägg till webbhook som triggas för <strong>alla utvecklingskataloger</strong> under denna organisationen.
|
||||
|
||||
settings.labels_desc=Lägg till etiketter som kan användas till ärenden för <strong>alla utvecklingskataloger</strong> under denna organisation.
|
||||
|
|
|
|||
|
|
@ -1345,7 +1345,6 @@ editor.update=%s Güncelle
|
|||
editor.delete=%s Sil
|
||||
editor.patch=Yama Uygula
|
||||
editor.patching=Yamalanıyor:
|
||||
editor.fail_to_apply_patch=`"%s" yaması uygulanamıyor`
|
||||
editor.new_patch=Yeni Yama
|
||||
editor.commit_message_desc=İsteğe bağlı uzun bir açıklama ekleyin…
|
||||
editor.signoff_desc=İşleme günlüğü mesajının sonuna işleyen tarafından imzalanan bir fragman ekleyin.
|
||||
|
|
@ -1365,8 +1364,6 @@ editor.branch_already_exists=Bu depoda "%s" dalı zaten var.
|
|||
editor.directory_is_a_file=Dizin adı "%s" zaten bu depoda bir dosya adı olarak kullanılmaktadır.
|
||||
editor.file_is_a_symlink=`"%s" sembolik bir bağlantıdır. Sembolik bağlantılar web düzenleyicisinde düzenlenemez`
|
||||
editor.filename_is_a_directory=Dosya adı "%s" zaten bu depoda bir dizin adı olarak kullanılmaktadır.
|
||||
editor.file_editing_no_longer_exists=Düzenlenmekte olan "%s" dosyası artık bu depoda yer almıyor.
|
||||
editor.file_deleting_no_longer_exists=Silinen "%s" dosyası artık bu depoda yer almıyor.
|
||||
editor.file_changed_while_editing=Düzenlemeye başladığınızdan beri dosya içeriği değişti. Görmek için <a target="_blank" rel="noopener noreferrer" href="%s">burayı tıklayın</a> veya üzerine yazmak için <strong>değişiklikleri yine de işleyin</strong>.
|
||||
editor.file_already_exists=Bu depoda "%s" isimli bir dosya zaten var.
|
||||
editor.commit_id_not_matching=İşleme ID'si, düzenlemeye başladığınız ID ile uyuşmuyor, bir yama dalına işleme yapın ve sonra birleştirin.
|
||||
|
|
@ -1374,8 +1371,6 @@ editor.push_out_of_date=İtme eskimiş.
|
|||
editor.commit_empty_file_header=Boş bir dosya işle
|
||||
editor.commit_empty_file_text=İşlemek üzere olduğunuz dosya boş. Devam edilsin mi?
|
||||
editor.no_changes_to_show=Gösterilecek değişiklik yok.
|
||||
editor.fail_to_update_file=`"%s" dosyası güncellenemedi/oluşturulamadı.`
|
||||
editor.fail_to_update_file_summary=Hata Mesajı:
|
||||
editor.push_rejected_no_message=Değişiklik, bir ileti olmadan sunucu tarafından reddedildi. Git Hooks'u kontrol edin.
|
||||
editor.push_rejected=Değişiklik sunucu tarafından reddedildi. Lütfen Git Hooks'u kontrol edin.
|
||||
editor.push_rejected_summary=Tam Red Mesajı:
|
||||
|
|
@ -1390,6 +1385,7 @@ editor.require_signed_commit=Dal imzalı bir işleme gerektirir
|
|||
editor.cherry_pick=%s şunun üzerine cımbızla:
|
||||
editor.revert=%s şuna geri döndür:
|
||||
|
||||
|
||||
commits.desc=Kaynak kodu değişiklik geçmişine göz atın.
|
||||
commits.commits=İşleme
|
||||
commits.no_commits=Ortak bir işleme yok. "%s" ve "%s" tamamen farklı geçmişlere sahip.
|
||||
|
|
@ -2735,15 +2731,13 @@ settings.visibility.private_shortname=Özel
|
|||
|
||||
settings.update_settings=Ayarları Güncelle
|
||||
settings.update_setting_success=Organizasyon ayarları güncellendi.
|
||||
settings.change_orgname_prompt=Not: Organizasyon adını değiştirmek organizasyonunuzun URL'sini de değiştirecek ve eski ismi serbest bıracaktır.
|
||||
settings.change_orgname_redirect_prompt=Eski ad, talep edilene kadar yeniden yönlendirilecektir.
|
||||
|
||||
|
||||
settings.update_avatar_success=Organizasyonun resmi güncellendi.
|
||||
settings.delete=Organizasyonu Sil
|
||||
settings.delete_account=Bu Organizasyonu Sil
|
||||
settings.delete_prompt=Organizasyon kalıcı olarak kaldırılacaktır. Bu işlem <strong>GERİ ALINAMAZ</strong>!
|
||||
settings.confirm_delete_account=Silmeyi Onaylıyorum
|
||||
settings.delete_org_title=Organizasyonu Sil
|
||||
settings.delete_org_desc=Bu organizasyon kalıcı olarak silinecektir. Devam edilsin mi?
|
||||
settings.hooks_desc=Bu organizasyon altındaki <strong>tüm depolar</strong> için tetiklenecek webhook'lar ekle.
|
||||
|
||||
settings.labels_desc=Bu organizasyonun altındaki <strong>tüm depolar</strong> ile ilgili konularda kullanılabilecek etiketler ekleyin.
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ remove=Видалити
|
|||
remove_all=Видалити все
|
||||
remove_label_str=`Видалити елемент "%s"`
|
||||
edit=Редагувати
|
||||
view=Переглянути
|
||||
test=Тест
|
||||
|
||||
enabled=Увімкнено
|
||||
|
|
@ -414,6 +415,7 @@ remember_me.compromised=Токен для входу більше не дійс
|
|||
forgot_password_title=Забув пароль
|
||||
forgot_password=Забули пароль?
|
||||
need_account=Потрібен обліковий запис?
|
||||
sign_up_tip=Ви реєструєте перший обліковий запис у системі, з правами адміністратора. Будь ласка, уважно запам'ятайте своє ім'я користувача та пароль. Якщо ви їх забудете, зверніться до документації Gitea, щоб відновити обліковий запис.
|
||||
sign_up_now=Зареєструватися.
|
||||
sign_up_successful=Обліковий запис створено успішно. Вітаю!
|
||||
confirmation_mail_sent_prompt_ex=Новий лист з підтвердженням було надіслано на <b>%s</b>. Будь ласка, перевірте свою поштову скриньку протягом наступних %s, щоб завершити процес реєстрації. Якщо ви вказали невірну адресу електронної пошти, ви можете увійти ще раз і змінити її.
|
||||
|
|
@ -970,6 +972,7 @@ passcode_invalid=Некоректний пароль. Спробуй ще раз
|
|||
twofa_failed_get_secret=Не вдалося отримати код.
|
||||
|
||||
webauthn_register_key=Додати ключ безпеки
|
||||
webauthn_nickname=Псевдонім
|
||||
webauthn_delete_key=Видалити ключ безпеки
|
||||
webauthn_delete_key_desc=Якщо ви видалите ключ безпеки, ви більше не зможете ввійти за його допомогою. Продовжити?
|
||||
webauthn_key_loss_warning=Якщо ви втратите ключі безпеки, ви втратите доступ до свого облікового запису.
|
||||
|
|
@ -1320,7 +1323,6 @@ editor.update=Оновити %s
|
|||
editor.delete=Видалити %s
|
||||
editor.patch=Застосувати патч
|
||||
editor.patching=Застосування виправлень:
|
||||
editor.fail_to_apply_patch=`Не вдалося застосувати патч "%s"`
|
||||
editor.new_patch=Новий патч
|
||||
editor.commit_message_desc=Додати необов'язковий розширений опис…
|
||||
editor.signoff_desc=Додати «Підписано комітером» в кінці повідомлення коміту.
|
||||
|
|
@ -1337,13 +1339,11 @@ editor.commit_email=Електронна пошта коміту
|
|||
editor.invalid_commit_email=Адреса електронної пошти для коміту недійсна.
|
||||
editor.file_is_a_symlink=`"%s" - це символічне посилання. Символічні посилання не можна редагувати у веб-редакторі`
|
||||
editor.filename_is_a_directory=Назва файлу '%s' вже використовується як назва каталогу у цьому сховищі.
|
||||
editor.file_deleting_no_longer_exists=Видалений файл '%s' більше не існує в цьому сховищі.
|
||||
editor.file_modifying_no_longer_exists=Редагований файл '%s' більше не існує в цьому сховищі.
|
||||
editor.file_changed_while_editing=Зміст файлу змінився з моменту початку редагування. <a target="_blank" rel="noopener" href="%s"> Натисніть тут </a>, щоб переглянути що було змінено, або <strong>закомітьте зміни ще раз</strong>, щоб переписати їх.
|
||||
editor.commit_empty_file_header=Закомітити порожній файл
|
||||
editor.commit_empty_file_text=Файл, який ви збираєтеся закомітити, порожній. Продовжувати?
|
||||
editor.no_changes_to_show=Немає змін.
|
||||
editor.fail_to_update_file=Не вдалося оновити/створити файл "%s".
|
||||
editor.fail_to_update_file_summary=Помилка:
|
||||
editor.push_rejected_no_message=Зміну відхилено сервером без повідомлення. Будь ласка, перевірте Git-хуки.
|
||||
editor.push_rejected=Зміну відхилено сервером. Будь ласка, перевірте Git-хуки.
|
||||
editor.push_rejected_summary=Повне повідомлення про відмову:
|
||||
|
|
@ -1353,9 +1353,14 @@ editor.upload_file_is_locked=Файл "%s" заблоковано %s.
|
|||
editor.upload_files_to_dir=`Завантажити файли до "%s"`
|
||||
editor.no_commit_to_branch=Не вдалося внести коміт безпосередньо до гілки, тому що:
|
||||
editor.require_signed_commit=Гілка вимагає підписаного коміту
|
||||
editor.revert=Повернути %s до:
|
||||
editor.failed_to_commit=Не вдалося зафіксувати зміни.
|
||||
editor.failed_to_commit_summary=Помилка:
|
||||
|
||||
|
||||
commits.desc=Переглянути історію зміни коду.
|
||||
commits.commits=Коміти
|
||||
commits.no_commits=Немає спільних комітів. '%s' та '%s' мають різну історію.
|
||||
commits.nothing_to_compare=Ці гілки однакові.
|
||||
commits.search_branch=Ця гілка
|
||||
commits.search_all=Усі гілки
|
||||
|
|
@ -1372,6 +1377,7 @@ commits.ssh_key_fingerprint=Відбиток ключа SSH
|
|||
commits.view_path=Переглянути в історії
|
||||
commits.view_file_diff=Переглянути зміни до цього файлу в цьому коміті
|
||||
|
||||
commit.operations=Дії
|
||||
commit.revert=Повернути до попереднього стану
|
||||
commit.revert-header=Повернути: %s
|
||||
commit.revert-content=Виберіть гілку, до якої хочете повернутися:
|
||||
|
|
@ -1446,6 +1452,7 @@ issues.new.clear_assignees=Прибрати виконавців
|
|||
issues.new.no_assignees=Немає виконавців
|
||||
issues.new.no_reviewers=Немає рецензентів
|
||||
issues.new.blocked_user=Не вдалося створити задачу, тому що ви заблоковані власником сховища.
|
||||
issues.edit.blocked_user=Неможливо редагувати вміст, оскільки вас заблоковано автором або власником сховища.
|
||||
issues.choose.get_started=Розпочати
|
||||
issues.choose.open_external_link=Відкрити
|
||||
issues.choose.blank=Типово
|
||||
|
|
@ -1463,6 +1470,7 @@ issues.label_templates.title=Завантажити визначений наб
|
|||
issues.label_templates.info=Ще немає міток. Натисніть 'Нова мітка' або використовуйте попередньо визначений набір міток:
|
||||
issues.label_templates.helper=Оберіть набір міток
|
||||
issues.label_templates.use=Використати набір міток
|
||||
issues.label_templates.fail_to_load_file=Не вдалося завантажити файл шаблона мітки '%s': %v
|
||||
issues.add_label=додано %s з міткою %s
|
||||
issues.add_labels=додано %s з мітками %s
|
||||
issues.remove_label=видалено %s з міткою %s
|
||||
|
|
@ -1498,6 +1506,7 @@ issues.filter_project=Проєкт
|
|||
issues.filter_project_all=Всі проєкти
|
||||
issues.filter_project_none=Проєкт відсутній
|
||||
issues.filter_assignee=Виконавець
|
||||
issues.filter_assignee_no_assignee=Нікому не присвоєно
|
||||
issues.filter_assignee_any_assignee=Призначено будь-кому
|
||||
issues.filter_poster=Автор
|
||||
issues.filter_user_placeholder=Пошук користувачів
|
||||
|
|
@ -1508,6 +1517,7 @@ issues.filter_type.all_pull_requests=Усі запити на злиття
|
|||
issues.filter_type.assigned_to_you=Призначене вам
|
||||
issues.filter_type.created_by_you=Створено вами
|
||||
issues.filter_type.mentioning_you=Вас згадано
|
||||
issues.filter_type.review_requested=Запит на рецензію
|
||||
issues.filter_type.reviewed_by_you=Перевірено вами
|
||||
issues.filter_sort=Сортувати
|
||||
issues.filter_sort.latest=Найновіші
|
||||
|
|
@ -1547,7 +1557,9 @@ issues.context.quote_reply=Цитувати відповідь
|
|||
issues.context.reference_issue=Посилання в новій задачі
|
||||
issues.context.edit=Редагувати
|
||||
issues.context.delete=Видалити
|
||||
issues.no_content=Немає опису.
|
||||
issues.close=Закрити задачу
|
||||
issues.comment_pull_merged_at=об'єднав(-ла) коміти %[1]s в %[2]s %[3]s
|
||||
issues.comment_manually_pull_merged_at=вручну об'єднав(-ла) коміти %[1]s в %[2]s %[3]s
|
||||
issues.close_comment_issue=Закрити з коментарем
|
||||
issues.reopen_issue=Відкрити знову
|
||||
|
|
@ -1590,6 +1602,7 @@ issues.label_title=Назва мітки
|
|||
issues.label_description=Опис мітки
|
||||
issues.label_color=Колір
|
||||
issues.label_color_invalid=Недійсний колір
|
||||
issues.label_exclusive=Ексклюзивно
|
||||
issues.label_archive=Мітка архіву
|
||||
issues.label_archived_filter=Показати архівовані мітки
|
||||
issues.label_archive_tooltip=Архівовані мітки типово виключаються з пропозицій під час пошуку за мітками.
|
||||
|
|
@ -1781,7 +1794,13 @@ pulls.switch_comparison_type=Перемкнути тип порівняння
|
|||
pulls.switch_head_and_base=Поміняти місцями основну та базову гілку
|
||||
pulls.filter_branch=Фільтр по гілці
|
||||
pulls.show_all_commits=Показати всі коміти
|
||||
pulls.show_changes_since_your_last_review=Показати зміни після вашого останнього відгуку
|
||||
pulls.showing_only_single_commit=Відображаються лише зміни коміту %[1]s
|
||||
pulls.showing_specified_commit_range=Відображаються лише зміни між %[1]s..%[2]s
|
||||
pulls.select_commit_hold_shift_for_range=Виберіть коміт. Натисніть клавішу Shift + клацніть, щоб виділити діапазон
|
||||
pulls.filter_changes_by_commit=Фільтр за комітом
|
||||
pulls.nothing_to_compare=Ці гілки однакові. Немає необхідності створювати запитів на злиття.
|
||||
pulls.nothing_to_compare_have_tag=Виділена гілка або мітка ідентичні.
|
||||
pulls.nothing_to_compare_and_allow_empty_pr=Одинакові гілки. Цей PR буде порожнім.
|
||||
pulls.has_pull_request=`Запит злиття для цих гілок вже існує: <a href="%[1]s">%[2]s#%[3]d</a>`
|
||||
pulls.create=Створити запит на злиття
|
||||
|
|
@ -1794,6 +1813,7 @@ pulls.tab_files=Змінені файли
|
|||
pulls.reopen_to_merge=Будь ласка, заново відкрийте цей запит щоб виконати злиття.
|
||||
pulls.cant_reopen_deleted_branch=Цей запит не можна повторно відкрити, оскільки гілку видалено.
|
||||
pulls.merged=Злито
|
||||
pulls.merged_success=Запит на злиття успішно об'єднано і закрито
|
||||
pulls.closed=Запит на злиття закрито
|
||||
pulls.manually_merged=Ручне злиття
|
||||
pulls.merged_info_text=Гілку %s тепер можна видалити.
|
||||
|
|
@ -1806,6 +1826,7 @@ pulls.remove_prefix=Видалити префікс <strong>%s</strong>
|
|||
pulls.data_broken=Збій цього запиту на злиття через відсутність інформації про форк.
|
||||
pulls.files_conflicted=Цей запит на злиття має зміни, що конфліктують з цільовою гілкою.
|
||||
pulls.is_checking=Перевірка конфліктів об'єднання (merge) ...
|
||||
pulls.is_ancestor=Цю гілку вже включено до цільової гілки. Нема чого об'єднувати.
|
||||
pulls.required_status_check_failed=Деякі необхідні перевірки виконані з помилками.
|
||||
pulls.required_status_check_missing=Декілька з необхідних перевірок відсутні.
|
||||
pulls.required_status_check_administrator=Як адміністратор ви все одно можете об'єднати цей запит на злиття.
|
||||
|
|
@ -1873,6 +1894,9 @@ pulls.auto_merge_not_scheduled=Цей запит на злиття не план
|
|||
|
||||
pulls.delete.title=Видалити цей запит на злиття?
|
||||
|
||||
pulls.upstream_diverging_prompt_behind_1=Ця гілка на %[1]d коміт позаду %[2]s
|
||||
pulls.upstream_diverging_prompt_behind_n=Ця гілка на %[1]d комітів позаду %[2]s
|
||||
pulls.upstream_diverging_prompt_base_newer=Базова гілка %s має нові зміни
|
||||
pulls.upstream_diverging_merge_confirm=Хочете об’єднати "%[1]s" з "%[2]s"?
|
||||
|
||||
pull.deleted_branch=(видалена):%s
|
||||
|
|
@ -2252,6 +2276,10 @@ settings.event_pull_request_review=Запит на злиття рецензов
|
|||
settings.event_pull_request_review_desc=Запит на злиття підтверджено, відхилено або прокоментовано.
|
||||
settings.event_pull_request_sync=Запит на злиття синхронізується
|
||||
settings.event_pull_request_sync_desc=Запит до злиття синхронізовано.
|
||||
settings.event_header_workflow=Події робочого процесу
|
||||
settings.event_workflow_run=Запущений робочий процес
|
||||
settings.event_workflow_run_desc=Запущений робочий процес Gitea в черзі, в очікуванні, в процесі виконання або завершений.
|
||||
settings.event_workflow_job=Завдання робочого процесу
|
||||
settings.event_package=Пакет
|
||||
settings.branch_filter=Фільтр гілок
|
||||
settings.authorization_header=Заголовок авторизації
|
||||
|
|
@ -2590,6 +2618,7 @@ team_permission_desc=Права доступу
|
|||
team_unit_desc=Дозволити доступ до розділів репозиторію
|
||||
team_unit_disabled=(Вимкнено)
|
||||
|
||||
form.name_been_taken=Назва організації "%s" вже зайнята.
|
||||
form.name_reserved=Назву організації "%s" зарезервовано.
|
||||
form.name_pattern_not_allowed=Шаблон "%s" не допускається в назві організації.
|
||||
form.create_org_not_allowed=Вам не дозволено створювати організації.
|
||||
|
|
@ -2611,15 +2640,28 @@ settings.visibility.private_shortname=Приватний
|
|||
|
||||
settings.update_settings=Оновити налаштування
|
||||
settings.update_setting_success=Налаштування організації оновлені.
|
||||
settings.change_orgname_prompt=Примітка: Зміна назви організації також змінить URL-адресу вашої організації та звільнить стару назву.
|
||||
settings.change_orgname_redirect_prompt=Стара назва буде перенаправлятися до тих пір, поки не буде заброньована.
|
||||
|
||||
settings.rename=Перейменувати організацію
|
||||
settings.rename_desc=Зміна назви організації також змінить URL адресу вашої організації і звільнить стару назву.
|
||||
settings.rename_success=Організацію %[1]s успішно перейменована на %[2].
|
||||
settings.rename_no_change=Назва організації не змінилася.
|
||||
settings.rename_new_org_name=Назва нової організації
|
||||
settings.rename_failed=Не вдалося перейменувати організацію через внутрішню помилку
|
||||
settings.rename_notices_1=Цю операцію <strong>НЕМОЖЛИВО</strong> скасувати.
|
||||
settings.rename_notices_2=Стара назва буде перенаправлятися на нову, поки хтось не використає її.
|
||||
|
||||
settings.update_avatar_success=Аватар організації оновлений.
|
||||
settings.delete=Видалити організацію
|
||||
settings.delete_account=Видалити цю організацію
|
||||
settings.delete_prompt=Організацію буде остаточно видалено. Це <strong>НЕМОЖЛИВО</strong> скасувати!
|
||||
settings.name_confirm=Введіть назву організації для підтвердження:
|
||||
settings.delete_notices_1=Цю операцію <strong>НЕМОЖЛИВО</strong> скасувати.
|
||||
settings.delete_notices_2=Ця операція назавжди видалить <strong>сховища</strong> <strong>%s</strong>, включно з кодом, задачами, коментарями, даними вікі та налаштуваннями співавторів.
|
||||
settings.delete_notices_3=Ця операція назавжди видалить всі <strong>пакети</strong> <strong>%s</strong>.
|
||||
settings.delete_notices_4=Ця операція назавжди видалить всі <strong>проєкти</strong> <strong>%s</strong>.
|
||||
settings.confirm_delete_account=Підтвердити видалення
|
||||
settings.delete_org_title=Видалити організацію
|
||||
settings.delete_org_desc=Ця організація буде безповоротно видалена. Продовжити?
|
||||
settings.delete_failed=Не вдалося видалити організацію через внутрішню помилку
|
||||
settings.delete_successful=Організацію <b>%s</b> успішно видалено.
|
||||
settings.hooks_desc=Додайте веб-хуки, які спрацьовуватимуть для <strong>всіх сховищ</strong> у цій організації.
|
||||
|
||||
settings.labels_desc=Додайте мітки, які можна використовувати у задачах для <strong>усіх сховищ</strong> у цій організації.
|
||||
|
|
@ -2645,6 +2687,7 @@ teams.leave.detail=Покинути %s?
|
|||
teams.can_create_org_repo=Створити репозиторії
|
||||
teams.can_create_org_repo_helper=Учасники можуть створювати нові репозиторії в організації. Автор отримає доступ адміністратора до нового репозиторію.
|
||||
teams.none_access=Немає доступу
|
||||
teams.none_access_helper=Учасники не можуть переглядати або виконувати будь-які інші дії з цією одиницею. Це не впливає на загальнодоступні сховища.
|
||||
teams.general_access=Загальний доступ
|
||||
teams.general_access_helper=Дозволи учасників будуть визначатися відповідно до наведеної нижче таблиці дозволів.
|
||||
teams.read_access=Читання
|
||||
|
|
@ -2673,6 +2716,7 @@ teams.remove_all_repos_title=Видалити всі репозиторії ко
|
|||
teams.remove_all_repos_desc=Це видалить усі репозиторії команди.
|
||||
teams.add_all_repos_title=Додати всі репозиторії
|
||||
teams.add_all_repos_desc=Це додасть всі репозиторії організації до команди.
|
||||
teams.add_nonexistent_repo=Сховище, яке ви намагаєтеся додати, не існує, будь ласка, створіть його спочатку.
|
||||
teams.add_duplicate_users=Користувач уже є членом команди.
|
||||
teams.repos.none=Для команди немає доступних репозиторіїв.
|
||||
teams.members.none=Немає членів в цій команді.
|
||||
|
|
@ -2764,6 +2808,7 @@ dashboard.resync_all_hooks=Заново синхронізувати хуки п
|
|||
dashboard.reinit_missing_repos=Заново ініціалізувати всі відсутні сховища Git'а, для яких існують записи
|
||||
dashboard.sync_external_users=Синхронізувати дані зовнішніх користувачів
|
||||
dashboard.cleanup_hook_task_table=Очистити таблицю hook_task
|
||||
dashboard.cleanup_packages=Очистити застарілі пакети
|
||||
dashboard.cleanup_actions=Очищення ресурсів прострочених дій
|
||||
dashboard.server_uptime=Час роботи сервера
|
||||
dashboard.current_goroutine=Поточна кількість Goroutines
|
||||
|
|
@ -2795,11 +2840,15 @@ dashboard.total_gc_pause=Загальна пауза збирача сміття
|
|||
dashboard.last_gc_pause=Остання пауза збирача сміття (GC)
|
||||
dashboard.gc_times=Кількість запусків збирача сміття (GC)
|
||||
dashboard.delete_old_actions=Видалити всі старі дії з бази даних
|
||||
dashboard.delete_old_actions.started=Видалення всіх старих дій з бази даних розпочато.
|
||||
dashboard.update_checker=Перевірка оновлень
|
||||
dashboard.delete_old_system_notices=Видалити всі старі системні повідомлення з бази даних
|
||||
dashboard.gc_lfs=Збір сміття мета-об'єктів LFS
|
||||
dashboard.stop_endless_tasks=Зупинити нескінченні завдання
|
||||
dashboard.cancel_abandoned_jobs=Скасувати покинуті завдання
|
||||
dashboard.start_schedule_tasks=Запуск запланованих завдань
|
||||
dashboard.sync_branch.started=Розпочато синхронізацію гілок
|
||||
dashboard.sync_tag.started=Розпочато синхронізацію міток
|
||||
dashboard.rebuild_issue_indexer=Перебудувати індексатор задач
|
||||
dashboard.sync_repo_licenses=Синхронізувати ліцензії сховища
|
||||
|
||||
|
|
@ -3193,6 +3242,7 @@ monitor.queue.settings.remove_all_items_done=Усі елементи черги
|
|||
|
||||
notices.system_notice_list=Сповіщення системи
|
||||
notices.view_detail_header=Переглянути деталі повідомлення
|
||||
notices.operations=Дії
|
||||
notices.select_all=Вибрати все
|
||||
notices.deselect_all=Скасувати виділення
|
||||
notices.inverse_selection=Інвертувати виділене
|
||||
|
|
@ -3260,6 +3310,7 @@ seconds=%d секунди
|
|||
minutes=%d хвилини
|
||||
hours=%d години
|
||||
days=%d дні
|
||||
weeks=%d тижні(в)
|
||||
months=%d місяці
|
||||
years=%d роки
|
||||
raw_seconds=секунди
|
||||
|
|
@ -3330,6 +3381,7 @@ details.license=Ліцензія
|
|||
assets=Ресурси
|
||||
versions=Версії
|
||||
versions.view_all=Переглянути все
|
||||
dependency.id=ID
|
||||
dependency.version=Версія
|
||||
search_in_external_registry=Шукати в %s
|
||||
alpine.registry=Налаштуйте цей реєстр, додавши URL у ваш файл <code>/etc/apk/repositories</code>:
|
||||
|
|
@ -3469,6 +3521,8 @@ actions=Дії
|
|||
unit.desc=Керувати діями
|
||||
|
||||
status.unknown=Невідомий
|
||||
status.waiting=Очікування
|
||||
status.running=Виконується
|
||||
status.success=Успіх
|
||||
status.failure=Невдача
|
||||
status.cancelled=Скасовано
|
||||
|
|
@ -3476,6 +3530,7 @@ status.skipped=Пропущено
|
|||
status.blocked=Заблоковано
|
||||
|
||||
runners.status=Статус
|
||||
runners.id=ID
|
||||
runners.name=Назва
|
||||
runners.owner_type=Тип
|
||||
runners.description=Опис
|
||||
|
|
@ -3498,23 +3553,36 @@ runs.all_workflows=Всі робочі процеси
|
|||
runs.commit=Коміт
|
||||
runs.scheduled=Заплановано
|
||||
runs.pushed_by=завантажено
|
||||
runs.invalid_workflow_helper=Файл конфігурації робочих процесів недійсний. Будь ласка, перевірте файл конфігурації: %s
|
||||
runs.no_job_without_needs=Робочий процес повинен містити принаймні одну задачу без залежностей.
|
||||
runs.no_job=Робочий процес повинен містити принаймні одну задачу
|
||||
runs.actor=Актор
|
||||
runs.status=Статус
|
||||
runs.actors_no_select=Усі актори
|
||||
runs.status_no_select=Всі статуси
|
||||
runs.no_results=Збігів немає.
|
||||
runs.no_workflows=Робочих процесів наразі немає.
|
||||
runs.no_workflows.quick_start=Не знаєте, як почати з Gitea Дії? Дивіться <a target="_blank" rel="noopener noreferrer" href="%s">посібник швидкого старту</a>.
|
||||
runs.no_workflows.documentation=Для отримання додаткової інформації про Gitea Дії, перегляньте <a target="_blank" rel="noopener noreferrer" href="%s">документацію</a>.
|
||||
runs.no_runs=Робочий процес ще не виконувався.
|
||||
runs.empty_commit_message=(порожнє повідомлення коміту)
|
||||
runs.expire_log_message=Журнали були очищені, тому що вони були занадто старі.
|
||||
runs.delete=Видалити запущений робочий процес
|
||||
runs.delete.description=Ви впевнені, що хочете остаточно видалити цей робочий процес? Цю дію неможливо скасувати.
|
||||
runs.not_done=Виконання цього робочого процесу не завершено.
|
||||
runs.view_workflow_file=Перегляд файлу робочого процесу
|
||||
|
||||
workflow.disable=Вимкнути робочий процес
|
||||
workflow.disable_success=Робочий процес '%s' успішно вимкнено.
|
||||
workflow.enable=Увімкнути робочий процес
|
||||
workflow.enable_success=Робочий процес '%s' успішно ввімкнено.
|
||||
workflow.disabled=Робочий процес вимкнений.
|
||||
workflow.run=Запустити робочий процес
|
||||
workflow.not_found=Робочий процес '%s' не знайдено.
|
||||
workflow.run_success=Робочий процес '%s' завершився успішно.
|
||||
workflow.from_ref=Використати робочий процес з
|
||||
workflow.has_workflow_dispatch=Цей робочий процес має тригер події workflow_dispatch.
|
||||
workflow.has_no_workflow_dispatch=Робочий процес “%s” не має тригера події workflow_dispatch.
|
||||
|
||||
|
||||
variables=Змінні
|
||||
|
|
|
|||
|
|
@ -1354,7 +1354,6 @@ editor.update=更新 %s
|
|||
editor.delete=删除 %s
|
||||
editor.patch=应用补丁
|
||||
editor.patching=打补丁:
|
||||
editor.fail_to_apply_patch=无法应用补丁「%s」
|
||||
editor.new_patch=新补丁
|
||||
editor.commit_message_desc=添加一个可选的扩展描述...
|
||||
editor.signoff_desc=在提交日志消息末尾添加签署人信息。
|
||||
|
|
@ -1374,8 +1373,6 @@ editor.branch_already_exists=此仓库已存在名为「%s」的分支。
|
|||
editor.directory_is_a_file=目录名「%s」已作为文件名在此仓库中存在。
|
||||
editor.file_is_a_symlink=`「%s」是一个符号链接,无法在 Web 编辑器中编辑`
|
||||
editor.filename_is_a_directory=文件名「%s」已作为目录名在此仓库中存在。
|
||||
editor.file_editing_no_longer_exists=正在编辑的文件「%s」已不存在于此仓库。
|
||||
editor.file_deleting_no_longer_exists=正在删除的文件「%s」已不存在于此仓库。
|
||||
editor.file_changed_while_editing=文件内容在您进行编辑时已经发生变动。<a target="_blank" rel="noopener noreferrer" href="%s">单击此处</a> 查看变动的具体内容,或者 <strong>再次提交</strong> 覆盖已发生的变动。
|
||||
editor.file_already_exists=此仓库已经存在名为「%s」的文件。
|
||||
editor.commit_id_not_matching=提交 ID 与您开始编辑时的 ID 不匹配。请提交到补丁分支然后合并。
|
||||
|
|
@ -1383,8 +1380,6 @@ editor.push_out_of_date=推送似乎已经过时。
|
|||
editor.commit_empty_file_header=提交一个空文件
|
||||
editor.commit_empty_file_text=您要提交的文件是空的,继续吗?
|
||||
editor.no_changes_to_show=没有可以显示的变更。
|
||||
editor.fail_to_update_file=更新/创建文件「%s」失败。
|
||||
editor.fail_to_update_file_summary=错误信息:
|
||||
editor.push_rejected_no_message=此修改被服务器拒绝并且没有反馈消息。请检查 Git 钩子。
|
||||
editor.push_rejected=此修改被服务器拒绝。请检查 Git 钩子。
|
||||
editor.push_rejected_summary=详细拒绝信息:
|
||||
|
|
@ -1399,6 +1394,7 @@ editor.require_signed_commit=分支需要签名提交
|
|||
editor.cherry_pick=拣选提交 %s 到:
|
||||
editor.revert=将 %s 还原到:
|
||||
|
||||
|
||||
commits.desc=浏览代码修改历史
|
||||
commits.commits=次代码提交
|
||||
commits.no_commits=没有共同的提交。「%s」和「%s」的历史完全不同。
|
||||
|
|
@ -2831,15 +2827,13 @@ settings.visibility.private_shortname=私有
|
|||
|
||||
settings.update_settings=更新组织设置
|
||||
settings.update_setting_success=组织设置已更新。
|
||||
settings.change_orgname_prompt=注意:更改组织名称同时会更改组织的 URL 地址并释放旧的名称。
|
||||
settings.change_orgname_redirect_prompt=在被人使用前,旧用户名将会被重定向。
|
||||
|
||||
|
||||
settings.update_avatar_success=组织头像已经更新。
|
||||
settings.delete=删除组织
|
||||
settings.delete_account=删除当前组织
|
||||
settings.delete_prompt=删除操作会永久清除该组织的信息,并且 <strong>不可恢复</strong>!
|
||||
settings.confirm_delete_account=确认删除组织
|
||||
settings.delete_org_title=删除组织
|
||||
settings.delete_org_desc=此组织将会永久删除,确认继续吗?
|
||||
settings.hooks_desc=在此处添加的 Web 钩子将会应用到该组织下的 <strong>所有仓库</strong>。
|
||||
|
||||
settings.labels_desc=添加能够被该组织下的 <strong>所有仓库</strong> 的工单使用的标签。
|
||||
|
|
|
|||
|
|
@ -374,6 +374,7 @@ editor.create_new_branch=建立 <strong>新的分支</strong> 為此提交和開
|
|||
editor.cancel=取消
|
||||
editor.no_changes_to_show=沒有可以顯示的變更。
|
||||
|
||||
|
||||
commits.commits=次程式碼提交
|
||||
commits.author=作者
|
||||
commits.message=備註
|
||||
|
|
@ -656,10 +657,11 @@ settings.visibility.private_shortname=私有庫
|
|||
|
||||
settings.update_settings=更新組織設定
|
||||
settings.update_setting_success=組織設定已更新。
|
||||
|
||||
|
||||
settings.delete=刪除組織
|
||||
settings.delete_account=刪除當前組織
|
||||
settings.confirm_delete_account=確認刪除組織
|
||||
settings.delete_org_title=刪除組織
|
||||
settings.hooks_desc=新增 webhooks 將觸發在這個組織下 <strong>全部的儲存庫</strong> 。
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1318,7 +1318,6 @@ editor.update=更新 %s
|
|||
editor.delete=刪除 %s
|
||||
editor.patch=套用 Patch
|
||||
editor.patching=正在 Patch:
|
||||
editor.fail_to_apply_patch=無法套用 Patch「%s」
|
||||
editor.new_patch=新增 Patch
|
||||
editor.commit_message_desc=(選用) 加入詳細說明...
|
||||
editor.signoff_desc=在提交訊息底部加入提交者的「Signed-off-by」資訊。
|
||||
|
|
@ -1336,8 +1335,6 @@ editor.branch_already_exists=此儲存庫已有名為「%s」的分支。
|
|||
editor.directory_is_a_file=目錄名稱「%s」已被此儲存庫的檔案使用。
|
||||
editor.file_is_a_symlink=`"%s" 是一個符號連結。符號連結無法在網頁編輯器中編輯`
|
||||
editor.filename_is_a_directory=檔名「%s」已被此儲存庫的目錄名稱使用。
|
||||
editor.file_editing_no_longer_exists=正要編輯的檔案「%s」已不存在此儲存庫中。
|
||||
editor.file_deleting_no_longer_exists=正要刪除的檔案「%s」已不存在此儲存庫中。
|
||||
editor.file_changed_while_editing=檔案內容在您編輯的途中已被變更。<a target="_blank" rel="noopener noreferrer" href="%s">按一下此處</a>查看更動的地方或<strong>再次提交</strong>以覆蓋這些變更。
|
||||
editor.file_already_exists=此儲存庫已有名為「%s」的檔案。
|
||||
editor.commit_id_not_matching=提交 ID 與您開始編輯時的 ID 不匹配。請提交到一個補丁分支然後合併。
|
||||
|
|
@ -1345,8 +1342,6 @@ editor.push_out_of_date=推送似乎已過時。
|
|||
editor.commit_empty_file_header=提交空白檔案
|
||||
editor.commit_empty_file_text=你準備提交的檔案是空白的,是否繼續?
|
||||
editor.no_changes_to_show=沒有可以顯示的變更。
|
||||
editor.fail_to_update_file=更新/建立檔案「%s」失敗。
|
||||
editor.fail_to_update_file_summary=錯誤訊息:
|
||||
editor.push_rejected_no_message=該變更被伺服器拒絕但未提供其他資訊。請檢查 Git Hook。
|
||||
editor.push_rejected=該變更被伺服器拒絕。請檢查 Git Hook。
|
||||
editor.push_rejected_summary=完整的拒絕訊息:
|
||||
|
|
@ -1361,6 +1356,7 @@ editor.require_signed_commit=分支僅接受經簽署的提交
|
|||
editor.cherry_pick=Cherry-pick %s 到:
|
||||
editor.revert=還原 %s 到:
|
||||
|
||||
|
||||
commits.desc=瀏覽原始碼修改歷程。
|
||||
commits.commits=次程式碼提交
|
||||
commits.no_commits=沒有共同的提交。「%s」和「%s」的歷史完全不同。
|
||||
|
|
@ -2756,15 +2752,13 @@ settings.visibility.private_shortname=私有
|
|||
|
||||
settings.update_settings=更新設定
|
||||
settings.update_setting_success=組織設定已更新。
|
||||
settings.change_orgname_prompt=注意:更改組織名稱將同時更改組織的 URL 並釋放舊名稱。
|
||||
settings.change_orgname_redirect_prompt=舊的名稱被領用前,會重新導向新名稱。
|
||||
|
||||
|
||||
settings.update_avatar_success=已更新組織的大頭貼。
|
||||
settings.delete=刪除組織
|
||||
settings.delete_account=刪除這個組織
|
||||
settings.delete_prompt=該組織將被永久刪除。此動作<strong>不可</strong>還原!
|
||||
settings.confirm_delete_account=確認刪除組織
|
||||
settings.delete_org_title=刪除組織
|
||||
settings.delete_org_desc=即將永久刪除這個組織,是否繼續?
|
||||
settings.hooks_desc=此組織下的<strong>所有存儲庫</strong>都會觸發在此新增的 Webhook。
|
||||
|
||||
settings.labels_desc=在此處新增的標籤可用於此組織下的<strong>所有儲存庫</strong>。
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
"esbuild-loader": "4.3.0",
|
||||
"escape-goat": "4.0.0",
|
||||
"fast-glob": "3.3.3",
|
||||
"htmx.org": "2.0.4",
|
||||
"htmx.org": "2.0.5",
|
||||
"idiomorph": "0.7.3",
|
||||
"jquery": "3.7.1",
|
||||
"katex": "0.16.22",
|
||||
|
|
@ -8233,9 +8233,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/htmx.org": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-2.0.4.tgz",
|
||||
"integrity": "sha512-HLxMCdfXDOJirs3vBZl/ZLoY+c7PfM4Ahr2Ad4YXh6d22T5ltbTXFFkpx9Tgb2vvmWFMbIc3LqN2ToNkZJvyYQ==",
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-2.0.5.tgz",
|
||||
"integrity": "sha512-ocgvtHCShWFW0DvSV1NbJC7Y5EzUMy2eo5zeWvGj2Ac4LOr7sv9YKg4jzCZJdXN21fXACmCViwKSy+cm6i2dWQ==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
"esbuild-loader": "4.3.0",
|
||||
"escape-goat": "4.0.0",
|
||||
"fast-glob": "3.3.3",
|
||||
"htmx.org": "2.0.4",
|
||||
"htmx.org": "2.0.5",
|
||||
"idiomorph": "0.7.3",
|
||||
"jquery": "3.7.1",
|
||||
"katex": "0.16.22",
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ package packages
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
|
|
@ -282,42 +280,10 @@ func CommonRoutes() *web.Router {
|
|||
})
|
||||
})
|
||||
}, reqPackageAccess(perm.AccessModeRead))
|
||||
r.Group("/conda", func() {
|
||||
var (
|
||||
downloadPattern = regexp.MustCompile(`\A(.+/)?(.+)/((?:[^/]+(?:\.tar\.bz2|\.conda))|(?:current_)?repodata\.json(?:\.bz2)?)\z`)
|
||||
uploadPattern = regexp.MustCompile(`\A(.+/)?([^/]+(?:\.tar\.bz2|\.conda))\z`)
|
||||
)
|
||||
|
||||
r.Get("/*", func(ctx *context.Context) {
|
||||
m := downloadPattern.FindStringSubmatch(ctx.PathParam("*"))
|
||||
if len(m) == 0 {
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.SetPathParam("channel", strings.TrimSuffix(m[1], "/"))
|
||||
ctx.SetPathParam("architecture", m[2])
|
||||
ctx.SetPathParam("filename", m[3])
|
||||
|
||||
switch m[3] {
|
||||
case "repodata.json", "repodata.json.bz2", "current_repodata.json", "current_repodata.json.bz2":
|
||||
conda.EnumeratePackages(ctx)
|
||||
default:
|
||||
conda.DownloadPackageFile(ctx)
|
||||
}
|
||||
})
|
||||
r.Put("/*", reqPackageAccess(perm.AccessModeWrite), func(ctx *context.Context) {
|
||||
m := uploadPattern.FindStringSubmatch(ctx.PathParam("*"))
|
||||
if len(m) == 0 {
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.SetPathParam("channel", strings.TrimSuffix(m[1], "/"))
|
||||
ctx.SetPathParam("filename", m[2])
|
||||
|
||||
conda.UploadPackageFile(ctx)
|
||||
})
|
||||
r.PathGroup("/conda/*", func(g *web.RouterPathGroup) {
|
||||
g.MatchPath("GET", "/<architecture>/<filename>", conda.ListOrGetPackages)
|
||||
g.MatchPath("GET", "/<channel:*>/<architecture>/<filename>", conda.ListOrGetPackages)
|
||||
g.MatchPath("PUT", "/<channel:*>/<filename>", reqPackageAccess(perm.AccessModeWrite), conda.UploadPackageFile)
|
||||
}, reqPackageAccess(perm.AccessModeRead))
|
||||
r.Group("/cran", func() {
|
||||
r.Group("/src", func() {
|
||||
|
|
@ -358,60 +324,15 @@ func CommonRoutes() *web.Router {
|
|||
}, reqPackageAccess(perm.AccessModeRead))
|
||||
r.Group("/go", func() {
|
||||
r.Put("/upload", reqPackageAccess(perm.AccessModeWrite), goproxy.UploadPackage)
|
||||
r.Get("/sumdb/sum.golang.org/supported", func(ctx *context.Context) {
|
||||
ctx.Status(http.StatusNotFound)
|
||||
})
|
||||
r.Get("/sumdb/sum.golang.org/supported", http.NotFound)
|
||||
|
||||
// Manual mapping of routes because the package name contains slashes which chi does not support
|
||||
// https://go.dev/ref/mod#goproxy-protocol
|
||||
r.Get("/*", func(ctx *context.Context) {
|
||||
path := ctx.PathParam("*")
|
||||
|
||||
if strings.HasSuffix(path, "/@latest") {
|
||||
ctx.SetPathParam("name", path[:len(path)-len("/@latest")])
|
||||
ctx.SetPathParam("version", "latest")
|
||||
|
||||
goproxy.PackageVersionMetadata(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
parts := strings.SplitN(path, "/@v/", 2)
|
||||
if len(parts) != 2 {
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.SetPathParam("name", parts[0])
|
||||
|
||||
// <package/name>/@v/list
|
||||
if parts[1] == "list" {
|
||||
goproxy.EnumeratePackageVersions(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
// <package/name>/@v/<version>.zip
|
||||
if strings.HasSuffix(parts[1], ".zip") {
|
||||
ctx.SetPathParam("version", parts[1][:len(parts[1])-len(".zip")])
|
||||
|
||||
goproxy.DownloadPackageFile(ctx)
|
||||
return
|
||||
}
|
||||
// <package/name>/@v/<version>.info
|
||||
if strings.HasSuffix(parts[1], ".info") {
|
||||
ctx.SetPathParam("version", parts[1][:len(parts[1])-len(".info")])
|
||||
|
||||
goproxy.PackageVersionMetadata(ctx)
|
||||
return
|
||||
}
|
||||
// <package/name>/@v/<version>.mod
|
||||
if strings.HasSuffix(parts[1], ".mod") {
|
||||
ctx.SetPathParam("version", parts[1][:len(parts[1])-len(".mod")])
|
||||
|
||||
goproxy.PackageVersionGoModContent(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNotFound)
|
||||
r.PathGroup("/*", func(g *web.RouterPathGroup) {
|
||||
g.MatchPath("GET", "/<name:*>/@<version:latest>", goproxy.PackageVersionMetadata)
|
||||
g.MatchPath("GET", "/<name:*>/@v/list", goproxy.EnumeratePackageVersions)
|
||||
g.MatchPath("GET", "/<name:*>/@v/<version>.zip", goproxy.DownloadPackageFile)
|
||||
g.MatchPath("GET", "/<name:*>/@v/<version>.info", goproxy.PackageVersionMetadata)
|
||||
g.MatchPath("GET", "/<name:*>/@v/<version>.mod", goproxy.PackageVersionGoModContent)
|
||||
})
|
||||
}, reqPackageAccess(perm.AccessModeRead))
|
||||
r.Group("/generic", func() {
|
||||
|
|
@ -532,82 +453,24 @@ func CommonRoutes() *web.Router {
|
|||
})
|
||||
})
|
||||
}, reqPackageAccess(perm.AccessModeRead))
|
||||
|
||||
r.Group("/pypi", func() {
|
||||
r.Post("/", reqPackageAccess(perm.AccessModeWrite), pypi.UploadPackageFile)
|
||||
r.Get("/files/{id}/{version}/{filename}", pypi.DownloadPackageFile)
|
||||
r.Get("/simple/{id}", pypi.PackageMetadata)
|
||||
}, reqPackageAccess(perm.AccessModeRead))
|
||||
r.Group("/rpm", func() {
|
||||
r.Group("/repository.key", func() {
|
||||
r.Head("", rpm.GetRepositoryKey)
|
||||
r.Get("", rpm.GetRepositoryKey)
|
||||
})
|
||||
|
||||
var (
|
||||
repoPattern = regexp.MustCompile(`\A(.*?)\.repo\z`)
|
||||
uploadPattern = regexp.MustCompile(`\A(.*?)/upload\z`)
|
||||
filePattern = regexp.MustCompile(`\A(.*?)/package/([^/]+)/([^/]+)/([^/]+)(?:/([^/]+\.rpm)|)\z`)
|
||||
repoFilePattern = regexp.MustCompile(`\A(.*?)/repodata/([^/]+)\z`)
|
||||
)
|
||||
|
||||
r.Methods("HEAD,GET,PUT,DELETE", "*", func(ctx *context.Context) {
|
||||
path := ctx.PathParam("*")
|
||||
isHead := ctx.Req.Method == http.MethodHead
|
||||
isGetHead := ctx.Req.Method == http.MethodHead || ctx.Req.Method == http.MethodGet
|
||||
isPut := ctx.Req.Method == http.MethodPut
|
||||
isDelete := ctx.Req.Method == http.MethodDelete
|
||||
|
||||
m := repoPattern.FindStringSubmatch(path)
|
||||
if len(m) == 2 && isGetHead {
|
||||
ctx.SetPathParam("group", strings.Trim(m[1], "/"))
|
||||
rpm.GetRepositoryConfig(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
m = repoFilePattern.FindStringSubmatch(path)
|
||||
if len(m) == 3 && isGetHead {
|
||||
ctx.SetPathParam("group", strings.Trim(m[1], "/"))
|
||||
ctx.SetPathParam("filename", m[2])
|
||||
if isHead {
|
||||
rpm.CheckRepositoryFileExistence(ctx)
|
||||
} else {
|
||||
rpm.GetRepositoryFile(ctx)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
m = uploadPattern.FindStringSubmatch(path)
|
||||
if len(m) == 2 && isPut {
|
||||
reqPackageAccess(perm.AccessModeWrite)(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
ctx.SetPathParam("group", strings.Trim(m[1], "/"))
|
||||
rpm.UploadPackageFile(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
m = filePattern.FindStringSubmatch(path)
|
||||
if len(m) == 6 && (isGetHead || isDelete) {
|
||||
ctx.SetPathParam("group", strings.Trim(m[1], "/"))
|
||||
ctx.SetPathParam("name", m[2])
|
||||
ctx.SetPathParam("version", m[3])
|
||||
ctx.SetPathParam("architecture", m[4])
|
||||
if isGetHead {
|
||||
rpm.DownloadPackageFile(ctx)
|
||||
} else {
|
||||
reqPackageAccess(perm.AccessModeWrite)(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
rpm.DeletePackageFile(ctx)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNotFound)
|
||||
})
|
||||
r.Methods("HEAD,GET", "/rpm.repo", reqPackageAccess(perm.AccessModeRead), rpm.GetRepositoryConfig)
|
||||
r.PathGroup("/rpm/*", func(g *web.RouterPathGroup) {
|
||||
g.MatchPath("HEAD,GET", "/repository.key", rpm.GetRepositoryKey)
|
||||
g.MatchPath("HEAD,GET", "/<group:*>.repo", rpm.GetRepositoryConfig)
|
||||
g.MatchPath("HEAD", "/<group:*>/repodata/<filename>", rpm.CheckRepositoryFileExistence)
|
||||
g.MatchPath("GET", "/<group:*>/repodata/<filename>", rpm.GetRepositoryFile)
|
||||
g.MatchPath("PUT", "/<group:*>/upload", reqPackageAccess(perm.AccessModeWrite), rpm.UploadPackageFile)
|
||||
g.MatchPath("HEAD,GET", "/<group:*>/package/<name>/<version>/<architecture>", rpm.DownloadPackageFile)
|
||||
g.MatchPath("DELETE", "/<group:*>/package/<name>/<version>/<architecture>", reqPackageAccess(perm.AccessModeWrite), rpm.DeletePackageFile)
|
||||
}, reqPackageAccess(perm.AccessModeRead))
|
||||
|
||||
r.Group("/rubygems", func() {
|
||||
r.Get("/specs.4.8.gz", rubygems.EnumeratePackages)
|
||||
r.Get("/latest_specs.4.8.gz", rubygems.EnumeratePackagesLatest)
|
||||
|
|
@ -621,6 +484,7 @@ func CommonRoutes() *web.Router {
|
|||
r.Delete("/yank", rubygems.DeletePackage)
|
||||
}, reqPackageAccess(perm.AccessModeWrite))
|
||||
}, reqPackageAccess(perm.AccessModeRead))
|
||||
|
||||
r.Group("/swift", func() {
|
||||
r.Group("", func() { // Needs to be unauthenticated.
|
||||
r.Post("", swift.CheckAuthenticate)
|
||||
|
|
@ -632,31 +496,12 @@ func CommonRoutes() *web.Router {
|
|||
r.Get("", swift.EnumeratePackageVersions)
|
||||
r.Get(".json", swift.EnumeratePackageVersions)
|
||||
}, swift.CheckAcceptMediaType(swift.AcceptJSON))
|
||||
r.Group("/{version}", func() {
|
||||
r.Get("/Package.swift", swift.CheckAcceptMediaType(swift.AcceptSwift), swift.DownloadManifest)
|
||||
r.Put("", reqPackageAccess(perm.AccessModeWrite), swift.CheckAcceptMediaType(swift.AcceptJSON), swift.UploadPackageFile)
|
||||
r.Get("", func(ctx *context.Context) {
|
||||
// Can't use normal routes here: https://github.com/go-chi/chi/issues/781
|
||||
|
||||
version := ctx.PathParam("version")
|
||||
if strings.HasSuffix(version, ".zip") {
|
||||
swift.CheckAcceptMediaType(swift.AcceptZip)(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
ctx.SetPathParam("version", version[:len(version)-4])
|
||||
swift.DownloadPackageFile(ctx)
|
||||
} else {
|
||||
swift.CheckAcceptMediaType(swift.AcceptJSON)(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
if strings.HasSuffix(version, ".json") {
|
||||
ctx.SetPathParam("version", version[:len(version)-5])
|
||||
}
|
||||
swift.PackageVersionMetadata(ctx)
|
||||
}
|
||||
})
|
||||
r.PathGroup("/*", func(g *web.RouterPathGroup) {
|
||||
g.MatchPath("GET", "/<version>.json", swift.CheckAcceptMediaType(swift.AcceptJSON), swift.PackageVersionMetadata)
|
||||
g.MatchPath("GET", "/<version>.zip", swift.CheckAcceptMediaType(swift.AcceptZip), swift.DownloadPackageFile)
|
||||
g.MatchPath("GET", "/<version>/Package.swift", swift.CheckAcceptMediaType(swift.AcceptSwift), swift.DownloadManifest)
|
||||
g.MatchPath("GET", "/<version>", swift.CheckAcceptMediaType(swift.AcceptJSON), swift.PackageVersionMetadata)
|
||||
g.MatchPath("PUT", "/<version>", reqPackageAccess(perm.AccessModeWrite), swift.CheckAcceptMediaType(swift.AcceptJSON), swift.UploadPackageFile)
|
||||
})
|
||||
})
|
||||
r.Get("/identifiers", swift.CheckAcceptMediaType(swift.AcceptJSON), swift.LookupPackageIdentifiers)
|
||||
|
|
@ -705,18 +550,13 @@ func ContainerRoutes() *web.Router {
|
|||
r.PathGroup("/*", func(g *web.RouterPathGroup) {
|
||||
g.MatchPath("POST", "/<image:*>/blobs/uploads", reqPackageAccess(perm.AccessModeWrite), container.VerifyImageName, container.PostBlobsUploads)
|
||||
g.MatchPath("GET", "/<image:*>/tags/list", container.VerifyImageName, container.GetTagsList)
|
||||
g.MatchPath("GET,PATCH,PUT,DELETE", `/<image:*>/blobs/uploads/<uuid:[-.=\w]+>`, reqPackageAccess(perm.AccessModeWrite), container.VerifyImageName, func(ctx *context.Context) {
|
||||
switch ctx.Req.Method {
|
||||
case http.MethodGet:
|
||||
container.GetBlobsUpload(ctx)
|
||||
case http.MethodPatch:
|
||||
container.PatchBlobsUpload(ctx)
|
||||
case http.MethodPut:
|
||||
container.PutBlobsUpload(ctx)
|
||||
default: /* DELETE */
|
||||
container.DeleteBlobsUpload(ctx)
|
||||
}
|
||||
})
|
||||
|
||||
patternBlobsUploadsUUID := g.PatternRegexp(`/<image:*>/blobs/uploads/<uuid:[-.=\w]+>`, reqPackageAccess(perm.AccessModeWrite), container.VerifyImageName)
|
||||
g.MatchPattern("GET", patternBlobsUploadsUUID, container.GetBlobsUpload)
|
||||
g.MatchPattern("PATCH", patternBlobsUploadsUUID, container.PatchBlobsUpload)
|
||||
g.MatchPattern("PUT", patternBlobsUploadsUUID, container.PutBlobsUpload)
|
||||
g.MatchPattern("DELETE", patternBlobsUploadsUUID, container.DeleteBlobsUpload)
|
||||
|
||||
g.MatchPath("HEAD", `/<image:*>/blobs/<digest>`, container.VerifyImageName, container.HeadBlob)
|
||||
g.MatchPath("GET", `/<image:*>/blobs/<digest>`, container.VerifyImageName, container.GetBlob)
|
||||
g.MatchPath("DELETE", `/<image:*>/blobs/<digest>`, container.VerifyImageName, reqPackageAccess(perm.AccessModeWrite), container.DeleteBlob)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,24 @@ func apiError(ctx *context.Context, status int, obj any) {
|
|||
})
|
||||
}
|
||||
|
||||
func isCondaPackageFileName(filename string) bool {
|
||||
return strings.HasSuffix(filename, ".tar.bz2") || strings.HasSuffix(filename, ".conda")
|
||||
}
|
||||
|
||||
func ListOrGetPackages(ctx *context.Context) {
|
||||
filename := ctx.PathParam("filename")
|
||||
switch filename {
|
||||
case "repodata.json", "repodata.json.bz2", "current_repodata.json", "current_repodata.json.bz2":
|
||||
EnumeratePackages(ctx)
|
||||
return
|
||||
}
|
||||
if isCondaPackageFileName(filename) {
|
||||
DownloadPackageFile(ctx)
|
||||
return
|
||||
}
|
||||
ctx.NotFound(nil)
|
||||
}
|
||||
|
||||
func EnumeratePackages(ctx *context.Context) {
|
||||
type Info struct {
|
||||
Subdir string `json:"subdir"`
|
||||
|
|
@ -174,6 +192,12 @@ func EnumeratePackages(ctx *context.Context) {
|
|||
}
|
||||
|
||||
func UploadPackageFile(ctx *context.Context) {
|
||||
filename := ctx.PathParam("filename")
|
||||
if !isCondaPackageFileName(filename) {
|
||||
apiError(ctx, http.StatusBadRequest, nil)
|
||||
return
|
||||
}
|
||||
|
||||
upload, needToClose, err := ctx.UploadStream()
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
|
|
@ -191,7 +215,7 @@ func UploadPackageFile(ctx *context.Context) {
|
|||
defer buf.Close()
|
||||
|
||||
var pck *conda_module.Package
|
||||
if strings.HasSuffix(strings.ToLower(ctx.PathParam("filename")), ".tar.bz2") {
|
||||
if strings.HasSuffix(filename, ".tar.bz2") {
|
||||
pck, err = conda_module.ParsePackageBZ2(buf)
|
||||
} else {
|
||||
pck, err = conda_module.ParsePackageConda(buf, buf.Size())
|
||||
|
|
|
|||
|
|
@ -90,14 +90,14 @@ func mountBlob(ctx context.Context, pi *packages_service.PackageInfo, pb *packag
|
|||
})
|
||||
}
|
||||
|
||||
func containerPkgName(piOwnerID int64, piName string) string {
|
||||
return fmt.Sprintf("pkg_%d_container_%s", piOwnerID, strings.ToLower(piName))
|
||||
func containerGlobalLockKey(piOwnerID int64, piName, usage string) string {
|
||||
return fmt.Sprintf("pkg_%d_container_%s_%s", piOwnerID, strings.ToLower(piName), usage)
|
||||
}
|
||||
|
||||
func getOrCreateUploadVersion(ctx context.Context, pi *packages_service.PackageInfo) (*packages_model.PackageVersion, error) {
|
||||
var uploadVersion *packages_model.PackageVersion
|
||||
|
||||
releaser, err := globallock.Lock(ctx, containerPkgName(pi.Owner.ID, pi.Name))
|
||||
releaser, err := globallock.Lock(ctx, containerGlobalLockKey(pi.Owner.ID, pi.Name, "package"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -178,7 +178,7 @@ func createFileForBlob(ctx context.Context, pv *packages_model.PackageVersion, p
|
|||
}
|
||||
|
||||
func deleteBlob(ctx context.Context, ownerID int64, image string, digest digest.Digest) error {
|
||||
releaser, err := globallock.Lock(ctx, containerPkgName(ownerID, image))
|
||||
releaser, err := globallock.Lock(ctx, containerGlobalLockKey(ownerID, image, "blob"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import (
|
|||
packages_service "code.gitea.io/gitea/services/packages"
|
||||
container_service "code.gitea.io/gitea/services/packages/container"
|
||||
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// maximum size of a container manifest
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
packages_model "code.gitea.io/gitea/models/packages"
|
||||
container_model "code.gitea.io/gitea/models/packages/container"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/globallock"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
packages_module "code.gitea.io/gitea/modules/packages"
|
||||
|
|
@ -61,6 +62,13 @@ func processManifest(ctx context.Context, mci *manifestCreationInfo, buf *packag
|
|||
}
|
||||
}
|
||||
|
||||
// .../container/manifest.go:453:createManifestBlob() [E] Error inserting package blob: Error 1062 (23000): Duplicate entry '..........' for key 'package_blob.UQE_package_blob_md5'
|
||||
releaser, err := globallock.Lock(ctx, containerGlobalLockKey(mci.Owner.ID, mci.Image, "manifest"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer releaser()
|
||||
|
||||
if container_module.IsMediaTypeImageManifest(mci.MediaType) {
|
||||
return processOciImageManifest(ctx, mci, buf)
|
||||
} else if container_module.IsMediaTypeImageIndex(mci.MediaType) {
|
||||
|
|
|
|||
|
|
@ -601,5 +601,7 @@ func SubmitInstall(ctx *context.Context) {
|
|||
// InstallDone shows the "post-install" page, makes it easier to develop the page.
|
||||
// The name is not called as "PostInstall" to avoid misinterpretation as a handler for "POST /install"
|
||||
func InstallDone(ctx *context.Context) { //nolint
|
||||
hasUsers, _ := user_model.HasUsers(ctx)
|
||||
ctx.Data["IsAccountCreated"] = hasUsers.HasAnyUser
|
||||
ctx.HTML(http.StatusOK, tplPostInstall)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -421,9 +421,11 @@ func SignOut(ctx *context.Context) {
|
|||
// SignUp render the register page
|
||||
func SignUp(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("sign_up")
|
||||
|
||||
ctx.Data["SignUpLink"] = setting.AppSubURL + "/user/sign_up"
|
||||
|
||||
hasUsers, _ := user_model.HasUsers(ctx)
|
||||
ctx.Data["IsFirstTimeRegistration"] = !hasUsers.HasAnyUser
|
||||
|
||||
oauth2Providers, err := oauth2.GetOAuth2Providers(ctx, optional.Some(true))
|
||||
if err != nil {
|
||||
ctx.ServerError("UserSignUp", err)
|
||||
|
|
@ -610,7 +612,13 @@ func createUserInContext(ctx *context.Context, tpl templates.TplName, form any,
|
|||
// sends a confirmation email if required.
|
||||
func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth.User) (ok bool) {
|
||||
// Auto-set admin for the only user.
|
||||
if user_model.CountUsers(ctx, nil) == 1 {
|
||||
hasUsers, err := user_model.HasUsers(ctx)
|
||||
if err != nil {
|
||||
ctx.ServerError("HasUsers", err)
|
||||
return false
|
||||
}
|
||||
if hasUsers.HasOnlyOneUser {
|
||||
// the only user is the one just created, will set it as admin
|
||||
opts := &user_service.UpdateOptions{
|
||||
IsActive: optional.Some(true),
|
||||
IsAdmin: user_service.UpdateOptionFieldFromValue(true),
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ func Repos(ctx *context.Context) {
|
|||
ctx.Data["CodePageIsDisabled"] = setting.Service.Explore.DisableCodePage
|
||||
ctx.Data["Title"] = ctx.Tr("explore")
|
||||
ctx.Data["PageIsExplore"] = true
|
||||
ctx.Data["ShowRepoOwnerOnList"] = true
|
||||
ctx.Data["PageIsExploreRepositories"] = true
|
||||
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import (
|
|||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
shared_user "code.gitea.io/gitea/routers/web/shared/user"
|
||||
user_setting "code.gitea.io/gitea/routers/web/user/setting"
|
||||
|
|
@ -31,8 +32,6 @@ import (
|
|||
const (
|
||||
// tplSettingsOptions template path for render settings
|
||||
tplSettingsOptions templates.TplName = "org/settings/options"
|
||||
// tplSettingsDelete template path for render delete repository
|
||||
tplSettingsDelete templates.TplName = "org/settings/delete"
|
||||
// tplSettingsHooks template path for render hook settings
|
||||
tplSettingsHooks templates.TplName = "org/settings/hooks"
|
||||
// tplSettingsLabels template path for render labels settings
|
||||
|
|
@ -71,26 +70,6 @@ func SettingsPost(ctx *context.Context) {
|
|||
|
||||
org := ctx.Org.Organization
|
||||
|
||||
if org.Name != form.Name {
|
||||
if err := user_service.RenameUser(ctx, org.AsUser(), form.Name); err != nil {
|
||||
if user_model.IsErrUserAlreadyExist(err) {
|
||||
ctx.Data["Err_Name"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), tplSettingsOptions, &form)
|
||||
} else if db.IsErrNameReserved(err) {
|
||||
ctx.Data["Err_Name"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(db.ErrNameReserved).Name), tplSettingsOptions, &form)
|
||||
} else if db.IsErrNamePatternNotAllowed(err) {
|
||||
ctx.Data["Err_Name"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(db.ErrNamePatternNotAllowed).Pattern), tplSettingsOptions, &form)
|
||||
} else {
|
||||
ctx.ServerError("RenameUser", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Org.OrgLink = setting.AppSubURL + "/org/" + url.PathEscape(org.Name)
|
||||
}
|
||||
|
||||
if form.Email != "" {
|
||||
if err := user_service.ReplacePrimaryEmailAddress(ctx, org.AsUser(), form.Email); err != nil {
|
||||
ctx.Data["Err_Email"] = true
|
||||
|
|
@ -163,42 +142,27 @@ func SettingsDeleteAvatar(ctx *context.Context) {
|
|||
ctx.JSONRedirect(ctx.Org.OrgLink + "/settings")
|
||||
}
|
||||
|
||||
// SettingsDelete response for deleting an organization
|
||||
func SettingsDelete(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("org.settings")
|
||||
ctx.Data["PageIsOrgSettings"] = true
|
||||
ctx.Data["PageIsSettingsDelete"] = true
|
||||
// SettingsDeleteOrgPost response for deleting an organization
|
||||
func SettingsDeleteOrgPost(ctx *context.Context) {
|
||||
if ctx.Org.Organization.Name != ctx.FormString("org_name") {
|
||||
ctx.JSONError(ctx.Tr("form.enterred_invalid_org_name"))
|
||||
return
|
||||
}
|
||||
|
||||
if ctx.Req.Method == http.MethodPost {
|
||||
if ctx.Org.Organization.Name != ctx.FormString("org_name") {
|
||||
ctx.Data["Err_OrgName"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_org_name"), tplSettingsDelete, nil)
|
||||
return
|
||||
}
|
||||
|
||||
if err := org_service.DeleteOrganization(ctx, ctx.Org.Organization, false); err != nil {
|
||||
if repo_model.IsErrUserOwnRepos(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.org_still_own_repo"))
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/settings/delete")
|
||||
} else if packages_model.IsErrUserOwnPackages(err) {
|
||||
ctx.Flash.Error(ctx.Tr("form.org_still_own_packages"))
|
||||
ctx.Redirect(ctx.Org.OrgLink + "/settings/delete")
|
||||
} else {
|
||||
ctx.ServerError("DeleteOrganization", err)
|
||||
}
|
||||
if err := org_service.DeleteOrganization(ctx, ctx.Org.Organization, false /* no purge */); err != nil {
|
||||
if repo_model.IsErrUserOwnRepos(err) {
|
||||
ctx.JSONError(ctx.Tr("form.org_still_own_repo"))
|
||||
} else if packages_model.IsErrUserOwnPackages(err) {
|
||||
ctx.JSONError(ctx.Tr("form.org_still_own_packages"))
|
||||
} else {
|
||||
log.Trace("Organization deleted: %s", ctx.Org.Organization.Name)
|
||||
ctx.Redirect(setting.AppSubURL + "/")
|
||||
log.Error("DeleteOrganization: %v", err)
|
||||
ctx.JSONError(util.Iif(ctx.Doer.IsAdmin, err.Error(), string(ctx.Tr("org.settings.delete_failed"))))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := shared_user.RenderUserOrgHeader(ctx); err != nil {
|
||||
ctx.ServerError("RenderUserOrgHeader", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.HTML(http.StatusOK, tplSettingsDelete)
|
||||
ctx.Flash.Success(ctx.Tr("org.settings.delete_successful", ctx.Org.Organization.Name))
|
||||
ctx.JSONRedirect(setting.AppSubURL + "/")
|
||||
}
|
||||
|
||||
// Webhooks render webhook list page
|
||||
|
|
@ -250,3 +214,40 @@ func Labels(ctx *context.Context) {
|
|||
|
||||
ctx.HTML(http.StatusOK, tplSettingsLabels)
|
||||
}
|
||||
|
||||
// SettingsRenamePost response for renaming organization
|
||||
func SettingsRenamePost(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.RenameOrgForm)
|
||||
if ctx.HasError() {
|
||||
ctx.JSONError(ctx.GetErrMsg())
|
||||
return
|
||||
}
|
||||
|
||||
oldOrgName, newOrgName := ctx.Org.Organization.Name, form.NewOrgName
|
||||
|
||||
if form.OrgName != oldOrgName {
|
||||
ctx.JSONError(ctx.Tr("form.enterred_invalid_org_name"))
|
||||
return
|
||||
}
|
||||
if newOrgName == oldOrgName {
|
||||
ctx.JSONError(ctx.Tr("org.settings.rename_no_change"))
|
||||
return
|
||||
}
|
||||
|
||||
if err := user_service.RenameUser(ctx, ctx.Org.Organization.AsUser(), newOrgName); err != nil {
|
||||
if user_model.IsErrUserAlreadyExist(err) {
|
||||
ctx.JSONError(ctx.Tr("org.form.name_been_taken", newOrgName))
|
||||
} else if db.IsErrNameReserved(err) {
|
||||
ctx.JSONError(ctx.Tr("org.form.name_reserved", newOrgName))
|
||||
} else if db.IsErrNamePatternNotAllowed(err) {
|
||||
ctx.JSONError(ctx.Tr("org.form.name_pattern_not_allowed", newOrgName))
|
||||
} else {
|
||||
log.Error("RenameOrganization: %v", err)
|
||||
ctx.JSONError(util.Iif(ctx.Doer.IsAdmin, err.Error(), string(ctx.Tr("org.settings.rename_failed"))))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("org.settings.rename_success", oldOrgName, newOrgName))
|
||||
ctx.JSONRedirect(setting.AppSubURL + "/org/" + url.PathEscape(newOrgName) + "/settings")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ func prepareWorkflowList(ctx *context.Context, workflows []Workflow) {
|
|||
ctx.Data["Page"] = pager
|
||||
ctx.Data["HasWorkflowsOrRuns"] = len(workflows) > 0 || len(runs) > 0
|
||||
|
||||
ctx.Data["AllowDeleteWorkflowRuns"] = ctx.Repo.CanWrite(unit.TypeActions)
|
||||
ctx.Data["CanWriteRepoUnitActions"] = ctx.Repo.CanWrite(unit.TypeActions)
|
||||
}
|
||||
|
||||
// loadIsRefDeleted loads the IsRefDeleted field for each run in the list.
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/charset"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/httplib"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
|
|
@ -39,7 +40,7 @@ const (
|
|||
editorCommitChoiceNewBranch string = "commit-to-new-branch"
|
||||
)
|
||||
|
||||
func prepareEditorCommitFormOptions(ctx *context.Context, editorAction string) {
|
||||
func prepareEditorCommitFormOptions(ctx *context.Context, editorAction string) *context.CommitFormOptions {
|
||||
cleanedTreePath := files_service.CleanGitTreePath(ctx.Repo.TreePath)
|
||||
if cleanedTreePath != ctx.Repo.TreePath {
|
||||
redirectTo := fmt.Sprintf("%s/%s/%s/%s", ctx.Repo.RepoLink, editorAction, util.PathEscapeSegments(ctx.Repo.BranchName), util.PathEscapeSegments(cleanedTreePath))
|
||||
|
|
@ -47,18 +48,28 @@ func prepareEditorCommitFormOptions(ctx *context.Context, editorAction string) {
|
|||
redirectTo += "?" + ctx.Req.URL.RawQuery
|
||||
}
|
||||
ctx.Redirect(redirectTo)
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
commitFormBehaviors, err := ctx.Repo.PrepareCommitFormBehaviors(ctx, ctx.Doer)
|
||||
commitFormOptions, err := context.PrepareCommitFormOptions(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.Permission, ctx.Repo.RefFullName)
|
||||
if err != nil {
|
||||
ctx.ServerError("PrepareCommitFormBehaviors", err)
|
||||
return
|
||||
ctx.ServerError("PrepareCommitFormOptions", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if commitFormOptions.NeedFork {
|
||||
ForkToEdit(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
if commitFormOptions.WillSubmitToFork && !commitFormOptions.TargetRepo.CanEnableEditor() {
|
||||
ctx.Data["NotFoundPrompt"] = ctx.Locale.Tr("repo.editor.fork_not_editable")
|
||||
ctx.NotFound(nil)
|
||||
}
|
||||
|
||||
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
||||
ctx.Data["TreePath"] = ctx.Repo.TreePath
|
||||
ctx.Data["CommitFormBehaviors"] = commitFormBehaviors
|
||||
ctx.Data["CommitFormOptions"] = commitFormOptions
|
||||
|
||||
// for online editor
|
||||
ctx.Data["PreviewableExtensions"] = strings.Join(markup.PreviewableExtensions(), ",")
|
||||
|
|
@ -69,25 +80,27 @@ func prepareEditorCommitFormOptions(ctx *context.Context, editorAction string) {
|
|||
// form fields
|
||||
ctx.Data["commit_summary"] = ""
|
||||
ctx.Data["commit_message"] = ""
|
||||
ctx.Data["commit_choice"] = util.Iif(commitFormBehaviors.CanCommitToBranch, editorCommitChoiceDirect, editorCommitChoiceNewBranch)
|
||||
ctx.Data["new_branch_name"] = getUniquePatchBranchName(ctx, ctx.Doer.LowerName, ctx.Repo.Repository)
|
||||
ctx.Data["commit_choice"] = util.Iif(commitFormOptions.CanCommitToBranch, editorCommitChoiceDirect, editorCommitChoiceNewBranch)
|
||||
ctx.Data["new_branch_name"] = getUniquePatchBranchName(ctx, ctx.Doer.LowerName, commitFormOptions.TargetRepo)
|
||||
ctx.Data["last_commit"] = ctx.Repo.CommitID
|
||||
return commitFormOptions
|
||||
}
|
||||
|
||||
func prepareTreePathFieldsAndPaths(ctx *context.Context, treePath string) {
|
||||
// show the tree path fields in the "breadcrumb" and help users to edit the target tree path
|
||||
ctx.Data["TreeNames"], ctx.Data["TreePaths"] = getParentTreeFields(treePath)
|
||||
ctx.Data["TreeNames"], ctx.Data["TreePaths"] = getParentTreeFields(strings.TrimPrefix(treePath, "/"))
|
||||
}
|
||||
|
||||
type parsedEditorCommitForm[T any] struct {
|
||||
form T
|
||||
commonForm *forms.CommitCommonForm
|
||||
CommitFormBehaviors *context.CommitFormBehaviors
|
||||
TargetBranchName string
|
||||
GitCommitter *files_service.IdentityOptions
|
||||
type preparedEditorCommitForm[T any] struct {
|
||||
form T
|
||||
commonForm *forms.CommitCommonForm
|
||||
CommitFormOptions *context.CommitFormOptions
|
||||
OldBranchName string
|
||||
NewBranchName string
|
||||
GitCommitter *files_service.IdentityOptions
|
||||
}
|
||||
|
||||
func (f *parsedEditorCommitForm[T]) GetCommitMessage(defaultCommitMessage string) string {
|
||||
func (f *preparedEditorCommitForm[T]) GetCommitMessage(defaultCommitMessage string) string {
|
||||
commitMessage := util.IfZero(strings.TrimSpace(f.commonForm.CommitSummary), defaultCommitMessage)
|
||||
if body := strings.TrimSpace(f.commonForm.CommitMessage); body != "" {
|
||||
commitMessage += "\n\n" + body
|
||||
|
|
@ -95,7 +108,7 @@ func (f *parsedEditorCommitForm[T]) GetCommitMessage(defaultCommitMessage string
|
|||
return commitMessage
|
||||
}
|
||||
|
||||
func parseEditorCommitSubmittedForm[T forms.CommitCommonFormInterface](ctx *context.Context) *parsedEditorCommitForm[T] {
|
||||
func prepareEditorCommitSubmittedForm[T forms.CommitCommonFormInterface](ctx *context.Context) *preparedEditorCommitForm[T] {
|
||||
form := web.GetForm(ctx).(T)
|
||||
if ctx.HasError() {
|
||||
ctx.JSONError(ctx.GetErrMsg())
|
||||
|
|
@ -105,15 +118,22 @@ func parseEditorCommitSubmittedForm[T forms.CommitCommonFormInterface](ctx *cont
|
|||
commonForm := form.GetCommitCommonForm()
|
||||
commonForm.TreePath = files_service.CleanGitTreePath(commonForm.TreePath)
|
||||
|
||||
commitFormBehaviors, err := ctx.Repo.PrepareCommitFormBehaviors(ctx, ctx.Doer)
|
||||
commitFormOptions, err := context.PrepareCommitFormOptions(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.Permission, ctx.Repo.RefFullName)
|
||||
if err != nil {
|
||||
ctx.ServerError("PrepareCommitFormBehaviors", err)
|
||||
ctx.ServerError("PrepareCommitFormOptions", err)
|
||||
return nil
|
||||
}
|
||||
if commitFormOptions.NeedFork {
|
||||
// It shouldn't happen, because we should have done the checks in the "GET" request. But just in case.
|
||||
ctx.JSONError(ctx.Locale.TrString("error.not_found"))
|
||||
return nil
|
||||
}
|
||||
|
||||
// check commit behavior
|
||||
targetBranchName := util.Iif(commonForm.CommitChoice == editorCommitChoiceNewBranch, commonForm.NewBranchName, ctx.Repo.BranchName)
|
||||
if targetBranchName == ctx.Repo.BranchName && !commitFormBehaviors.CanCommitToBranch {
|
||||
fromBaseBranch := ctx.FormString("from_base_branch")
|
||||
commitToNewBranch := commonForm.CommitChoice == editorCommitChoiceNewBranch || fromBaseBranch != ""
|
||||
targetBranchName := util.Iif(commitToNewBranch, commonForm.NewBranchName, ctx.Repo.BranchName)
|
||||
if targetBranchName == ctx.Repo.BranchName && !commitFormOptions.CanCommitToBranch {
|
||||
ctx.JSONError(ctx.Tr("repo.editor.cannot_commit_to_protected_branch", targetBranchName))
|
||||
return nil
|
||||
}
|
||||
|
|
@ -125,28 +145,63 @@ func parseEditorCommitSubmittedForm[T forms.CommitCommonFormInterface](ctx *cont
|
|||
return nil
|
||||
}
|
||||
|
||||
return &parsedEditorCommitForm[T]{
|
||||
form: form,
|
||||
commonForm: commonForm,
|
||||
CommitFormBehaviors: commitFormBehaviors,
|
||||
TargetBranchName: targetBranchName,
|
||||
GitCommitter: gitCommitter,
|
||||
if commitToNewBranch {
|
||||
// if target branch exists, we should stop
|
||||
targetBranchExists, err := git_model.IsBranchExist(ctx, commitFormOptions.TargetRepo.ID, targetBranchName)
|
||||
if err != nil {
|
||||
ctx.ServerError("IsBranchExist", err)
|
||||
return nil
|
||||
} else if targetBranchExists {
|
||||
if fromBaseBranch != "" {
|
||||
ctx.JSONError(ctx.Tr("repo.editor.fork_branch_exists", targetBranchName))
|
||||
} else {
|
||||
ctx.JSONError(ctx.Tr("repo.editor.branch_already_exists", targetBranchName))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
oldBranchName := ctx.Repo.BranchName
|
||||
if fromBaseBranch != "" {
|
||||
err = editorPushBranchToForkedRepository(ctx, ctx.Doer, ctx.Repo.Repository.BaseRepo, fromBaseBranch, commitFormOptions.TargetRepo, targetBranchName)
|
||||
if err != nil {
|
||||
log.Error("Unable to editorPushBranchToForkedRepository: %v", err)
|
||||
ctx.JSONError(ctx.Tr("repo.editor.fork_failed_to_push_branch", targetBranchName))
|
||||
return nil
|
||||
}
|
||||
// we have pushed the base branch as the new branch, now we need to commit the changes directly to the new branch
|
||||
oldBranchName = targetBranchName
|
||||
}
|
||||
|
||||
return &preparedEditorCommitForm[T]{
|
||||
form: form,
|
||||
commonForm: commonForm,
|
||||
CommitFormOptions: commitFormOptions,
|
||||
OldBranchName: oldBranchName,
|
||||
NewBranchName: targetBranchName,
|
||||
GitCommitter: gitCommitter,
|
||||
}
|
||||
}
|
||||
|
||||
// redirectForCommitChoice redirects after committing the edit to a branch
|
||||
func redirectForCommitChoice[T any](ctx *context.Context, parsed *parsedEditorCommitForm[T], treePath string) {
|
||||
func redirectForCommitChoice[T any](ctx *context.Context, parsed *preparedEditorCommitForm[T], treePath string) {
|
||||
// when editing a file in a PR, it should return to the origin location
|
||||
if returnURI := ctx.FormString("return_uri"); returnURI != "" && httplib.IsCurrentGiteaSiteURL(ctx, returnURI) {
|
||||
ctx.JSONRedirect(returnURI)
|
||||
return
|
||||
}
|
||||
|
||||
if parsed.commonForm.CommitChoice == editorCommitChoiceNewBranch {
|
||||
// Redirect to a pull request when possible
|
||||
redirectToPullRequest := false
|
||||
repo, baseBranch, headBranch := ctx.Repo.Repository, ctx.Repo.BranchName, parsed.TargetBranchName
|
||||
if repo.UnitEnabled(ctx, unit.TypePullRequests) {
|
||||
redirectToPullRequest = true
|
||||
} else if parsed.CommitFormBehaviors.CanCreateBasePullRequest {
|
||||
repo, baseBranch, headBranch := ctx.Repo.Repository, parsed.OldBranchName, parsed.NewBranchName
|
||||
if ctx.Repo.Repository.IsFork && parsed.CommitFormOptions.CanCreateBasePullRequest {
|
||||
redirectToPullRequest = true
|
||||
baseBranch = repo.BaseRepo.DefaultBranch
|
||||
headBranch = repo.Owner.Name + "/" + repo.Name + ":" + headBranch
|
||||
repo = repo.BaseRepo
|
||||
} else if repo.UnitEnabled(ctx, unit.TypePullRequests) {
|
||||
redirectToPullRequest = true
|
||||
}
|
||||
if redirectToPullRequest {
|
||||
ctx.JSONRedirect(repo.Link() + "/compare/" + util.PathEscapeSegments(baseBranch) + "..." + util.PathEscapeSegments(headBranch))
|
||||
|
|
@ -154,11 +209,9 @@ func redirectForCommitChoice[T any](ctx *context.Context, parsed *parsedEditorCo
|
|||
}
|
||||
}
|
||||
|
||||
returnURI := ctx.FormString("return_uri")
|
||||
if returnURI == "" || !httplib.IsCurrentGiteaSiteURL(ctx, returnURI) {
|
||||
returnURI = util.URLJoin(ctx.Repo.RepoLink, "src/branch", util.PathEscapeSegments(parsed.TargetBranchName), util.PathEscapeSegments(treePath))
|
||||
}
|
||||
ctx.JSONRedirect(returnURI)
|
||||
// redirect to the newly updated file
|
||||
redirectTo := util.URLJoin(ctx.Repo.RepoLink, "src/branch", util.PathEscapeSegments(parsed.NewBranchName), util.PathEscapeSegments(treePath))
|
||||
ctx.JSONRedirect(redirectTo)
|
||||
}
|
||||
|
||||
func editFileOpenExisting(ctx *context.Context) (prefetch []byte, dataRc io.ReadCloser, fInfo *fileInfo) {
|
||||
|
|
@ -268,7 +321,7 @@ func EditFile(ctx *context.Context) {
|
|||
func EditFilePost(ctx *context.Context) {
|
||||
editorAction := ctx.PathParam("editor_action")
|
||||
isNewFile := editorAction == "_new"
|
||||
parsed := parseEditorCommitSubmittedForm[*forms.EditRepoFileForm](ctx)
|
||||
parsed := prepareEditorCommitSubmittedForm[*forms.EditRepoFileForm](ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
|
@ -292,8 +345,8 @@ func EditFilePost(ctx *context.Context) {
|
|||
|
||||
_, err := files_service.ChangeRepoFiles(ctx, ctx.Repo.Repository, ctx.Doer, &files_service.ChangeRepoFilesOptions{
|
||||
LastCommitID: parsed.form.LastCommit,
|
||||
OldBranch: ctx.Repo.BranchName,
|
||||
NewBranch: parsed.TargetBranchName,
|
||||
OldBranch: parsed.OldBranchName,
|
||||
NewBranch: parsed.NewBranchName,
|
||||
Message: parsed.GetCommitMessage(defaultCommitMessage),
|
||||
Files: []*files_service.ChangeRepoFile{
|
||||
{
|
||||
|
|
@ -308,7 +361,7 @@ func EditFilePost(ctx *context.Context) {
|
|||
Committer: parsed.GitCommitter,
|
||||
})
|
||||
if err != nil {
|
||||
editorHandleFileOperationError(ctx, parsed.TargetBranchName, err)
|
||||
editorHandleFileOperationError(ctx, parsed.NewBranchName, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -327,7 +380,7 @@ func DeleteFile(ctx *context.Context) {
|
|||
|
||||
// DeleteFilePost response for deleting file
|
||||
func DeleteFilePost(ctx *context.Context) {
|
||||
parsed := parseEditorCommitSubmittedForm[*forms.DeleteRepoFileForm](ctx)
|
||||
parsed := prepareEditorCommitSubmittedForm[*forms.DeleteRepoFileForm](ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
|
@ -335,8 +388,8 @@ func DeleteFilePost(ctx *context.Context) {
|
|||
treePath := ctx.Repo.TreePath
|
||||
_, err := files_service.ChangeRepoFiles(ctx, ctx.Repo.Repository, ctx.Doer, &files_service.ChangeRepoFilesOptions{
|
||||
LastCommitID: parsed.form.LastCommit,
|
||||
OldBranch: ctx.Repo.BranchName,
|
||||
NewBranch: parsed.TargetBranchName,
|
||||
OldBranch: parsed.OldBranchName,
|
||||
NewBranch: parsed.NewBranchName,
|
||||
Files: []*files_service.ChangeRepoFile{
|
||||
{
|
||||
Operation: "delete",
|
||||
|
|
@ -349,29 +402,29 @@ func DeleteFilePost(ctx *context.Context) {
|
|||
Committer: parsed.GitCommitter,
|
||||
})
|
||||
if err != nil {
|
||||
editorHandleFileOperationError(ctx, parsed.TargetBranchName, err)
|
||||
editorHandleFileOperationError(ctx, parsed.NewBranchName, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.editor.file_delete_success", treePath))
|
||||
redirectTreePath := getClosestParentWithFiles(ctx.Repo.GitRepo, parsed.TargetBranchName, treePath)
|
||||
redirectTreePath := getClosestParentWithFiles(ctx.Repo.GitRepo, parsed.NewBranchName, treePath)
|
||||
redirectForCommitChoice(ctx, parsed, redirectTreePath)
|
||||
}
|
||||
|
||||
func UploadFile(ctx *context.Context) {
|
||||
ctx.Data["PageIsUpload"] = true
|
||||
upload.AddUploadContext(ctx, "repo")
|
||||
prepareTreePathFieldsAndPaths(ctx, ctx.Repo.TreePath)
|
||||
|
||||
prepareEditorCommitFormOptions(ctx, "_upload")
|
||||
opts := prepareEditorCommitFormOptions(ctx, "_upload")
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
upload.AddUploadContextForRepo(ctx, opts.TargetRepo)
|
||||
|
||||
ctx.HTML(http.StatusOK, tplUploadFile)
|
||||
}
|
||||
|
||||
func UploadFilePost(ctx *context.Context) {
|
||||
parsed := parseEditorCommitSubmittedForm[*forms.UploadRepoFileForm](ctx)
|
||||
parsed := prepareEditorCommitSubmittedForm[*forms.UploadRepoFileForm](ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
|
@ -379,8 +432,8 @@ func UploadFilePost(ctx *context.Context) {
|
|||
defaultCommitMessage := ctx.Locale.TrString("repo.editor.upload_files_to_dir", util.IfZero(parsed.form.TreePath, "/"))
|
||||
err := files_service.UploadRepoFiles(ctx, ctx.Repo.Repository, ctx.Doer, &files_service.UploadRepoFileOptions{
|
||||
LastCommitID: parsed.form.LastCommit,
|
||||
OldBranch: ctx.Repo.BranchName,
|
||||
NewBranch: parsed.TargetBranchName,
|
||||
OldBranch: parsed.OldBranchName,
|
||||
NewBranch: parsed.NewBranchName,
|
||||
TreePath: parsed.form.TreePath,
|
||||
Message: parsed.GetCommitMessage(defaultCommitMessage),
|
||||
Files: parsed.form.Files,
|
||||
|
|
@ -389,7 +442,7 @@ func UploadFilePost(ctx *context.Context) {
|
|||
Committer: parsed.GitCommitter,
|
||||
})
|
||||
if err != nil {
|
||||
editorHandleFileOperationError(ctx, parsed.TargetBranchName, err)
|
||||
editorHandleFileOperationError(ctx, parsed.NewBranchName, err)
|
||||
return
|
||||
}
|
||||
redirectForCommitChoice(ctx, parsed, parsed.form.TreePath)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ func NewDiffPatch(ctx *context.Context) {
|
|||
|
||||
// NewDiffPatchPost response for sending patch page
|
||||
func NewDiffPatchPost(ctx *context.Context) {
|
||||
parsed := parseEditorCommitSubmittedForm[*forms.EditRepoFileForm](ctx)
|
||||
parsed := prepareEditorCommitSubmittedForm[*forms.EditRepoFileForm](ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
|
@ -33,8 +33,8 @@ func NewDiffPatchPost(ctx *context.Context) {
|
|||
defaultCommitMessage := ctx.Locale.TrString("repo.editor.patch")
|
||||
_, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, &files.ApplyDiffPatchOptions{
|
||||
LastCommitID: parsed.form.LastCommit,
|
||||
OldBranch: ctx.Repo.BranchName,
|
||||
NewBranch: parsed.TargetBranchName,
|
||||
OldBranch: parsed.OldBranchName,
|
||||
NewBranch: parsed.NewBranchName,
|
||||
Message: parsed.GetCommitMessage(defaultCommitMessage),
|
||||
Content: strings.ReplaceAll(parsed.form.Content.Value(), "\r\n", "\n"),
|
||||
Author: parsed.GitCommitter,
|
||||
|
|
@ -44,7 +44,7 @@ func NewDiffPatchPost(ctx *context.Context) {
|
|||
err = util.ErrorWrapLocale(err, "repo.editor.fail_to_apply_patch")
|
||||
}
|
||||
if err != nil {
|
||||
editorHandleFileOperationError(ctx, parsed.TargetBranchName, err)
|
||||
editorHandleFileOperationError(ctx, parsed.NewBranchName, err)
|
||||
return
|
||||
}
|
||||
redirectForCommitChoice(ctx, parsed, parsed.form.TreePath)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ func CherryPick(ctx *context.Context) {
|
|||
|
||||
func CherryPickPost(ctx *context.Context) {
|
||||
fromCommitID := ctx.PathParam("sha")
|
||||
parsed := parseEditorCommitSubmittedForm[*forms.CherryPickForm](ctx)
|
||||
parsed := prepareEditorCommitSubmittedForm[*forms.CherryPickForm](ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
|
@ -53,8 +53,8 @@ func CherryPickPost(ctx *context.Context) {
|
|||
defaultCommitMessage := util.Iif(parsed.form.Revert, ctx.Locale.TrString("repo.commit.revert-header", fromCommitID), ctx.Locale.TrString("repo.commit.cherry-pick-header", fromCommitID))
|
||||
opts := &files.ApplyDiffPatchOptions{
|
||||
LastCommitID: parsed.form.LastCommit,
|
||||
OldBranch: ctx.Repo.BranchName,
|
||||
NewBranch: parsed.TargetBranchName,
|
||||
OldBranch: parsed.OldBranchName,
|
||||
NewBranch: parsed.NewBranchName,
|
||||
Message: parsed.GetCommitMessage(defaultCommitMessage),
|
||||
Author: parsed.GitCommitter,
|
||||
Committer: parsed.GitCommitter,
|
||||
|
|
@ -78,7 +78,7 @@ func CherryPickPost(ctx *context.Context) {
|
|||
}
|
||||
}
|
||||
if err != nil {
|
||||
editorHandleFileOperationError(ctx, parsed.TargetBranchName, err)
|
||||
editorHandleFileOperationError(ctx, parsed.NewBranchName, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
)
|
||||
|
||||
const tplEditorFork templates.TplName = "repo/editor/fork"
|
||||
|
||||
func ForkToEdit(ctx *context.Context) {
|
||||
ctx.HTML(http.StatusOK, tplEditorFork)
|
||||
}
|
||||
|
||||
func ForkToEditPost(ctx *context.Context) {
|
||||
ForkRepoTo(ctx, ctx.Doer, repo_service.ForkRepoOptions{
|
||||
BaseRepo: ctx.Repo.Repository,
|
||||
Name: getUniqueRepositoryName(ctx, ctx.Doer.ID, ctx.Repo.Repository.Name),
|
||||
Description: ctx.Repo.Repository.Description,
|
||||
SingleBranch: ctx.Repo.Repository.DefaultBranch, // maybe we only need the default branch in the fork?
|
||||
})
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
ctx.JSONRedirect("") // reload the page, the new fork should be editable now
|
||||
}
|
||||
|
|
@ -11,9 +11,11 @@ import (
|
|||
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
context_service "code.gitea.io/gitea/services/context"
|
||||
)
|
||||
|
||||
|
|
@ -83,3 +85,26 @@ func getParentTreeFields(treePath string) (treeNames, treePaths []string) {
|
|||
}
|
||||
return treeNames, treePaths
|
||||
}
|
||||
|
||||
// getUniqueRepositoryName Gets a unique repository name for a user
|
||||
// It will append a -<num> postfix if the name is already taken
|
||||
func getUniqueRepositoryName(ctx context.Context, ownerID int64, name string) string {
|
||||
uniqueName := name
|
||||
for i := 1; i < 1000; i++ {
|
||||
_, err := repo_model.GetRepositoryByName(ctx, ownerID, uniqueName)
|
||||
if err != nil || repo_model.IsErrRepoNotExist(err) {
|
||||
return uniqueName
|
||||
}
|
||||
uniqueName = fmt.Sprintf("%s-%d", name, i)
|
||||
i++
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func editorPushBranchToForkedRepository(ctx context.Context, doer *user_model.User, baseRepo *repo_model.Repository, baseBranchName string, targetRepo *repo_model.Repository, targetBranchName string) error {
|
||||
return git.Push(ctx, baseRepo.RepoPath(), git.PushOptions{
|
||||
Remote: targetRepo.RepoPath(),
|
||||
Branch: baseBranchName + ":" + targetBranchName,
|
||||
Env: repo_module.PushingEnvironment(doer, targetRepo),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,17 +189,25 @@ func ForkPost(ctx *context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
repo, err := repo_service.ForkRepository(ctx, ctx.Doer, ctxUser, repo_service.ForkRepoOptions{
|
||||
repo := ForkRepoTo(ctx, ctxUser, repo_service.ForkRepoOptions{
|
||||
BaseRepo: forkRepo,
|
||||
Name: form.RepoName,
|
||||
Description: form.Description,
|
||||
SingleBranch: form.ForkSingleBranch,
|
||||
})
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
ctx.JSONRedirect(ctxUser.HomeLink() + "/" + url.PathEscape(repo.Name))
|
||||
}
|
||||
|
||||
func ForkRepoTo(ctx *context.Context, owner *user_model.User, forkOpts repo_service.ForkRepoOptions) *repo_model.Repository {
|
||||
repo, err := repo_service.ForkRepository(ctx, ctx.Doer, owner, forkOpts)
|
||||
if err != nil {
|
||||
ctx.Data["Err_RepoName"] = true
|
||||
switch {
|
||||
case repo_model.IsErrReachLimitOfRepo(err):
|
||||
maxCreationLimit := ctxUser.MaxCreationLimit()
|
||||
maxCreationLimit := owner.MaxCreationLimit()
|
||||
msg := ctx.TrN(maxCreationLimit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_n", maxCreationLimit)
|
||||
ctx.JSONError(msg)
|
||||
case repo_model.IsErrRepoAlreadyExist(err):
|
||||
|
|
@ -224,9 +232,7 @@ func ForkPost(ctx *context.Context) {
|
|||
default:
|
||||
ctx.ServerError("ForkPost", err)
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Trace("Repository forked[%d]: %s/%s", forkRepo.ID, ctxUser.Name, repo.Name)
|
||||
ctx.JSONRedirect(ctxUser.HomeLink() + "/" + url.PathEscape(repo.Name))
|
||||
return repo
|
||||
}
|
||||
|
|
|
|||
|
|
@ -394,9 +394,10 @@ func Forks(ctx *context.Context) {
|
|||
}
|
||||
|
||||
pager := context.NewPagination(int(total), pageSize, page, 5)
|
||||
ctx.Data["ShowRepoOwnerAvatar"] = true
|
||||
ctx.Data["ShowRepoOwnerOnList"] = true
|
||||
ctx.Data["Page"] = pager
|
||||
|
||||
ctx.Data["Forks"] = forks
|
||||
ctx.Data["Repos"] = forks
|
||||
|
||||
ctx.HTML(http.StatusOK, tplForks)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
|
|||
|
||||
func prepareToRenderButtons(ctx *context.Context, lfsLock *git_model.LFSLock) {
|
||||
// archived or mirror repository, the buttons should not be shown
|
||||
if ctx.Repo.Repository.IsArchived || !ctx.Repo.Repository.CanEnableEditor() {
|
||||
if !ctx.Repo.Repository.CanEnableEditor() {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -302,7 +302,9 @@ func prepareToRenderButtons(ctx *context.Context, lfsLock *git_model.LFSLock) {
|
|||
}
|
||||
|
||||
if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
|
||||
ctx.Data["CanEditFile"] = true
|
||||
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.fork_before_edit")
|
||||
ctx.Data["CanDeleteFile"] = true
|
||||
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_have_write_access")
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ func prepareToRenderReadmeFile(ctx *context.Context, subfolder string, readmeFil
|
|||
ctx.Data["EscapeStatus"], ctx.Data["FileContent"] = charset.EscapeControlHTML(template.HTML(contentEscaped), ctx.Locale)
|
||||
}
|
||||
|
||||
if !fInfo.isLFSFile && ctx.Repo.CanEnableEditor(ctx, ctx.Doer) {
|
||||
if !fInfo.isLFSFile && ctx.Repo.Repository.CanEnableEditor() {
|
||||
ctx.Data["CanEditReadmeFile"] = true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ package repo
|
|||
import (
|
||||
"bytes"
|
||||
gocontext "context"
|
||||
"html/template"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
|
@ -61,9 +62,9 @@ func MustEnableWiki(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
unit, err := ctx.Repo.Repository.GetUnit(ctx, unit.TypeExternalWiki)
|
||||
repoUnit, err := ctx.Repo.Repository.GetUnit(ctx, unit.TypeExternalWiki)
|
||||
if err == nil {
|
||||
ctx.Redirect(unit.ExternalWikiConfig().ExternalWikiURL)
|
||||
ctx.Redirect(repoUnit.ExternalWikiConfig().ExternalWikiURL)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -95,7 +96,7 @@ func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error)
|
|||
}
|
||||
|
||||
func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) {
|
||||
wikiGitRepo, errGitRepo := gitrepo.OpenRepository(ctx, ctx.Repo.Repository.WikiStorageRepo())
|
||||
wikiGitRepo, errGitRepo := gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository.WikiStorageRepo())
|
||||
if errGitRepo != nil {
|
||||
ctx.ServerError("OpenRepository", errGitRepo)
|
||||
return nil, nil, errGitRepo
|
||||
|
|
@ -178,23 +179,17 @@ func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName wiki_
|
|||
}
|
||||
|
||||
func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
||||
wikiRepo, commit, err := findWikiRepoCommit(ctx)
|
||||
wikiGitRepo, commit, err := findWikiRepoCommit(ctx)
|
||||
if err != nil {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
if !git.IsErrNotExist(err) {
|
||||
ctx.ServerError("GetBranchCommit", err)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Get page list.
|
||||
// get the wiki pages list.
|
||||
entries, err := commit.ListEntries()
|
||||
if err != nil {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
ctx.ServerError("ListEntries", err)
|
||||
return nil, nil
|
||||
}
|
||||
|
|
@ -208,9 +203,6 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
|||
if repo_model.IsErrWikiInvalidFileName(err) {
|
||||
continue
|
||||
}
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
ctx.ServerError("WikiFilenameToName", err)
|
||||
return nil, nil
|
||||
} else if wikiName == "_Sidebar" || wikiName == "_Footer" {
|
||||
|
|
@ -249,58 +241,26 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
|||
ctx.Redirect(util.URLJoin(ctx.Repo.RepoLink, "wiki/raw", string(pageName)))
|
||||
}
|
||||
if entry == nil || ctx.Written() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// get filecontent
|
||||
// get page content
|
||||
data := wikiContentsByEntry(ctx, entry)
|
||||
if ctx.Written() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var sidebarContent []byte
|
||||
if !isSideBar {
|
||||
sidebarContent, _, _, _ = wikiContentsByName(ctx, commit, "_Sidebar")
|
||||
if ctx.Written() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
} else {
|
||||
sidebarContent = data
|
||||
}
|
||||
|
||||
var footerContent []byte
|
||||
if !isFooter {
|
||||
footerContent, _, _, _ = wikiContentsByName(ctx, commit, "_Footer")
|
||||
if ctx.Written() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
} else {
|
||||
footerContent = data
|
||||
}
|
||||
|
||||
rctx := renderhelper.NewRenderContextRepoWiki(ctx, ctx.Repo.Repository)
|
||||
|
||||
buf := &strings.Builder{}
|
||||
renderFn := func(data []byte) (escaped *charset.EscapeStatus, output string, err error) {
|
||||
renderFn := func(data []byte) (escaped *charset.EscapeStatus, output template.HTML, err error) {
|
||||
buf := &strings.Builder{}
|
||||
markupRd, markupWr := io.Pipe()
|
||||
defer markupWr.Close()
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
// We allow NBSP here this is rendered
|
||||
escaped, _ = charset.EscapeControlReader(markupRd, buf, ctx.Locale, charset.RuneNBSP)
|
||||
output = buf.String()
|
||||
output = template.HTML(buf.String())
|
||||
buf.Reset()
|
||||
close(done)
|
||||
}()
|
||||
|
|
@ -311,75 +271,61 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
|||
return escaped, output, err
|
||||
}
|
||||
|
||||
ctx.Data["EscapeStatus"], ctx.Data["content"], err = renderFn(data)
|
||||
ctx.Data["EscapeStatus"], ctx.Data["WikiContentHTML"], err = renderFn(data)
|
||||
if err != nil {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
ctx.ServerError("Render", err)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if rctx.SidebarTocNode != nil {
|
||||
sb := &strings.Builder{}
|
||||
err = markdown.SpecializedMarkdown(rctx).Renderer().Render(sb, nil, rctx.SidebarTocNode)
|
||||
if err != nil {
|
||||
sb := strings.Builder{}
|
||||
if err = markdown.SpecializedMarkdown(rctx).Renderer().Render(&sb, nil, rctx.SidebarTocNode); err != nil {
|
||||
log.Error("Failed to render wiki sidebar TOC: %v", err)
|
||||
} else {
|
||||
ctx.Data["sidebarTocContent"] = sb.String()
|
||||
}
|
||||
ctx.Data["WikiSidebarTocHTML"] = templates.SanitizeHTML(sb.String())
|
||||
}
|
||||
|
||||
if !isSideBar {
|
||||
buf.Reset()
|
||||
ctx.Data["sidebarEscapeStatus"], ctx.Data["sidebarContent"], err = renderFn(sidebarContent)
|
||||
sidebarContent, _, _, _ := wikiContentsByName(ctx, commit, "_Sidebar")
|
||||
if ctx.Written() {
|
||||
return nil, nil
|
||||
}
|
||||
ctx.Data["WikiSidebarEscapeStatus"], ctx.Data["WikiSidebarHTML"], err = renderFn(sidebarContent)
|
||||
if err != nil {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
ctx.ServerError("Render", err)
|
||||
return nil, nil
|
||||
}
|
||||
ctx.Data["sidebarPresent"] = sidebarContent != nil
|
||||
} else {
|
||||
ctx.Data["sidebarPresent"] = false
|
||||
}
|
||||
|
||||
if !isFooter {
|
||||
buf.Reset()
|
||||
ctx.Data["footerEscapeStatus"], ctx.Data["footerContent"], err = renderFn(footerContent)
|
||||
footerContent, _, _, _ := wikiContentsByName(ctx, commit, "_Footer")
|
||||
if ctx.Written() {
|
||||
return nil, nil
|
||||
}
|
||||
ctx.Data["WikiFooterEscapeStatus"], ctx.Data["WikiFooterHTML"], err = renderFn(footerContent)
|
||||
if err != nil {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
ctx.ServerError("Render", err)
|
||||
return nil, nil
|
||||
}
|
||||
ctx.Data["footerPresent"] = footerContent != nil
|
||||
} else {
|
||||
ctx.Data["footerPresent"] = false
|
||||
}
|
||||
|
||||
// get commit count - wiki revisions
|
||||
commitsCount, _ := wikiRepo.FileCommitsCount(ctx.Repo.Repository.DefaultWikiBranch, pageFilename)
|
||||
commitsCount, _ := wikiGitRepo.FileCommitsCount(ctx.Repo.Repository.DefaultWikiBranch, pageFilename)
|
||||
ctx.Data["CommitCount"] = commitsCount
|
||||
|
||||
return wikiRepo, entry
|
||||
return wikiGitRepo, entry
|
||||
}
|
||||
|
||||
func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
||||
wikiRepo, commit, err := findWikiRepoCommit(ctx)
|
||||
wikiGitRepo, commit, err := findWikiRepoCommit(ctx)
|
||||
if err != nil {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
if !git.IsErrNotExist(err) {
|
||||
ctx.ServerError("GetBranchCommit", err)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// get requested pagename
|
||||
// get requested page name
|
||||
pageName := wiki_service.WebPathFromRequest(ctx.PathParamRaw("*"))
|
||||
if len(pageName) == 0 {
|
||||
pageName = "Home"
|
||||
|
|
@ -394,50 +340,35 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
|
|||
ctx.Data["Username"] = ctx.Repo.Owner.Name
|
||||
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
|
||||
|
||||
// lookup filename in wiki - get filecontent, gitTree entry , real filename
|
||||
data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
|
||||
// lookup filename in wiki - get page content, gitTree entry , real filename
|
||||
_, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
|
||||
if noEntry {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages")
|
||||
}
|
||||
if entry == nil || ctx.Written() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
ctx.Data["content"] = string(data)
|
||||
ctx.Data["sidebarPresent"] = false
|
||||
ctx.Data["sidebarContent"] = ""
|
||||
ctx.Data["footerPresent"] = false
|
||||
ctx.Data["footerContent"] = ""
|
||||
|
||||
// get commit count - wiki revisions
|
||||
commitsCount, _ := wikiRepo.FileCommitsCount(ctx.Repo.Repository.DefaultWikiBranch, pageFilename)
|
||||
commitsCount, _ := wikiGitRepo.FileCommitsCount(ctx.Repo.Repository.DefaultWikiBranch, pageFilename)
|
||||
ctx.Data["CommitCount"] = commitsCount
|
||||
|
||||
// get page
|
||||
page := max(ctx.FormInt("page"), 1)
|
||||
|
||||
// get Commit Count
|
||||
commitsHistory, err := wikiRepo.CommitsByFileAndRange(
|
||||
commitsHistory, err := wikiGitRepo.CommitsByFileAndRange(
|
||||
git.CommitsByFileAndRangeOptions{
|
||||
Revision: ctx.Repo.Repository.DefaultWikiBranch,
|
||||
File: pageFilename,
|
||||
Page: page,
|
||||
})
|
||||
if err != nil {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
ctx.ServerError("CommitsByFileAndRange", err)
|
||||
return nil, nil
|
||||
}
|
||||
ctx.Data["Commits"], err = git_service.ConvertFromGitCommit(ctx, commitsHistory, ctx.Repo.Repository)
|
||||
if err != nil {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
ctx.ServerError("ConvertFromGitCommit", err)
|
||||
return nil, nil
|
||||
}
|
||||
|
|
@ -446,16 +377,11 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
|
|||
pager.AddParamFromRequest(ctx.Req)
|
||||
ctx.Data["Page"] = pager
|
||||
|
||||
return wikiRepo, entry
|
||||
return wikiGitRepo, entry
|
||||
}
|
||||
|
||||
func renderEditPage(ctx *context.Context) {
|
||||
wikiRepo, commit, err := findWikiRepoCommit(ctx)
|
||||
defer func() {
|
||||
if wikiRepo != nil {
|
||||
_ = wikiRepo.Close()
|
||||
}
|
||||
}()
|
||||
_, commit, err := findWikiRepoCommit(ctx)
|
||||
if err != nil {
|
||||
if !git.IsErrNotExist(err) {
|
||||
ctx.ServerError("GetBranchCommit", err)
|
||||
|
|
@ -463,7 +389,7 @@ func renderEditPage(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// get requested pagename
|
||||
// get requested page name
|
||||
pageName := wiki_service.WebPathFromRequest(ctx.PathParamRaw("*"))
|
||||
if len(pageName) == 0 {
|
||||
pageName = "Home"
|
||||
|
|
@ -487,17 +413,13 @@ func renderEditPage(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// get filecontent
|
||||
// get wiki page content
|
||||
data := wikiContentsByEntry(ctx, entry)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["content"] = string(data)
|
||||
ctx.Data["sidebarPresent"] = false
|
||||
ctx.Data["sidebarContent"] = ""
|
||||
ctx.Data["footerPresent"] = false
|
||||
ctx.Data["footerContent"] = ""
|
||||
ctx.Data["WikiEditContent"] = string(data)
|
||||
}
|
||||
|
||||
// WikiPost renders post of wiki page
|
||||
|
|
@ -559,12 +481,7 @@ func Wiki(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
wikiRepo, entry := renderViewPage(ctx)
|
||||
defer func() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
}()
|
||||
wikiGitRepo, entry := renderViewPage(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
|
@ -580,7 +497,7 @@ func Wiki(ctx *context.Context) {
|
|||
ctx.Data["FormatWarning"] = ext + " rendering is not supported at the moment. Rendered as Markdown."
|
||||
}
|
||||
// Get last change information.
|
||||
lastCommit, err := wikiRepo.GetCommitByPath(wikiPath)
|
||||
lastCommit, err := wikiGitRepo.GetCommitByPath(wikiPath)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetCommitByPath", err)
|
||||
return
|
||||
|
|
@ -600,13 +517,7 @@ func WikiRevision(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
wikiRepo, entry := renderRevisionPage(ctx)
|
||||
defer func() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
wikiGitRepo, entry := renderRevisionPage(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
|
@ -618,7 +529,7 @@ func WikiRevision(ctx *context.Context) {
|
|||
|
||||
// Get last change information.
|
||||
wikiPath := entry.Name()
|
||||
lastCommit, err := wikiRepo.GetCommitByPath(wikiPath)
|
||||
lastCommit, err := wikiGitRepo.GetCommitByPath(wikiPath)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetCommitByPath", err)
|
||||
return
|
||||
|
|
@ -638,12 +549,7 @@ func WikiPages(ctx *context.Context) {
|
|||
ctx.Data["Title"] = ctx.Tr("repo.wiki.pages")
|
||||
ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(unit.TypeWiki) && !ctx.Repo.Repository.IsArchived
|
||||
|
||||
wikiRepo, commit, err := findWikiRepoCommit(ctx)
|
||||
defer func() {
|
||||
if wikiRepo != nil {
|
||||
_ = wikiRepo.Close()
|
||||
}
|
||||
}()
|
||||
_, commit, err := findWikiRepoCommit(ctx)
|
||||
if err != nil {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki")
|
||||
return
|
||||
|
|
@ -697,13 +603,7 @@ func WikiPages(ctx *context.Context) {
|
|||
|
||||
// WikiRaw outputs raw blob requested by user (image for example)
|
||||
func WikiRaw(ctx *context.Context) {
|
||||
wikiRepo, commit, err := findWikiRepoCommit(ctx)
|
||||
defer func() {
|
||||
if wikiRepo != nil {
|
||||
wikiRepo.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
_, commit, err := findWikiRepoCommit(ctx)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
ctx.NotFound(nil)
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ func TestEditWiki(t *testing.T) {
|
|||
EditWiki(ctx)
|
||||
assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus())
|
||||
assert.EqualValues(t, "Home", ctx.Data["Title"])
|
||||
assert.Equal(t, wikiContent(t, ctx.Repo.Repository, "Home"), ctx.Data["content"])
|
||||
assert.Equal(t, wikiContent(t, ctx.Repo.Repository, "Home"), ctx.Data["WikiEditContent"])
|
||||
|
||||
ctx, _ = contexttest.MockContext(t, "user2/repo1/wiki/jpeg.jpg?action=_edit")
|
||||
ctx.SetPathParam("*", "jpeg.jpg")
|
||||
|
|
|
|||
|
|
@ -197,6 +197,7 @@ func prepareUserProfileTabData(ctx *context.Context, profileDbRepo *repo_model.R
|
|||
total = int(count)
|
||||
case "stars":
|
||||
ctx.Data["PageIsProfileStarList"] = true
|
||||
ctx.Data["ShowRepoOwnerOnList"] = true
|
||||
repos, count, err = repo_model.SearchRepository(ctx, repo_model.SearchRepoOptions{
|
||||
ListOptions: db.ListOptions{
|
||||
PageSize: pagingNum,
|
||||
|
|
|
|||
|
|
@ -964,7 +964,8 @@ func registerWebRoutes(m *web.Router) {
|
|||
addSettingsVariablesRoutes()
|
||||
}, actions.MustEnableActions)
|
||||
|
||||
m.Methods("GET,POST", "/delete", org.SettingsDelete)
|
||||
m.Post("/rename", web.Bind(forms.RenameOrgForm{}), org.SettingsRenamePost)
|
||||
m.Post("/delete", org.SettingsDeleteOrgPost)
|
||||
|
||||
m.Group("/packages", func() {
|
||||
m.Get("", org.Packages)
|
||||
|
|
@ -1312,23 +1313,35 @@ func registerWebRoutes(m *web.Router) {
|
|||
}, reqSignIn, context.RepoAssignment, context.RepoMustNotBeArchived())
|
||||
// end "/{username}/{reponame}": create or edit issues, pulls, labels, milestones
|
||||
|
||||
m.Group("/{username}/{reponame}", func() { // repo code
|
||||
m.Group("/{username}/{reponame}", func() { // repo code (at least "code reader")
|
||||
m.Group("", func() {
|
||||
m.Group("", func() {
|
||||
m.Post("/_preview/*", repo.DiffPreviewPost)
|
||||
m.Combo("/{editor_action:_edit}/*").Get(repo.EditFile).
|
||||
Post(web.Bind(forms.EditRepoFileForm{}), repo.EditFilePost)
|
||||
m.Combo("/{editor_action:_new}/*").Get(repo.EditFile).
|
||||
Post(web.Bind(forms.EditRepoFileForm{}), repo.EditFilePost)
|
||||
m.Combo("/_delete/*").Get(repo.DeleteFile).
|
||||
Post(web.Bind(forms.DeleteRepoFileForm{}), repo.DeleteFilePost)
|
||||
m.Combo("/_upload/*", repo.MustBeAbleToUpload).Get(repo.UploadFile).
|
||||
Post(web.Bind(forms.UploadRepoFileForm{}), repo.UploadFilePost)
|
||||
m.Combo("/_diffpatch/*").Get(repo.NewDiffPatch).
|
||||
Post(web.Bind(forms.EditRepoFileForm{}), repo.NewDiffPatchPost)
|
||||
m.Combo("/_cherrypick/{sha:([a-f0-9]{7,64})}/*").Get(repo.CherryPick).
|
||||
Post(web.Bind(forms.CherryPickForm{}), repo.CherryPickPost)
|
||||
}, context.RepoRefByType(git.RefTypeBranch), context.CanWriteToBranch(), repo.WebGitOperationCommonData)
|
||||
// "GET" requests only need "code reader" permission, "POST" requests need "code writer" permission.
|
||||
// Because reader can "fork and edit"
|
||||
canWriteToBranch := context.CanWriteToBranch()
|
||||
m.Post("/_preview/*", repo.DiffPreviewPost) // read-only, fine with "code reader"
|
||||
m.Post("/_fork/*", repo.ForkToEditPost) // read-only, fork to own repo, fine with "code reader"
|
||||
|
||||
// the path params are used in PrepareCommitFormOptions to construct the correct form action URL
|
||||
m.Combo("/{editor_action:_edit}/*").
|
||||
Get(repo.EditFile).
|
||||
Post(web.Bind(forms.EditRepoFileForm{}), canWriteToBranch, repo.EditFilePost)
|
||||
m.Combo("/{editor_action:_new}/*").
|
||||
Get(repo.EditFile).
|
||||
Post(web.Bind(forms.EditRepoFileForm{}), canWriteToBranch, repo.EditFilePost)
|
||||
m.Combo("/{editor_action:_delete}/*").
|
||||
Get(repo.DeleteFile).
|
||||
Post(web.Bind(forms.DeleteRepoFileForm{}), canWriteToBranch, repo.DeleteFilePost)
|
||||
m.Combo("/{editor_action:_upload}/*", repo.MustBeAbleToUpload).
|
||||
Get(repo.UploadFile).
|
||||
Post(web.Bind(forms.UploadRepoFileForm{}), canWriteToBranch, repo.UploadFilePost)
|
||||
m.Combo("/{editor_action:_diffpatch}/*").
|
||||
Get(repo.NewDiffPatch).
|
||||
Post(web.Bind(forms.EditRepoFileForm{}), canWriteToBranch, repo.NewDiffPatchPost)
|
||||
m.Combo("/{editor_action:_cherrypick}/{sha:([a-f0-9]{7,64})}/*").
|
||||
Get(repo.CherryPick).
|
||||
Post(web.Bind(forms.CherryPickForm{}), canWriteToBranch, repo.CherryPickPost)
|
||||
}, context.RepoRefByType(git.RefTypeBranch), repo.WebGitOperationCommonData)
|
||||
m.Group("", func() {
|
||||
m.Post("/upload-file", repo.UploadFileToServer)
|
||||
m.Post("/upload-remove", repo.RemoveUploadFileFromServer)
|
||||
|
|
|
|||
|
|
@ -71,11 +71,6 @@ func (r *Repository) CanWriteToBranch(ctx context.Context, user *user_model.User
|
|||
return issues_model.CanMaintainerWriteToBranch(ctx, r.Permission, branch, user)
|
||||
}
|
||||
|
||||
// CanEnableEditor returns true if repository is editable and user has proper access level.
|
||||
func (r *Repository) CanEnableEditor(ctx context.Context, user *user_model.User) bool {
|
||||
return r.RefFullName.IsBranch() && r.CanWriteToBranch(ctx, user, r.BranchName) && r.Repository.CanEnableEditor() && !r.Repository.IsArchived
|
||||
}
|
||||
|
||||
// CanCreateBranch returns true if repository is editable and user has proper access level.
|
||||
func (r *Repository) CanCreateBranch() bool {
|
||||
return r.Permission.CanWrite(unit_model.TypeCode) && r.Repository.CanCreateBranch()
|
||||
|
|
@ -94,9 +89,13 @@ func RepoMustNotBeArchived() func(ctx *Context) {
|
|||
}
|
||||
}
|
||||
|
||||
type CommitFormBehaviors struct {
|
||||
type CommitFormOptions struct {
|
||||
NeedFork bool
|
||||
|
||||
TargetRepo *repo_model.Repository
|
||||
TargetFormAction string
|
||||
WillSubmitToFork bool
|
||||
CanCommitToBranch bool
|
||||
EditorEnabled bool
|
||||
UserCanPush bool
|
||||
RequireSigned bool
|
||||
WillSign bool
|
||||
|
|
@ -106,51 +105,84 @@ type CommitFormBehaviors struct {
|
|||
CanCreateBasePullRequest bool
|
||||
}
|
||||
|
||||
func (r *Repository) PrepareCommitFormBehaviors(ctx *Context, doer *user_model.User) (*CommitFormBehaviors, error) {
|
||||
protectedBranch, err := git_model.GetFirstMatchProtectedBranchRule(ctx, r.Repository.ID, r.BranchName)
|
||||
func PrepareCommitFormOptions(ctx *Context, doer *user_model.User, targetRepo *repo_model.Repository, doerRepoPerm access_model.Permission, refName git.RefName) (*CommitFormOptions, error) {
|
||||
if !refName.IsBranch() {
|
||||
// it shouldn't happen because middleware already checks
|
||||
return nil, util.NewInvalidArgumentErrorf("ref %q is not a branch", refName)
|
||||
}
|
||||
|
||||
originRepo := targetRepo
|
||||
branchName := refName.ShortName()
|
||||
// TODO: CanMaintainerWriteToBranch is a bad name, but it really does what "CanWriteToBranch" does
|
||||
if !issues_model.CanMaintainerWriteToBranch(ctx, doerRepoPerm, branchName, doer) {
|
||||
targetRepo = repo_model.GetForkedRepo(ctx, doer.ID, targetRepo.ID)
|
||||
if targetRepo == nil {
|
||||
return &CommitFormOptions{NeedFork: true}, nil
|
||||
}
|
||||
// now, we get our own forked repo; it must be writable by us.
|
||||
}
|
||||
submitToForkedRepo := targetRepo.ID != originRepo.ID
|
||||
err := targetRepo.GetBaseRepo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userCanPush := true
|
||||
requireSigned := false
|
||||
if protectedBranch != nil {
|
||||
protectedBranch.Repo = r.Repository
|
||||
userCanPush = protectedBranch.CanUserPush(ctx, doer)
|
||||
requireSigned = protectedBranch.RequireSignedCommits
|
||||
}
|
||||
|
||||
sign, keyID, _, err := asymkey_service.SignCRUDAction(ctx, r.Repository.RepoPath(), doer, r.Repository.RepoPath(), git.BranchPrefix+r.BranchName)
|
||||
|
||||
canEnableEditor := r.CanEnableEditor(ctx, doer)
|
||||
canCommit := canEnableEditor && userCanPush
|
||||
if requireSigned {
|
||||
canCommit = canCommit && sign
|
||||
}
|
||||
wontSignReason := ""
|
||||
protectedBranch, err := git_model.GetFirstMatchProtectedBranchRule(ctx, targetRepo.ID, branchName)
|
||||
if err != nil {
|
||||
if asymkey_service.IsErrWontSign(err) {
|
||||
wontSignReason = string(err.(*asymkey_service.ErrWontSign).Reason)
|
||||
err = nil
|
||||
} else {
|
||||
wontSignReason = "error"
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
canPushWithProtection := true
|
||||
protectionRequireSigned := false
|
||||
if protectedBranch != nil {
|
||||
protectedBranch.Repo = targetRepo
|
||||
canPushWithProtection = protectedBranch.CanUserPush(ctx, doer)
|
||||
protectionRequireSigned = protectedBranch.RequireSignedCommits
|
||||
}
|
||||
|
||||
canCreateBasePullRequest := ctx.Repo.Repository.BaseRepo != nil && ctx.Repo.Repository.BaseRepo.UnitEnabled(ctx, unit_model.TypePullRequests)
|
||||
canCreatePullRequest := ctx.Repo.Repository.UnitEnabled(ctx, unit_model.TypePullRequests) || canCreateBasePullRequest
|
||||
willSign, signKeyID, _, err := asymkey_service.SignCRUDAction(ctx, targetRepo.RepoPath(), doer, targetRepo.RepoPath(), refName.String())
|
||||
wontSignReason := ""
|
||||
if asymkey_service.IsErrWontSign(err) {
|
||||
wontSignReason = string(err.(*asymkey_service.ErrWontSign).Reason)
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &CommitFormBehaviors{
|
||||
CanCommitToBranch: canCommit,
|
||||
EditorEnabled: canEnableEditor,
|
||||
UserCanPush: userCanPush,
|
||||
RequireSigned: requireSigned,
|
||||
WillSign: sign,
|
||||
SigningKey: keyID,
|
||||
canCommitToBranch := !submitToForkedRepo /* same repo */ && targetRepo.CanEnableEditor() && canPushWithProtection
|
||||
if protectionRequireSigned {
|
||||
canCommitToBranch = canCommitToBranch && willSign
|
||||
}
|
||||
|
||||
canCreateBasePullRequest := targetRepo.BaseRepo != nil && targetRepo.BaseRepo.UnitEnabled(ctx, unit_model.TypePullRequests)
|
||||
canCreatePullRequest := targetRepo.UnitEnabled(ctx, unit_model.TypePullRequests) || canCreateBasePullRequest
|
||||
|
||||
opts := &CommitFormOptions{
|
||||
TargetRepo: targetRepo,
|
||||
WillSubmitToFork: submitToForkedRepo,
|
||||
CanCommitToBranch: canCommitToBranch,
|
||||
UserCanPush: canPushWithProtection,
|
||||
RequireSigned: protectionRequireSigned,
|
||||
WillSign: willSign,
|
||||
SigningKey: signKeyID,
|
||||
WontSignReason: wontSignReason,
|
||||
|
||||
CanCreatePullRequest: canCreatePullRequest,
|
||||
CanCreateBasePullRequest: canCreateBasePullRequest,
|
||||
}, err
|
||||
}
|
||||
editorAction := ctx.PathParam("editor_action")
|
||||
editorPathParamRemaining := util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
if submitToForkedRepo {
|
||||
// there is only "default branch" in forked repo, we will use "from_base_branch" to get a new branch from base repo
|
||||
editorPathParamRemaining = util.PathEscapeSegments(targetRepo.DefaultBranch) + "/" + util.PathEscapeSegments(ctx.Repo.TreePath) + "?from_base_branch=" + url.QueryEscape(branchName)
|
||||
}
|
||||
if editorAction == "_cherrypick" {
|
||||
opts.TargetFormAction = targetRepo.Link() + "/" + editorAction + "/" + ctx.PathParam("sha") + "/" + editorPathParamRemaining
|
||||
} else {
|
||||
opts.TargetFormAction = targetRepo.Link() + "/" + editorAction + "/" + editorPathParamRemaining
|
||||
}
|
||||
if ctx.Req.URL.RawQuery != "" {
|
||||
opts.TargetFormAction += util.Iif(strings.Contains(opts.TargetFormAction, "?"), "&", "?") + ctx.Req.URL.RawQuery
|
||||
}
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
// CanUseTimetracker returns whether a user can use the timetracker.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/reqctx"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
)
|
||||
|
|
@ -106,14 +108,17 @@ func AddUploadContext(ctx *context.Context, uploadType string) {
|
|||
ctx.Data["UploadAccepts"] = strings.ReplaceAll(setting.Attachment.AllowedTypes, "|", ",")
|
||||
ctx.Data["UploadMaxFiles"] = setting.Attachment.MaxFiles
|
||||
ctx.Data["UploadMaxSize"] = setting.Attachment.MaxSize
|
||||
case "repo":
|
||||
ctx.Data["UploadUrl"] = ctx.Repo.RepoLink + "/upload-file"
|
||||
ctx.Data["UploadRemoveUrl"] = ctx.Repo.RepoLink + "/upload-remove"
|
||||
ctx.Data["UploadLinkUrl"] = ctx.Repo.RepoLink + "/upload-file"
|
||||
ctx.Data["UploadAccepts"] = strings.ReplaceAll(setting.Repository.Upload.AllowedTypes, "|", ",")
|
||||
ctx.Data["UploadMaxFiles"] = setting.Repository.Upload.MaxFiles
|
||||
ctx.Data["UploadMaxSize"] = setting.Repository.Upload.FileMaxSize
|
||||
default:
|
||||
setting.PanicInDevOrTesting("Invalid upload type: %s", uploadType)
|
||||
}
|
||||
}
|
||||
|
||||
func AddUploadContextForRepo(ctx reqctx.RequestContext, repo *repo_model.Repository) {
|
||||
ctxData, repoLink := ctx.GetData(), repo.Link()
|
||||
ctxData["UploadUrl"] = repoLink + "/upload-file"
|
||||
ctxData["UploadRemoveUrl"] = repoLink + "/upload-remove"
|
||||
ctxData["UploadLinkUrl"] = repoLink + "/upload-file"
|
||||
ctxData["UploadAccepts"] = strings.ReplaceAll(setting.Repository.Upload.AllowedTypes, "|", ",")
|
||||
ctxData["UploadMaxFiles"] = setting.Repository.Upload.MaxFiles
|
||||
ctxData["UploadMaxSize"] = setting.Repository.Upload.FileMaxSize
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ func (f *CreateOrgForm) Validate(req *http.Request, errs binding.Errors) binding
|
|||
|
||||
// UpdateOrgSettingForm form for updating organization settings
|
||||
type UpdateOrgSettingForm struct {
|
||||
Name string `binding:"Required;Username;MaxSize(40)" locale:"org.org_name_holder"`
|
||||
FullName string `binding:"MaxSize(100)"`
|
||||
Email string `binding:"MaxSize(255)"`
|
||||
Description string `binding:"MaxSize(255)"`
|
||||
|
|
@ -53,6 +52,11 @@ func (f *UpdateOrgSettingForm) Validate(req *http.Request, errs binding.Errors)
|
|||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type RenameOrgForm struct {
|
||||
OrgName string `binding:"Required"`
|
||||
NewOrgName string `binding:"Required;Username;MaxSize(40)" locale:"org.org_name_holder"`
|
||||
}
|
||||
|
||||
// ___________
|
||||
// \__ ___/___ _____ _____
|
||||
// | |_/ __ \\__ \ / \
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import (
|
|||
container_module "code.gitea.io/gitea/modules/packages/container"
|
||||
packages_service "code.gitea.io/gitea/services/packages"
|
||||
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// Cleanup removes expired container data
|
||||
|
|
|
|||
|
|
@ -38,20 +38,23 @@ func MergeRequiredContextsCommitStatus(commitStatuses []*git_model.CommitStatus,
|
|||
}
|
||||
|
||||
requiredCommitStatuses := make([]*git_model.CommitStatus, 0, len(commitStatuses))
|
||||
allRequiredContextsMatched := true
|
||||
for _, gp := range requiredContextsGlob {
|
||||
requiredContextMatched := false
|
||||
for _, commitStatus := range commitStatuses {
|
||||
if gp.Match(commitStatus.Context) {
|
||||
requiredCommitStatuses = append(requiredCommitStatuses, commitStatus)
|
||||
break
|
||||
requiredContextMatched = true
|
||||
}
|
||||
}
|
||||
allRequiredContextsMatched = allRequiredContextsMatched && requiredContextMatched
|
||||
}
|
||||
if len(requiredCommitStatuses) == 0 {
|
||||
return commitstatus.CommitStatusPending
|
||||
}
|
||||
|
||||
returnedStatus := git_model.CalcCommitStatus(requiredCommitStatuses).State
|
||||
if len(requiredCommitStatuses) == len(requiredContexts) {
|
||||
if allRequiredContextsMatched {
|
||||
return returnedStatus
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,15 @@ func TestMergeRequiredContextsCommitStatus(t *testing.T) {
|
|||
requiredContexts: []string{"Build*", "Build 2t*"},
|
||||
expected: commitstatus.CommitStatusFailure,
|
||||
},
|
||||
{
|
||||
commitStatuses: []*git_model.CommitStatus{
|
||||
{Context: "Build 1", State: commitstatus.CommitStatusSuccess},
|
||||
{Context: "Build 2", State: commitstatus.CommitStatusSuccess},
|
||||
{Context: "Build 2t", State: commitstatus.CommitStatusFailure},
|
||||
},
|
||||
requiredContexts: []string{"Build*"},
|
||||
expected: commitstatus.CommitStatusFailure,
|
||||
},
|
||||
{
|
||||
commitStatuses: []*git_model.CommitStatus{
|
||||
{Context: "Build 1", State: commitstatus.CommitStatusSuccess},
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ func (telegramConvertor) WorkflowJob(p *api.WorkflowJobPayload) (TelegramPayload
|
|||
func createTelegramPayloadHTML(msgHTML string) TelegramPayload {
|
||||
// https://core.telegram.org/bots/api#formatting-options
|
||||
return TelegramPayload{
|
||||
Message: strings.TrimSpace(markup.Sanitize(msgHTML)),
|
||||
Message: strings.TrimSpace(string(markup.Sanitize(msgHTML))),
|
||||
ParseMode: "HTML",
|
||||
DisableWebPreview: true,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
{{ctx.Locale.Tr "admin.repositories"}} ({{ctx.Locale.Tr "admin.total" .ReposTotal}})
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
{{template "explore/repo_list" .}}
|
||||
{{template "shared/repo/list" .}}
|
||||
</div>
|
||||
<h4 class="ui top attached header">
|
||||
{{ctx.Locale.Tr "settings.organization"}} ({{ctx.Locale.Tr "admin.total" .OrgsTotal}})
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
<div role="main" aria-label="{{.Title}}" class="page-content explore repositories">
|
||||
{{template "explore/navbar" .}}
|
||||
<div class="ui container">
|
||||
{{template "shared/repo_search" .}}
|
||||
{{template "explore/repo_list" .}}
|
||||
{{template "shared/repo/search" .}}
|
||||
{{template "shared/repo/list" .}}
|
||||
{{template "base/paginate" .}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
{{if .ProfileReadmeContent}}
|
||||
<div id="readme_profile" class="render-content markup" data-profile-view-as-member="{{.IsViewingOrgAsMember}}">{{.ProfileReadmeContent}}</div>
|
||||
{{end}}
|
||||
{{template "shared/repo_search" .}}
|
||||
{{template "explore/repo_list" .}}
|
||||
{{template "shared/repo/search" .}}
|
||||
{{template "shared/repo/list" .}}
|
||||
{{template "base/paginate" .}}
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
{{template "org/settings/layout_head" (dict "ctxData" . "pageClass" "organization settings delete")}}
|
||||
|
||||
<div class="org-setting-content">
|
||||
<h4 class="ui top attached error header">
|
||||
{{ctx.Locale.Tr "org.settings.delete_account"}}
|
||||
</h4>
|
||||
<div class="ui attached error segment">
|
||||
<div class="ui red message">
|
||||
<p class="text left">{{svg "octicon-alert"}} {{ctx.Locale.Tr "org.settings.delete_prompt"}}</p>
|
||||
</div>
|
||||
<form class="ui form ignore-dirty" id="delete-form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="inline required field {{if .Err_OrgName}}error{{end}}">
|
||||
<label for="org_name">{{ctx.Locale.Tr "org.org_name_holder"}}</label>
|
||||
<input id="org_name" name="org_name" value="" autocomplete="off" autofocus required>
|
||||
</div>
|
||||
<button class="ui red button delete-button" data-type="form" data-form="#delete-form">
|
||||
{{ctx.Locale.Tr "org.settings.confirm_delete_account"}}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui g-modal-confirm delete modal">
|
||||
<div class="header">
|
||||
{{svg "octicon-trash"}}
|
||||
{{ctx.Locale.Tr "org.settings.delete_org_title"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{ctx.Locale.Tr "org.settings.delete_org_desc"}}</p>
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
|
||||
{{template "org/settings/layout_footer" .}}
|
||||
|
|
@ -41,8 +41,5 @@
|
|||
</div>
|
||||
</details>
|
||||
{{end}}
|
||||
<a class="{{if .PageIsSettingsDelete}}active {{end}}item" href="{{.OrgLink}}/settings/delete">
|
||||
{{ctx.Locale.Tr "org.settings.delete"}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,101 +1,97 @@
|
|||
{{template "org/settings/layout_head" (dict "ctxData" . "pageClass" "organization settings options")}}
|
||||
<div class="org-setting-content">
|
||||
<h4 class="ui top attached header">
|
||||
{{ctx.Locale.Tr "org.settings.options"}}
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="required field {{if .Err_Name}}error{{end}}">
|
||||
<label for="org_name">{{ctx.Locale.Tr "org.org_name_holder"}}
|
||||
<span class="text red tw-hidden" id="org-name-change-prompt">
|
||||
<br>{{ctx.Locale.Tr "org.settings.change_orgname_prompt"}}<br>{{ctx.Locale.Tr "org.settings.change_orgname_redirect_prompt"}}
|
||||
</span>
|
||||
</label>
|
||||
<input id="org_name" name="name" value="{{.Org.Name}}" data-org-name="{{.Org.Name}}" required maxlength="40">
|
||||
</div>
|
||||
<div class="field {{if .Err_FullName}}error{{end}}">
|
||||
<label for="full_name">{{ctx.Locale.Tr "org.org_full_name_holder"}}</label>
|
||||
<input id="full_name" name="full_name" value="{{.Org.FullName}}" maxlength="100">
|
||||
</div>
|
||||
<div class="field {{if .Err_Email}}error{{end}}">
|
||||
<label for="email">{{ctx.Locale.Tr "org.settings.email"}}</label>
|
||||
<input id="email" name="email" type="email" value="{{.Org.Email}}" maxlength="255">
|
||||
</div>
|
||||
<div class="field {{if .Err_Description}}error{{end}}">
|
||||
{{/* it is rendered as markdown, but the length is limited, so at the moment we do not use the markdown editor here */}}
|
||||
<label for="description">{{ctx.Locale.Tr "org.org_desc"}}</label>
|
||||
<textarea id="description" name="description" rows="2" maxlength="255">{{.Org.Description}}</textarea>
|
||||
</div>
|
||||
<div class="field {{if .Err_Website}}error{{end}}">
|
||||
<label for="website">{{ctx.Locale.Tr "org.settings.website"}}</label>
|
||||
<input id="website" name="website" type="url" value="{{.Org.Website}}" maxlength="255">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="location">{{ctx.Locale.Tr "org.settings.location"}}</label>
|
||||
<input id="location" name="location" value="{{.Org.Location}}" maxlength="50">
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
<div class="field" id="visibility_box">
|
||||
<label for="visibility">{{ctx.Locale.Tr "org.settings.visibility"}}</label>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input class="enable-system-radio" name="visibility" type="radio" value="0" {{if eq .CurrentVisibility 0}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "org.settings.visibility.public"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input class="enable-system-radio" name="visibility" type="radio" value="1" {{if eq .CurrentVisibility 1}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "org.settings.visibility.limited"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input class="enable-system-radio" name="visibility" type="radio" value="2" {{if eq .CurrentVisibility 2}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "org.settings.visibility.private"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui segments org-setting-content">
|
||||
<h4 class="ui top attached header">
|
||||
{{ctx.Locale.Tr "org.settings.options"}}
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="field {{if .Err_FullName}}error{{end}}">
|
||||
<label for="full_name">{{ctx.Locale.Tr "org.org_full_name_holder"}}</label>
|
||||
<input id="full_name" name="full_name" value="{{.Org.FullName}}" maxlength="100">
|
||||
</div>
|
||||
<div class="field {{if .Err_Email}}error{{end}}">
|
||||
<label for="email">{{ctx.Locale.Tr "org.settings.email"}}</label>
|
||||
<input id="email" name="email" type="email" value="{{.Org.Email}}" maxlength="255">
|
||||
</div>
|
||||
<div class="field {{if .Err_Description}}error{{end}}">
|
||||
{{/* it is rendered as markdown, but the length is limited, so at the moment we do not use the markdown editor here */}}
|
||||
<label for="description">{{ctx.Locale.Tr "org.org_desc"}}</label>
|
||||
<textarea id="description" name="description" rows="2" maxlength="255">{{.Org.Description}}</textarea>
|
||||
</div>
|
||||
<div class="field {{if .Err_Website}}error{{end}}">
|
||||
<label for="website">{{ctx.Locale.Tr "org.settings.website"}}</label>
|
||||
<input id="website" name="website" type="url" value="{{.Org.Website}}" maxlength="255">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="location">{{ctx.Locale.Tr "org.settings.location"}}</label>
|
||||
<input id="location" name="location" value="{{.Org.Location}}" maxlength="50">
|
||||
</div>
|
||||
|
||||
<div class="field" id="permission_box">
|
||||
<label>{{ctx.Locale.Tr "org.settings.permission"}}</label>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" name="repo_admin_change_team_access" {{if .RepoAdminChangeTeamAccess}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "org.settings.repoadminchangeteam"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if .SignedUser.IsAdmin}}
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="inline field {{if .Err_MaxRepoCreation}}error{{end}}">
|
||||
<label for="max_repo_creation">{{ctx.Locale.Tr "admin.users.max_repo_creation"}}</label>
|
||||
<input id="max_repo_creation" name="max_repo_creation" type="number" min="-1" value="{{.Org.MaxRepoCreation}}">
|
||||
<p class="help">{{ctx.Locale.Tr "admin.users.max_repo_creation_desc"}}</p>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="field">
|
||||
<button class="ui primary button">{{ctx.Locale.Tr "org.settings.update_settings"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<form class="ui form" action="{{.Link}}/avatar" method="post" enctype="multipart/form-data">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="inline field">
|
||||
{{template "shared/avatar_upload_crop" dict "LabelText" (ctx.Locale.Tr "settings.choose_new_avatar")}}
|
||||
</div>
|
||||
<div class="field">
|
||||
<button class="ui primary button">{{ctx.Locale.Tr "settings.update_avatar"}}</button>
|
||||
<button class="ui red button link-action" data-url="{{.Link}}/avatar/delete">{{ctx.Locale.Tr "settings.delete_current_avatar"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="divider"></div>
|
||||
<div class="field" id="visibility_box">
|
||||
<label for="visibility">{{ctx.Locale.Tr "org.settings.visibility"}}</label>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input class="enable-system-radio" name="visibility" type="radio" value="0" {{if eq .CurrentVisibility 0}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "org.settings.visibility.public"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input class="enable-system-radio" name="visibility" type="radio" value="1" {{if eq .CurrentVisibility 1}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "org.settings.visibility.limited"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input class="enable-system-radio" name="visibility" type="radio" value="2" {{if eq .CurrentVisibility 2}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "org.settings.visibility.private"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field" id="permission_box">
|
||||
<label>{{ctx.Locale.Tr "org.settings.permission"}}</label>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" name="repo_admin_change_team_access" {{if .RepoAdminChangeTeamAccess}}checked{{end}}>
|
||||
<label>{{ctx.Locale.Tr "org.settings.repoadminchangeteam"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{if .SignedUser.IsAdmin}}
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="inline field {{if .Err_MaxRepoCreation}}error{{end}}">
|
||||
<label for="max_repo_creation">{{ctx.Locale.Tr "admin.users.max_repo_creation"}}</label>
|
||||
<input id="max_repo_creation" name="max_repo_creation" type="number" min="-1" value="{{.Org.MaxRepoCreation}}">
|
||||
<p class="help">{{ctx.Locale.Tr "admin.users.max_repo_creation_desc"}}</p>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="field">
|
||||
<button class="ui primary button">{{ctx.Locale.Tr "org.settings.update_settings"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<form class="ui form" action="{{.Link}}/avatar" method="post" enctype="multipart/form-data">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="inline field">
|
||||
{{template "shared/avatar_upload_crop" dict "LabelText" (ctx.Locale.Tr "settings.choose_new_avatar")}}
|
||||
</div>
|
||||
<div class="field">
|
||||
<button class="ui primary button">{{ctx.Locale.Tr "settings.update_avatar"}}</button>
|
||||
<button class="ui red button link-action" data-url="{{.Link}}/avatar/delete">{{ctx.Locale.Tr "settings.delete_current_avatar"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{template "org/settings/options_dangerzone" .}}
|
||||
|
||||
{{template "org/settings/layout_footer" .}}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,93 @@
|
|||
<h4 class="ui top attached error header">
|
||||
{{ctx.Locale.Tr "repo.settings.danger_zone"}}
|
||||
</h4>
|
||||
<div class="ui attached error danger segment">
|
||||
<div class="flex-list">
|
||||
<div class="flex-item tw-items-center">
|
||||
<div class="flex-item-main">
|
||||
<div class="flex-item-title">{{ctx.Locale.Tr "org.settings.rename"}}</div>
|
||||
<div class="flex-item-body">{{ctx.Locale.Tr "org.settings.rename_desc"}}</div>
|
||||
</div>
|
||||
<div class="flex-item-trailing">
|
||||
<button class="ui basic red show-modal button" data-modal="#rename-org-modal">{{ctx.Locale.Tr "org.settings.rename"}}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-item">
|
||||
<div class="flex-item-main">
|
||||
<div class="flex-item-title">{{ctx.Locale.Tr "org.settings.delete_account"}}</div>
|
||||
<div class="flex-item-body">{{ctx.Locale.Tr "org.settings.delete_prompt"}}</div>
|
||||
</div>
|
||||
<div class="flex-item-trailing">
|
||||
<button class="ui basic red show-modal button" data-modal="#delete-org-modal">{{ctx.Locale.Tr "org.settings.delete_account"}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui small modal" id="rename-org-modal">
|
||||
<div class="header">
|
||||
{{ctx.Locale.Tr "org.settings.rename"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<ul class="ui warning message">
|
||||
<li>{{ctx.Locale.Tr "org.settings.rename_notices_1"}}</li>
|
||||
<li>{{ctx.Locale.Tr "org.settings.rename_notices_2"}}</li>
|
||||
</ul>
|
||||
<form class="ui form form-fetch-action" action="{{.Link}}/rename" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="field">
|
||||
<label>
|
||||
{{ctx.Locale.Tr "org.settings.name_confirm"}}
|
||||
<span class="text red">{{.Org.Name}}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label for="org_name_to_rename">{{ctx.Locale.Tr "org.org_name_holder"}}</label>
|
||||
<input id="org_name_to_rename" name="org_name" required>
|
||||
</div>
|
||||
|
||||
<div class="required field">
|
||||
<label>{{ctx.Locale.Tr "org.settings.rename_new_org_name"}}</label>
|
||||
<input name="new_org_name" required>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button class="ui cancel button">{{ctx.Locale.Tr "settings.cancel"}}</button>
|
||||
<button class="ui red button">{{ctx.Locale.Tr "org.settings.rename"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui small modal" id="delete-org-modal">
|
||||
<div class="header">
|
||||
{{ctx.Locale.Tr "org.settings.delete_account"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<ul class="ui warning message">
|
||||
<li>{{ctx.Locale.Tr "org.settings.delete_notices_1"}}</li>
|
||||
<li>{{ctx.Locale.Tr "org.settings.delete_notices_2" .Org.Name}}</li>
|
||||
<li>{{ctx.Locale.Tr "org.settings.delete_notices_3" .Org.Name}}</li>
|
||||
<li>{{ctx.Locale.Tr "org.settings.delete_notices_4" .Org.Name}}</li>
|
||||
</ul>
|
||||
<form class="ui form form-fetch-action" action="{{.Link}}/delete" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="field">
|
||||
<label>
|
||||
{{ctx.Locale.Tr "org.settings.name_confirm"}}
|
||||
<span class="text red">{{.Org.Name}}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="required field">
|
||||
<label>{{ctx.Locale.Tr "org.org_name_holder"}}</label>
|
||||
<input name="org_name" required>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button class="ui cancel button">{{ctx.Locale.Tr "settings.cancel"}}</button>
|
||||
<button class="ui red button">{{ctx.Locale.Tr "org.settings.delete_account"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<!-- the "cup" has a handler, so move it a little leftward to make it visually in the center -->
|
||||
<div class="tw-ml-[-30px]"><img width="160" src="{{AssetUrlPrefix}}/img/loading.png" alt aria-hidden="true"></div>
|
||||
<div class="tw-my-[2em] tw-text-[18px]">
|
||||
<a id="goto-user-login" href="{{AppSubUrl}}/user/login">{{ctx.Locale.Tr "install.installing_desc"}}</a>
|
||||
<a id="goto-after-install" href="{{AppSubUrl}}{{Iif .IsAccountCreated "/user/login" "/user/sign_up"}}">{{ctx.Locale.Tr "install.installing_desc"}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,12 @@
|
|||
{{svg "octicon-kebab-horizontal"}}
|
||||
<div class="menu flex-items-menu">
|
||||
<a class="item" href="{{$run.Link}}/workflow">{{svg "octicon-play"}}{{ctx.Locale.Tr "actions.runs.view_workflow_file"}}</a>
|
||||
{{if and $.AllowDeleteWorkflowRuns $run.Status.IsDone}}
|
||||
{{if and $.CanWriteRepoUnitActions (not $run.Status.IsDone)}}
|
||||
<a class="item link-action" data-url="{{$run.Link}}/cancel">
|
||||
{{svg "octicon-x"}}{{ctx.Locale.Tr "actions.runs.cancel"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if and $.CanWriteRepoUnitActions $run.Status.IsDone}}
|
||||
<a class="item link-action"
|
||||
data-url="{{$run.Link}}/delete"
|
||||
data-modal-confirm="{{ctx.Locale.Tr "actions.runs.delete.description"}}"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
data-actions-url="{{.ActionsURL}}"
|
||||
|
||||
data-locale-approve="{{ctx.Locale.Tr "repo.diff.review.approve"}}"
|
||||
data-locale-cancel="{{ctx.Locale.Tr "cancel"}}"
|
||||
data-locale-cancel="{{ctx.Locale.Tr "actions.runs.cancel"}}"
|
||||
data-locale-rerun="{{ctx.Locale.Tr "rerun"}}"
|
||||
data-locale-rerun-all="{{ctx.Locale.Tr "rerun_all"}}"
|
||||
data-locale-runs-scheduled="{{ctx.Locale.Tr "actions.runs.scheduled"}}"
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@
|
|||
{{template "repo/header" .}}
|
||||
<div class="ui container">
|
||||
{{template "base/alert" .}}
|
||||
<form class="ui edit form form-fetch-action" method="post" action="{{.RepoLink}}/_cherrypick/{{.FromCommitID}}/{{.BranchName | PathEscapeSegments}}">
|
||||
<form class="ui edit form form-fetch-action" method="post" action="{{.CommitFormOptions.TargetFormAction}}">
|
||||
{{.CsrfTokenHtml}}
|
||||
{{template "repo/editor/common_top" .}}
|
||||
<input type="hidden" name="revert" value="{{if eq .CherryPickType "revert"}}true{{else}}false{{end}}">
|
||||
<div class="repo-editor-header">
|
||||
<div class="breadcrumb">
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<div class="commit-form-wrapper">
|
||||
{{ctx.AvatarUtils.Avatar .SignedUser 40 "commit-avatar"}}
|
||||
<div class="commit-form">
|
||||
<h3>{{- if .CommitFormBehaviors.WillSign}}
|
||||
<span title="{{ctx.Locale.Tr "repo.signing.will_sign" .CommitFormBehaviors.SigningKey}}">{{svg "octicon-lock" 24}}</span>
|
||||
<h3>{{- if .CommitFormOptions.WillSign}}
|
||||
<span title="{{ctx.Locale.Tr "repo.signing.will_sign" .CommitFormOptions.SigningKey}}">{{svg "octicon-lock" 24}}</span>
|
||||
{{ctx.Locale.Tr "repo.editor.commit_signed_changes"}}
|
||||
{{- else}}
|
||||
<span title="{{ctx.Locale.Tr (printf "repo.signing.wont_sign.%s" .CommitFormBehaviors.WontSignReason)}}">{{svg "octicon-unlock" 24}}</span>
|
||||
<span title="{{ctx.Locale.Tr (printf "repo.signing.wont_sign.%s" .CommitFormOptions.WontSignReason)}}">{{svg "octicon-unlock" 24}}</span>
|
||||
{{ctx.Locale.Tr "repo.editor.commit_changes"}}
|
||||
{{- end}}</h3>
|
||||
<div class="field">
|
||||
|
|
@ -22,17 +22,17 @@
|
|||
</div>
|
||||
<div class="quick-pull-choice js-quick-pull-choice">
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox {{if not .CommitFormBehaviors.CanCommitToBranch}}disabled{{end}}">
|
||||
<div class="ui radio checkbox {{if not .CommitFormOptions.CanCommitToBranch}}disabled{{end}}">
|
||||
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="direct" data-button-text="{{ctx.Locale.Tr "repo.editor.commit_changes"}}" {{if eq .commit_choice "direct"}}checked{{end}}>
|
||||
<label>
|
||||
{{svg "octicon-git-commit"}}
|
||||
{{ctx.Locale.Tr "repo.editor.commit_directly_to_this_branch" .BranchName}}
|
||||
{{if not .CommitFormBehaviors.CanCommitToBranch}}
|
||||
{{if not .CommitFormOptions.CanCommitToBranch}}
|
||||
<div class="ui visible small warning message">
|
||||
{{ctx.Locale.Tr "repo.editor.no_commit_to_branch"}}
|
||||
<ul>
|
||||
{{if not .CommitFormBehaviors.UserCanPush}}<li>{{ctx.Locale.Tr "repo.editor.user_no_push_to_branch"}}</li>{{end}}
|
||||
{{if and .CommitFormBehaviors.RequireSigned (not .CommitFormBehaviors.WillSign)}}<li>{{ctx.Locale.Tr "repo.editor.require_signed_commit"}}</li>{{end}}
|
||||
{{if not .CommitFormOptions.UserCanPush}}<li>{{ctx.Locale.Tr "repo.editor.user_no_push_to_branch"}}</li>{{end}}
|
||||
{{if and .CommitFormOptions.RequireSigned (not .CommitFormOptions.WillSign)}}<li>{{ctx.Locale.Tr "repo.editor.require_signed_commit"}}</li>{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
@ -42,14 +42,14 @@
|
|||
{{if and (not .Repository.IsEmpty) (not .IsEditingFileOnly)}}
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
{{if .CommitFormBehaviors.CanCreatePullRequest}}
|
||||
{{if .CommitFormOptions.CanCreatePullRequest}}
|
||||
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="commit-to-new-branch" data-button-text="{{ctx.Locale.Tr "repo.editor.propose_file_change"}}" {{if eq .commit_choice "commit-to-new-branch"}}checked{{end}}>
|
||||
{{else}}
|
||||
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="commit-to-new-branch" data-button-text="{{ctx.Locale.Tr "repo.editor.commit_changes"}}" {{if eq .commit_choice "commit-to-new-branch"}}checked{{end}}>
|
||||
{{end}}
|
||||
<label>
|
||||
{{svg "octicon-git-pull-request"}}
|
||||
{{if .CommitFormBehaviors.CanCreatePullRequest}}
|
||||
{{if .CommitFormOptions.CanCreatePullRequest}}
|
||||
{{ctx.Locale.Tr "repo.editor.create_new_branch"}}
|
||||
{{else}}
|
||||
{{ctx.Locale.Tr "repo.editor.create_new_branch_np"}}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
{{if .CommitFormOptions.WillSubmitToFork}}
|
||||
<div class="ui blue message">
|
||||
{{$repoLinkHTML := HTMLFormat `<a href="%s">%s</a>` .CommitFormOptions.TargetRepo.Link .CommitFormOptions.TargetRepo.FullName}}
|
||||
{{ctx.Locale.Tr "repo.editor.fork_edit_description" $repoLinkHTML}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
@ -3,8 +3,9 @@
|
|||
{{template "repo/header" .}}
|
||||
<div class="ui container">
|
||||
{{template "base/alert" .}}
|
||||
<form class="ui form form-fetch-action" method="post">
|
||||
<form class="ui form form-fetch-action" method="post" action="{{.CommitFormOptions.TargetFormAction}}">
|
||||
{{.CsrfTokenHtml}}
|
||||
{{template "repo/editor/common_top" .}}
|
||||
{{template "repo/editor/commit_form" .}}
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@
|
|||
{{template "repo/header" .}}
|
||||
<div class="ui container">
|
||||
{{template "base/alert" .}}
|
||||
<form class="ui edit form form-fetch-action" method="post"
|
||||
<form class="ui edit form form-fetch-action" method="post" action="{{.CommitFormOptions.TargetFormAction}}"
|
||||
data-text-empty-confirm-header="{{ctx.Locale.Tr "repo.editor.commit_empty_file_header"}}"
|
||||
data-text-empty-confirm-content="{{ctx.Locale.Tr "repo.editor.commit_empty_file_text"}}"
|
||||
>
|
||||
{{.CsrfTokenHtml}}
|
||||
{{template "repo/editor/common_top" .}}
|
||||
<div class="repo-editor-header">
|
||||
{{template "repo/editor/common_breadcrumb" .}}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
{{template "base/head" .}}
|
||||
<div role="main" aria-label="{{.Title}}" class="page-content repository">
|
||||
{{template "repo/header" .}}
|
||||
<div class="ui container">
|
||||
{{template "base/alert" .}}
|
||||
<form class="ui form form-fetch-action" method="post" action="{{.RepoLink}}/_fork/{{.BranchName | PathEscapeSegments}}">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="tw-text-center">
|
||||
<div class="tw-my-[40px]">
|
||||
<h3>{{ctx.Locale.Tr "repo.editor.fork_create"}}</h3>
|
||||
<p>{{ctx.Locale.Tr "repo.editor.fork_create_description"}}</p>
|
||||
</div>
|
||||
<button class="ui primary button">{{ctx.Locale.Tr "repo.fork_repo"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
||||
|
|
@ -3,11 +3,12 @@
|
|||
{{template "repo/header" .}}
|
||||
<div class="ui container">
|
||||
{{template "base/alert" .}}
|
||||
<form class="ui edit form form-fetch-action" method="post" action="{{.RepoLink}}/_diffpatch/{{.BranchName | PathEscapeSegments}}"
|
||||
<form class="ui edit form form-fetch-action" method="post" action="{{.CommitFormOptions.TargetFormAction}}"
|
||||
data-text-empty-confirm-header="{{ctx.Locale.Tr "repo.editor.commit_empty_file_header"}}"
|
||||
data-text-empty-confirm-content="{{ctx.Locale.Tr "repo.editor.commit_empty_file_text"}}"
|
||||
>
|
||||
{{.CsrfTokenHtml}}
|
||||
{{template "repo/editor/common_top" .}}
|
||||
<div class="repo-editor-header">
|
||||
<div class="breadcrumb">
|
||||
{{ctx.Locale.Tr "repo.editor.patching"}}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@
|
|||
{{template "repo/header" .}}
|
||||
<div class="ui container">
|
||||
{{template "base/alert" .}}
|
||||
<form class="ui comment form form-fetch-action" method="post">
|
||||
<form class="ui comment form form-fetch-action" method="post" action="{{.CommitFormOptions.TargetFormAction}}">
|
||||
{{.CsrfTokenHtml}}
|
||||
{{template "repo/editor/common_top" .}}
|
||||
<div class="repo-editor-header">
|
||||
{{template "repo/editor/common_breadcrumb" .}}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,20 +1,12 @@
|
|||
{{template "base/head" .}}
|
||||
<div role="main" aria-label="{{.Title}}" class="page-content repository forks">
|
||||
{{template "repo/header" .}}
|
||||
<div class="ui container">
|
||||
<div class="ui container fork-list">
|
||||
<h2 class="ui dividing header">
|
||||
{{ctx.Locale.Tr "repo.forks"}}
|
||||
</h2>
|
||||
<div class="flex-list">
|
||||
{{range .Forks}}
|
||||
<div class="flex-item tw-border-0 repo-fork-item">
|
||||
<span>{{ctx.AvatarUtils.Avatar .Owner}}</span>
|
||||
<span><a href="{{.Owner.HomeLink}}">{{.Owner.Name}}</a> / <a href="{{.Link}}">{{.Name}}</a></span>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{template "shared/repo/list" .}}
|
||||
{{template "base/paginate" .}}
|
||||
</div>
|
||||
|
||||
{{template "base/paginate" .}}
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
{{if .EscapeStatus}}
|
||||
{{if .EscapeStatus.HasInvisible}}
|
||||
<div class="ui warning message unicode-escape-prompt tw-text-left">
|
||||
<div class="ui warning message unicode-escape-prompt">
|
||||
<button class="btn close icon hide-panel" data-panel-closest=".message">{{svg "octicon-x" 16 "close inside"}}</button>
|
||||
<div class="header">
|
||||
{{ctx.Locale.Tr "repo.invisible_runes_header"}}
|
||||
</div>
|
||||
<p>{{ctx.Locale.Tr "repo.invisible_runes_description"}}</p>
|
||||
<div>{{ctx.Locale.Tr "repo.invisible_runes_description"}}</div>
|
||||
{{if .EscapeStatus.HasAmbiguous}}
|
||||
<p>{{ctx.Locale.Tr "repo.ambiguous_runes_description"}}</p>
|
||||
<div>{{ctx.Locale.Tr "repo.ambiguous_runes_description"}}</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{else if .EscapeStatus.HasAmbiguous}}
|
||||
<div class="ui warning message unicode-escape-prompt tw-text-left">
|
||||
<div class="ui warning message unicode-escape-prompt">
|
||||
<button class="btn close icon hide-panel" data-panel-closest=".message">{{svg "octicon-x" 16 "close inside"}}</button>
|
||||
<div class="header">
|
||||
{{ctx.Locale.Tr "repo.ambiguous_runes_header"}}
|
||||
</div>
|
||||
<p>{{ctx.Locale.Tr "repo.ambiguous_runes_description"}}</p>
|
||||
<div>{{ctx.Locale.Tr "repo.ambiguous_runes_description"}}</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@
|
|||
<a href="{{.Repository.Link}}/find/{{.RefTypeNameSubURL}}" class="ui compact basic button">{{ctx.Locale.Tr "repo.find_file.go_to_file"}}</a>
|
||||
{{end}}
|
||||
|
||||
{{if and .CanWriteCode .RefFullName.IsBranch (not .Repository.IsMirror) (not .Repository.IsArchived) (not .IsViewFile)}}
|
||||
<button class="ui dropdown basic compact jump button"{{if not .Repository.CanEnableEditor}} disabled{{end}}>
|
||||
{{if and .RefFullName.IsBranch (not .IsViewFile)}}
|
||||
<button class="ui dropdown basic compact jump button repo-add-file" {{if not .Repository.CanEnableEditor}}disabled{{end}}>
|
||||
{{ctx.Locale.Tr "repo.editor.add_file"}}
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
<div class="menu">
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
{{ctx.Locale.Tr "repo.wiki.page_name_desc"}}
|
||||
</div>
|
||||
|
||||
{{$content := .content}}
|
||||
{{$content := .WikiEditContent}}
|
||||
{{if not .PageIsWikiEdit}}
|
||||
{{$content = ctx.Locale.Tr "repo.wiki.welcome"}}
|
||||
{{end}}
|
||||
|
|
|
|||
|
|
@ -62,36 +62,34 @@
|
|||
{{end}}
|
||||
|
||||
<div class="wiki-content-parts">
|
||||
{{if .sidebarTocContent}}
|
||||
{{if .WikiSidebarTocHTML}}
|
||||
<div class="render-content markup wiki-content-sidebar wiki-content-toc">
|
||||
{{.sidebarTocContent | SafeHTML}}
|
||||
{{.WikiSidebarTocHTML}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="render-content markup wiki-content-main {{if or .sidebarTocContent .sidebarPresent}}with-sidebar{{end}}">
|
||||
{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}}
|
||||
{{.content | SafeHTML}}
|
||||
<div class="render-content markup wiki-content-main {{if or .WikiSidebarTocHTML .WikiSidebarHTML}}with-sidebar{{end}}">
|
||||
{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus}}
|
||||
{{.WikiContentHTML}}
|
||||
</div>
|
||||
|
||||
{{if .sidebarPresent}}
|
||||
{{if .WikiSidebarHTML}}
|
||||
<div class="render-content markup wiki-content-sidebar">
|
||||
{{if and .CanWriteWiki (not .Repository.IsMirror)}}
|
||||
<a class="tw-float-right muted" href="{{.RepoLink}}/wiki/_Sidebar?action=_edit" aria-label="{{ctx.Locale.Tr "repo.wiki.edit_page_button"}}">{{svg "octicon-pencil"}}</a>
|
||||
{{end}}
|
||||
{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .sidebarEscapeStatus "root" $}}
|
||||
{{.sidebarContent | SafeHTML}}
|
||||
{{.WikiSidebarHTML}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="tw-clear-both"></div>
|
||||
|
||||
{{if .footerPresent}}
|
||||
{{if .WikiFooterHTML}}
|
||||
<div class="render-content markup wiki-content-footer">
|
||||
{{if and .CanWriteWiki (not .Repository.IsMirror)}}
|
||||
<a class="tw-float-right muted" href="{{.RepoLink}}/wiki/_Footer?action=_edit" aria-label="{{ctx.Locale.Tr "repo.wiki.edit_page_button"}}">{{svg "octicon-pencil"}}</a>
|
||||
{{end}}
|
||||
{{template "repo/unicode_escape_prompt" dict "footerEscapeStatus" .sidebarEscapeStatus "root" $}}
|
||||
{{.footerContent | SafeHTML}}
|
||||
{{.WikiFooterHTML}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,12 +2,16 @@
|
|||
{{range .Repos}}
|
||||
<div class="flex-item">
|
||||
<div class="flex-item-leading">
|
||||
{{template "repo/icon" .}}
|
||||
{{if $.ShowRepoOwnerAvatar}}
|
||||
{{ctx.AvatarUtils.Avatar .Owner 24}}
|
||||
{{else}}
|
||||
{{template "repo/icon" .}}
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="flex-item-main">
|
||||
<div class="flex-item-header">
|
||||
<div class="flex-item-title">
|
||||
{{if and (or $.PageIsExplore $.PageIsProfileStarList) .Owner}}
|
||||
{{if and $.ShowRepoOwnerOnList .Owner}}
|
||||
<a class="text primary name" href="{{.Owner.HomeLink}}">{{.Owner.Name}}</a>/
|
||||
{{end}}
|
||||
<a class="text primary name" href="{{.Link}}">{{.Name}}</a>
|
||||
|
|
@ -7,6 +7,9 @@
|
|||
{{end}}
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
{{if .IsFirstTimeRegistration}}
|
||||
<p>{{ctx.Locale.Tr "auth.sign_up_tip"}}</p>
|
||||
{{end}}
|
||||
<form class="ui form" action="{{.SignUpLink}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
{{if or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister)}}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue