mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-25 23:06:11 +02:00
Merge branch 'main' into kerwin612-add-file-tree-to-file-view-page
This commit is contained in:
commit
eff3568d31
@ -112,8 +112,8 @@ const (
|
|||||||
CommentTypePRScheduledToAutoMerge // 34 pr was scheduled to auto merge when checks succeed
|
CommentTypePRScheduledToAutoMerge // 34 pr was scheduled to auto merge when checks succeed
|
||||||
CommentTypePRUnScheduledToAutoMerge // 35 pr was un scheduled to auto merge when checks succeed
|
CommentTypePRUnScheduledToAutoMerge // 35 pr was un scheduled to auto merge when checks succeed
|
||||||
|
|
||||||
CommentTypePin // 36 pin Issue
|
CommentTypePin // 36 pin Issue/PullRequest
|
||||||
CommentTypeUnpin // 37 unpin Issue
|
CommentTypeUnpin // 37 unpin Issue/PullRequest
|
||||||
|
|
||||||
CommentTypeChangeTimeEstimate // 38 Change time estimate
|
CommentTypeChangeTimeEstimate // 38 Change time estimate
|
||||||
)
|
)
|
||||||
|
@ -56,16 +56,11 @@ func repoArchiverForRelativePath(relativePath string) (*RepoArchiver, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, util.SilentWrap{Message: fmt.Sprintf("invalid storage path: %s", relativePath), Err: util.ErrInvalidArgument}
|
return nil, util.SilentWrap{Message: fmt.Sprintf("invalid storage path: %s", relativePath), Err: util.ErrInvalidArgument}
|
||||||
}
|
}
|
||||||
nameExts := strings.SplitN(parts[2], ".", 2)
|
commitID, archiveType := git.SplitArchiveNameType(parts[2])
|
||||||
if len(nameExts) != 2 {
|
if archiveType == git.ArchiveUnknown {
|
||||||
return nil, util.SilentWrap{Message: fmt.Sprintf("invalid storage path: %s", relativePath), Err: util.ErrInvalidArgument}
|
return nil, util.SilentWrap{Message: fmt.Sprintf("invalid storage path: %s", relativePath), Err: util.ErrInvalidArgument}
|
||||||
}
|
}
|
||||||
|
return &RepoArchiver{RepoID: repoID, CommitID: commitID, Type: archiveType}, nil
|
||||||
return &RepoArchiver{
|
|
||||||
RepoID: repoID,
|
|
||||||
CommitID: parts[1] + nameExts[0],
|
|
||||||
Type: git.ToArchiveType(nameExts[1]),
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRepoArchiver get an archiver
|
// GetRepoArchiver get an archiver
|
||||||
|
9
modules/cache/cache.go
vendored
9
modules/cache/cache.go
vendored
@ -37,10 +37,15 @@ func Init() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
testCacheKey = "DefaultCache.TestKey"
|
testCacheKey = "DefaultCache.TestKey"
|
||||||
SlowCacheThreshold = 100 * time.Microsecond
|
// SlowCacheThreshold marks cache tests as slow
|
||||||
|
// set to 30ms per discussion: https://github.com/go-gitea/gitea/issues/33190
|
||||||
|
// TODO: Replace with metrics histogram
|
||||||
|
SlowCacheThreshold = 30 * time.Millisecond
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Test performs delete, put and get operations on a predefined key
|
||||||
|
// returns
|
||||||
func Test() (time.Duration, error) {
|
func Test() (time.Duration, error) {
|
||||||
if defaultCache == nil {
|
if defaultCache == nil {
|
||||||
return 0, fmt.Errorf("default cache not initialized")
|
return 0, fmt.Errorf("default cache not initialized")
|
||||||
|
3
modules/cache/cache_test.go
vendored
3
modules/cache/cache_test.go
vendored
@ -43,7 +43,8 @@ func TestTest(t *testing.T) {
|
|||||||
elapsed, err := Test()
|
elapsed, err := Test()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// mem cache should take from 300ns up to 1ms on modern hardware ...
|
// mem cache should take from 300ns up to 1ms on modern hardware ...
|
||||||
assert.Less(t, elapsed, time.Millisecond)
|
assert.Positive(t, elapsed)
|
||||||
|
assert.Less(t, elapsed, SlowCacheThreshold)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetCache(t *testing.T) {
|
func TestGetCache(t *testing.T) {
|
||||||
|
@ -80,6 +80,10 @@ func RefNameFromTag(shortName string) RefName {
|
|||||||
return RefName(TagPrefix + shortName)
|
return RefName(TagPrefix + shortName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RefNameFromCommit(shortName string) RefName {
|
||||||
|
return RefName(shortName)
|
||||||
|
}
|
||||||
|
|
||||||
func (ref RefName) String() string {
|
func (ref RefName) String() string {
|
||||||
return string(ref)
|
return string(ref)
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@ func TestRefName(t *testing.T) {
|
|||||||
|
|
||||||
// Test pull names
|
// Test pull names
|
||||||
assert.Equal(t, "1", RefName("refs/pull/1/head").PullName())
|
assert.Equal(t, "1", RefName("refs/pull/1/head").PullName())
|
||||||
|
assert.True(t, RefName("refs/pull/1/head").IsPull())
|
||||||
|
assert.True(t, RefName("refs/pull/1/merge").IsPull())
|
||||||
assert.Equal(t, "my/pull", RefName("refs/pull/my/pull/head").PullName())
|
assert.Equal(t, "my/pull", RefName("refs/pull/my/pull/head").PullName())
|
||||||
|
|
||||||
// Test for branch names
|
// Test for branch names
|
||||||
|
@ -16,37 +16,35 @@ import (
|
|||||||
type ArchiveType int
|
type ArchiveType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ZIP zip archive type
|
ArchiveUnknown ArchiveType = iota
|
||||||
ZIP ArchiveType = iota + 1
|
ArchiveZip // 1
|
||||||
// TARGZ tar gz archive type
|
ArchiveTarGz // 2
|
||||||
TARGZ
|
ArchiveBundle // 3
|
||||||
// BUNDLE bundle archive type
|
|
||||||
BUNDLE
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// String converts an ArchiveType to string
|
// String converts an ArchiveType to string: the extension of the archive file without prefix dot
|
||||||
func (a ArchiveType) String() string {
|
func (a ArchiveType) String() string {
|
||||||
switch a {
|
switch a {
|
||||||
case ZIP:
|
case ArchiveZip:
|
||||||
return "zip"
|
return "zip"
|
||||||
case TARGZ:
|
case ArchiveTarGz:
|
||||||
return "tar.gz"
|
return "tar.gz"
|
||||||
case BUNDLE:
|
case ArchiveBundle:
|
||||||
return "bundle"
|
return "bundle"
|
||||||
}
|
}
|
||||||
return "unknown"
|
return "unknown"
|
||||||
}
|
}
|
||||||
|
|
||||||
func ToArchiveType(s string) ArchiveType {
|
func SplitArchiveNameType(s string) (string, ArchiveType) {
|
||||||
switch s {
|
switch {
|
||||||
case "zip":
|
case strings.HasSuffix(s, ".zip"):
|
||||||
return ZIP
|
return strings.TrimSuffix(s, ".zip"), ArchiveZip
|
||||||
case "tar.gz":
|
case strings.HasSuffix(s, ".tar.gz"):
|
||||||
return TARGZ
|
return strings.TrimSuffix(s, ".tar.gz"), ArchiveTarGz
|
||||||
case "bundle":
|
case strings.HasSuffix(s, ".bundle"):
|
||||||
return BUNDLE
|
return strings.TrimSuffix(s, ".bundle"), ArchiveBundle
|
||||||
}
|
}
|
||||||
return 0
|
return s, ArchiveUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateArchive create archive content to the target path
|
// CreateArchive create archive content to the target path
|
||||||
|
32
modules/git/repo_archive_test.go
Normal file
32
modules/git/repo_archive_test.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestArchiveType(t *testing.T) {
|
||||||
|
name, archiveType := SplitArchiveNameType("test.tar.gz")
|
||||||
|
assert.Equal(t, "test", name)
|
||||||
|
assert.Equal(t, "tar.gz", archiveType.String())
|
||||||
|
|
||||||
|
name, archiveType = SplitArchiveNameType("a/b/test.zip")
|
||||||
|
assert.Equal(t, "a/b/test", name)
|
||||||
|
assert.Equal(t, "zip", archiveType.String())
|
||||||
|
|
||||||
|
name, archiveType = SplitArchiveNameType("1234.bundle")
|
||||||
|
assert.Equal(t, "1234", name)
|
||||||
|
assert.Equal(t, "bundle", archiveType.String())
|
||||||
|
|
||||||
|
name, archiveType = SplitArchiveNameType("test")
|
||||||
|
assert.Equal(t, "test", name)
|
||||||
|
assert.Equal(t, "unknown", archiveType.String())
|
||||||
|
|
||||||
|
name, archiveType = SplitArchiveNameType("test.xz")
|
||||||
|
assert.Equal(t, "test.xz", name)
|
||||||
|
assert.Equal(t, "unknown", archiveType.String())
|
||||||
|
}
|
@ -46,7 +46,7 @@ func (Renderer) Render(ctx *markup.RenderContext, _ io.Reader, output io.Writer)
|
|||||||
setting.AppSubURL,
|
setting.AppSubURL,
|
||||||
url.PathEscape(ctx.RenderOptions.Metas["user"]),
|
url.PathEscape(ctx.RenderOptions.Metas["user"]),
|
||||||
url.PathEscape(ctx.RenderOptions.Metas["repo"]),
|
url.PathEscape(ctx.RenderOptions.Metas["repo"]),
|
||||||
ctx.RenderOptions.Metas["BranchNameSubURL"],
|
ctx.RenderOptions.Metas["RefTypeNameSubURL"],
|
||||||
url.PathEscape(ctx.RenderOptions.RelativePath),
|
url.PathEscape(ctx.RenderOptions.RelativePath),
|
||||||
)
|
)
|
||||||
return ctx.RenderInternal.FormatWithSafeAttrs(output, `<div class="%s" %s="%s"></div>`, playerClassName, playerSrcAttr, rawURL)
|
return ctx.RenderInternal.FormatWithSafeAttrs(output, `<div class="%s" %s="%s"></div>`, playerClassName, playerSrcAttr, rawURL)
|
||||||
|
@ -44,7 +44,7 @@ type RenderOptions struct {
|
|||||||
MarkupType string
|
MarkupType string
|
||||||
|
|
||||||
// user&repo, format&style®exp (for external issue pattern), teams&org (for mention)
|
// user&repo, format&style®exp (for external issue pattern), teams&org (for mention)
|
||||||
// BranchNameSubURL (for iframe&asciicast)
|
// RefTypeNameSubURL (for iframe&asciicast)
|
||||||
// markupAllowShortIssuePattern
|
// markupAllowShortIssuePattern
|
||||||
// markdownLineBreakStyle (comment, document)
|
// markdownLineBreakStyle (comment, document)
|
||||||
Metas map[string]string
|
Metas map[string]string
|
||||||
@ -170,7 +170,7 @@ sandbox="allow-scripts"
|
|||||||
setting.AppSubURL,
|
setting.AppSubURL,
|
||||||
url.PathEscape(ctx.RenderOptions.Metas["user"]),
|
url.PathEscape(ctx.RenderOptions.Metas["user"]),
|
||||||
url.PathEscape(ctx.RenderOptions.Metas["repo"]),
|
url.PathEscape(ctx.RenderOptions.Metas["repo"]),
|
||||||
ctx.RenderOptions.Metas["BranchNameSubURL"],
|
ctx.RenderOptions.Metas["RefTypeNameSubURL"],
|
||||||
url.PathEscape(ctx.RenderOptions.RelativePath),
|
url.PathEscape(ctx.RenderOptions.RelativePath),
|
||||||
))
|
))
|
||||||
return err
|
return err
|
||||||
|
@ -1651,7 +1651,7 @@ issues.attachment.open_tab=`Klikněte pro zobrazení „%s“ v nové záložce`
|
|||||||
issues.attachment.download=`Klikněte pro stažení „%s“`
|
issues.attachment.download=`Klikněte pro stažení „%s“`
|
||||||
issues.subscribe=Odebírat
|
issues.subscribe=Odebírat
|
||||||
issues.unsubscribe=Zrušit odběr
|
issues.unsubscribe=Zrušit odběr
|
||||||
issues.unpin_issue=Odepnout úkol
|
issues.unpin=Odepnout
|
||||||
issues.max_pinned=Nemůžete připnout další úkoly
|
issues.max_pinned=Nemůžete připnout další úkoly
|
||||||
issues.pin_comment=připnuto %s
|
issues.pin_comment=připnuto %s
|
||||||
issues.unpin_comment=odepnul/a tento %s
|
issues.unpin_comment=odepnul/a tento %s
|
||||||
|
@ -1646,7 +1646,7 @@ issues.attachment.open_tab=`Klicken, um „%s“ in einem neuen Tab zu öffnen`
|
|||||||
issues.attachment.download=`Klicken, um „%s“ herunterzuladen`
|
issues.attachment.download=`Klicken, um „%s“ herunterzuladen`
|
||||||
issues.subscribe=Abonnieren
|
issues.subscribe=Abonnieren
|
||||||
issues.unsubscribe=Abbestellen
|
issues.unsubscribe=Abbestellen
|
||||||
issues.unpin_issue=Issue abheften
|
issues.unpin=Loslösen
|
||||||
issues.max_pinned=Du kannst keine weiteren Issues anheften
|
issues.max_pinned=Du kannst keine weiteren Issues anheften
|
||||||
issues.pin_comment=hat das %s angeheftet
|
issues.pin_comment=hat das %s angeheftet
|
||||||
issues.unpin_comment=hat das %s abgeheftet
|
issues.unpin_comment=hat das %s abgeheftet
|
||||||
|
@ -1495,7 +1495,7 @@ issues.attachment.open_tab=`Κάντε κλικ για να δείτε το "%s"
|
|||||||
issues.attachment.download=`Κάντε κλικ για να λάβετε το "%s"`
|
issues.attachment.download=`Κάντε κλικ για να λάβετε το "%s"`
|
||||||
issues.subscribe=Εγγραφή
|
issues.subscribe=Εγγραφή
|
||||||
issues.unsubscribe=Διαγραφή
|
issues.unsubscribe=Διαγραφή
|
||||||
issues.unpin_issue=Άφεση Ζητήματος
|
issues.unpin=Άφεση
|
||||||
issues.max_pinned=Δεν μπορείτε να διατηρήσετε περισσότερα ζητήματα
|
issues.max_pinned=Δεν μπορείτε να διατηρήσετε περισσότερα ζητήματα
|
||||||
issues.pin_comment=διατήρησε αυτό %s
|
issues.pin_comment=διατήρησε αυτό %s
|
||||||
issues.unpin_comment=άφησε αυτό %s
|
issues.unpin_comment=άφησε αυτό %s
|
||||||
|
@ -1115,9 +1115,7 @@ blame.ignore_revs = Ignoring revisions in <a href="%s">.git-blame-ignore-revs</a
|
|||||||
blame.ignore_revs.failed = Failed to ignore revisions in <a href="%s">.git-blame-ignore-revs</a>.
|
blame.ignore_revs.failed = Failed to ignore revisions in <a href="%s">.git-blame-ignore-revs</a>.
|
||||||
user_search_tooltip = Shows a maximum of 30 users
|
user_search_tooltip = Shows a maximum of 30 users
|
||||||
|
|
||||||
tree_path_not_found_commit = Path %[1]s doesn't exist in commit %[2]s
|
tree_path_not_found = Path %[1]s doesn't exist in %[2]s
|
||||||
tree_path_not_found_branch = Path %[1]s doesn't exist in branch %[2]s
|
|
||||||
tree_path_not_found_tag = Path %[1]s doesn't exist in tag %[2]s
|
|
||||||
|
|
||||||
transfer.accept = Accept Transfer
|
transfer.accept = Accept Transfer
|
||||||
transfer.accept_desc = Transfer to "%s"
|
transfer.accept_desc = Transfer to "%s"
|
||||||
@ -1652,7 +1650,7 @@ issues.attachment.open_tab = `Click to see "%s" in a new tab`
|
|||||||
issues.attachment.download = `Click to download "%s"`
|
issues.attachment.download = `Click to download "%s"`
|
||||||
issues.subscribe = Subscribe
|
issues.subscribe = Subscribe
|
||||||
issues.unsubscribe = Unsubscribe
|
issues.unsubscribe = Unsubscribe
|
||||||
issues.unpin_issue = Unpin Issue
|
issues.unpin = Unpin
|
||||||
issues.max_pinned = "You can't pin more issues"
|
issues.max_pinned = "You can't pin more issues"
|
||||||
issues.pin_comment = "pinned this %s"
|
issues.pin_comment = "pinned this %s"
|
||||||
issues.unpin_comment = "unpinned this %s"
|
issues.unpin_comment = "unpinned this %s"
|
||||||
|
@ -1485,7 +1485,7 @@ issues.attachment.open_tab='Haga clic para ver "%s" en una pestaña nueva'
|
|||||||
issues.attachment.download=`Haga clic para descargar "%s"`
|
issues.attachment.download=`Haga clic para descargar "%s"`
|
||||||
issues.subscribe=Suscribir
|
issues.subscribe=Suscribir
|
||||||
issues.unsubscribe=Desuscribirse
|
issues.unsubscribe=Desuscribirse
|
||||||
issues.unpin_issue=Desanclar incidencia
|
issues.unpin=Desanclar
|
||||||
issues.max_pinned=No puedes anclar más incidencias
|
issues.max_pinned=No puedes anclar más incidencias
|
||||||
issues.pin_comment=anclado este %s
|
issues.pin_comment=anclado este %s
|
||||||
issues.unpin_comment=desanclado este %s
|
issues.unpin_comment=desanclado este %s
|
||||||
|
@ -46,7 +46,7 @@ webauthn_unsupported_browser=Votre navigateur ne prend actuellement pas en charg
|
|||||||
webauthn_error_unknown=Une erreur indéterminée s'est produite. Veuillez réessayer.
|
webauthn_error_unknown=Une erreur indéterminée s'est produite. Veuillez réessayer.
|
||||||
webauthn_error_insecure=`WebAuthn ne prend en charge que les connexions sécurisées. Pour les tests via HTTP, vous pouvez utiliser l'origine "localhost" ou "127.0.0.1"`
|
webauthn_error_insecure=`WebAuthn ne prend en charge que les connexions sécurisées. Pour les tests via HTTP, vous pouvez utiliser l'origine "localhost" ou "127.0.0.1"`
|
||||||
webauthn_error_unable_to_process=Le serveur n'a pas pu traiter votre demande.
|
webauthn_error_unable_to_process=Le serveur n'a pas pu traiter votre demande.
|
||||||
webauthn_error_duplicated=La clé de sécurité n'est pas autorisée pour cette demande. Veuillez vous assurer que la clé n'est pas déjà enregistrée.
|
webauthn_error_duplicated=La clé de sécurité n’est pas autorisée pour cette demande. Veuillez vous assurer que la clé n’est pas déjà enregistrée.
|
||||||
webauthn_error_empty=Vous devez définir un nom pour cette clé.
|
webauthn_error_empty=Vous devez définir un nom pour cette clé.
|
||||||
webauthn_error_timeout=Le délai d'attente imparti a été atteint avant que votre clé ne puisse être lue. Veuillez recharger la page pour réessayer.
|
webauthn_error_timeout=Le délai d'attente imparti a été atteint avant que votre clé ne puisse être lue. Veuillez recharger la page pour réessayer.
|
||||||
webauthn_reload=Recharger
|
webauthn_reload=Recharger
|
||||||
@ -469,7 +469,7 @@ sspi_auth_failed=Échec de l'authentification SSPI
|
|||||||
password_pwned=Le mot de passe que vous avez choisi <a target="_blank" rel="noopener noreferrer" href="%s">fait partit des mots de passe ayant fuité</a> sur internet. Veuillez réessayer avec un mot de passe différent et considérez remplacer ce mot de passe si vous l’utilisez ailleurs.
|
password_pwned=Le mot de passe que vous avez choisi <a target="_blank" rel="noopener noreferrer" href="%s">fait partit des mots de passe ayant fuité</a> sur internet. Veuillez réessayer avec un mot de passe différent et considérez remplacer ce mot de passe si vous l’utilisez ailleurs.
|
||||||
password_pwned_err=Impossible d'envoyer la demande à HaveIBeenPwned
|
password_pwned_err=Impossible d'envoyer la demande à HaveIBeenPwned
|
||||||
last_admin=Vous ne pouvez pas supprimer ce compte car au moins un administrateur est requis.
|
last_admin=Vous ne pouvez pas supprimer ce compte car au moins un administrateur est requis.
|
||||||
signin_passkey=Se connecter avec une clé d’identification (passkey)
|
signin_passkey=Se connecter avec une clé d’accès (passkey)
|
||||||
back_to_sign_in=Revenir à la page de connexion
|
back_to_sign_in=Revenir à la page de connexion
|
||||||
|
|
||||||
[mail]
|
[mail]
|
||||||
@ -818,7 +818,7 @@ manage_ssh_keys=Gérer les clés SSH
|
|||||||
manage_ssh_principals=Gérer les certificats principaux SSH
|
manage_ssh_principals=Gérer les certificats principaux SSH
|
||||||
manage_gpg_keys=Gérer les clés GPG
|
manage_gpg_keys=Gérer les clés GPG
|
||||||
add_key=Ajouter une clé
|
add_key=Ajouter une clé
|
||||||
ssh_desc=Ces clefs SSH publiques sont associées à votre compte. Les clefs privées correspondantes permettent l'accès complet à vos repos.
|
ssh_desc=Ces clés SSH publiques sont associées à votre compte. Les clés privées correspondantes permettent l’accès complet à vos dépôts.
|
||||||
principal_desc=Ces Principaux de certificats SSH sont associés à votre compte et permettent un accès complet à vos dépôts.
|
principal_desc=Ces Principaux de certificats SSH sont associés à votre compte et permettent un accès complet à vos dépôts.
|
||||||
gpg_desc=Ces clés GPG sont associées à votre compte. Conservez-les en lieu sûr, car elles permettent de vérifier vos révisions.
|
gpg_desc=Ces clés GPG sont associées à votre compte. Conservez-les en lieu sûr, car elles permettent de vérifier vos révisions.
|
||||||
ssh_helper=<strong>Besoin d'aide ?</strong> Consultez le guide de GitHub pour <a href="%s">créer vos propres clés SSH</a> ou <a href="%s">résoudre les problèmes courants</a> que vous pourriez rencontrer en utilisant SSH.
|
ssh_helper=<strong>Besoin d'aide ?</strong> Consultez le guide de GitHub pour <a href="%s">créer vos propres clés SSH</a> ou <a href="%s">résoudre les problèmes courants</a> que vous pourriez rencontrer en utilisant SSH.
|
||||||
@ -969,7 +969,7 @@ passcode_invalid=Le mot de passe est invalide. Réessayez.
|
|||||||
twofa_enrolled=L’authentification à deux facteurs a été activée pour votre compte. Gardez votre clé de secours (%s) en lieu sûr, car il ne vous sera montré qu'une seule fois.
|
twofa_enrolled=L’authentification à deux facteurs a été activée pour votre compte. Gardez votre clé de secours (%s) en lieu sûr, car il ne vous sera montré qu'une seule fois.
|
||||||
twofa_failed_get_secret=Impossible d'obtenir le secret.
|
twofa_failed_get_secret=Impossible d'obtenir le secret.
|
||||||
|
|
||||||
webauthn_desc=Les clefs de sécurité sont des dispositifs matériels contenant des clefs cryptographiques. Elles peuvent être utilisées pour l’authentification à deux facteurs. La clef de sécurité doit supporter le standard <a rel="noreferrer" target="_blank" href="%s">WebAuthn Authenticator</a>.
|
webauthn_desc=Les clés de sécurité sont des dispositifs matériels contenant des clés cryptographiques. Elles peuvent être utilisées pour l’authentification à deux facteurs. La clé de sécurité doit supporter le standard <a rel="noreferrer" target="_blank" href="%s">WebAuthn Authenticator</a>.
|
||||||
webauthn_register_key=Ajouter une clé de sécurité
|
webauthn_register_key=Ajouter une clé de sécurité
|
||||||
webauthn_nickname=Pseudonyme
|
webauthn_nickname=Pseudonyme
|
||||||
webauthn_delete_key=Retirer la clé de sécurité
|
webauthn_delete_key=Retirer la clé de sécurité
|
||||||
@ -1651,7 +1651,7 @@ issues.attachment.open_tab=`Cliquez ici pour voir « %s » dans un nouvel ongl
|
|||||||
issues.attachment.download=`Cliquez pour télécharger « %s ».`
|
issues.attachment.download=`Cliquez pour télécharger « %s ».`
|
||||||
issues.subscribe=S’abonner
|
issues.subscribe=S’abonner
|
||||||
issues.unsubscribe=Se désabonner
|
issues.unsubscribe=Se désabonner
|
||||||
issues.unpin_issue=Désépingler le ticket
|
issues.unpin=Désépingler
|
||||||
issues.max_pinned=Vous ne pouvez pas épingler plus de tickets
|
issues.max_pinned=Vous ne pouvez pas épingler plus de tickets
|
||||||
issues.pin_comment=a épinglé ça %s.
|
issues.pin_comment=a épinglé ça %s.
|
||||||
issues.unpin_comment=a désépinglé ça %s.
|
issues.unpin_comment=a désépinglé ça %s.
|
||||||
@ -2400,17 +2400,17 @@ settings.packagist_api_token=Jeton API
|
|||||||
settings.packagist_package_url=URL du paquet Packagist
|
settings.packagist_package_url=URL du paquet Packagist
|
||||||
settings.deploy_keys=Clés de déploiement
|
settings.deploy_keys=Clés de déploiement
|
||||||
settings.add_deploy_key=Ajouter une clé de déploiement
|
settings.add_deploy_key=Ajouter une clé de déploiement
|
||||||
settings.deploy_key_desc=Les clefs de déploiement ont un accès en lecture seule au dépôt.
|
settings.deploy_key_desc=Les clés de déploiement ont un accès en lecture seule au dépôt.
|
||||||
settings.is_writable=Activer l'accès en écriture
|
settings.is_writable=Activer l'accès en écriture
|
||||||
settings.is_writable_info=Autoriser cette clé de déploiement à <strong>soumettre</strong> sur le dépôt.
|
settings.is_writable_info=Autoriser cette clé de déploiement à <strong>soumettre</strong> sur le dépôt.
|
||||||
settings.no_deploy_keys=Il n'y a pas encore de clefs de déploiement.
|
settings.no_deploy_keys=Il n’y a pas encore de clés de déploiement.
|
||||||
settings.title=Titre
|
settings.title=Titre
|
||||||
settings.deploy_key_content=Contenu
|
settings.deploy_key_content=Contenu
|
||||||
settings.key_been_used=Une clef de déploiement identique est déjà en cours d'utilisation.
|
settings.key_been_used=Une clé de déploiement identique est déjà en cours d’utilisation.
|
||||||
settings.key_name_used=Une clef de déploiement du même nom existe déjà.
|
settings.key_name_used=Une clé de déploiement du même nom existe déjà.
|
||||||
settings.add_key_success=La clé de déploiement "%s" a été ajoutée.
|
settings.add_key_success=La clé de déploiement « %s » a été ajoutée.
|
||||||
settings.deploy_key_deletion=Supprimer une clef de déploiement
|
settings.deploy_key_deletion=Supprimer une clé de déploiement
|
||||||
settings.deploy_key_deletion_desc=La suppression d'une clef de déploiement révoque son accès à ce dépôt. Continuer ?
|
settings.deploy_key_deletion_desc=La suppression d’une clé de déploiement révoque son accès à ce dépôt. Continuer ?
|
||||||
settings.deploy_key_deletion_success=La clé de déploiement a été supprimée.
|
settings.deploy_key_deletion_success=La clé de déploiement a été supprimée.
|
||||||
settings.branches=Branches
|
settings.branches=Branches
|
||||||
settings.protected_branch=Protection de branche
|
settings.protected_branch=Protection de branche
|
||||||
@ -2627,6 +2627,9 @@ diff.image.overlay=Superposition
|
|||||||
diff.has_escaped=Cette ligne contient des caractères Unicode cachés
|
diff.has_escaped=Cette ligne contient des caractères Unicode cachés
|
||||||
diff.show_file_tree=Afficher l’arborescence des fichiers
|
diff.show_file_tree=Afficher l’arborescence des fichiers
|
||||||
diff.hide_file_tree=Masquer l’arborescence des fichiers
|
diff.hide_file_tree=Masquer l’arborescence des fichiers
|
||||||
|
diff.submodule_added=Sous-module %[1]s ajouté à %[2]s
|
||||||
|
diff.submodule_deleted=Sous-module %[1]s supprimé de %[2]s
|
||||||
|
diff.submodule_updated=Sous-module %[1]s mis-à-jour : %[2]s
|
||||||
|
|
||||||
releases.desc=Suivi des publications et des téléchargements.
|
releases.desc=Suivi des publications et des téléchargements.
|
||||||
release.releases=Publications
|
release.releases=Publications
|
||||||
@ -3116,7 +3119,7 @@ auths.attribute_username_placeholder=Laisser vide afin d'utiliser le nom d'utili
|
|||||||
auths.attribute_name=Attribut prénom
|
auths.attribute_name=Attribut prénom
|
||||||
auths.attribute_surname=Attribut nom de famille
|
auths.attribute_surname=Attribut nom de famille
|
||||||
auths.attribute_mail=Attribut e-mail
|
auths.attribute_mail=Attribut e-mail
|
||||||
auths.attribute_ssh_public_key=Attribut clef SSH publique
|
auths.attribute_ssh_public_key=Attribut clé SSH publique
|
||||||
auths.attribute_avatar=Attribut de l'avatar
|
auths.attribute_avatar=Attribut de l'avatar
|
||||||
auths.attributes_in_bind=Aller chercher les attributs dans le contexte de liaison DN
|
auths.attributes_in_bind=Aller chercher les attributs dans le contexte de liaison DN
|
||||||
auths.allow_deactivate_all=Permettre à un résultat de recherche vide de désactiver tous les utilisateurs
|
auths.allow_deactivate_all=Permettre à un résultat de recherche vide de désactiver tous les utilisateurs
|
||||||
@ -3240,7 +3243,7 @@ config.ssh_port=Port
|
|||||||
config.ssh_listen_port=Port d'écoute
|
config.ssh_listen_port=Port d'écoute
|
||||||
config.ssh_root_path=Emplacement racine
|
config.ssh_root_path=Emplacement racine
|
||||||
config.ssh_key_test_path=Chemin de test des clés
|
config.ssh_key_test_path=Chemin de test des clés
|
||||||
config.ssh_keygen_path=Chemin vers le générateur de clefs ("ssh-keygen")
|
config.ssh_keygen_path=Chemin vers le générateur de clés (« ssh-keygen »)
|
||||||
config.ssh_minimum_key_size_check=Vérification de la longueur de clé minimale
|
config.ssh_minimum_key_size_check=Vérification de la longueur de clé minimale
|
||||||
config.ssh_minimum_key_sizes=Tailles de clé minimales
|
config.ssh_minimum_key_sizes=Tailles de clé minimales
|
||||||
|
|
||||||
|
@ -244,6 +244,7 @@ license_desc=Téigh go bhfaighidh <a target="_blank" rel="noopener noreferrer" h
|
|||||||
|
|
||||||
[install]
|
[install]
|
||||||
install=Suiteáil
|
install=Suiteáil
|
||||||
|
installing_desc=Suiteáil anois, fan go fóill...
|
||||||
title=Cumraíocht Tosaigh
|
title=Cumraíocht Tosaigh
|
||||||
docker_helper=Má ritheann tú Gitea taobh istigh de Docker, léigh an <a target="_blank" rel="noopener noreferrer" href="%s">doiciméadúchán</a> roimh aon socruithe a athrú.
|
docker_helper=Má ritheann tú Gitea taobh istigh de Docker, léigh an <a target="_blank" rel="noopener noreferrer" href="%s">doiciméadúchán</a> roimh aon socruithe a athrú.
|
||||||
require_db_desc=Éilíonn Gitea MySQL, PostgreSQL, MSSQL, SQLite3 nó TiDB (prótacal MySQL).
|
require_db_desc=Éilíonn Gitea MySQL, PostgreSQL, MSSQL, SQLite3 nó TiDB (prótacal MySQL).
|
||||||
@ -1015,6 +1016,9 @@ new_repo_helper=Tá gach comhad tionscadail i stór, lena n-áirítear stair ath
|
|||||||
owner=Úinéir
|
owner=Úinéir
|
||||||
owner_helper=B'fhéidir nach dtaispeánfar roinnt eagraíochtaí sa anuas mar gheall ar theorainn uasta comhaireamh stórais.
|
owner_helper=B'fhéidir nach dtaispeánfar roinnt eagraíochtaí sa anuas mar gheall ar theorainn uasta comhaireamh stórais.
|
||||||
repo_name=Ainm Stórais
|
repo_name=Ainm Stórais
|
||||||
|
repo_name_profile_public_hint=Is stóras speisialta é .profile is féidir leat a úsáid chun README.md a chur le do phróifíl eagraíochta poiblí, le feiceáil ag aon duine. Cinntigh go bhfuil sé poiblí agus tosaigh é le README san eolaire próifíle le tosú.
|
||||||
|
repo_name_profile_private_hint=Is stóras speisialta é .profile-private is féidir leat a úsáid chun README.md a chur le do phróifíl bhall eagraíochta, nach féidir a fheiceáil ach ag baill eagraíochta. Cinntigh go bhfuil sé príobháideach agus tosaigh le README sa eolaire próifíle chun tús a chur leis.
|
||||||
|
repo_name_helper=Úsáideann ainmneacha maith stóras focail eochair gairide, áithnid agus uathúla. D'fhéadfaí stóras darbh ainm '.profile' nó '.profile-private' a úsáid chun README.md a chur leis an bpróifíl úsáideora/eagraíochta.
|
||||||
repo_size=Méid an Stóras
|
repo_size=Méid an Stóras
|
||||||
template=Teimpléad
|
template=Teimpléad
|
||||||
template_select=Roghnaigh teimpléad.
|
template_select=Roghnaigh teimpléad.
|
||||||
@ -1231,6 +1235,7 @@ create_new_repo_command=Stóras nua a chruthú ar an líne ordaithe
|
|||||||
push_exist_repo=Stóras atá ann cheana a bhrú ón líne ordaithe
|
push_exist_repo=Stóras atá ann cheana a bhrú ón líne ordaithe
|
||||||
empty_message=Níl aon ábhar sa stóras seo.
|
empty_message=Níl aon ábhar sa stóras seo.
|
||||||
broken_message=Ní féidir na sonraí Git atá mar bhunús leis an stóras seo a léamh. Déan teagmháil le riarthóir an chás seo nó scrios an stóras seo.
|
broken_message=Ní féidir na sonraí Git atá mar bhunús leis an stóras seo a léamh. Déan teagmháil le riarthóir an chás seo nó scrios an stóras seo.
|
||||||
|
no_branch=Níl aon bhrainsí ag an stóras seo.
|
||||||
|
|
||||||
code=Cód
|
code=Cód
|
||||||
code.desc=Rochtain ar chód foinse, comhaid, gealltanais agus brainsí.
|
code.desc=Rochtain ar chód foinse, comhaid, gealltanais agus brainsí.
|
||||||
@ -1646,7 +1651,7 @@ issues.attachment.open_tab=`Cliceáil chun "%s" a fheiceáil i gcluaisín nua`
|
|||||||
issues.attachment.download=`Cliceáil chun "%s" a íoslódáil
|
issues.attachment.download=`Cliceáil chun "%s" a íoslódáil
|
||||||
issues.subscribe=Liostáil
|
issues.subscribe=Liostáil
|
||||||
issues.unsubscribe=Díliostáil
|
issues.unsubscribe=Díliostáil
|
||||||
issues.unpin_issue=Bain pionna an t-eagrán
|
issues.unpin=Díphoráil
|
||||||
issues.max_pinned=Ní féidir leat níos mó saincheisteanna a phionadh
|
issues.max_pinned=Ní féidir leat níos mó saincheisteanna a phionadh
|
||||||
issues.pin_comment=phionnáil an %s seo
|
issues.pin_comment=phionnáil an %s seo
|
||||||
issues.unpin_comment=bain pionna an %s seo
|
issues.unpin_comment=bain pionna an %s seo
|
||||||
@ -2622,6 +2627,9 @@ diff.image.overlay=Forleagan
|
|||||||
diff.has_escaped=Tá carachtair Unicode i bhfolach ag an líne seo
|
diff.has_escaped=Tá carachtair Unicode i bhfolach ag an líne seo
|
||||||
diff.show_file_tree=Taispeáin crann comhad
|
diff.show_file_tree=Taispeáin crann comhad
|
||||||
diff.hide_file_tree=Folaigh crann comhad
|
diff.hide_file_tree=Folaigh crann comhad
|
||||||
|
diff.submodule_added=Fomhodúl %[1]s curtha leis ag %[2]s
|
||||||
|
diff.submodule_deleted=Scriosadh fomhodúl %[1]s ó %[2]s
|
||||||
|
diff.submodule_updated=Nuashonraíodh fomhodúl %[1]s: %[2]s
|
||||||
|
|
||||||
releases.desc=Rian leaganacha tionscadal agus íoslódálacha.
|
releases.desc=Rian leaganacha tionscadal agus íoslódálacha.
|
||||||
release.releases=Eisiúintí
|
release.releases=Eisiúintí
|
||||||
@ -2860,6 +2868,9 @@ teams.invite.title=Tugadh cuireadh duit dul isteach i bhfoireann <strong>%s</str
|
|||||||
teams.invite.by=Ar cuireadh ó %s
|
teams.invite.by=Ar cuireadh ó %s
|
||||||
teams.invite.description=Cliceáil ar an gcnaipe thíos le do thoil chun dul isteach san fhoireann.
|
teams.invite.description=Cliceáil ar an gcnaipe thíos le do thoil chun dul isteach san fhoireann.
|
||||||
|
|
||||||
|
view_as_role=Féach mar: %s
|
||||||
|
view_as_public_hint=Tá tú ag féachaint ar an README mar úsáideoir poiblí.
|
||||||
|
view_as_member_hint=Tá tú ag féachaint ar an README mar bhall den eagraíocht seo.
|
||||||
|
|
||||||
[admin]
|
[admin]
|
||||||
maintenance=Cothabháil
|
maintenance=Cothabháil
|
||||||
@ -3530,6 +3541,7 @@ versions=Leaganacha
|
|||||||
versions.view_all=Féach ar gach
|
versions.view_all=Féach ar gach
|
||||||
dependency.id=ID
|
dependency.id=ID
|
||||||
dependency.version=Leagan
|
dependency.version=Leagan
|
||||||
|
search_in_external_registry=Cuardaigh i %s
|
||||||
alpine.registry=Socraigh an chlár seo tríd an url a chur i do chomhad <code>/etc/apk/repositories</code>:
|
alpine.registry=Socraigh an chlár seo tríd an url a chur i do chomhad <code>/etc/apk/repositories</code>:
|
||||||
alpine.registry.key=Íoslódáil eochair RSA poiblí na clárlainne isteach san fhillteán <code>/etc/apk/keys/</code> chun an síniú innéacs a fhíorú:
|
alpine.registry.key=Íoslódáil eochair RSA poiblí na clárlainne isteach san fhillteán <code>/etc/apk/keys/</code> chun an síniú innéacs a fhíorú:
|
||||||
alpine.registry.info=Roghnaigh $branch agus $repository ón liosta thíos.
|
alpine.registry.info=Roghnaigh $branch agus $repository ón liosta thíos.
|
||||||
@ -3755,6 +3767,7 @@ workflow.not_found=Níor aimsíodh sreabhadh oibre '%s'.
|
|||||||
workflow.run_success=Ritheann sreabhadh oibre '%s' go rathúil.
|
workflow.run_success=Ritheann sreabhadh oibre '%s' go rathúil.
|
||||||
workflow.from_ref=Úsáid sreabhadh oibre ó
|
workflow.from_ref=Úsáid sreabhadh oibre ó
|
||||||
workflow.has_workflow_dispatch=Tá comhoibriú ag an gcur i bhfeidhm seo le himeacht workflow_dispatch.
|
workflow.has_workflow_dispatch=Tá comhoibriú ag an gcur i bhfeidhm seo le himeacht workflow_dispatch.
|
||||||
|
workflow.has_no_workflow_dispatch=Níl aon truicear teagmhais workflow_dispatch ag sreabhadh oibre '%s'.
|
||||||
|
|
||||||
need_approval_desc=Teastaíonn faomhadh chun sreafaí oibre a rith le haghaidh iarratas tarraingt forc.
|
need_approval_desc=Teastaíonn faomhadh chun sreafaí oibre a rith le haghaidh iarratas tarraingt forc.
|
||||||
|
|
||||||
|
@ -818,6 +818,7 @@ issues.attachment.open_tab=`Klik untuk melihat "%s" di tab baru`
|
|||||||
issues.attachment.download=`Klik untuk mengunduh "%s"`
|
issues.attachment.download=`Klik untuk mengunduh "%s"`
|
||||||
issues.subscribe=Berlangganan
|
issues.subscribe=Berlangganan
|
||||||
issues.unsubscribe=Berhenti berlangganan
|
issues.unsubscribe=Berhenti berlangganan
|
||||||
|
issues.unpin=Lepas sematan
|
||||||
issues.delete=Hapus
|
issues.delete=Hapus
|
||||||
|
|
||||||
|
|
||||||
|
@ -1015,6 +1015,7 @@ new_repo_helper=リポジトリには、プロジェクトのすべてのファ
|
|||||||
owner=オーナー
|
owner=オーナー
|
||||||
owner_helper=リポジトリ数の上限により、一部の組織はドロップダウンに表示されない場合があります。
|
owner_helper=リポジトリ数の上限により、一部の組織はドロップダウンに表示されない場合があります。
|
||||||
repo_name=リポジトリ名
|
repo_name=リポジトリ名
|
||||||
|
repo_name_helper=リポジトリ名は、短く、覚えやすく、他と重複しないキーワードを使用しましょう。 リポジトリ名を ".profile" または ".profile-private" にして README.md を追加すると、ユーザーや組織のプロフィールとなります。
|
||||||
repo_size=リポジトリサイズ
|
repo_size=リポジトリサイズ
|
||||||
template=テンプレート
|
template=テンプレート
|
||||||
template_select=テンプレートを選択してください。
|
template_select=テンプレートを選択してください。
|
||||||
@ -1641,7 +1642,7 @@ issues.attachment.open_tab=`クリックして新しいタブで "%s" を見る`
|
|||||||
issues.attachment.download=`クリックして "%s" をダウンロード`
|
issues.attachment.download=`クリックして "%s" をダウンロード`
|
||||||
issues.subscribe=購読する
|
issues.subscribe=購読する
|
||||||
issues.unsubscribe=購読を解除
|
issues.unsubscribe=購読を解除
|
||||||
issues.unpin_issue=イシューのピン留めを解除
|
issues.unpin=ピン留め解除
|
||||||
issues.max_pinned=これ以上イシューをピン留めできません
|
issues.max_pinned=これ以上イシューをピン留めできません
|
||||||
issues.pin_comment=がピン留め %s
|
issues.pin_comment=がピン留め %s
|
||||||
issues.unpin_comment=がピン留めを解除 %s
|
issues.unpin_comment=がピン留めを解除 %s
|
||||||
@ -2852,6 +2853,8 @@ teams.invite.title=あなたは組織 <strong>%[2]s</strong> 内のチーム <st
|
|||||||
teams.invite.by=%s からの招待
|
teams.invite.by=%s からの招待
|
||||||
teams.invite.description=下のボタンをクリックしてチームに参加してください。
|
teams.invite.description=下のボタンをクリックしてチームに参加してください。
|
||||||
|
|
||||||
|
view_as_public_hint=READMEを公開ユーザーとして見ています。
|
||||||
|
view_as_member_hint=READMEをこの組織のメンバーとして見ています。
|
||||||
|
|
||||||
[admin]
|
[admin]
|
||||||
maintenance=メンテナンス
|
maintenance=メンテナンス
|
||||||
@ -3530,6 +3533,8 @@ alpine.repository=リポジトリ情報
|
|||||||
alpine.repository.branches=Branches
|
alpine.repository.branches=Branches
|
||||||
alpine.repository.repositories=Repositories
|
alpine.repository.repositories=Repositories
|
||||||
alpine.repository.architectures=Architectures
|
alpine.repository.architectures=Architectures
|
||||||
|
arch.registry=<code>/etc/pacman.conf</code> にリポジトリとアーキテクチャを含めてサーバーを追加します:
|
||||||
|
arch.install=pacmanでパッケージを同期します:
|
||||||
arch.repository=リポジトリ情報
|
arch.repository=リポジトリ情報
|
||||||
arch.repository.repositories=リポジトリ
|
arch.repository.repositories=リポジトリ
|
||||||
arch.repository.architectures=Architectures
|
arch.repository.architectures=Architectures
|
||||||
@ -3712,6 +3717,7 @@ runners.status.active=稼働中
|
|||||||
runners.status.offline=オフライン
|
runners.status.offline=オフライン
|
||||||
runners.version=バージョン
|
runners.version=バージョン
|
||||||
runners.reset_registration_token=登録トークンをリセット
|
runners.reset_registration_token=登録トークンをリセット
|
||||||
|
runners.reset_registration_token_confirm=現在のトークンを無効にして、新しいトークンを生成しますか?
|
||||||
runners.reset_registration_token_success=ランナー登録トークンをリセットしました
|
runners.reset_registration_token_success=ランナー登録トークンをリセットしました
|
||||||
|
|
||||||
runs.all_workflows=すべてのワークフロー
|
runs.all_workflows=すべてのワークフロー
|
||||||
|
@ -1501,7 +1501,7 @@ issues.attachment.open_tab=`Noklikšķiniet, lai apskatītos "%s" jaunā logā`
|
|||||||
issues.attachment.download=`Noklikšķiniet, lai lejupielādētu "%s"`
|
issues.attachment.download=`Noklikšķiniet, lai lejupielādētu "%s"`
|
||||||
issues.subscribe=Abonēt
|
issues.subscribe=Abonēt
|
||||||
issues.unsubscribe=Atrakstīties
|
issues.unsubscribe=Atrakstīties
|
||||||
issues.unpin_issue=Atspraust problēmu
|
issues.unpin=Atspraust
|
||||||
issues.max_pinned=Nevar piespraust vairāk problēmas
|
issues.max_pinned=Nevar piespraust vairāk problēmas
|
||||||
issues.pin_comment=piesprauda šo %s
|
issues.pin_comment=piesprauda šo %s
|
||||||
issues.unpin_comment=atsprauda šo %s
|
issues.unpin_comment=atsprauda šo %s
|
||||||
|
@ -1491,7 +1491,7 @@ issues.attachment.open_tab=`Clique para ver "%s" em uma nova aba`
|
|||||||
issues.attachment.download=`Clique para baixar "%s"`
|
issues.attachment.download=`Clique para baixar "%s"`
|
||||||
issues.subscribe=Inscrever-se
|
issues.subscribe=Inscrever-se
|
||||||
issues.unsubscribe=Desinscrever
|
issues.unsubscribe=Desinscrever
|
||||||
issues.unpin_issue=Desfixar issue
|
issues.unpin=Desfixar
|
||||||
issues.max_pinned=Você não pode fixar mais issues
|
issues.max_pinned=Você não pode fixar mais issues
|
||||||
issues.pin_comment=fixou isto %s
|
issues.pin_comment=fixou isto %s
|
||||||
issues.unpin_comment=desafixou isto %s
|
issues.unpin_comment=desafixou isto %s
|
||||||
|
@ -1651,7 +1651,7 @@ issues.attachment.open_tab=`Clique para ver "%s" num separador novo`
|
|||||||
issues.attachment.download=`Clique para descarregar "%s"`
|
issues.attachment.download=`Clique para descarregar "%s"`
|
||||||
issues.subscribe=Subscrever
|
issues.subscribe=Subscrever
|
||||||
issues.unsubscribe=Anular subscrição
|
issues.unsubscribe=Anular subscrição
|
||||||
issues.unpin_issue=Desafixar questão
|
issues.unpin=Desafixar
|
||||||
issues.max_pinned=Já não pode fixar mais questões
|
issues.max_pinned=Já não pode fixar mais questões
|
||||||
issues.pin_comment=fixou isto %s
|
issues.pin_comment=fixou isto %s
|
||||||
issues.unpin_comment=desafixou isto %s
|
issues.unpin_comment=desafixou isto %s
|
||||||
|
@ -1471,7 +1471,7 @@ issues.attachment.open_tab=`Нажмите, чтобы увидеть «%s» в
|
|||||||
issues.attachment.download=`Нажмите, чтобы скачать «%s»`
|
issues.attachment.download=`Нажмите, чтобы скачать «%s»`
|
||||||
issues.subscribe=Подписаться
|
issues.subscribe=Подписаться
|
||||||
issues.unsubscribe=Отказаться от подписки
|
issues.unsubscribe=Отказаться от подписки
|
||||||
issues.unpin_issue=Открепить задачу
|
issues.unpin=Открепить
|
||||||
issues.max_pinned=Нельзя закрепить больше задач
|
issues.max_pinned=Нельзя закрепить больше задач
|
||||||
issues.pin_comment=закрепил(а) эту задачу %s
|
issues.pin_comment=закрепил(а) эту задачу %s
|
||||||
issues.unpin_comment=открепил(а) эту задачу %s
|
issues.unpin_comment=открепил(а) эту задачу %s
|
||||||
|
@ -1068,6 +1068,7 @@ issues.dismiss_review=Zamietnuť revíziu
|
|||||||
issues.dismiss_review_warning=Naozaj chcete zrušiť túto revíziu?
|
issues.dismiss_review_warning=Naozaj chcete zrušiť túto revíziu?
|
||||||
issues.cancel=Zrušiť
|
issues.cancel=Zrušiť
|
||||||
issues.save=Uložiť
|
issues.save=Uložiť
|
||||||
|
issues.unpin=Odopnúť
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1605,7 +1605,7 @@ issues.attachment.open_tab=`Yeni bir sekmede "%s" görmek için tıkla`
|
|||||||
issues.attachment.download=`"%s" indirmek için tıkla`
|
issues.attachment.download=`"%s" indirmek için tıkla`
|
||||||
issues.subscribe=Abone Ol
|
issues.subscribe=Abone Ol
|
||||||
issues.unsubscribe=Abonelikten Çık
|
issues.unsubscribe=Abonelikten Çık
|
||||||
issues.unpin_issue=Konuyu Sabitlemeden Kaldır
|
issues.unpin=Sabitlemeyi kaldır
|
||||||
issues.max_pinned=Daha fazla konuyu sabitleyemezsiniz
|
issues.max_pinned=Daha fazla konuyu sabitleyemezsiniz
|
||||||
issues.pin_comment=%s sabitlendi
|
issues.pin_comment=%s sabitlendi
|
||||||
issues.unpin_comment=%s sabitlenmesi kaldırıldı
|
issues.unpin_comment=%s sabitlenmesi kaldırıldı
|
||||||
|
@ -1646,7 +1646,7 @@ issues.attachment.open_tab=`在新的标签页中查看 '%s'`
|
|||||||
issues.attachment.download=`点击下载 '%s'`
|
issues.attachment.download=`点击下载 '%s'`
|
||||||
issues.subscribe=订阅
|
issues.subscribe=订阅
|
||||||
issues.unsubscribe=取消订阅
|
issues.unsubscribe=取消订阅
|
||||||
issues.unpin_issue=取消置顶
|
issues.unpin=取消置顶
|
||||||
issues.max_pinned=您不能置顶更多工单
|
issues.max_pinned=您不能置顶更多工单
|
||||||
issues.pin_comment=于 %s 被置顶
|
issues.pin_comment=于 %s 被置顶
|
||||||
issues.unpin_comment=于 %s 取消置顶
|
issues.unpin_comment=于 %s 取消置顶
|
||||||
|
@ -1640,7 +1640,7 @@ issues.attachment.open_tab=`在新分頁中查看「%s」`
|
|||||||
issues.attachment.download=`點擊下載「%s」`
|
issues.attachment.download=`點擊下載「%s」`
|
||||||
issues.subscribe=訂閱
|
issues.subscribe=訂閱
|
||||||
issues.unsubscribe=取消訂閱
|
issues.unsubscribe=取消訂閱
|
||||||
issues.unpin_issue=取消固定問題
|
issues.unpin=取消固定
|
||||||
issues.max_pinned=您不能固定更多問題
|
issues.max_pinned=您不能固定更多問題
|
||||||
issues.pin_comment=固定於 %s
|
issues.pin_comment=固定於 %s
|
||||||
issues.unpin_comment=取消固定於 %s
|
issues.unpin_comment=取消固定於 %s
|
||||||
|
@ -17,11 +17,11 @@ func DownloadArchive(ctx *context.APIContext) {
|
|||||||
var tp git.ArchiveType
|
var tp git.ArchiveType
|
||||||
switch ballType := ctx.PathParam("ball_type"); ballType {
|
switch ballType := ctx.PathParam("ball_type"); ballType {
|
||||||
case "tarball":
|
case "tarball":
|
||||||
tp = git.TARGZ
|
tp = git.ArchiveTarGz
|
||||||
case "zipball":
|
case "zipball":
|
||||||
tp = git.ZIP
|
tp = git.ArchiveZip
|
||||||
case "bundle":
|
case "bundle":
|
||||||
tp = git.BUNDLE
|
tp = git.ArchiveBundle
|
||||||
default:
|
default:
|
||||||
ctx.Error(http.StatusBadRequest, "", fmt.Sprintf("Unknown archive type: %s", ballType))
|
ctx.Error(http.StatusBadRequest, "", fmt.Sprintf("Unknown archive type: %s", ballType))
|
||||||
return
|
return
|
||||||
@ -36,7 +36,7 @@ func DownloadArchive(ctx *context.APIContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"), tp)
|
r, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*")+"."+tp.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("NewRequest", err)
|
ctx.ServerError("NewRequest", err)
|
||||||
return
|
return
|
||||||
|
@ -293,14 +293,7 @@ func GetArchive(ctx *context.APIContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func archiveDownload(ctx *context.APIContext) {
|
func archiveDownload(ctx *context.APIContext) {
|
||||||
uri := ctx.PathParam("*")
|
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"))
|
||||||
ext, tp, err := archiver_service.ParseFileName(uri)
|
|
||||||
if err != nil {
|
|
||||||
ctx.Error(http.StatusBadRequest, "ParseFileName", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, strings.TrimSuffix(uri, ext), tp)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
|
if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
|
||||||
ctx.Error(http.StatusBadRequest, "unknown archive format", err)
|
ctx.Error(http.StatusBadRequest, "unknown archive format", err)
|
||||||
|
@ -23,7 +23,7 @@ func ShowBranchFeed(ctx *context.Context, repo *repo.Repository, formatType stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
title := fmt.Sprintf("Latest commits for branch %s", ctx.Repo.BranchName)
|
title := fmt.Sprintf("Latest commits for branch %s", ctx.Repo.BranchName)
|
||||||
link := &feeds.Link{Href: repo.HTMLURL() + "/" + ctx.Repo.BranchNameSubURL()}
|
link := &feeds.Link{Href: repo.HTMLURL() + "/" + ctx.Repo.RefTypeNameSubURL()}
|
||||||
|
|
||||||
feed := &feeds.Feed{
|
feed := &feeds.Feed{
|
||||||
Title: title,
|
Title: title,
|
||||||
|
@ -24,7 +24,7 @@ func ShowFileFeed(ctx *context.Context, repo *repo.Repository, formatType string
|
|||||||
}
|
}
|
||||||
commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(
|
commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(
|
||||||
git.CommitsByFileAndRangeOptions{
|
git.CommitsByFileAndRangeOptions{
|
||||||
Revision: ctx.Repo.RefName,
|
Revision: ctx.Repo.RefFullName.ShortName(), // FIXME: legacy code used ShortName
|
||||||
File: fileName,
|
File: fileName,
|
||||||
Page: 1,
|
Page: 1,
|
||||||
})
|
})
|
||||||
@ -35,7 +35,7 @@ func ShowFileFeed(ctx *context.Context, repo *repo.Repository, formatType string
|
|||||||
|
|
||||||
title := fmt.Sprintf("Latest commits for file %s", ctx.Repo.TreePath)
|
title := fmt.Sprintf("Latest commits for file %s", ctx.Repo.TreePath)
|
||||||
|
|
||||||
link := &feeds.Link{Href: repo.HTMLURL() + "/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)}
|
link := &feeds.Link{Href: repo.HTMLURL() + "/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)}
|
||||||
|
|
||||||
feed := &feeds.Feed{
|
feed := &feeds.Feed{
|
||||||
Title: title,
|
Title: title,
|
||||||
|
@ -59,9 +59,9 @@ func RefBlame(ctx *context.Context) {
|
|||||||
ShowFileViewTreeSidebar: showFileViewTreeSidebar,
|
ShowFileViewTreeSidebar: showFileViewTreeSidebar,
|
||||||
}
|
}
|
||||||
|
|
||||||
branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
||||||
treeLink := branchLink
|
treeLink := branchLink
|
||||||
rawLink := ctx.Repo.RepoLink + "/raw/" + ctx.Repo.BranchNameSubURL()
|
rawLink := ctx.Repo.RepoLink + "/raw/" + ctx.Repo.RefTypeNameSubURL()
|
||||||
|
|
||||||
if len(ctx.Repo.TreePath) > 0 {
|
if len(ctx.Repo.TreePath) > 0 {
|
||||||
treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||||
|
@ -185,7 +185,7 @@ func CreateBranch(ctx *context.Context) {
|
|||||||
|
|
||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
ctx.Flash.Error(ctx.GetErrMsg())
|
ctx.Flash.Error(ctx.GetErrMsg())
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
|
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,25 +205,25 @@ func CreateBranch(ctx *context.Context) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if release_service.IsErrProtectedTagName(err) {
|
if release_service.IsErrProtectedTagName(err) {
|
||||||
ctx.Flash.Error(ctx.Tr("repo.release.tag_name_protected"))
|
ctx.Flash.Error(ctx.Tr("repo.release.tag_name_protected"))
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
|
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if release_service.IsErrTagAlreadyExists(err) {
|
if release_service.IsErrTagAlreadyExists(err) {
|
||||||
e := err.(release_service.ErrTagAlreadyExists)
|
e := err.(release_service.ErrTagAlreadyExists)
|
||||||
ctx.Flash.Error(ctx.Tr("repo.branch.tag_collision", e.TagName))
|
ctx.Flash.Error(ctx.Tr("repo.branch.tag_collision", e.TagName))
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
|
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if git_model.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) {
|
if git_model.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) {
|
||||||
ctx.Flash.Error(ctx.Tr("repo.branch.branch_already_exists", form.NewBranchName))
|
ctx.Flash.Error(ctx.Tr("repo.branch.branch_already_exists", form.NewBranchName))
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
|
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if git_model.IsErrBranchNameConflict(err) {
|
if git_model.IsErrBranchNameConflict(err) {
|
||||||
e := err.(git_model.ErrBranchNameConflict)
|
e := err.(git_model.ErrBranchNameConflict)
|
||||||
ctx.Flash.Error(ctx.Tr("repo.branch.branch_name_conflict", form.NewBranchName, e.BranchName))
|
ctx.Flash.Error(ctx.Tr("repo.branch.branch_name_conflict", form.NewBranchName, e.BranchName))
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
|
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if git.IsErrPushRejected(err) {
|
if git.IsErrPushRejected(err) {
|
||||||
@ -242,7 +242,7 @@ func CreateBranch(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
ctx.Flash.Error(flashError)
|
ctx.Flash.Error(flashError)
|
||||||
}
|
}
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
|
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ func CherryPick(ctx *context.Context) {
|
|||||||
ctx.Data["new_branch_name"] = GetUniquePatchBranchName(ctx)
|
ctx.Data["new_branch_name"] = GetUniquePatchBranchName(ctx)
|
||||||
ctx.Data["last_commit"] = ctx.Repo.CommitID
|
ctx.Data["last_commit"] = ctx.Repo.CommitID
|
||||||
ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
|
ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
|
||||||
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
||||||
|
|
||||||
ctx.HTML(200, tplCherryPick)
|
ctx.HTML(200, tplCherryPick)
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ func CherryPickPost(ctx *context.Context) {
|
|||||||
ctx.Data["new_branch_name"] = form.NewBranchName
|
ctx.Data["new_branch_name"] = form.NewBranchName
|
||||||
ctx.Data["last_commit"] = ctx.Repo.CommitID
|
ctx.Data["last_commit"] = ctx.Repo.CommitID
|
||||||
ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
|
ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
|
||||||
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
||||||
|
|
||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
ctx.HTML(200, tplCherryPick)
|
ctx.HTML(200, tplCherryPick)
|
||||||
|
@ -191,7 +191,7 @@ func SearchCommits(ctx *context.Context) {
|
|||||||
|
|
||||||
query := ctx.FormTrim("q")
|
query := ctx.FormTrim("q")
|
||||||
if len(query) == 0 {
|
if len(query) == 0 {
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/commits/" + ctx.Repo.BranchNameSubURL())
|
ctx.Redirect(ctx.Repo.RepoLink + "/commits/" + ctx.Repo.RefTypeNameSubURL())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +222,7 @@ func FileHistory(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
commitsCount, err := ctx.Repo.GitRepo.FileCommitsCount(ctx.Repo.RefName, fileName)
|
commitsCount, err := ctx.Repo.GitRepo.FileCommitsCount(ctx.Repo.RefFullName.ShortName(), fileName) // FIXME: legacy code used ShortName
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("FileCommitsCount", err)
|
ctx.ServerError("FileCommitsCount", err)
|
||||||
return
|
return
|
||||||
@ -238,7 +238,7 @@ func FileHistory(ctx *context.Context) {
|
|||||||
|
|
||||||
commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(
|
commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(
|
||||||
git.CommitsByFileAndRangeOptions{
|
git.CommitsByFileAndRangeOptions{
|
||||||
Revision: ctx.Repo.RefName,
|
Revision: ctx.Repo.RefFullName.ShortName(), // FIXME: legacy code used ShortName
|
||||||
File: fileName,
|
File: fileName,
|
||||||
Page: page,
|
Page: page,
|
||||||
})
|
})
|
||||||
|
@ -180,7 +180,7 @@ func editFile(ctx *context.Context, isNewFile bool) {
|
|||||||
|
|
||||||
ctx.Data["TreeNames"] = treeNames
|
ctx.Data["TreeNames"] = treeNames
|
||||||
ctx.Data["TreePaths"] = treePaths
|
ctx.Data["TreePaths"] = treePaths
|
||||||
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
||||||
ctx.Data["commit_summary"] = ""
|
ctx.Data["commit_summary"] = ""
|
||||||
ctx.Data["commit_message"] = ""
|
ctx.Data["commit_message"] = ""
|
||||||
if canCommit {
|
if canCommit {
|
||||||
@ -428,7 +428,7 @@ func DiffPreviewPost(ctx *context.Context) {
|
|||||||
// DeleteFile render delete file page
|
// DeleteFile render delete file page
|
||||||
func DeleteFile(ctx *context.Context) {
|
func DeleteFile(ctx *context.Context) {
|
||||||
ctx.Data["PageIsDelete"] = true
|
ctx.Data["PageIsDelete"] = true
|
||||||
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
||||||
treePath := cleanUploadFileName(ctx.Repo.TreePath)
|
treePath := cleanUploadFileName(ctx.Repo.TreePath)
|
||||||
|
|
||||||
if treePath != ctx.Repo.TreePath {
|
if treePath != ctx.Repo.TreePath {
|
||||||
@ -462,7 +462,7 @@ func DeleteFilePost(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["PageIsDelete"] = true
|
ctx.Data["PageIsDelete"] = true
|
||||||
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
||||||
ctx.Data["TreePath"] = ctx.Repo.TreePath
|
ctx.Data["TreePath"] = ctx.Repo.TreePath
|
||||||
ctx.Data["commit_summary"] = form.CommitSummary
|
ctx.Data["commit_summary"] = form.CommitSummary
|
||||||
ctx.Data["commit_message"] = form.CommitMessage
|
ctx.Data["commit_message"] = form.CommitMessage
|
||||||
@ -604,7 +604,7 @@ func UploadFile(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.Data["TreeNames"] = treeNames
|
ctx.Data["TreeNames"] = treeNames
|
||||||
ctx.Data["TreePaths"] = treePaths
|
ctx.Data["TreePaths"] = treePaths
|
||||||
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
||||||
ctx.Data["commit_summary"] = ""
|
ctx.Data["commit_summary"] = ""
|
||||||
ctx.Data["commit_message"] = ""
|
ctx.Data["commit_message"] = ""
|
||||||
if canCommit {
|
if canCommit {
|
||||||
|
@ -4,25 +4,14 @@
|
|||||||
package repo
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/url"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/services/context"
|
"code.gitea.io/gitea/services/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
func HandleGitError(ctx *context.Context, msg string, err error) {
|
func HandleGitError(ctx *context.Context, msg string, err error) {
|
||||||
if git.IsErrNotExist(err) {
|
if git.IsErrNotExist(err) {
|
||||||
refType := ""
|
ctx.Data["NotFoundPrompt"] = ctx.Locale.Tr("repo.tree_path_not_found", ctx.Repo.TreePath, ctx.Repo.RefTypeNameSubURL())
|
||||||
switch {
|
ctx.Data["NotFoundGoBackURL"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
||||||
case ctx.Repo.IsViewBranch:
|
|
||||||
refType = "branch"
|
|
||||||
case ctx.Repo.IsViewTag:
|
|
||||||
refType = "tag"
|
|
||||||
case ctx.Repo.IsViewCommit:
|
|
||||||
refType = "commit"
|
|
||||||
}
|
|
||||||
ctx.Data["NotFoundPrompt"] = ctx.Locale.Tr("repo.tree_path_not_found_"+refType, ctx.Repo.TreePath, url.PathEscape(ctx.Repo.RefName))
|
|
||||||
ctx.Data["NotFoundGoBackURL"] = ctx.Repo.RepoLink + "/src/" + refType + "/" + url.PathEscape(ctx.Repo.RefName)
|
|
||||||
ctx.NotFound(msg, err)
|
ctx.NotFound(msg, err)
|
||||||
} else {
|
} else {
|
||||||
ctx.ServerError(msg, err)
|
ctx.ServerError(msg, err)
|
||||||
|
@ -4,12 +4,9 @@
|
|||||||
package repo
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
system_model "code.gitea.io/gitea/models/system"
|
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/git"
|
|
||||||
"code.gitea.io/gitea/modules/optional"
|
"code.gitea.io/gitea/modules/optional"
|
||||||
"code.gitea.io/gitea/services/context"
|
"code.gitea.io/gitea/services/context"
|
||||||
user_service "code.gitea.io/gitea/services/user"
|
user_service "code.gitea.io/gitea/services/user"
|
||||||
@ -22,12 +19,9 @@ func SetEditorconfigIfExists(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ec, _, err := ctx.Repo.GetEditorconfig()
|
ec, _, err := ctx.Repo.GetEditorconfig()
|
||||||
|
if err != nil {
|
||||||
if err != nil && !git.IsErrNotExist(err) {
|
// it used to check `!git.IsErrNotExist(err)` and create a system notice, but it is quite annoying and useless
|
||||||
description := fmt.Sprintf("Error while getting .editorconfig file: %v", err)
|
// because network errors also happen frequently, so we just ignore it
|
||||||
if err := system_model.CreateRepositoryNotice(description); err != nil {
|
|
||||||
ctx.ServerError("ErrCreatingReporitoryNotice", err)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,9 +62,7 @@ func Packages(ctx *context.Context) {
|
|||||||
ctx.Data["PackageType"] = packageType
|
ctx.Data["PackageType"] = packageType
|
||||||
ctx.Data["AvailableTypes"] = packages.TypeList
|
ctx.Data["AvailableTypes"] = packages.TypeList
|
||||||
ctx.Data["HasPackages"] = hasPackages
|
ctx.Data["HasPackages"] = hasPackages
|
||||||
if ctx.Repo != nil {
|
ctx.Data["CanWritePackages"] = ctx.Repo.CanWrite(unit.TypePackages) || ctx.IsUserSiteAdmin()
|
||||||
ctx.Data["CanWritePackages"] = ctx.IsUserRepoWriter([]unit.Type{unit.TypePackages}) || ctx.IsUserSiteAdmin()
|
|
||||||
}
|
|
||||||
ctx.Data["PackageDescriptors"] = pds
|
ctx.Data["PackageDescriptors"] = pds
|
||||||
ctx.Data["Total"] = total
|
ctx.Data["Total"] = total
|
||||||
ctx.Data["RepositoryAccessMap"] = map[int64]bool{ctx.Repo.Repository.ID: true} // There is only the current repository
|
ctx.Data["RepositoryAccessMap"] = map[int64]bool{ctx.Repo.Repository.ID: true} // There is only the current repository
|
||||||
|
@ -37,7 +37,7 @@ func NewDiffPatch(ctx *context.Context) {
|
|||||||
ctx.Data["new_branch_name"] = GetUniquePatchBranchName(ctx)
|
ctx.Data["new_branch_name"] = GetUniquePatchBranchName(ctx)
|
||||||
ctx.Data["last_commit"] = ctx.Repo.CommitID
|
ctx.Data["last_commit"] = ctx.Repo.CommitID
|
||||||
ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
|
ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
|
||||||
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
||||||
|
|
||||||
ctx.HTML(200, tplPatchFile)
|
ctx.HTML(200, tplPatchFile)
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ func NewDiffPatchPost(ctx *context.Context) {
|
|||||||
branchName = form.NewBranchName
|
branchName = form.NewBranchName
|
||||||
}
|
}
|
||||||
ctx.Data["PageIsPatch"] = true
|
ctx.Data["PageIsPatch"] = true
|
||||||
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
||||||
ctx.Data["FileContent"] = form.Content
|
ctx.Data["FileContent"] = form.Content
|
||||||
ctx.Data["commit_summary"] = form.CommitSummary
|
ctx.Data["commit_summary"] = form.CommitSummary
|
||||||
ctx.Data["commit_message"] = form.CommitMessage
|
ctx.Data["commit_message"] = form.CommitMessage
|
||||||
|
@ -435,19 +435,19 @@ func NewReleasePost(ctx *context.Context) {
|
|||||||
if release_service.IsErrTagAlreadyExists(err) {
|
if release_service.IsErrTagAlreadyExists(err) {
|
||||||
e := err.(release_service.ErrTagAlreadyExists)
|
e := err.(release_service.ErrTagAlreadyExists)
|
||||||
ctx.Flash.Error(ctx.Tr("repo.branch.tag_collision", e.TagName))
|
ctx.Flash.Error(ctx.Tr("repo.branch.tag_collision", e.TagName))
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
|
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if release_service.IsErrInvalidTagName(err) {
|
if release_service.IsErrInvalidTagName(err) {
|
||||||
ctx.Flash.Error(ctx.Tr("repo.release.tag_name_invalid"))
|
ctx.Flash.Error(ctx.Tr("repo.release.tag_name_invalid"))
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
|
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if release_service.IsErrProtectedTagName(err) {
|
if release_service.IsErrProtectedTagName(err) {
|
||||||
ctx.Flash.Error(ctx.Tr("repo.release.tag_name_protected"))
|
ctx.Flash.Error(ctx.Tr("repo.release.tag_name_protected"))
|
||||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
|
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ func RenderFile(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rctx := renderhelper.NewRenderContextRepoFile(ctx, ctx.Repo.Repository, renderhelper.RepoFileOptions{
|
rctx := renderhelper.NewRenderContextRepoFile(ctx, ctx.Repo.Repository, renderhelper.RepoFileOptions{
|
||||||
CurrentRefPath: ctx.Repo.BranchNameSubURL(),
|
CurrentRefPath: ctx.Repo.RefTypeNameSubURL(),
|
||||||
CurrentTreePath: path.Dir(ctx.Repo.TreePath),
|
CurrentTreePath: path.Dir(ctx.Repo.TreePath),
|
||||||
}).WithRelativePath(ctx.Repo.TreePath).WithInStandalonePage(true)
|
}).WithRelativePath(ctx.Repo.TreePath).WithInStandalonePage(true)
|
||||||
|
|
||||||
|
@ -465,13 +465,7 @@ func RedirectDownload(ctx *context.Context) {
|
|||||||
|
|
||||||
// Download an archive of a repository
|
// Download an archive of a repository
|
||||||
func Download(ctx *context.Context) {
|
func Download(ctx *context.Context) {
|
||||||
uri := ctx.PathParam("*")
|
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"))
|
||||||
ext, tp, err := archiver_service.ParseFileName(uri)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("ParseFileName", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, strings.TrimSuffix(uri, ext), tp)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
|
if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
|
||||||
ctx.Error(http.StatusBadRequest, err.Error())
|
ctx.Error(http.StatusBadRequest, err.Error())
|
||||||
@ -529,15 +523,9 @@ func download(ctx *context.Context, archiveName string, archiver *repo_model.Rep
|
|||||||
// a request that's already in-progress, but the archiver service will just
|
// a request that's already in-progress, but the archiver service will just
|
||||||
// kind of drop it on the floor if this is the case.
|
// kind of drop it on the floor if this is the case.
|
||||||
func InitiateDownload(ctx *context.Context) {
|
func InitiateDownload(ctx *context.Context) {
|
||||||
uri := ctx.PathParam("*")
|
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"))
|
||||||
ext, tp, err := archiver_service.ParseFileName(uri)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("ParseFileName", err)
|
ctx.Error(http.StatusBadRequest, "invalid archive request")
|
||||||
return
|
|
||||||
}
|
|
||||||
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, strings.TrimSuffix(uri, ext), tp)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("archiver_service.NewRequest", err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if aReq == nil {
|
if aReq == nil {
|
||||||
|
@ -244,7 +244,7 @@ func LastCommit(ctx *context.Context) {
|
|||||||
ctx.Data["ParentPath"] = "/" + paths[len(paths)-2]
|
ctx.Data["ParentPath"] = "/" + paths[len(paths)-2]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
||||||
ctx.Data["BranchLink"] = branchLink
|
ctx.Data["BranchLink"] = branchLink
|
||||||
|
|
||||||
ctx.HTML(http.StatusOK, tplRepoViewList)
|
ctx.HTML(http.StatusOK, tplRepoViewList)
|
||||||
@ -302,7 +302,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
||||||
treeLink := branchLink
|
treeLink := branchLink
|
||||||
|
|
||||||
if len(ctx.Repo.TreePath) > 0 {
|
if len(ctx.Repo.TreePath) > 0 {
|
||||||
|
@ -42,10 +42,10 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
|
|||||||
}
|
}
|
||||||
defer dataRc.Close()
|
defer dataRc.Close()
|
||||||
|
|
||||||
ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefName)
|
ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefFullName.ShortName())
|
||||||
ctx.Data["FileIsSymlink"] = entry.IsLink()
|
ctx.Data["FileIsSymlink"] = entry.IsLink()
|
||||||
ctx.Data["FileName"] = blob.Name()
|
ctx.Data["FileName"] = blob.Name()
|
||||||
ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/raw/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/raw/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||||
|
|
||||||
commit, err := ctx.Repo.Commit.GetCommitByPath(ctx.Repo.TreePath)
|
commit, err := ctx.Repo.Commit.GetCommitByPath(ctx.Repo.TreePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -92,7 +92,7 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
|
|||||||
isDisplayingRendered := !isDisplayingSource
|
isDisplayingRendered := !isDisplayingSource
|
||||||
|
|
||||||
if fInfo.isLFSFile {
|
if fInfo.isLFSFile {
|
||||||
ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/media/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/media/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
isRepresentableAsText := fInfo.st.IsRepresentableAsText()
|
isRepresentableAsText := fInfo.st.IsRepresentableAsText()
|
||||||
@ -170,9 +170,9 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
|
|||||||
ctx.Data["IsMarkup"] = true
|
ctx.Data["IsMarkup"] = true
|
||||||
ctx.Data["MarkupType"] = markupType
|
ctx.Data["MarkupType"] = markupType
|
||||||
metas := ctx.Repo.Repository.ComposeDocumentMetas(ctx)
|
metas := ctx.Repo.Repository.ComposeDocumentMetas(ctx)
|
||||||
metas["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL()
|
metas["RefTypeNameSubURL"] = ctx.Repo.RefTypeNameSubURL()
|
||||||
rctx := renderhelper.NewRenderContextRepoFile(ctx, ctx.Repo.Repository, renderhelper.RepoFileOptions{
|
rctx := renderhelper.NewRenderContextRepoFile(ctx, ctx.Repo.Repository, renderhelper.RepoFileOptions{
|
||||||
CurrentRefPath: ctx.Repo.BranchNameSubURL(),
|
CurrentRefPath: ctx.Repo.RefTypeNameSubURL(),
|
||||||
CurrentTreePath: path.Dir(ctx.Repo.TreePath),
|
CurrentTreePath: path.Dir(ctx.Repo.TreePath),
|
||||||
}).
|
}).
|
||||||
WithMarkupType(markupType).
|
WithMarkupType(markupType).
|
||||||
@ -262,7 +262,7 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
|
|||||||
ctx.Data["MarkupType"] = markupType
|
ctx.Data["MarkupType"] = markupType
|
||||||
|
|
||||||
rctx := renderhelper.NewRenderContextRepoFile(ctx, ctx.Repo.Repository, renderhelper.RepoFileOptions{
|
rctx := renderhelper.NewRenderContextRepoFile(ctx, ctx.Repo.Repository, renderhelper.RepoFileOptions{
|
||||||
CurrentRefPath: ctx.Repo.BranchNameSubURL(),
|
CurrentRefPath: ctx.Repo.RefTypeNameSubURL(),
|
||||||
CurrentTreePath: path.Dir(ctx.Repo.TreePath),
|
CurrentTreePath: path.Dir(ctx.Repo.TreePath),
|
||||||
}).
|
}).
|
||||||
WithMarkupType(markupType).
|
WithMarkupType(markupType).
|
||||||
|
@ -137,7 +137,7 @@ func prepareToRenderDirectory(ctx *context.Context) {
|
|||||||
|
|
||||||
if ctx.Repo.TreePath != "" {
|
if ctx.Repo.TreePath != "" {
|
||||||
ctx.Data["HideRepoInfo"] = true
|
ctx.Data["HideRepoInfo"] = true
|
||||||
ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefName)
|
ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefFullName.ShortName())
|
||||||
}
|
}
|
||||||
|
|
||||||
subfolder, readmeFile, err := findReadmeFileInEntries(ctx, entries, true)
|
subfolder, readmeFile, err := findReadmeFileInEntries(ctx, entries, true)
|
||||||
@ -361,7 +361,7 @@ func Home(ctx *context.Context) {
|
|||||||
|
|
||||||
// prepare the tree path
|
// prepare the tree path
|
||||||
var treeNames, paths []string
|
var treeNames, paths []string
|
||||||
branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
|
||||||
treeLink := branchLink
|
treeLink := branchLink
|
||||||
if ctx.Repo.TreePath != "" {
|
if ctx.Repo.TreePath != "" {
|
||||||
treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||||
|
@ -189,7 +189,7 @@ func prepareToRenderReadmeFile(ctx *context.Context, subfolder string, readmeFil
|
|||||||
ctx.Data["MarkupType"] = markupType
|
ctx.Data["MarkupType"] = markupType
|
||||||
|
|
||||||
rctx := renderhelper.NewRenderContextRepoFile(ctx, ctx.Repo.Repository, renderhelper.RepoFileOptions{
|
rctx := renderhelper.NewRenderContextRepoFile(ctx, ctx.Repo.Repository, renderhelper.RepoFileOptions{
|
||||||
CurrentRefPath: ctx.Repo.BranchNameSubURL(),
|
CurrentRefPath: ctx.Repo.RefTypeNameSubURL(),
|
||||||
CurrentTreePath: path.Join(ctx.Repo.TreePath, subfolder),
|
CurrentTreePath: path.Join(ctx.Repo.TreePath, subfolder),
|
||||||
}).
|
}).
|
||||||
WithMarkupType(markupType).
|
WithMarkupType(markupType).
|
||||||
|
@ -3,27 +3,7 @@
|
|||||||
|
|
||||||
package context
|
package context
|
||||||
|
|
||||||
import (
|
|
||||||
"code.gitea.io/gitea/models/unit"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsUserSiteAdmin returns true if current user is a site admin
|
// IsUserSiteAdmin returns true if current user is a site admin
|
||||||
func (ctx *Context) IsUserSiteAdmin() bool {
|
func (ctx *Context) IsUserSiteAdmin() bool {
|
||||||
return ctx.IsSigned && ctx.Doer.IsAdmin
|
return ctx.IsSigned && ctx.Doer.IsAdmin
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsUserRepoAdmin returns true if current user is admin in current repo
|
|
||||||
func (ctx *Context) IsUserRepoAdmin() bool {
|
|
||||||
return ctx.Repo.IsAdmin()
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsUserRepoWriter returns true if current user has write privilege in current repo
|
|
||||||
func (ctx *Context) IsUserRepoWriter(unitTypes []unit.Type) bool {
|
|
||||||
for _, unitType := range unitTypes {
|
|
||||||
if ctx.Repo.CanWrite(unitType) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
unit_model "code.gitea.io/gitea/models/unit"
|
unit_model "code.gitea.io/gitea/models/unit"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/base"
|
|
||||||
"code.gitea.io/gitea/modules/cache"
|
"code.gitea.io/gitea/modules/cache"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/gitrepo"
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
@ -47,22 +46,27 @@ type PullRequest struct {
|
|||||||
// Repository contains information to operate a repository
|
// Repository contains information to operate a repository
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
access_model.Permission
|
access_model.Permission
|
||||||
IsWatching bool
|
|
||||||
|
Repository *repo_model.Repository
|
||||||
|
Owner *user_model.User
|
||||||
|
|
||||||
|
RepoLink string
|
||||||
|
GitRepo *git.Repository
|
||||||
|
|
||||||
|
// these fields indicate the current ref type, for example: ".../src/branch/master" means IsViewBranch=true
|
||||||
IsViewBranch bool
|
IsViewBranch bool
|
||||||
IsViewTag bool
|
IsViewTag bool
|
||||||
IsViewCommit bool
|
IsViewCommit bool
|
||||||
Repository *repo_model.Repository
|
|
||||||
Owner *user_model.User
|
RefFullName git.RefName
|
||||||
Commit *git.Commit
|
BranchName string
|
||||||
Tag *git.Tag
|
TagName string
|
||||||
GitRepo *git.Repository
|
TreePath string
|
||||||
RefName string
|
|
||||||
BranchName string
|
// Commit it is always set to the commit for the branch or tag
|
||||||
TagName string
|
Commit *git.Commit
|
||||||
TreePath string
|
CommitID string
|
||||||
CommitID string
|
|
||||||
RepoLink string
|
|
||||||
CloneLink repo_model.CloneLink
|
|
||||||
CommitsCount int64
|
CommitsCount int64
|
||||||
|
|
||||||
PullRequest *PullRequest
|
PullRequest *PullRequest
|
||||||
@ -150,7 +154,7 @@ func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.Use
|
|||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanUseTimetracker returns whether or not a user can use the timetracker.
|
// CanUseTimetracker returns whether a user can use the timetracker.
|
||||||
func (r *Repository) CanUseTimetracker(ctx context.Context, issue *issues_model.Issue, user *user_model.User) bool {
|
func (r *Repository) CanUseTimetracker(ctx context.Context, issue *issues_model.Issue, user *user_model.User) bool {
|
||||||
// Checking for following:
|
// Checking for following:
|
||||||
// 1. Is timetracker enabled
|
// 1. Is timetracker enabled
|
||||||
@ -200,8 +204,12 @@ func (r *Repository) GetCommitGraphsCount(ctx context.Context, hidePRRefs bool,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// BranchNameSubURL sub-URL for the BranchName field
|
// RefTypeNameSubURL makes a sub-url for the current ref (branch/tag/commit) field, for example:
|
||||||
func (r *Repository) BranchNameSubURL() string {
|
// * "branch/master"
|
||||||
|
// * "tag/v1.0.0"
|
||||||
|
// * "commit/123456"
|
||||||
|
// It is usually used to construct a link like ".../src/{{RefTypeNameSubURL}}/{{PathEscapeSegments TreePath}}"
|
||||||
|
func (r *Repository) RefTypeNameSubURL() string {
|
||||||
switch {
|
switch {
|
||||||
case r.IsViewBranch:
|
case r.IsViewBranch:
|
||||||
return "branch/" + util.PathEscapeSegments(r.BranchName)
|
return "branch/" + util.PathEscapeSegments(r.BranchName)
|
||||||
@ -214,21 +222,6 @@ func (r *Repository) BranchNameSubURL() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileExists returns true if a file exists in the given repo branch
|
|
||||||
func (r *Repository) FileExists(path, branch string) (bool, error) {
|
|
||||||
if branch == "" {
|
|
||||||
branch = r.Repository.DefaultBranch
|
|
||||||
}
|
|
||||||
commit, err := r.GitRepo.GetBranchCommit(branch)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if _, err := commit.GetTreeEntryByPath(path); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetEditorconfig returns the .editorconfig definition if found in the
|
// GetEditorconfig returns the .editorconfig definition if found in the
|
||||||
// HEAD of the default repo branch.
|
// HEAD of the default repo branch.
|
||||||
func (r *Repository) GetEditorconfig(optCommit ...*git.Commit) (cfg *editorconfig.Editorconfig, warning, err error) {
|
func (r *Repository) GetEditorconfig(optCommit ...*git.Commit) (cfg *editorconfig.Editorconfig, warning, err error) {
|
||||||
@ -399,33 +392,25 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) {
|
|||||||
|
|
||||||
// RepoAssignment returns a middleware to handle repository assignment
|
// RepoAssignment returns a middleware to handle repository assignment
|
||||||
func RepoAssignment(ctx *Context) {
|
func RepoAssignment(ctx *Context) {
|
||||||
if _, repoAssignmentOnce := ctx.Data["repoAssignmentExecuted"]; repoAssignmentOnce {
|
if ctx.Data["Repository"] != nil {
|
||||||
// FIXME: it should panic in dev/test modes to have a clear behavior
|
setting.PanicInDevOrTesting("RepoAssignment should not be executed twice")
|
||||||
if !setting.IsProd || setting.IsInTesting {
|
|
||||||
panic("RepoAssignment should not be executed twice")
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
ctx.Data["repoAssignmentExecuted"] = true
|
|
||||||
|
|
||||||
var (
|
|
||||||
owner *user_model.User
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
|
var err error
|
||||||
userName := ctx.PathParam("username")
|
userName := ctx.PathParam("username")
|
||||||
repoName := ctx.PathParam("reponame")
|
repoName := ctx.PathParam("reponame")
|
||||||
repoName = strings.TrimSuffix(repoName, ".git")
|
repoName = strings.TrimSuffix(repoName, ".git")
|
||||||
if setting.Other.EnableFeed {
|
if setting.Other.EnableFeed {
|
||||||
|
ctx.Data["EnableFeed"] = true
|
||||||
repoName = strings.TrimSuffix(repoName, ".rss")
|
repoName = strings.TrimSuffix(repoName, ".rss")
|
||||||
repoName = strings.TrimSuffix(repoName, ".atom")
|
repoName = strings.TrimSuffix(repoName, ".atom")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the user is the same as the repository owner
|
// Check if the user is the same as the repository owner
|
||||||
if ctx.IsSigned && ctx.Doer.LowerName == strings.ToLower(userName) {
|
if ctx.IsSigned && ctx.Doer.LowerName == strings.ToLower(userName) {
|
||||||
owner = ctx.Doer
|
ctx.Repo.Owner = ctx.Doer
|
||||||
} else {
|
} else {
|
||||||
owner, err = user_model.GetUserByName(ctx, userName)
|
ctx.Repo.Owner, err = user_model.GetUserByName(ctx, userName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if user_model.IsErrUserNotExist(err) {
|
if user_model.IsErrUserNotExist(err) {
|
||||||
// go-get does not support redirects
|
// go-get does not support redirects
|
||||||
@ -448,10 +433,8 @@ func RepoAssignment(ctx *Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.Repo.Owner = owner
|
ctx.ContextUser = ctx.Repo.Owner
|
||||||
ctx.ContextUser = owner
|
|
||||||
ctx.Data["ContextUser"] = ctx.ContextUser
|
ctx.Data["ContextUser"] = ctx.ContextUser
|
||||||
ctx.Data["Username"] = ctx.Repo.Owner.Name
|
|
||||||
|
|
||||||
// redirect link to wiki
|
// redirect link to wiki
|
||||||
if strings.HasSuffix(repoName, ".wiki") {
|
if strings.HasSuffix(repoName, ".wiki") {
|
||||||
@ -474,10 +457,10 @@ func RepoAssignment(ctx *Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get repository.
|
// Get repository.
|
||||||
repo, err := repo_model.GetRepositoryByName(ctx, owner.ID, repoName)
|
repo, err := repo_model.GetRepositoryByName(ctx, ctx.Repo.Owner.ID, repoName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if repo_model.IsErrRepoNotExist(err) {
|
if repo_model.IsErrRepoNotExist(err) {
|
||||||
redirectRepoID, err := repo_model.LookupRedirect(ctx, owner.ID, repoName)
|
redirectRepoID, err := repo_model.LookupRedirect(ctx, ctx.Repo.Owner.ID, repoName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
RedirectToRepo(ctx.Base, redirectRepoID)
|
RedirectToRepo(ctx.Base, redirectRepoID)
|
||||||
} else if repo_model.IsErrRedirectNotExist(err) {
|
} else if repo_model.IsErrRedirectNotExist(err) {
|
||||||
@ -494,7 +477,7 @@ func RepoAssignment(ctx *Context) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
repo.Owner = owner
|
repo.Owner = ctx.Repo.Owner
|
||||||
|
|
||||||
repoAssignment(ctx, repo)
|
repoAssignment(ctx, repo)
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
@ -503,12 +486,7 @@ func RepoAssignment(ctx *Context) {
|
|||||||
|
|
||||||
ctx.Repo.RepoLink = repo.Link()
|
ctx.Repo.RepoLink = repo.Link()
|
||||||
ctx.Data["RepoLink"] = ctx.Repo.RepoLink
|
ctx.Data["RepoLink"] = ctx.Repo.RepoLink
|
||||||
ctx.Data["RepoRelPath"] = ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name
|
ctx.Data["FeedURL"] = ctx.Repo.RepoLink
|
||||||
|
|
||||||
if setting.Other.EnableFeed {
|
|
||||||
ctx.Data["EnableFeed"] = true
|
|
||||||
ctx.Data["FeedURL"] = ctx.Repo.RepoLink
|
|
||||||
}
|
|
||||||
|
|
||||||
unit, err := ctx.Repo.Repository.GetUnit(ctx, unit_model.TypeExternalTracker)
|
unit, err := ctx.Repo.Repository.GetUnit(ctx, unit_model.TypeExternalTracker)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -535,12 +513,9 @@ func RepoAssignment(ctx *Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["Title"] = owner.Name + "/" + repo.Name
|
ctx.Data["Title"] = repo.Owner.Name + "/" + repo.Name
|
||||||
ctx.Data["Repository"] = repo
|
ctx.Data["Repository"] = repo
|
||||||
ctx.Data["Owner"] = ctx.Repo.Repository.Owner
|
ctx.Data["Owner"] = ctx.Repo.Repository.Owner
|
||||||
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner()
|
|
||||||
ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin()
|
|
||||||
ctx.Data["RepoOwnerIsOrganization"] = repo.Owner.IsOrganization()
|
|
||||||
ctx.Data["CanWriteCode"] = ctx.Repo.CanWrite(unit_model.TypeCode)
|
ctx.Data["CanWriteCode"] = ctx.Repo.CanWrite(unit_model.TypeCode)
|
||||||
ctx.Data["CanWriteIssues"] = ctx.Repo.CanWrite(unit_model.TypeIssues)
|
ctx.Data["CanWriteIssues"] = ctx.Repo.CanWrite(unit_model.TypeIssues)
|
||||||
ctx.Data["CanWritePulls"] = ctx.Repo.CanWrite(unit_model.TypePullRequests)
|
ctx.Data["CanWritePulls"] = ctx.Repo.CanWrite(unit_model.TypePullRequests)
|
||||||
@ -608,7 +583,6 @@ func RepoAssignment(ctx *Context) {
|
|||||||
|
|
||||||
// Disable everything when the repo is being created
|
// Disable everything when the repo is being created
|
||||||
if ctx.Repo.Repository.IsBeingCreated() || ctx.Repo.Repository.IsBroken() {
|
if ctx.Repo.Repository.IsBeingCreated() || ctx.Repo.Repository.IsBroken() {
|
||||||
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
|
|
||||||
if !isHomeOrSettings {
|
if !isHomeOrSettings {
|
||||||
ctx.Redirect(ctx.Repo.RepoLink)
|
ctx.Redirect(ctx.Repo.RepoLink)
|
||||||
}
|
}
|
||||||
@ -616,9 +590,7 @@ func RepoAssignment(ctx *Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Repo.GitRepo != nil {
|
if ctx.Repo.GitRepo != nil {
|
||||||
if !setting.IsProd || setting.IsInTesting {
|
setting.PanicInDevOrTesting("RepoAssignment: GitRepo should be nil")
|
||||||
panic("RepoAssignment: GitRepo should be nil")
|
|
||||||
}
|
|
||||||
_ = ctx.Repo.GitRepo.Close()
|
_ = ctx.Repo.GitRepo.Close()
|
||||||
ctx.Repo.GitRepo = nil
|
ctx.Repo.GitRepo = nil
|
||||||
}
|
}
|
||||||
@ -628,7 +600,6 @@ func RepoAssignment(ctx *Context) {
|
|||||||
if strings.Contains(err.Error(), "repository does not exist") || strings.Contains(err.Error(), "no such file or directory") {
|
if strings.Contains(err.Error(), "repository does not exist") || strings.Contains(err.Error(), "no such file or directory") {
|
||||||
log.Error("Repository %-v has a broken repository on the file system: %s Error: %v", ctx.Repo.Repository, ctx.Repo.Repository.RepoPath(), err)
|
log.Error("Repository %-v has a broken repository on the file system: %s Error: %v", ctx.Repo.Repository, ctx.Repo.Repository.RepoPath(), err)
|
||||||
ctx.Repo.Repository.MarkAsBrokenEmpty()
|
ctx.Repo.Repository.MarkAsBrokenEmpty()
|
||||||
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
|
|
||||||
// Only allow access to base of repo or settings
|
// Only allow access to base of repo or settings
|
||||||
if !isHomeOrSettings {
|
if !isHomeOrSettings {
|
||||||
ctx.Redirect(ctx.Repo.RepoLink)
|
ctx.Redirect(ctx.Repo.RepoLink)
|
||||||
@ -641,7 +612,6 @@ func RepoAssignment(ctx *Context) {
|
|||||||
|
|
||||||
// Stop at this point when the repo is empty.
|
// Stop at this point when the repo is empty.
|
||||||
if ctx.Repo.Repository.IsEmpty {
|
if ctx.Repo.Repository.IsEmpty {
|
||||||
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,22 +637,6 @@ func RepoAssignment(ctx *Context) {
|
|||||||
|
|
||||||
ctx.Data["BranchesCount"] = branchesTotal
|
ctx.Data["BranchesCount"] = branchesTotal
|
||||||
|
|
||||||
// If no branch is set in the request URL, try to guess a default one.
|
|
||||||
if len(ctx.Repo.BranchName) == 0 {
|
|
||||||
if len(ctx.Repo.Repository.DefaultBranch) > 0 && ctx.Repo.GitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) {
|
|
||||||
ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch
|
|
||||||
} else {
|
|
||||||
ctx.Repo.BranchName, _ = gitrepo.GetDefaultBranch(ctx, ctx.Repo.Repository)
|
|
||||||
if ctx.Repo.BranchName == "" {
|
|
||||||
// If it still can't get a default branch, fall back to default branch from setting.
|
|
||||||
// Something might be wrong. Either site admin should fix the repo sync or Gitea should fix a potential bug.
|
|
||||||
ctx.Repo.BranchName = setting.Repository.DefaultBranch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.Repo.RefName = ctx.Repo.BranchName
|
|
||||||
}
|
|
||||||
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
|
||||||
|
|
||||||
// People who have push access or have forked repository can propose a new pull request.
|
// People who have push access or have forked repository can propose a new pull request.
|
||||||
canPush := ctx.Repo.CanWrite(unit_model.TypeCode) ||
|
canPush := ctx.Repo.CanWrite(unit_model.TypeCode) ||
|
||||||
(ctx.IsSigned && repo_model.HasForkedRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID))
|
(ctx.IsSigned && repo_model.HasForkedRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID))
|
||||||
@ -725,7 +679,7 @@ func RepoAssignment(ctx *Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ctx.FormString("go-get") == "1" {
|
if ctx.FormString("go-get") == "1" {
|
||||||
ctx.Data["GoGetImport"] = ComposeGoGetImport(ctx, owner.Name, repo.Name)
|
ctx.Data["GoGetImport"] = ComposeGoGetImport(ctx, repo.Owner.Name, repo.Name)
|
||||||
fullURLPrefix := repo.HTMLURL() + "/src/branch/" + util.PathEscapeSegments(ctx.Repo.BranchName)
|
fullURLPrefix := repo.HTMLURL() + "/src/branch/" + util.PathEscapeSegments(ctx.Repo.BranchName)
|
||||||
ctx.Data["GoDocDirectory"] = fullURLPrefix + "{/dir}"
|
ctx.Data["GoDocDirectory"] = fullURLPrefix + "{/dir}"
|
||||||
ctx.Data["GoDocFile"] = fullURLPrefix + "{/dir}/{file}#L{line}"
|
ctx.Data["GoDocFile"] = fullURLPrefix + "{/dir}/{file}#L{line}"
|
||||||
@ -871,26 +825,39 @@ type RepoRefByTypeOptions struct {
|
|||||||
IgnoreNotExistErr bool
|
IgnoreNotExistErr bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func repoRefFullName(shortName string, typ RepoRefType) git.RefName {
|
||||||
|
switch typ {
|
||||||
|
case RepoRefBranch:
|
||||||
|
return git.RefNameFromBranch(shortName)
|
||||||
|
case RepoRefTag:
|
||||||
|
return git.RefNameFromTag(shortName)
|
||||||
|
case RepoRefCommit:
|
||||||
|
return git.RefNameFromCommit(shortName)
|
||||||
|
default:
|
||||||
|
setting.PanicInDevOrTesting("Unknown RepoRefType: %v", typ)
|
||||||
|
return git.RefNameFromBranch("main") // just a dummy result, it shouldn't happen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// RepoRefByType handles repository reference name for a specific type
|
// RepoRefByType handles repository reference name for a specific type
|
||||||
// of repository reference
|
// of repository reference
|
||||||
func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func(*Context) {
|
func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func(*Context) {
|
||||||
opt := util.OptionalArg(opts)
|
opt := util.OptionalArg(opts)
|
||||||
return func(ctx *Context) {
|
return func(ctx *Context) {
|
||||||
|
var err error
|
||||||
refType := detectRefType
|
refType := detectRefType
|
||||||
// Empty repository does not have reference information.
|
// Empty repository does not have reference information.
|
||||||
if ctx.Repo.Repository.IsEmpty {
|
if ctx.Repo.Repository.IsEmpty {
|
||||||
// assume the user is viewing the (non-existent) default branch
|
// assume the user is viewing the (non-existent) default branch
|
||||||
ctx.Repo.IsViewBranch = true
|
ctx.Repo.IsViewBranch = true
|
||||||
ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch
|
ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch
|
||||||
|
ctx.Repo.RefFullName = git.RefNameFromBranch(ctx.Repo.BranchName)
|
||||||
|
// these variables are used by the template to "add/upload" new files
|
||||||
|
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
||||||
ctx.Data["TreePath"] = ""
|
ctx.Data["TreePath"] = ""
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
refName string
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
if ctx.Repo.GitRepo == nil {
|
if ctx.Repo.GitRepo == nil {
|
||||||
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
|
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -900,22 +867,23 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get default branch.
|
// Get default branch.
|
||||||
|
var refShortName string
|
||||||
reqPath := ctx.PathParam("*")
|
reqPath := ctx.PathParam("*")
|
||||||
if reqPath == "" {
|
if reqPath == "" {
|
||||||
refName = ctx.Repo.Repository.DefaultBranch
|
refShortName = ctx.Repo.Repository.DefaultBranch
|
||||||
if !ctx.Repo.GitRepo.IsBranchExist(refName) {
|
if !ctx.Repo.GitRepo.IsBranchExist(refShortName) {
|
||||||
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 1)
|
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 1)
|
||||||
if err == nil && len(brs) != 0 {
|
if err == nil && len(brs) != 0 {
|
||||||
refName = brs[0].Name
|
refShortName = brs[0].Name
|
||||||
} else if len(brs) == 0 {
|
} else if len(brs) == 0 {
|
||||||
log.Error("No branches in non-empty repository %s", ctx.Repo.GitRepo.Path)
|
log.Error("No branches in non-empty repository %s", ctx.Repo.GitRepo.Path)
|
||||||
} else {
|
} else {
|
||||||
log.Error("GetBranches error: %v", err)
|
log.Error("GetBranches error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.Repo.RefName = refName
|
ctx.Repo.RefFullName = git.RefNameFromBranch(refShortName)
|
||||||
ctx.Repo.BranchName = refName
|
ctx.Repo.BranchName = refShortName
|
||||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
|
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refShortName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
|
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
|
||||||
} else if strings.Contains(err.Error(), "fatal: not a git repository") || strings.Contains(err.Error(), "object does not exist") {
|
} else if strings.Contains(err.Error(), "fatal: not a git repository") || strings.Contains(err.Error(), "object does not exist") {
|
||||||
@ -929,35 +897,37 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func
|
|||||||
} else { // there is a path in request
|
} else { // there is a path in request
|
||||||
guessLegacyPath := refType == RepoRefUnknown
|
guessLegacyPath := refType == RepoRefUnknown
|
||||||
if guessLegacyPath {
|
if guessLegacyPath {
|
||||||
refName, refType = getRefNameLegacy(ctx.Base, ctx.Repo, reqPath, "")
|
refShortName, refType = getRefNameLegacy(ctx.Base, ctx.Repo, reqPath, "")
|
||||||
} else {
|
} else {
|
||||||
refName = getRefName(ctx.Base, ctx.Repo, reqPath, refType)
|
refShortName = getRefName(ctx.Base, ctx.Repo, reqPath, refType)
|
||||||
}
|
}
|
||||||
ctx.Repo.RefName = refName
|
ctx.Repo.RefFullName = repoRefFullName(refShortName, refType)
|
||||||
isRenamedBranch, has := ctx.Data["IsRenamedBranch"].(bool)
|
isRenamedBranch, has := ctx.Data["IsRenamedBranch"].(bool)
|
||||||
if isRenamedBranch && has {
|
if isRenamedBranch && has {
|
||||||
renamedBranchName := ctx.Data["RenamedBranchName"].(string)
|
renamedBranchName := ctx.Data["RenamedBranchName"].(string)
|
||||||
ctx.Flash.Info(ctx.Tr("repo.branch.renamed", refName, renamedBranchName))
|
ctx.Flash.Info(ctx.Tr("repo.branch.renamed", refShortName, renamedBranchName))
|
||||||
link := setting.AppSubURL + strings.Replace(ctx.Req.URL.EscapedPath(), util.PathEscapeSegments(refName), util.PathEscapeSegments(renamedBranchName), 1)
|
link := setting.AppSubURL + strings.Replace(ctx.Req.URL.EscapedPath(), util.PathEscapeSegments(refShortName), util.PathEscapeSegments(renamedBranchName), 1)
|
||||||
ctx.Redirect(link)
|
ctx.Redirect(link)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if refType == RepoRefBranch && ctx.Repo.GitRepo.IsBranchExist(refName) {
|
if refType == RepoRefBranch && ctx.Repo.GitRepo.IsBranchExist(refShortName) {
|
||||||
ctx.Repo.IsViewBranch = true
|
ctx.Repo.IsViewBranch = true
|
||||||
ctx.Repo.BranchName = refName
|
ctx.Repo.BranchName = refShortName
|
||||||
|
ctx.Repo.RefFullName = git.RefNameFromBranch(refShortName)
|
||||||
|
|
||||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
|
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refShortName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("GetBranchCommit", err)
|
ctx.ServerError("GetBranchCommit", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
|
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
|
||||||
} else if refType == RepoRefTag && ctx.Repo.GitRepo.IsTagExist(refName) {
|
} else if refType == RepoRefTag && ctx.Repo.GitRepo.IsTagExist(refShortName) {
|
||||||
ctx.Repo.IsViewTag = true
|
ctx.Repo.IsViewTag = true
|
||||||
ctx.Repo.TagName = refName
|
ctx.Repo.RefFullName = git.RefNameFromTag(refShortName)
|
||||||
|
ctx.Repo.TagName = refShortName
|
||||||
|
|
||||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName)
|
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refShortName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if git.IsErrNotExist(err) {
|
if git.IsErrNotExist(err) {
|
||||||
ctx.NotFound("GetTagCommit", err)
|
ctx.NotFound("GetTagCommit", err)
|
||||||
@ -967,25 +937,26 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
|
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
|
||||||
} else if git.IsStringLikelyCommitID(ctx.Repo.GetObjectFormat(), refName, 7) {
|
} else if git.IsStringLikelyCommitID(ctx.Repo.GetObjectFormat(), refShortName, 7) {
|
||||||
ctx.Repo.IsViewCommit = true
|
ctx.Repo.IsViewCommit = true
|
||||||
ctx.Repo.CommitID = refName
|
ctx.Repo.RefFullName = git.RefNameFromCommit(refShortName)
|
||||||
|
ctx.Repo.CommitID = refShortName
|
||||||
|
|
||||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName)
|
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refShortName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.NotFound("GetCommit", err)
|
ctx.NotFound("GetCommit", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// If short commit ID add canonical link header
|
// If short commit ID add canonical link header
|
||||||
if len(refName) < ctx.Repo.GetObjectFormat().FullLength() {
|
if len(refShortName) < ctx.Repo.GetObjectFormat().FullLength() {
|
||||||
canonicalURL := util.URLJoin(httplib.GuessCurrentAppURL(ctx), strings.Replace(ctx.Req.URL.RequestURI(), util.PathEscapeSegments(refName), url.PathEscape(ctx.Repo.Commit.ID.String()), 1))
|
canonicalURL := util.URLJoin(httplib.GuessCurrentAppURL(ctx), strings.Replace(ctx.Req.URL.RequestURI(), util.PathEscapeSegments(refShortName), url.PathEscape(ctx.Repo.Commit.ID.String()), 1))
|
||||||
ctx.RespHeader().Set("Link", fmt.Sprintf(`<%s>; rel="canonical"`, canonicalURL))
|
ctx.RespHeader().Set("Link", fmt.Sprintf(`<%s>; rel="canonical"`, canonicalURL))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if opt.IgnoreNotExistErr {
|
if opt.IgnoreNotExistErr {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.NotFound("RepoRef invalid repo", fmt.Errorf("branch or tag not exist: %s", refName))
|
ctx.NotFound("RepoRef invalid repo", fmt.Errorf("branch or tag not exist: %s", refShortName))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -995,24 +966,26 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func
|
|||||||
redirect := path.Join(
|
redirect := path.Join(
|
||||||
ctx.Repo.RepoLink,
|
ctx.Repo.RepoLink,
|
||||||
util.PathEscapeSegments(prefix),
|
util.PathEscapeSegments(prefix),
|
||||||
ctx.Repo.BranchNameSubURL(),
|
ctx.Repo.RefTypeNameSubURL(),
|
||||||
util.PathEscapeSegments(ctx.Repo.TreePath))
|
util.PathEscapeSegments(ctx.Repo.TreePath))
|
||||||
ctx.Redirect(redirect)
|
ctx.Redirect(redirect)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
ctx.Data["RefFullName"] = ctx.Repo.RefFullName
|
||||||
ctx.Data["RefName"] = ctx.Repo.RefName
|
ctx.Data["RefTypeNameSubURL"] = ctx.Repo.RefTypeNameSubURL()
|
||||||
ctx.Data["RefShortName"] = util.Iif(refType == RepoRefCommit, base.ShortSha(ctx.Repo.RefName), ctx.Repo.RefName)
|
|
||||||
ctx.Data["RefType"] = RefTypeName(refType)
|
|
||||||
ctx.Data["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL()
|
|
||||||
ctx.Data["TagName"] = ctx.Repo.TagName
|
|
||||||
ctx.Data["CommitID"] = ctx.Repo.CommitID
|
|
||||||
ctx.Data["TreePath"] = ctx.Repo.TreePath
|
ctx.Data["TreePath"] = ctx.Repo.TreePath
|
||||||
|
|
||||||
ctx.Data["IsViewBranch"] = ctx.Repo.IsViewBranch
|
ctx.Data["IsViewBranch"] = ctx.Repo.IsViewBranch
|
||||||
|
ctx.Data["BranchName"] = ctx.Repo.BranchName
|
||||||
|
|
||||||
ctx.Data["IsViewTag"] = ctx.Repo.IsViewTag
|
ctx.Data["IsViewTag"] = ctx.Repo.IsViewTag
|
||||||
|
ctx.Data["TagName"] = ctx.Repo.TagName
|
||||||
|
|
||||||
ctx.Data["IsViewCommit"] = ctx.Repo.IsViewCommit
|
ctx.Data["IsViewCommit"] = ctx.Repo.IsViewCommit
|
||||||
|
ctx.Data["CommitID"] = ctx.Repo.CommitID
|
||||||
|
|
||||||
ctx.Data["CanCreateBranch"] = ctx.Repo.CanCreateBranch() // only used by the branch selector dropdown: AllowCreateNewRef
|
ctx.Data["CanCreateBranch"] = ctx.Repo.CanCreateBranch() // only used by the branch selector dropdown: AllowCreateNewRef
|
||||||
|
|
||||||
ctx.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount()
|
ctx.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount()
|
||||||
|
@ -87,6 +87,7 @@ type mirrorSyncResult struct {
|
|||||||
/*
|
/*
|
||||||
// * [new tag] v0.1.8 -> v0.1.8
|
// * [new tag] v0.1.8 -> v0.1.8
|
||||||
// * [new branch] master -> origin/master
|
// * [new branch] master -> origin/master
|
||||||
|
// * [new ref] refs/pull/2/head -> refs/pull/2/head"
|
||||||
// - [deleted] (none) -> origin/test // delete a branch
|
// - [deleted] (none) -> origin/test // delete a branch
|
||||||
// - [deleted] (none) -> 1 // delete a tag
|
// - [deleted] (none) -> 1 // delete a tag
|
||||||
// 957a993..a87ba5f test -> origin/test
|
// 957a993..a87ba5f test -> origin/test
|
||||||
@ -117,6 +118,11 @@ func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult {
|
|||||||
refName: git.RefNameFromBranch(refName),
|
refName: git.RefNameFromBranch(refName),
|
||||||
oldCommitID: gitShortEmptySha,
|
oldCommitID: gitShortEmptySha,
|
||||||
})
|
})
|
||||||
|
case strings.HasPrefix(lines[i], " * [new ref]"): // new reference
|
||||||
|
results = append(results, &mirrorSyncResult{
|
||||||
|
refName: git.RefName(refName),
|
||||||
|
oldCommitID: gitShortEmptySha,
|
||||||
|
})
|
||||||
case strings.HasPrefix(lines[i], " - "): // Delete reference
|
case strings.HasPrefix(lines[i], " - "): // Delete reference
|
||||||
isTag := !strings.HasPrefix(refName, remoteName+"/")
|
isTag := !strings.HasPrefix(refName, remoteName+"/")
|
||||||
var refFullName git.RefName
|
var refFullName git.RefName
|
||||||
@ -159,8 +165,15 @@ func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult {
|
|||||||
log.Error("Expect two SHAs but not what found: %q", lines[i])
|
log.Error("Expect two SHAs but not what found: %q", lines[i])
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
var refFullName git.RefName
|
||||||
|
if strings.HasPrefix(refName, "refs/") {
|
||||||
|
refFullName = git.RefName(refName)
|
||||||
|
} else {
|
||||||
|
refFullName = git.RefNameFromBranch(strings.TrimPrefix(refName, remoteName+"/"))
|
||||||
|
}
|
||||||
|
|
||||||
results = append(results, &mirrorSyncResult{
|
results = append(results, &mirrorSyncResult{
|
||||||
refName: git.RefNameFromBranch(strings.TrimPrefix(refName, remoteName+"/")),
|
refName: refFullName,
|
||||||
oldCommitID: shas[0],
|
oldCommitID: shas[0],
|
||||||
newCommitID: shas[1],
|
newCommitID: shas[1],
|
||||||
})
|
})
|
||||||
|
@ -31,19 +31,20 @@ import (
|
|||||||
// handle elsewhere.
|
// handle elsewhere.
|
||||||
type ArchiveRequest struct {
|
type ArchiveRequest struct {
|
||||||
RepoID int64
|
RepoID int64
|
||||||
refName string
|
|
||||||
Type git.ArchiveType
|
Type git.ArchiveType
|
||||||
CommitID string
|
CommitID string
|
||||||
|
|
||||||
|
archiveRefShortName string // the ref short name to download the archive, for example: "master", "v1.0.0", "commit id"
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrUnknownArchiveFormat request archive format is not supported
|
// ErrUnknownArchiveFormat request archive format is not supported
|
||||||
type ErrUnknownArchiveFormat struct {
|
type ErrUnknownArchiveFormat struct {
|
||||||
RequestFormat string
|
RequestNameType string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error implements error
|
// Error implements error
|
||||||
func (err ErrUnknownArchiveFormat) Error() string {
|
func (err ErrUnknownArchiveFormat) Error() string {
|
||||||
return fmt.Sprintf("unknown format: %s", err.RequestFormat)
|
return fmt.Sprintf("unknown format: %s", err.RequestNameType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is implements error
|
// Is implements error
|
||||||
@ -54,12 +55,12 @@ func (ErrUnknownArchiveFormat) Is(err error) bool {
|
|||||||
|
|
||||||
// RepoRefNotFoundError is returned when a requested reference (commit, tag) was not found.
|
// RepoRefNotFoundError is returned when a requested reference (commit, tag) was not found.
|
||||||
type RepoRefNotFoundError struct {
|
type RepoRefNotFoundError struct {
|
||||||
RefName string
|
RefShortName string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error implements error.
|
// Error implements error.
|
||||||
func (e RepoRefNotFoundError) Error() string {
|
func (e RepoRefNotFoundError) Error() string {
|
||||||
return fmt.Sprintf("unrecognized repository reference: %s", e.RefName)
|
return fmt.Sprintf("unrecognized repository reference: %s", e.RefShortName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e RepoRefNotFoundError) Is(err error) bool {
|
func (e RepoRefNotFoundError) Is(err error) bool {
|
||||||
@ -67,43 +68,23 @@ func (e RepoRefNotFoundError) Is(err error) bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseFileName(uri string) (ext string, tp git.ArchiveType, err error) {
|
|
||||||
switch {
|
|
||||||
case strings.HasSuffix(uri, ".zip"):
|
|
||||||
ext = ".zip"
|
|
||||||
tp = git.ZIP
|
|
||||||
case strings.HasSuffix(uri, ".tar.gz"):
|
|
||||||
ext = ".tar.gz"
|
|
||||||
tp = git.TARGZ
|
|
||||||
case strings.HasSuffix(uri, ".bundle"):
|
|
||||||
ext = ".bundle"
|
|
||||||
tp = git.BUNDLE
|
|
||||||
default:
|
|
||||||
return "", 0, ErrUnknownArchiveFormat{RequestFormat: uri}
|
|
||||||
}
|
|
||||||
return ext, tp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRequest creates an archival request, based on the URI. The
|
// NewRequest creates an archival request, based on the URI. The
|
||||||
// resulting ArchiveRequest is suitable for being passed to Await()
|
// resulting ArchiveRequest is suitable for being passed to Await()
|
||||||
// if it's determined that the request still needs to be satisfied.
|
// if it's determined that the request still needs to be satisfied.
|
||||||
func NewRequest(repoID int64, repo *git.Repository, refName string, fileType git.ArchiveType) (*ArchiveRequest, error) {
|
func NewRequest(repoID int64, repo *git.Repository, archiveRefExt string) (*ArchiveRequest, error) {
|
||||||
if fileType < git.ZIP || fileType > git.BUNDLE {
|
// here the archiveRefShortName is not a clear ref, it could be a tag, branch or commit id
|
||||||
return nil, ErrUnknownArchiveFormat{RequestFormat: fileType.String()}
|
archiveRefShortName, archiveType := git.SplitArchiveNameType(archiveRefExt)
|
||||||
}
|
if archiveType == git.ArchiveUnknown {
|
||||||
|
return nil, ErrUnknownArchiveFormat{archiveRefExt}
|
||||||
r := &ArchiveRequest{
|
|
||||||
RepoID: repoID,
|
|
||||||
refName: refName,
|
|
||||||
Type: fileType,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get corresponding commit.
|
// Get corresponding commit.
|
||||||
commitID, err := repo.ConvertToGitID(r.refName)
|
commitID, err := repo.ConvertToGitID(archiveRefShortName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, RepoRefNotFoundError{RefName: r.refName}
|
return nil, RepoRefNotFoundError{RefShortName: archiveRefShortName}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r := &ArchiveRequest{RepoID: repoID, archiveRefShortName: archiveRefShortName, Type: archiveType}
|
||||||
r.CommitID = commitID.String()
|
r.CommitID = commitID.String()
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
@ -111,11 +92,11 @@ func NewRequest(repoID int64, repo *git.Repository, refName string, fileType git
|
|||||||
// GetArchiveName returns the name of the caller, based on the ref used by the
|
// GetArchiveName returns the name of the caller, based on the ref used by the
|
||||||
// caller to create this request.
|
// caller to create this request.
|
||||||
func (aReq *ArchiveRequest) GetArchiveName() string {
|
func (aReq *ArchiveRequest) GetArchiveName() string {
|
||||||
return strings.ReplaceAll(aReq.refName, "/", "-") + "." + aReq.Type.String()
|
return strings.ReplaceAll(aReq.archiveRefShortName, "/", "-") + "." + aReq.Type.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Await awaits the completion of an ArchiveRequest. If the archive has
|
// Await awaits the completion of an ArchiveRequest. If the archive has
|
||||||
// already been prepared the method returns immediately. Otherwise an archiver
|
// already been prepared the method returns immediately. Otherwise, an archiver
|
||||||
// process will be started and its completion awaited. On success the returned
|
// process will be started and its completion awaited. On success the returned
|
||||||
// RepoArchiver may be used to download the archive. Note that even if the
|
// RepoArchiver may be used to download the archive. Note that even if the
|
||||||
// context is cancelled/times out a started archiver will still continue to run
|
// context is cancelled/times out a started archiver will still continue to run
|
||||||
@ -208,8 +189,8 @@ func doArchive(ctx context.Context, r *ArchiveRequest) (*repo_model.RepoArchiver
|
|||||||
|
|
||||||
rd, w := io.Pipe()
|
rd, w := io.Pipe()
|
||||||
defer func() {
|
defer func() {
|
||||||
w.Close()
|
_ = w.Close()
|
||||||
rd.Close()
|
_ = rd.Close()
|
||||||
}()
|
}()
|
||||||
done := make(chan error, 1) // Ensure that there is some capacity which will ensure that the goroutine below can always finish
|
done := make(chan error, 1) // Ensure that there is some capacity which will ensure that the goroutine below can always finish
|
||||||
repo, err := repo_model.GetRepositoryByID(ctx, archiver.RepoID)
|
repo, err := repo_model.GetRepositoryByID(ctx, archiver.RepoID)
|
||||||
@ -230,7 +211,7 @@ func doArchive(ctx context.Context, r *ArchiveRequest) (*repo_model.RepoArchiver
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if archiver.Type == git.BUNDLE {
|
if archiver.Type == git.ArchiveBundle {
|
||||||
err = gitRepo.CreateBundle(
|
err = gitRepo.CreateBundle(
|
||||||
ctx,
|
ctx,
|
||||||
archiver.CommitID,
|
archiver.CommitID,
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
"code.gitea.io/gitea/modules/git"
|
|
||||||
"code.gitea.io/gitea/services/contexttest"
|
"code.gitea.io/gitea/services/contexttest"
|
||||||
|
|
||||||
_ "code.gitea.io/gitea/models/actions"
|
_ "code.gitea.io/gitea/models/actions"
|
||||||
@ -31,47 +30,47 @@ func TestArchive_Basic(t *testing.T) {
|
|||||||
contexttest.LoadGitRepo(t, ctx)
|
contexttest.LoadGitRepo(t, ctx)
|
||||||
defer ctx.Repo.GitRepo.Close()
|
defer ctx.Repo.GitRepo.Close()
|
||||||
|
|
||||||
bogusReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.ZIP)
|
bogusReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, bogusReq)
|
assert.NotNil(t, bogusReq)
|
||||||
assert.EqualValues(t, firstCommit+".zip", bogusReq.GetArchiveName())
|
assert.EqualValues(t, firstCommit+".zip", bogusReq.GetArchiveName())
|
||||||
|
|
||||||
// Check a series of bogus requests.
|
// Check a series of bogus requests.
|
||||||
// Step 1, valid commit with a bad extension.
|
// Step 1, valid commit with a bad extension.
|
||||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, 100)
|
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".unknown")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Nil(t, bogusReq)
|
assert.Nil(t, bogusReq)
|
||||||
|
|
||||||
// Step 2, missing commit.
|
// Step 2, missing commit.
|
||||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "dbffff", git.ZIP)
|
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "dbffff.zip")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Nil(t, bogusReq)
|
assert.Nil(t, bogusReq)
|
||||||
|
|
||||||
// Step 3, doesn't look like branch/tag/commit.
|
// Step 3, doesn't look like branch/tag/commit.
|
||||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "db", git.ZIP)
|
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "db.zip")
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Nil(t, bogusReq)
|
assert.Nil(t, bogusReq)
|
||||||
|
|
||||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "master", git.ZIP)
|
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "master.zip")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, bogusReq)
|
assert.NotNil(t, bogusReq)
|
||||||
assert.EqualValues(t, "master.zip", bogusReq.GetArchiveName())
|
assert.EqualValues(t, "master.zip", bogusReq.GetArchiveName())
|
||||||
|
|
||||||
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "test/archive", git.ZIP)
|
bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "test/archive.zip")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, bogusReq)
|
assert.NotNil(t, bogusReq)
|
||||||
assert.EqualValues(t, "test-archive.zip", bogusReq.GetArchiveName())
|
assert.EqualValues(t, "test-archive.zip", bogusReq.GetArchiveName())
|
||||||
|
|
||||||
// Now two valid requests, firstCommit with valid extensions.
|
// Now two valid requests, firstCommit with valid extensions.
|
||||||
zipReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.ZIP)
|
zipReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, zipReq)
|
assert.NotNil(t, zipReq)
|
||||||
|
|
||||||
tgzReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.TARGZ)
|
tgzReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".tar.gz")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, tgzReq)
|
assert.NotNil(t, tgzReq)
|
||||||
|
|
||||||
secondReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit, git.ZIP)
|
secondReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit+".bundle")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, secondReq)
|
assert.NotNil(t, secondReq)
|
||||||
|
|
||||||
@ -91,7 +90,7 @@ func TestArchive_Basic(t *testing.T) {
|
|||||||
// Sleep two seconds to make sure the queue doesn't change.
|
// Sleep two seconds to make sure the queue doesn't change.
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
|
|
||||||
zipReq2, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.ZIP)
|
zipReq2, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// This zipReq should match what's sitting in the queue, as we haven't
|
// This zipReq should match what's sitting in the queue, as we haven't
|
||||||
// let it release yet. From the consumer's point of view, this looks like
|
// let it release yet. From the consumer's point of view, this looks like
|
||||||
@ -106,12 +105,12 @@ func TestArchive_Basic(t *testing.T) {
|
|||||||
// Now we'll submit a request and TimedWaitForCompletion twice, before and
|
// Now we'll submit a request and TimedWaitForCompletion twice, before and
|
||||||
// after we release it. We should trigger both the timeout and non-timeout
|
// after we release it. We should trigger both the timeout and non-timeout
|
||||||
// cases.
|
// cases.
|
||||||
timedReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit, git.TARGZ)
|
timedReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, secondCommit+".tar.gz")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, timedReq)
|
assert.NotNil(t, timedReq)
|
||||||
doArchive(db.DefaultContext, timedReq)
|
doArchive(db.DefaultContext, timedReq)
|
||||||
|
|
||||||
zipReq2, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit, git.ZIP)
|
zipReq2, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// Now, we're guaranteed to have released the original zipReq from the queue.
|
// Now, we're guaranteed to have released the original zipReq from the queue.
|
||||||
// Ensure that we don't get handed back the released entry somehow, but they
|
// Ensure that we don't get handed back the released entry somehow, but they
|
||||||
@ -129,6 +128,6 @@ func TestArchive_Basic(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestErrUnknownArchiveFormat(t *testing.T) {
|
func TestErrUnknownArchiveFormat(t *testing.T) {
|
||||||
err := ErrUnknownArchiveFormat{RequestFormat: "master"}
|
err := ErrUnknownArchiveFormat{RequestNameType: "xxx"}
|
||||||
assert.ErrorIs(t, err, ErrUnknownArchiveFormat{})
|
assert.ErrorIs(t, err, ErrUnknownArchiveFormat{})
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{{if or .UsesIgnoreRevs .FaultyIgnoreRevsFile}}
|
{{if or .UsesIgnoreRevs .FaultyIgnoreRevsFile}}
|
||||||
{{$revsFileLink := URLJoin .RepoLink "src" .BranchNameSubURL "/.git-blame-ignore-revs"}}
|
{{$revsFileLink := URLJoin .RepoLink "src" .RefTypeNameSubURL "/.git-blame-ignore-revs"}}
|
||||||
{{if .UsesIgnoreRevs}}
|
{{if .UsesIgnoreRevs}}
|
||||||
<div class="ui info message">
|
<div class="ui info message">
|
||||||
<p>{{ctx.Locale.Tr "repo.blame.ignore_revs" $revsFileLink "?bypass-blame-ignore=true"}}</p>
|
<p>{{ctx.Locale.Tr "repo.blame.ignore_revs" $revsFileLink "?bypass-blame-ignore=true"}}</p>
|
||||||
@ -21,8 +21,8 @@
|
|||||||
{{if not .IsViewCommit}}
|
{{if not .IsViewCommit}}
|
||||||
<a class="ui tiny button" href="{{.RepoLink}}/src/commit/{{.CommitID | PathEscape}}/{{.TreePath | PathEscapeSegments}}">{{ctx.Locale.Tr "repo.file_permalink"}}</a>
|
<a class="ui tiny button" href="{{.RepoLink}}/src/commit/{{.CommitID | PathEscape}}/{{.TreePath | PathEscapeSegments}}">{{ctx.Locale.Tr "repo.file_permalink"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
<a class="ui tiny button" href="{{.RepoLink}}/src/{{.BranchNameSubURL}}/{{.TreePath | PathEscapeSegments}}">{{ctx.Locale.Tr "repo.normal_view"}}</a>
|
<a class="ui tiny button" href="{{.RepoLink}}/src/{{.RefTypeNameSubURL}}/{{.TreePath | PathEscapeSegments}}">{{ctx.Locale.Tr "repo.normal_view"}}</a>
|
||||||
<a class="ui tiny button" href="{{.RepoLink}}/commits/{{.BranchNameSubURL}}/{{.TreePath | PathEscapeSegments}}">{{ctx.Locale.Tr "repo.file_history"}}</a>
|
<a class="ui tiny button" href="{{.RepoLink}}/commits/{{.RefTypeNameSubURL}}/{{.TreePath | PathEscapeSegments}}">{{ctx.Locale.Tr "repo.file_history"}}</a>
|
||||||
<button class="ui tiny button unescape-button">{{ctx.Locale.Tr "repo.unescape_control_characters"}}</button>
|
<button class="ui tiny button unescape-button">{{ctx.Locale.Tr "repo.unescape_control_characters"}}</button>
|
||||||
<button class="ui tiny button escape-button tw-hidden">{{ctx.Locale.Tr "repo.escape_control_characters"}}</button>
|
<button class="ui tiny button escape-button tw-hidden">{{ctx.Locale.Tr "repo.escape_control_characters"}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
</button>
|
</button>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .EnableFeed}}
|
{{if .EnableFeed}}
|
||||||
<a role="button" class="btn interact-bg tw-p-2" href="{{$.FeedURL}}/rss/branch/{{PathEscapeSegments .DefaultBranchBranch.DBBranch.Name}}" data-tooltip-content="{{ctx.Locale.Tr "rss_feed"}}">{{svg "octicon-rss"}}</a>
|
<a role="button" class="btn interact-bg tw-p-2" href="{{$.RepoLink}}/rss/branch/{{PathEscapeSegments .DefaultBranchBranch.DBBranch.Name}}" data-tooltip-content="{{ctx.Locale.Tr "rss_feed"}}">{{svg "octicon-rss"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if not $.DisableDownloadSourceArchives}}
|
{{if not $.DisableDownloadSourceArchives}}
|
||||||
<div class="ui dropdown btn interact-bg tw-p-2" data-tooltip-content="{{ctx.Locale.Tr "repo.branch.download" ($.DefaultBranchBranch.DBBranch.Name)}}">
|
<div class="ui dropdown btn interact-bg tw-p-2" data-tooltip-content="{{ctx.Locale.Tr "repo.branch.download" ($.DefaultBranchBranch.DBBranch.Name)}}">
|
||||||
@ -162,7 +162,7 @@
|
|||||||
</button>
|
</button>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if $.EnableFeed}}
|
{{if $.EnableFeed}}
|
||||||
<a role="button" class="btn interact-bg tw-p-2" href="{{$.FeedURL}}/rss/branch/{{PathEscapeSegments .DBBranch.Name}}" data-tooltip-content="{{ctx.Locale.Tr "rss_feed"}}">{{svg "octicon-rss"}}</a>
|
<a role="button" class="btn interact-bg tw-p-2" href="{{$.RepoLink}}/rss/branch/{{PathEscapeSegments .DBBranch.Name}}" data-tooltip-content="{{ctx.Locale.Tr "rss_feed"}}">{{svg "octicon-rss"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if and (not .DBBranch.IsDeleted) (not $.DisableDownloadSourceArchives)}}
|
{{if and (not .DBBranch.IsDeleted) (not $.DisableDownloadSourceArchives)}}
|
||||||
<div class="ui dropdown btn interact-bg tw-p-2" data-tooltip-content="{{ctx.Locale.Tr "repo.branch.download" (.DBBranch.Name)}}">
|
<div class="ui dropdown btn interact-bg tw-p-2" data-tooltip-content="{{ctx.Locale.Tr "repo.branch.download" (.DBBranch.Name)}}">
|
||||||
|
@ -32,12 +32,14 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{if and (not $.DisableDownloadSourceArchives) $.RefName}}
|
{{if and (not $.DisableDownloadSourceArchives) $.RefFullName}}
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
<div class="flex-items-block clone-panel-list">
|
<div class="flex-items-block clone-panel-list">
|
||||||
<a class="item muted archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments $.RefName}}.zip" rel="nofollow">{{svg "octicon-file-zip"}} {{ctx.Locale.Tr "repo.download_zip"}}</a>
|
{{/* FIXME: here it only uses the shortname in the ref to build the link, it can't distinguish the branch/tag/commit with the same name
|
||||||
<a class="item muted archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments $.RefName}}.tar.gz" rel="nofollow">{{svg "octicon-file-zip"}} {{ctx.Locale.Tr "repo.download_tar"}}</a>
|
in the future, it's better to use something like "/archive/branch/the-name.zip", "/archive/tag/the-name.zip" */}}
|
||||||
<a class="item muted archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments $.RefName}}.bundle" rel="nofollow">{{svg "octicon-package"}} {{ctx.Locale.Tr "repo.download_bundle"}}</a>
|
<a class="item muted archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments $.RefFullName.ShortName}}.zip" rel="nofollow">{{svg "octicon-file-zip"}} {{ctx.Locale.Tr "repo.download_zip"}}</a>
|
||||||
|
<a class="item muted archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments $.RefFullName.ShortName}}.tar.gz" rel="nofollow">{{svg "octicon-file-zip"}} {{ctx.Locale.Tr "repo.download_tar"}}</a>
|
||||||
|
<a class="item muted archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments $.RefFullName.ShortName}}.bundle" rel="nofollow">{{svg "octicon-package"}} {{ctx.Locale.Tr "repo.download_bundle"}}</a>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
{{if .PageIsCommits}}
|
{{if .PageIsCommits}}
|
||||||
<div class="ui attached segment">
|
<div class="ui attached segment">
|
||||||
<form class="ignore-dirty" action="{{.RepoLink}}/commits/{{.BranchNameSubURL}}/search">
|
<form class="ignore-dirty" action="{{.RepoLink}}/commits/{{.RefTypeNameSubURL}}/search">
|
||||||
<div class="ui small fluid action input">
|
<div class="ui small fluid action input">
|
||||||
{{template "shared/search/input" dict "Value" .Keyword "Placeholder" (ctx.Locale.Tr "search.commit_kind")}}
|
{{template "shared/search/input" dict "Value" .Keyword "Placeholder" (ctx.Locale.Tr "search.commit_kind")}}
|
||||||
{{template "repo/commits_search_dropdown" .}}
|
{{template "repo/commits_search_dropdown" .}}
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
<div class="ui top attached header">
|
<div class="ui top attached header">
|
||||||
<div class="ui compact small menu small-menu-items repo-editor-menu">
|
<div class="ui compact small menu small-menu-items repo-editor-menu">
|
||||||
<a class="active item" data-tab="write">{{svg "octicon-code"}} {{if .IsNewFile}}{{ctx.Locale.Tr "repo.editor.new_file"}}{{else}}{{ctx.Locale.Tr "repo.editor.edit_file"}}{{end}}</a>
|
<a class="active item" data-tab="write">{{svg "octicon-code"}} {{if .IsNewFile}}{{ctx.Locale.Tr "repo.editor.new_file"}}{{else}}{{ctx.Locale.Tr "repo.editor.edit_file"}}{{end}}</a>
|
||||||
<a class="item" data-tab="preview" data-preview-url="{{.Repository.Link}}/markup" data-preview-context-ref="{{.RepoLink}}/src/{{.BranchNameSubURL}}">{{svg "octicon-eye"}} {{ctx.Locale.Tr "preview"}}</a>
|
<a class="item" data-tab="preview" data-preview-url="{{.Repository.Link}}/markup" data-preview-context-ref="{{.RepoLink}}/src/{{.RefTypeNameSubURL}}">{{svg "octicon-eye"}} {{ctx.Locale.Tr "preview"}}</a>
|
||||||
{{if not .IsNewFile}}
|
{{if not .IsNewFile}}
|
||||||
<a class="item" data-tab="diff" hx-params="context,content" hx-vals='{"context":"{{.BranchLink}}"}' hx-include="#edit_area" hx-swap="innerHTML" hx-target=".tab[data-tab='diff']" hx-indicator=".tab[data-tab='diff']" hx-post="{{.RepoLink}}/_preview/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">{{svg "octicon-diff"}} {{ctx.Locale.Tr "repo.editor.preview_changes"}}</a>
|
<a class="item" data-tab="diff" hx-params="context,content" hx-vals='{"context":"{{.BranchLink}}"}' hx-include="#edit_area" hx-swap="innerHTML" hx-target=".tab[data-tab='diff']" hx-indicator=".tab[data-tab='diff']" hx-post="{{.RepoLink}}/_preview/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">{{svg "octicon-diff"}} {{ctx.Locale.Tr "repo.editor.preview_changes"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -133,7 +133,7 @@
|
|||||||
{{if not (or .Repository.IsBeingCreated .Repository.IsBroken)}}
|
{{if not (or .Repository.IsBeingCreated .Repository.IsBroken)}}
|
||||||
<div class="overflow-menu-items">
|
<div class="overflow-menu-items">
|
||||||
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeCode}}
|
{{if .Permission.CanRead ctx.Consts.RepoUnitTypeCode}}
|
||||||
<a class="{{if .PageIsViewCode}}active {{end}}item" href="{{.RepoLink}}{{if and (ne .BranchName .Repository.DefaultBranch) (not $.PageIsWiki)}}/src/{{.BranchNameSubURL}}{{end}}">
|
<a class="{{if .PageIsViewCode}}active {{end}}item" href="{{.RepoLink}}{{if and (ne .BranchName .Repository.DefaultBranch) (not $.PageIsWiki)}}/src/{{.RefTypeNameSubURL}}{{end}}">
|
||||||
{{svg "octicon-code"}} {{ctx.Locale.Tr "repo.code"}}
|
{{svg "octicon-code"}} {{ctx.Locale.Tr "repo.code"}}
|
||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
"Repository" .ctxData.Repository
|
"Repository" .ctxData.Repository
|
||||||
"ShowTabBranches" true
|
"ShowTabBranches" true
|
||||||
"ShowTabTags" true
|
"ShowTabTags" true
|
||||||
"CurrentRefType" .ctxData.RefType
|
"CurrentRefType" .ctxData.RefFullName.RefType
|
||||||
"CurrentRefShortName" .ctxData.RefShortName
|
"CurrentRefShortName" .ctxData.RefFullName.ShortName
|
||||||
"CurrentTreePath" .ctxData.TreePath
|
"CurrentTreePath" .ctxData.TreePath
|
||||||
"RefLinkTemplate" "{RepoLink}/src/{RefType}/{RefShortName}/{TreePath}"
|
"RefLinkTemplate" "{RepoLink}/src/{RefTypeNameSubURL}/{TreePath}"
|
||||||
"AllowCreateNewRef" .ctxData.CanCreateBranch
|
"AllowCreateNewRef" .ctxData.CanCreateBranch
|
||||||
"ShowViewAllRefsEntry" true
|
"ShowViewAllRefsEntry" true
|
||||||
"ContainerClasses" .containerClasses
|
"ContainerClasses" .containerClasses
|
||||||
|
@ -7,12 +7,17 @@
|
|||||||
{{template "repo/sub_menu" .}}
|
{{template "repo/sub_menu" .}}
|
||||||
<div class="repo-button-row">
|
<div class="repo-button-row">
|
||||||
<div class="repo-button-row-left">
|
<div class="repo-button-row-left">
|
||||||
{{if $hasTreeSidebar}}
|
{{- template "repo/branch_dropdown" dict
|
||||||
<button class="show-tree-sidebar-button ui compact basic button icon not-mobile {{if $showTreeSidebar}}tw-hidden{{end}}" title="{{ctx.Locale.Tr "repo.diff.show_file_tree"}}">
|
"Repository" .Repository
|
||||||
{{svg "octicon-sidebar-collapse" 20 "icon"}}
|
"ShowTabBranches" true
|
||||||
</button>
|
"ShowTabTags" true
|
||||||
{{end}}
|
"CurrentRefType" .RefFullName.RefType
|
||||||
{{template "repo/home_branch_dropdown" (dict "ctxData" .)}}
|
"CurrentRefShortName" .RefFullName.ShortName
|
||||||
|
"CurrentTreePath" .TreePath
|
||||||
|
"RefLinkTemplate" "{RepoLink}/src/{RefTypeNameSubURL}/{TreePath}"
|
||||||
|
"AllowCreateNewRef" .CanCreateBranch
|
||||||
|
"ShowViewAllRefsEntry" true
|
||||||
|
-}}
|
||||||
{{if and .CanCompareOrPull .IsViewBranch (not .Repository.IsArchived)}}
|
{{if and .CanCompareOrPull .IsViewBranch (not .Repository.IsArchived)}}
|
||||||
{{$cmpBranch := ""}}
|
{{$cmpBranch := ""}}
|
||||||
{{if ne .Repository.ID .BaseRepo.ID}}
|
{{if ne .Repository.ID .BaseRepo.ID}}
|
||||||
@ -28,11 +33,11 @@
|
|||||||
|
|
||||||
<!-- Show go to file if on home page -->
|
<!-- Show go to file if on home page -->
|
||||||
{{if $isTreePathRoot}}
|
{{if $isTreePathRoot}}
|
||||||
<a href="{{.Repository.Link}}/find/{{.BranchNameSubURL}}" class="ui compact basic button">{{ctx.Locale.Tr "repo.find_file.go_to_file"}}</a>
|
<a href="{{.Repository.Link}}/find/{{.RefTypeNameSubURL}}" class="ui compact basic button">{{ctx.Locale.Tr "repo.find_file.go_to_file"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if and .CanWriteCode .IsViewBranch (not .Repository.IsMirror) (not .Repository.IsArchived) (not .IsViewFile)}}
|
{{if and .CanWriteCode .IsViewBranch (not .Repository.IsMirror) (not .Repository.IsArchived) (not .IsViewFile)}}
|
||||||
<button class="add-file-dropdown ui dropdown basic compact jump button"{{if not .Repository.CanEnableEditor}} disabled{{end}}>
|
<button class="ui dropdown basic compact jump button"{{if not .Repository.CanEnableEditor}} disabled{{end}}>
|
||||||
{{ctx.Locale.Tr "repo.editor.add_file"}}
|
{{ctx.Locale.Tr "repo.editor.add_file"}}
|
||||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
@ -60,7 +65,7 @@
|
|||||||
{{if not $isTreePathRoot}}
|
{{if not $isTreePathRoot}}
|
||||||
{{$treeNameIdxLast := Eval $treeNamesLen "-" 1}}
|
{{$treeNameIdxLast := Eval $treeNamesLen "-" 1}}
|
||||||
<span class="breadcrumb repo-path tw-ml-1">
|
<span class="breadcrumb repo-path tw-ml-1">
|
||||||
<a class="section" href="{{.RepoLink}}/src/{{.BranchNameSubURL}}" title="{{.Repository.Name}}">{{StringUtils.EllipsisString .Repository.Name 30}}</a>
|
<a class="section" href="{{.RepoLink}}/src/{{.RefTypeNameSubURL}}" title="{{.Repository.Name}}">{{StringUtils.EllipsisString .Repository.Name 30}}</a>
|
||||||
{{- range $i, $v := .TreeNames -}}
|
{{- range $i, $v := .TreeNames -}}
|
||||||
<span class="breadcrumb-divider">/</span>
|
<span class="breadcrumb-divider">/</span>
|
||||||
{{- if eq $i $treeNameIdxLast -}}
|
{{- if eq $i $treeNameIdxLast -}}
|
||||||
@ -80,16 +85,12 @@
|
|||||||
{{template "repo/clone_panel" .}}
|
{{template "repo/clone_panel" .}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if and (not $isTreePathRoot) (not .IsViewFile) (not .IsBlame)}}{{/* IsViewDirectory (not home), TODO: split the templates, avoid using "if" tricks */}}
|
{{if and (not $isTreePathRoot) (not .IsViewFile) (not .IsBlame)}}{{/* IsViewDirectory (not home), TODO: split the templates, avoid using "if" tricks */}}
|
||||||
<a class="ui button" href="{{.RepoLink}}/commits/{{.BranchNameSubURL}}/{{.TreePath | PathEscapeSegments}}">
|
<a class="ui button" href="{{.RepoLink}}/commits/{{.RefTypeNameSubURL}}/{{.TreePath | PathEscapeSegments}}">
|
||||||
{{svg "octicon-history" 16 "tw-mr-2"}}{{ctx.Locale.Tr "repo.file_history"}}
|
{{svg "octicon-history" 16 "tw-mr-2"}}{{ctx.Locale.Tr "repo.file_history"}}
|
||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{$treeNamesLen := len .TreeNames}}
|
|
||||||
{{$isTreePathRoot := eq $treeNamesLen 0}}
|
|
||||||
|
|
||||||
{{if .IsViewFile}}
|
{{if .IsViewFile}}
|
||||||
{{template "repo/view_file" .}}
|
{{template "repo/view_file" .}}
|
||||||
{{else if .IsBlame}}
|
{{else if .IsBlame}}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<a class="issue-card-title muted issue-title tw-break-anywhere" href="{{.Link}}">{{.Title | ctx.RenderUtils.RenderIssueSimpleTitle}}</a>
|
<a class="issue-card-title muted issue-title tw-break-anywhere" href="{{.Link}}">{{.Title | ctx.RenderUtils.RenderIssueSimpleTitle}}</a>
|
||||||
{{if and $.isPinnedIssueCard $.Page.IsRepoAdmin}}
|
{{if and $.isPinnedIssueCard $.Page.IsRepoAdmin}}
|
||||||
<a role="button" class="issue-card-unpin muted tw-flex tw-items-center" data-tooltip-content={{ctx.Locale.Tr "repo.issues.unpin_issue"}} data-issue-id="{{.ID}}" data-unpin-url="{{$.Page.Link}}/unpin/{{.Index}}">
|
<a role="button" class="issue-card-unpin muted tw-flex tw-items-center" data-tooltip-content={{ctx.Locale.Tr "repo.issues.unpin"}} data-issue-id="{{.ID}}" data-unpin-url="{{$.Page.Link}}/unpin/{{.Index}}">
|
||||||
{{svg "octicon-x" 16}}
|
{{svg "octicon-x" 16}}
|
||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="stats-table">
|
<div class="stats-table">
|
||||||
<a class="table-cell tiny background light grey"></a>
|
<a class="table-cell tiny tw-bg-grey"></a>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{ctx.Locale.TrN .Activity.ActiveIssueCount "repo.activity.active_issues_count_1" "repo.activity.active_issues_count_n" .Activity.ActiveIssueCount}}
|
{{ctx.Locale.TrN .Activity.ActiveIssueCount "repo.activity.active_issues_count_1" "repo.activity.active_issues_count_n" .Activity.ActiveIssueCount}}
|
||||||
|
@ -48,58 +48,58 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{if .RepoOwnerIsOrganization}}
|
{{if $.Repository.Owner.IsOrganization}}
|
||||||
<h4 class="ui top attached header">
|
<h4 class="ui top attached header">
|
||||||
{{ctx.Locale.Tr "repo.settings.teams"}}
|
{{ctx.Locale.Tr "repo.settings.teams"}}
|
||||||
</h4>
|
</h4>
|
||||||
{{$allowedToChangeTeams := (or (.Org.RepoAdminChangeTeamAccess) (.Permission.IsOwner))}}
|
{{$allowedToChangeTeams := (or (.Org.RepoAdminChangeTeamAccess) (.Permission.IsOwner))}}
|
||||||
{{if .Teams}}
|
{{if .Teams}}
|
||||||
<div class="ui attached segment">
|
<div class="ui attached segment">
|
||||||
<div class="flex-list">
|
<div class="flex-list">
|
||||||
{{range $t, $team := .Teams}}
|
{{range $t, $team := .Teams}}
|
||||||
<div class="flex-item">
|
<div class="flex-item">
|
||||||
<div class="flex-item-main">
|
<div class="flex-item-main">
|
||||||
<a class="flex-item-title text primary" href="{{AppSubUrl}}/org/{{$.OrgName|PathEscape}}/teams/{{.LowerName|PathEscape}}">
|
<a class="flex-item-title text primary" href="{{AppSubUrl}}/org/{{$.OrgName|PathEscape}}/teams/{{.LowerName|PathEscape}}">
|
||||||
{{.Name}}
|
{{.Name}}
|
||||||
</a>
|
</a>
|
||||||
<div class="flex-item-body flex-text-block">
|
<div class="flex-item-body flex-text-block">
|
||||||
{{svg "octicon-shield-lock"}}
|
{{svg "octicon-shield-lock"}}
|
||||||
{{if eq .AccessMode 1}}{{ctx.Locale.Tr "repo.settings.collaboration.read"}}{{else if eq .AccessMode 2}}{{ctx.Locale.Tr "repo.settings.collaboration.write"}}{{else if eq .AccessMode 3}}{{ctx.Locale.Tr "repo.settings.collaboration.admin"}}{{else if eq .AccessMode 4}}{{ctx.Locale.Tr "repo.settings.collaboration.owner"}}{{else}}{{ctx.Locale.Tr "repo.settings.collaboration.undefined"}}{{end}}
|
{{if eq .AccessMode 1}}{{ctx.Locale.Tr "repo.settings.collaboration.read"}}{{else if eq .AccessMode 2}}{{ctx.Locale.Tr "repo.settings.collaboration.write"}}{{else if eq .AccessMode 3}}{{ctx.Locale.Tr "repo.settings.collaboration.admin"}}{{else if eq .AccessMode 4}}{{ctx.Locale.Tr "repo.settings.collaboration.owner"}}{{else}}{{ctx.Locale.Tr "repo.settings.collaboration.undefined"}}{{end}}
|
||||||
|
</div>
|
||||||
|
{{if or (eq .AccessMode 1) (eq .AccessMode 2)}}
|
||||||
|
{{$first := true}}
|
||||||
|
<div class="flex-item-body" data-tooltip-content="{{ctx.Locale.Tr "repo.settings.change_team_permission_tip"}}">
|
||||||
|
Sections: {{range $u, $unit := $.Units}}{{if and ($.Repo.UnitEnabled ctx $unit.Type) ($team.UnitEnabled ctx $unit.Type)}}{{if $first}}{{$first = false}}{{else}}, {{end}}{{ctx.Locale.Tr $unit.NameKey}}{{end}}{{end}} {{if $first}}None{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{if or (eq .AccessMode 1) (eq .AccessMode 2)}}
|
{{if $allowedToChangeTeams}}
|
||||||
{{$first := true}}
|
<div class="flex-item-trailing" {{if .IncludesAllRepositories}} data-tooltip-content="{{ctx.Locale.Tr "repo.settings.delete_team_tip"}}"{{end}}>
|
||||||
<div class="flex-item-body" data-tooltip-content="{{ctx.Locale.Tr "repo.settings.change_team_permission_tip"}}">
|
<button class="ui red tiny button inline delete-button {{if .IncludesAllRepositories}}disabled{{end}}" data-url="{{$.Link}}/team/delete" data-id="{{.ID}}">
|
||||||
Sections: {{range $u, $unit := $.Units}}{{if and ($.Repo.UnitEnabled ctx $unit.Type) ($team.UnitEnabled ctx $unit.Type)}}{{if $first}}{{$first = false}}{{else}}, {{end}}{{ctx.Locale.Tr $unit.NameKey}}{{end}}{{end}} {{if $first}}None{{end}}
|
{{ctx.Locale.Tr "repo.settings.delete_collaborator"}}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{if $allowedToChangeTeams}}
|
{{end}}
|
||||||
<div class="flex-item-trailing" {{if .IncludesAllRepositories}} data-tooltip-content="{{ctx.Locale.Tr "repo.settings.delete_team_tip"}}"{{end}}>
|
</div>
|
||||||
<button class="ui red tiny button inline delete-button {{if .IncludesAllRepositories}}disabled{{end}}" data-url="{{$.Link}}/team/delete" data-id="{{.ID}}">
|
</div>
|
||||||
{{ctx.Locale.Tr "repo.settings.delete_collaborator"}}
|
{{end}}
|
||||||
</button>
|
<div class="ui bottom attached segment">
|
||||||
</div>
|
{{if $allowedToChangeTeams}}
|
||||||
{{end}}
|
<form class="ui form" id="repo-collab-team-form" action="{{.Link}}/team" method="post">
|
||||||
|
{{.CsrfTokenHtml}}
|
||||||
|
<div id="search-team-box" class="ui search input tw-align-middle" data-org-name="{{.OrgName}}">
|
||||||
|
<input class="prompt" name="team" placeholder="{{ctx.Locale.Tr "search.team_kind"}}" autocomplete="off" autofocus required>
|
||||||
|
</div>
|
||||||
|
<button class="ui primary button">{{ctx.Locale.Tr "repo.settings.add_team"}}</button>
|
||||||
|
</form>
|
||||||
|
{{else}}
|
||||||
|
<div class="item">
|
||||||
|
{{ctx.Locale.Tr "repo.settings.change_team_access_not_allowed"}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
<div class="ui bottom attached segment">
|
|
||||||
{{if $allowedToChangeTeams}}
|
|
||||||
<form class="ui form" id="repo-collab-team-form" action="{{.Link}}/team" method="post">
|
|
||||||
{{.CsrfTokenHtml}}
|
|
||||||
<div id="search-team-box" class="ui search input tw-align-middle" data-org-name="{{.OrgName}}">
|
|
||||||
<input class="prompt" name="team" placeholder="{{ctx.Locale.Tr "search.team_kind"}}" autocomplete="off" autofocus required>
|
|
||||||
</div>
|
|
||||||
<button class="ui primary button">{{ctx.Locale.Tr "repo.settings.add_team"}}</button>
|
|
||||||
</form>
|
|
||||||
{{else}}
|
|
||||||
<div class="item">
|
|
||||||
{{ctx.Locale.Tr "repo.settings.change_team_access_not_allowed"}}
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
</div>
|
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
{{range .LFSFiles}}
|
{{range .LFSFiles}}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{$.Link}}/show/{{.Oid}}" title="{{.Oid}}" class="ui brown button tw-font-mono">
|
<a href="{{$.Link}}/show/{{.Oid}}" title="{{.Oid}}" class="ui button tw-font-mono">
|
||||||
{{ShortSha .Oid}}
|
{{ShortSha .Oid}}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="ui segments repository-summary tw-mt-1 tw-mb-0">
|
<div class="ui segments repository-summary tw-mt-1 tw-mb-0">
|
||||||
<div class="ui segment sub-menu repository-menu">
|
<div class="ui segment sub-menu repository-menu">
|
||||||
{{if and (.Permission.CanRead ctx.Consts.RepoUnitTypeCode) (not .IsEmptyRepo)}}
|
{{if and (.Permission.CanRead ctx.Consts.RepoUnitTypeCode) (not .IsEmptyRepo)}}
|
||||||
<a class="item muted {{if .PageIsCommits}}active{{end}}" href="{{.RepoLink}}/commits/{{.BranchNameSubURL}}">
|
<a class="item muted {{if .PageIsCommits}}active{{end}}" href="{{.RepoLink}}/commits/{{.RefTypeNameSubURL}}">
|
||||||
{{svg "octicon-history"}} <b>{{ctx.Locale.PrettyNumber .CommitsCount}}</b> {{ctx.Locale.TrN .CommitsCount "repo.commit" "repo.commits"}}
|
{{svg "octicon-history"}} <b>{{ctx.Locale.PrettyNumber .CommitsCount}}</b> {{ctx.Locale.TrN .CommitsCount "repo.commit" "repo.commits"}}
|
||||||
</a>
|
</a>
|
||||||
<a class="item muted {{if .PageIsBranches}}active{{end}}" href="{{.RepoLink}}/branches">
|
<a class="item muted {{if .PageIsBranches}}active{{end}}" href="{{.RepoLink}}/branches">
|
||||||
|
@ -46,9 +46,9 @@
|
|||||||
<a class="ui mini basic button" href="{{.RepoLink}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}">{{ctx.Locale.Tr "repo.file_permalink"}}</a>
|
<a class="ui mini basic button" href="{{.RepoLink}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}">{{ctx.Locale.Tr "repo.file_permalink"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .IsRepresentableAsText}}
|
{{if .IsRepresentableAsText}}
|
||||||
<a class="ui mini basic button" href="{{.RepoLink}}/blame/{{.BranchNameSubURL}}/{{PathEscapeSegments .TreePath}}">{{ctx.Locale.Tr "repo.blame"}}</a>
|
<a class="ui mini basic button" href="{{.RepoLink}}/blame/{{.RefTypeNameSubURL}}/{{PathEscapeSegments .TreePath}}">{{ctx.Locale.Tr "repo.blame"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
<a class="ui mini basic button" href="{{.RepoLink}}/commits/{{.BranchNameSubURL}}/{{PathEscapeSegments .TreePath}}">{{ctx.Locale.Tr "repo.file_history"}}</a>
|
<a class="ui mini basic button" href="{{.RepoLink}}/commits/{{.RefTypeNameSubURL}}/{{PathEscapeSegments .TreePath}}">{{ctx.Locale.Tr "repo.file_history"}}</a>
|
||||||
{{if .EscapeStatus.Escaped}}
|
{{if .EscapeStatus.Escaped}}
|
||||||
<button class="ui mini basic button unescape-button tw-hidden">{{ctx.Locale.Tr "repo.unescape_control_characters"}}</button>
|
<button class="ui mini basic button unescape-button tw-hidden">{{ctx.Locale.Tr "repo.unescape_control_characters"}}</button>
|
||||||
<button class="ui mini basic button escape-button">{{ctx.Locale.Tr "repo.escape_control_characters"}}</button>
|
<button class="ui mini basic button escape-button">{{ctx.Locale.Tr "repo.escape_control_characters"}}</button>
|
||||||
@ -57,7 +57,7 @@
|
|||||||
<a download class="btn-octicon" data-tooltip-content="{{ctx.Locale.Tr "repo.download_file"}}" href="{{$.RawFileLink}}">{{svg "octicon-download"}}</a>
|
<a download class="btn-octicon" data-tooltip-content="{{ctx.Locale.Tr "repo.download_file"}}" href="{{$.RawFileLink}}">{{svg "octicon-download"}}</a>
|
||||||
<a id="copy-content" class="btn-octicon {{if not .CanCopyContent}} disabled{{end}}"{{if or .IsImageFile (and .HasSourceRenderedToggle (not .IsDisplayingSource))}} data-link="{{$.RawFileLink}}"{{end}} data-tooltip-content="{{if .CanCopyContent}}{{ctx.Locale.Tr "copy_content"}}{{else}}{{ctx.Locale.Tr "copy_type_unsupported"}}{{end}}">{{svg "octicon-copy"}}</a>
|
<a id="copy-content" class="btn-octicon {{if not .CanCopyContent}} disabled{{end}}"{{if or .IsImageFile (and .HasSourceRenderedToggle (not .IsDisplayingSource))}} data-link="{{$.RawFileLink}}"{{end}} data-tooltip-content="{{if .CanCopyContent}}{{ctx.Locale.Tr "copy_content"}}{{else}}{{ctx.Locale.Tr "copy_type_unsupported"}}{{end}}">{{svg "octicon-copy"}}</a>
|
||||||
{{if .EnableFeed}}
|
{{if .EnableFeed}}
|
||||||
<a class="btn-octicon" href="{{$.FeedURL}}/rss/{{$.BranchNameSubURL}}/{{PathEscapeSegments .TreePath}}" data-tooltip-content="{{ctx.Locale.Tr "rss_feed"}}">
|
<a class="btn-octicon" href="{{$.RepoLink}}/rss/{{$.RefTypeNameSubURL}}/{{PathEscapeSegments .TreePath}}" data-tooltip-content="{{ctx.Locale.Tr "rss_feed"}}">
|
||||||
{{svg "octicon-rss"}}
|
{{svg "octicon-rss"}}
|
||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<div id="view-file-tree" class="is-loading"
|
<div id="view-file-tree" class="is-loading"
|
||||||
data-api-base-url="{{.RepoLink}}"
|
data-api-base-url="{{.RepoLink}}"
|
||||||
data-tree-path="{{$.TreePath}}"
|
data-tree-path="{{$.TreePath}}"
|
||||||
data-current-ref-type="{{.RefType}}"
|
data-current-ref-type="{{.RefFullName.RefType}}"
|
||||||
data-current-ref-short-name="{{.RefShortName}}"
|
data-current-ref-short-name="{{.RefFullName.ShortName}}"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
{{if .IsRepositoryAdmin}}<div>{{ctx.Locale.Tr "repo.default_branch"}}: {{.Repository.DefaultWikiBranch}}</div>{{end}}
|
{{if $.Permission.IsAdmin}}<div>{{ctx.Locale.Tr "repo.default_branch"}}: {{.Repository.DefaultWikiBranch}}</div>{{end}}
|
||||||
<table class="ui table wiki-pages-list">
|
<table class="ui table wiki-pages-list">
|
||||||
<tbody>
|
<tbody>
|
||||||
{{range .Pages}}
|
{{range .Pages}}
|
||||||
|
@ -60,7 +60,9 @@ func TestEmptyRepoAddFile(t *testing.T) {
|
|||||||
session := loginUser(t, "user30")
|
session := loginUser(t, "user30")
|
||||||
req := NewRequest(t, "GET", "/user30/empty")
|
req := NewRequest(t, "GET", "/user30/empty")
|
||||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.Contains(t, resp.Body.String(), "empty-repo-guide")
|
bodyString := resp.Body.String()
|
||||||
|
assert.Contains(t, bodyString, "empty-repo-guide")
|
||||||
|
assert.True(t, test.IsNormalPageCompleted(bodyString))
|
||||||
|
|
||||||
req = NewRequest(t, "GET", "/user30/empty/_new/"+setting.Repository.DefaultBranch)
|
req = NewRequest(t, "GET", "/user30/empty/_new/"+setting.Repository.DefaultBranch)
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
@ -405,11 +405,6 @@ a.label,
|
|||||||
color: var(--color-text-light-2);
|
color: var(--color-text-light-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.form textarea:not([rows]) {
|
|
||||||
height: var(--min-height-textarea); /* override fomantic default 12em */
|
|
||||||
min-height: var(--min-height-textarea); /* override fomantic default 8em */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* styles from removed fomantic transition module */
|
/* styles from removed fomantic transition module */
|
||||||
.hidden.transition {
|
.hidden.transition {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
@ -511,97 +506,6 @@ img.ui.avatar,
|
|||||||
margin-top: calc(var(--page-spacing) - 1rem);
|
margin-top: calc(var(--page-spacing) - 1rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.form .fields.error .field textarea,
|
|
||||||
.ui.form .fields.error .field select,
|
|
||||||
.ui.form .fields.error .field input:not([type]),
|
|
||||||
.ui.form .fields.error .field input[type="date"],
|
|
||||||
.ui.form .fields.error .field input[type="datetime-local"],
|
|
||||||
.ui.form .fields.error .field input[type="email"],
|
|
||||||
.ui.form .fields.error .field input[type="number"],
|
|
||||||
.ui.form .fields.error .field input[type="password"],
|
|
||||||
.ui.form .fields.error .field input[type="search"],
|
|
||||||
.ui.form .fields.error .field input[type="tel"],
|
|
||||||
.ui.form .fields.error .field input[type="time"],
|
|
||||||
.ui.form .fields.error .field input[type="text"],
|
|
||||||
.ui.form .fields.error .field input[type="file"],
|
|
||||||
.ui.form .fields.error .field input[type="url"],
|
|
||||||
.ui.form .fields.error .field .ui.dropdown,
|
|
||||||
.ui.form .fields.error .field .ui.dropdown .item,
|
|
||||||
.ui.form .field.error .ui.dropdown,
|
|
||||||
.ui.form .field.error .ui.dropdown .text,
|
|
||||||
.ui.form .field.error .ui.dropdown .item,
|
|
||||||
.ui.form .field.error textarea,
|
|
||||||
.ui.form .field.error select,
|
|
||||||
.ui.form .field.error input:not([type]),
|
|
||||||
.ui.form .field.error input[type="date"],
|
|
||||||
.ui.form .field.error input[type="datetime-local"],
|
|
||||||
.ui.form .field.error input[type="email"],
|
|
||||||
.ui.form .field.error input[type="number"],
|
|
||||||
.ui.form .field.error input[type="password"],
|
|
||||||
.ui.form .field.error input[type="search"],
|
|
||||||
.ui.form .field.error input[type="tel"],
|
|
||||||
.ui.form .field.error input[type="time"],
|
|
||||||
.ui.form .field.error input[type="text"],
|
|
||||||
.ui.form .field.error input[type="file"],
|
|
||||||
.ui.form .field.error input[type="url"],
|
|
||||||
.ui.form .field.error select:focus,
|
|
||||||
.ui.form .field.error input:not([type]):focus,
|
|
||||||
.ui.form .field.error input[type="date"]:focus,
|
|
||||||
.ui.form .field.error input[type="datetime-local"]:focus,
|
|
||||||
.ui.form .field.error input[type="email"]:focus,
|
|
||||||
.ui.form .field.error input[type="number"]:focus,
|
|
||||||
.ui.form .field.error input[type="password"]:focus,
|
|
||||||
.ui.form .field.error input[type="search"]:focus,
|
|
||||||
.ui.form .field.error input[type="tel"]:focus,
|
|
||||||
.ui.form .field.error input[type="time"]:focus,
|
|
||||||
.ui.form .field.error input[type="text"]:focus,
|
|
||||||
.ui.form .field.error input[type="file"]:focus,
|
|
||||||
.ui.form .field.error input[type="url"]:focus {
|
|
||||||
background-color: var(--color-error-bg);
|
|
||||||
border-color: var(--color-error-border);
|
|
||||||
color: var(--color-error-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui.form .fields.error .field .ui.dropdown,
|
|
||||||
.ui.form .field.error .ui.dropdown,
|
|
||||||
.ui.form .fields.error .field .ui.dropdown:hover,
|
|
||||||
.ui.form .field.error .ui.dropdown:hover {
|
|
||||||
border-color: var(--color-error-border) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui.form .fields.error .field .ui.dropdown .menu .item:hover,
|
|
||||||
.ui.form .field.error .ui.dropdown .menu .item:hover {
|
|
||||||
background-color: var(--color-error-bg-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui.form .fields.error .field .ui.dropdown .menu .active.item,
|
|
||||||
.ui.form .field.error .ui.dropdown .menu .active.item {
|
|
||||||
background-color: var(--color-error-bg-active) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui.form .fields.error .dropdown .menu,
|
|
||||||
.ui.form .field.error .dropdown .menu {
|
|
||||||
border-color: var(--color-error-border) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:-webkit-autofill,
|
|
||||||
input:-webkit-autofill:focus,
|
|
||||||
input:-webkit-autofill:hover,
|
|
||||||
input:-webkit-autofill:active,
|
|
||||||
.ui.form .field.field input:-webkit-autofill,
|
|
||||||
.ui.form .field.field input:-webkit-autofill:focus,
|
|
||||||
.ui.form .field.field input:-webkit-autofill:hover,
|
|
||||||
.ui.form .field.field input:-webkit-autofill:active {
|
|
||||||
-webkit-background-clip: text;
|
|
||||||
-webkit-text-fill-color: var(--color-text);
|
|
||||||
box-shadow: 0 0 0 100px var(--color-primary-light-6) inset !important;
|
|
||||||
border-color: var(--color-primary-light-4) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui.form .field.muted {
|
|
||||||
opacity: var(--opacity-disabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
.text.primary {
|
.text.primary {
|
||||||
color: var(--color-primary) !important;
|
color: var(--color-primary) !important;
|
||||||
}
|
}
|
||||||
@ -618,38 +522,18 @@ input:-webkit-autofill:active,
|
|||||||
color: var(--color-yellow) !important;
|
color: var(--color-yellow) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text.olive {
|
|
||||||
color: var(--color-olive) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text.green {
|
.text.green {
|
||||||
color: var(--color-green) !important;
|
color: var(--color-green) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text.teal {
|
|
||||||
color: var(--color-teal) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text.blue {
|
.text.blue {
|
||||||
color: var(--color-blue) !important;
|
color: var(--color-blue) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text.violet {
|
|
||||||
color: var(--color-violet) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text.purple {
|
.text.purple {
|
||||||
color: var(--color-purple) !important;
|
color: var(--color-purple) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text.pink {
|
|
||||||
color: var(--color-pink) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text.brown {
|
|
||||||
color: var(--color-brown) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text.black {
|
.text.black {
|
||||||
color: var(--color-text) !important;
|
color: var(--color-text) !important;
|
||||||
}
|
}
|
||||||
@ -727,18 +611,6 @@ input:-webkit-autofill:active,
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui .form .autofill-dummy {
|
|
||||||
position: absolute;
|
|
||||||
width: 1px;
|
|
||||||
height: 1px;
|
|
||||||
overflow: hidden;
|
|
||||||
z-index: -10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .form .sub.field {
|
|
||||||
margin-left: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .sha.label {
|
.ui .sha.label {
|
||||||
font-family: var(--fonts-monospace);
|
font-family: var(--fonts-monospace);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
@ -766,46 +638,6 @@ input:-webkit-autofill:active,
|
|||||||
font-weight: var(--font-weight-normal);
|
font-weight: var(--font-weight-normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui .background.red {
|
|
||||||
background-color: var(--color-red) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .background.blue {
|
|
||||||
background-color: var(--color-blue) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .background.black {
|
|
||||||
background-color: var(--color-black) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .background.grey {
|
|
||||||
background-color: var(--color-grey) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .background.light.grey {
|
|
||||||
background-color: var(--color-grey) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .background.green {
|
|
||||||
background-color: var(--color-green) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .background.purple {
|
|
||||||
background-color: var(--color-purple) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .background.yellow {
|
|
||||||
background-color: var(--color-yellow) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .background.orange {
|
|
||||||
background-color: var(--color-orange) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .background.gold {
|
|
||||||
background-color: var(--color-gold) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .migrate {
|
.ui .migrate {
|
||||||
color: var(--color-text-light-2) !important;
|
color: var(--color-text-light-2) !important;
|
||||||
}
|
}
|
||||||
@ -822,46 +654,6 @@ input:-webkit-autofill:active,
|
|||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui .border.red {
|
|
||||||
border-color: var(--color-red) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .border.blue {
|
|
||||||
border-color: var(--color-blue) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .border.black {
|
|
||||||
border-color: var(--color-black) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .border.grey {
|
|
||||||
border-color: var(--color-grey) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .border.light.grey {
|
|
||||||
border-color: var(--color-grey) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .border.green {
|
|
||||||
border-color: var(--color-green) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .border.purple {
|
|
||||||
border-color: var(--color-purple) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .border.yellow {
|
|
||||||
border-color: var(--color-yellow) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .border.orange {
|
|
||||||
border-color: var(--color-orange) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui .border.gold {
|
|
||||||
border-color: var(--color-gold) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ui.floating.dropdown .overflow.menu .scrolling.menu.items {
|
.ui.floating.dropdown .overflow.menu .scrolling.menu.items {
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
|
@ -1,3 +1,111 @@
|
|||||||
|
.ui .form .autofill-dummy {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: -10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui .form .sub.field {
|
||||||
|
margin-left: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui.form .fields.error .field textarea,
|
||||||
|
.ui.form .fields.error .field select,
|
||||||
|
.ui.form .fields.error .field input:not([type]),
|
||||||
|
.ui.form .fields.error .field input[type="date"],
|
||||||
|
.ui.form .fields.error .field input[type="datetime-local"],
|
||||||
|
.ui.form .fields.error .field input[type="email"],
|
||||||
|
.ui.form .fields.error .field input[type="number"],
|
||||||
|
.ui.form .fields.error .field input[type="password"],
|
||||||
|
.ui.form .fields.error .field input[type="search"],
|
||||||
|
.ui.form .fields.error .field input[type="tel"],
|
||||||
|
.ui.form .fields.error .field input[type="time"],
|
||||||
|
.ui.form .fields.error .field input[type="text"],
|
||||||
|
.ui.form .fields.error .field input[type="file"],
|
||||||
|
.ui.form .fields.error .field input[type="url"],
|
||||||
|
.ui.form .fields.error .field .ui.dropdown,
|
||||||
|
.ui.form .fields.error .field .ui.dropdown .item,
|
||||||
|
.ui.form .field.error .ui.dropdown,
|
||||||
|
.ui.form .field.error .ui.dropdown .text,
|
||||||
|
.ui.form .field.error .ui.dropdown .item,
|
||||||
|
.ui.form .field.error textarea,
|
||||||
|
.ui.form .field.error select,
|
||||||
|
.ui.form .field.error input:not([type]),
|
||||||
|
.ui.form .field.error input[type="date"],
|
||||||
|
.ui.form .field.error input[type="datetime-local"],
|
||||||
|
.ui.form .field.error input[type="email"],
|
||||||
|
.ui.form .field.error input[type="number"],
|
||||||
|
.ui.form .field.error input[type="password"],
|
||||||
|
.ui.form .field.error input[type="search"],
|
||||||
|
.ui.form .field.error input[type="tel"],
|
||||||
|
.ui.form .field.error input[type="time"],
|
||||||
|
.ui.form .field.error input[type="text"],
|
||||||
|
.ui.form .field.error input[type="file"],
|
||||||
|
.ui.form .field.error input[type="url"],
|
||||||
|
.ui.form .field.error select:focus,
|
||||||
|
.ui.form .field.error input:not([type]):focus,
|
||||||
|
.ui.form .field.error input[type="date"]:focus,
|
||||||
|
.ui.form .field.error input[type="datetime-local"]:focus,
|
||||||
|
.ui.form .field.error input[type="email"]:focus,
|
||||||
|
.ui.form .field.error input[type="number"]:focus,
|
||||||
|
.ui.form .field.error input[type="password"]:focus,
|
||||||
|
.ui.form .field.error input[type="search"]:focus,
|
||||||
|
.ui.form .field.error input[type="tel"]:focus,
|
||||||
|
.ui.form .field.error input[type="time"]:focus,
|
||||||
|
.ui.form .field.error input[type="text"]:focus,
|
||||||
|
.ui.form .field.error input[type="file"]:focus,
|
||||||
|
.ui.form .field.error input[type="url"]:focus {
|
||||||
|
background-color: var(--color-error-bg);
|
||||||
|
border-color: var(--color-error-border);
|
||||||
|
color: var(--color-error-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui.form .fields.error .field .ui.dropdown,
|
||||||
|
.ui.form .field.error .ui.dropdown,
|
||||||
|
.ui.form .fields.error .field .ui.dropdown:hover,
|
||||||
|
.ui.form .field.error .ui.dropdown:hover {
|
||||||
|
border-color: var(--color-error-border) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui.form .fields.error .field .ui.dropdown .menu .item:hover,
|
||||||
|
.ui.form .field.error .ui.dropdown .menu .item:hover {
|
||||||
|
background-color: var(--color-error-bg-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui.form .fields.error .field .ui.dropdown .menu .active.item,
|
||||||
|
.ui.form .field.error .ui.dropdown .menu .active.item {
|
||||||
|
background-color: var(--color-error-bg-active) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui.form .fields.error .dropdown .menu,
|
||||||
|
.ui.form .field.error .dropdown .menu {
|
||||||
|
border-color: var(--color-error-border) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:-webkit-autofill,
|
||||||
|
input:-webkit-autofill:focus,
|
||||||
|
input:-webkit-autofill:hover,
|
||||||
|
input:-webkit-autofill:active,
|
||||||
|
.ui.form .field.field input:-webkit-autofill,
|
||||||
|
.ui.form .field.field input:-webkit-autofill:focus,
|
||||||
|
.ui.form .field.field input:-webkit-autofill:hover,
|
||||||
|
.ui.form .field.field input:-webkit-autofill:active {
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: var(--color-text);
|
||||||
|
box-shadow: 0 0 0 100px var(--color-primary-light-6) inset !important;
|
||||||
|
border-color: var(--color-primary-light-4) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui.form .field.muted {
|
||||||
|
opacity: var(--opacity-disabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui.form textarea:not([rows]) {
|
||||||
|
height: var(--min-height-textarea); /* override fomantic default 12em */
|
||||||
|
min-height: var(--min-height-textarea); /* override fomantic default 8em */
|
||||||
|
}
|
||||||
|
|
||||||
.ui.input textarea,
|
.ui.input textarea,
|
||||||
.ui.form textarea,
|
.ui.form textarea,
|
||||||
.ui.form input:not([type]),
|
.ui.form input:not([type]),
|
||||||
|
@ -38,9 +38,6 @@ export function initRepoEditor() {
|
|||||||
const dropzoneUpload = document.querySelector<HTMLElement>('.page-content.repository.editor.upload .dropzone');
|
const dropzoneUpload = document.querySelector<HTMLElement>('.page-content.repository.editor.upload .dropzone');
|
||||||
if (dropzoneUpload) initDropzone(dropzoneUpload);
|
if (dropzoneUpload) initDropzone(dropzoneUpload);
|
||||||
|
|
||||||
const editArea = document.querySelector<HTMLTextAreaElement>('.page-content.repository.editor textarea#edit_area');
|
|
||||||
if (!editArea) return;
|
|
||||||
|
|
||||||
for (const el of queryElems<HTMLInputElement>(document, '.js-quick-pull-choice-option')) {
|
for (const el of queryElems<HTMLInputElement>(document, '.js-quick-pull-choice-option')) {
|
||||||
el.addEventListener('input', () => {
|
el.addEventListener('input', () => {
|
||||||
if (el.value === 'commit-to-new-branch') {
|
if (el.value === 'commit-to-new-branch') {
|
||||||
@ -55,6 +52,7 @@ export function initRepoEditor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const filenameInput = document.querySelector<HTMLInputElement>('#file-name');
|
const filenameInput = document.querySelector<HTMLInputElement>('#file-name');
|
||||||
|
if (!filenameInput) return;
|
||||||
function joinTreePath() {
|
function joinTreePath() {
|
||||||
const parts = [];
|
const parts = [];
|
||||||
for (const el of document.querySelectorAll('.breadcrumb span.section')) {
|
for (const el of document.querySelectorAll('.breadcrumb span.section')) {
|
||||||
@ -144,6 +142,10 @@ export function initRepoEditor() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// on the upload page, there is no editor(textarea)
|
||||||
|
const editArea = document.querySelector<HTMLTextAreaElement>('.page-content.repository.editor textarea#edit_area');
|
||||||
|
if (!editArea) return;
|
||||||
|
|
||||||
const elForm = document.querySelector<HTMLFormElement>('.repository.editor .edit.form');
|
const elForm = document.querySelector<HTMLFormElement>('.repository.editor .edit.form');
|
||||||
initEditPreviewTab(elForm);
|
initEditPreviewTab(elForm);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user