diff --git a/models/issues/comment.go b/models/issues/comment.go
index a7ec8f57fc412..a2487088205f3 100644
--- a/models/issues/comment.go
+++ b/models/issues/comment.go
@@ -112,8 +112,8 @@ const (
CommentTypePRScheduledToAutoMerge // 34 pr was scheduled to auto merge when checks succeed
CommentTypePRUnScheduledToAutoMerge // 35 pr was un scheduled to auto merge when checks succeed
- CommentTypePin // 36 pin Issue
- CommentTypeUnpin // 37 unpin Issue
+ CommentTypePin // 36 pin Issue/PullRequest
+ CommentTypeUnpin // 37 unpin Issue/PullRequest
CommentTypeChangeTimeEstimate // 38 Change time estimate
)
diff --git a/models/repo/archiver.go b/models/repo/archiver.go
index 14ffa1d89b120..5a3eac9f148c0 100644
--- a/models/repo/archiver.go
+++ b/models/repo/archiver.go
@@ -56,16 +56,11 @@ func repoArchiverForRelativePath(relativePath string) (*RepoArchiver, error) {
if err != nil {
return nil, util.SilentWrap{Message: fmt.Sprintf("invalid storage path: %s", relativePath), Err: util.ErrInvalidArgument}
}
- nameExts := strings.SplitN(parts[2], ".", 2)
- if len(nameExts) != 2 {
+ commitID, archiveType := git.SplitArchiveNameType(parts[2])
+ if archiveType == git.ArchiveUnknown {
return nil, util.SilentWrap{Message: fmt.Sprintf("invalid storage path: %s", relativePath), Err: util.ErrInvalidArgument}
}
-
- return &RepoArchiver{
- RepoID: repoID,
- CommitID: parts[1] + nameExts[0],
- Type: git.ToArchiveType(nameExts[1]),
- }, nil
+ return &RepoArchiver{RepoID: repoID, CommitID: commitID, Type: archiveType}, nil
}
// GetRepoArchiver get an archiver
diff --git a/modules/cache/cache.go b/modules/cache/cache.go
index b5400b0bd6a14..f7828e3cae2df 100644
--- a/modules/cache/cache.go
+++ b/modules/cache/cache.go
@@ -37,10 +37,15 @@ func Init() error {
}
const (
- testCacheKey = "DefaultCache.TestKey"
- SlowCacheThreshold = 100 * time.Microsecond
+ testCacheKey = "DefaultCache.TestKey"
+ // 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) {
if defaultCache == nil {
return 0, fmt.Errorf("default cache not initialized")
diff --git a/modules/cache/cache_test.go b/modules/cache/cache_test.go
index d0352947a831a..5408020306b38 100644
--- a/modules/cache/cache_test.go
+++ b/modules/cache/cache_test.go
@@ -43,7 +43,8 @@ func TestTest(t *testing.T) {
elapsed, err := Test()
assert.NoError(t, err)
// 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) {
diff --git a/modules/git/ref.go b/modules/git/ref.go
index aab4c5d77d75c..051b75a15a1d5 100644
--- a/modules/git/ref.go
+++ b/modules/git/ref.go
@@ -80,6 +80,10 @@ func RefNameFromTag(shortName string) RefName {
return RefName(TagPrefix + shortName)
}
+func RefNameFromCommit(shortName string) RefName {
+ return RefName(shortName)
+}
+
func (ref RefName) String() string {
return string(ref)
}
diff --git a/modules/git/ref_test.go b/modules/git/ref_test.go
index 58f679b7d6ee8..1fd33b5163ead 100644
--- a/modules/git/ref_test.go
+++ b/modules/git/ref_test.go
@@ -20,6 +20,8 @@ func TestRefName(t *testing.T) {
// Test pull names
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())
// Test for branch names
diff --git a/modules/git/repo_archive.go b/modules/git/repo_archive.go
index 2b45a50f191b6..92f3e88f7cdcb 100644
--- a/modules/git/repo_archive.go
+++ b/modules/git/repo_archive.go
@@ -16,37 +16,35 @@ import (
type ArchiveType int
const (
- // ZIP zip archive type
- ZIP ArchiveType = iota + 1
- // TARGZ tar gz archive type
- TARGZ
- // BUNDLE bundle archive type
- BUNDLE
+ ArchiveUnknown ArchiveType = iota
+ ArchiveZip // 1
+ ArchiveTarGz // 2
+ ArchiveBundle // 3
)
-// 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 {
switch a {
- case ZIP:
+ case ArchiveZip:
return "zip"
- case TARGZ:
+ case ArchiveTarGz:
return "tar.gz"
- case BUNDLE:
+ case ArchiveBundle:
return "bundle"
}
return "unknown"
}
-func ToArchiveType(s string) ArchiveType {
- switch s {
- case "zip":
- return ZIP
- case "tar.gz":
- return TARGZ
- case "bundle":
- return BUNDLE
+func SplitArchiveNameType(s string) (string, ArchiveType) {
+ switch {
+ case strings.HasSuffix(s, ".zip"):
+ return strings.TrimSuffix(s, ".zip"), ArchiveZip
+ case strings.HasSuffix(s, ".tar.gz"):
+ return strings.TrimSuffix(s, ".tar.gz"), ArchiveTarGz
+ case strings.HasSuffix(s, ".bundle"):
+ return strings.TrimSuffix(s, ".bundle"), ArchiveBundle
}
- return 0
+ return s, ArchiveUnknown
}
// CreateArchive create archive content to the target path
diff --git a/modules/git/repo_archive_test.go b/modules/git/repo_archive_test.go
new file mode 100644
index 0000000000000..ff7e2dfce1b50
--- /dev/null
+++ b/modules/git/repo_archive_test.go
@@ -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())
+}
diff --git a/modules/markup/asciicast/asciicast.go b/modules/markup/asciicast/asciicast.go
index 1d0d631650c1a..d86d61d7c4ca3 100644
--- a/modules/markup/asciicast/asciicast.go
+++ b/modules/markup/asciicast/asciicast.go
@@ -46,7 +46,7 @@ func (Renderer) Render(ctx *markup.RenderContext, _ io.Reader, output io.Writer)
setting.AppSubURL,
url.PathEscape(ctx.RenderOptions.Metas["user"]),
url.PathEscape(ctx.RenderOptions.Metas["repo"]),
- ctx.RenderOptions.Metas["BranchNameSubURL"],
+ ctx.RenderOptions.Metas["RefTypeNameSubURL"],
url.PathEscape(ctx.RenderOptions.RelativePath),
)
return ctx.RenderInternal.FormatWithSafeAttrs(output, `
`, playerClassName, playerSrcAttr, rawURL)
diff --git a/modules/markup/render.go b/modules/markup/render.go
index b239e59687b7b..37a2a86687d72 100644
--- a/modules/markup/render.go
+++ b/modules/markup/render.go
@@ -44,7 +44,7 @@ type RenderOptions struct {
MarkupType string
// user&repo, format&style®exp (for external issue pattern), teams&org (for mention)
- // BranchNameSubURL (for iframe&asciicast)
+ // RefTypeNameSubURL (for iframe&asciicast)
// markupAllowShortIssuePattern
// markdownLineBreakStyle (comment, document)
Metas map[string]string
@@ -170,7 +170,7 @@ sandbox="allow-scripts"
setting.AppSubURL,
url.PathEscape(ctx.RenderOptions.Metas["user"]),
url.PathEscape(ctx.RenderOptions.Metas["repo"]),
- ctx.RenderOptions.Metas["BranchNameSubURL"],
+ ctx.RenderOptions.Metas["RefTypeNameSubURL"],
url.PathEscape(ctx.RenderOptions.RelativePath),
))
return err
diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini
index 1d3bc7d577556..ad15d22dd2400 100644
--- a/options/locale/locale_cs-CZ.ini
+++ b/options/locale/locale_cs-CZ.ini
@@ -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.subscribe=Odebírat
issues.unsubscribe=Zrušit odběr
-issues.unpin_issue=Odepnout úkol
+issues.unpin=Odepnout
issues.max_pinned=Nemůžete připnout další úkoly
issues.pin_comment=připnuto %s
issues.unpin_comment=odepnul/a tento %s
diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini
index ce2c43cb568d0..e805f7fe0ac39 100644
--- a/options/locale/locale_de-DE.ini
+++ b/options/locale/locale_de-DE.ini
@@ -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.subscribe=Abonnieren
issues.unsubscribe=Abbestellen
-issues.unpin_issue=Issue abheften
+issues.unpin=Loslösen
issues.max_pinned=Du kannst keine weiteren Issues anheften
issues.pin_comment=hat das %s angeheftet
issues.unpin_comment=hat das %s abgeheftet
diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini
index 31e57bbf97819..454e57eb128ab 100644
--- a/options/locale/locale_el-GR.ini
+++ b/options/locale/locale_el-GR.ini
@@ -1495,7 +1495,7 @@ issues.attachment.open_tab=`Κάντε κλικ για να δείτε το "%s"
issues.attachment.download=`Κάντε κλικ για να λάβετε το "%s"`
issues.subscribe=Εγγραφή
issues.unsubscribe=Διαγραφή
-issues.unpin_issue=Άφεση Ζητήματος
+issues.unpin=Άφεση
issues.max_pinned=Δεν μπορείτε να διατηρήσετε περισσότερα ζητήματα
issues.pin_comment=διατήρησε αυτό %s
issues.unpin_comment=άφησε αυτό %s
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 140e2efe57111..93155caa109f4 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -1115,9 +1115,7 @@ blame.ignore_revs = Ignoring revisions in .git-blame-ignore-revs.git-blame-ignore-revs.
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_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
+tree_path_not_found = Path %[1]s doesn't exist in %[2]s
transfer.accept = Accept Transfer
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.subscribe = Subscribe
issues.unsubscribe = Unsubscribe
-issues.unpin_issue = Unpin Issue
+issues.unpin = Unpin
issues.max_pinned = "You can't pin more issues"
issues.pin_comment = "pinned this %s"
issues.unpin_comment = "unpinned this %s"
diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini
index cdfe1fb2e5848..7dd8030d2b0c6 100644
--- a/options/locale/locale_es-ES.ini
+++ b/options/locale/locale_es-ES.ini
@@ -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.subscribe=Suscribir
issues.unsubscribe=Desuscribirse
-issues.unpin_issue=Desanclar incidencia
+issues.unpin=Desanclar
issues.max_pinned=No puedes anclar más incidencias
issues.pin_comment=anclado este %s
issues.unpin_comment=desanclado este %s
diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini
index becd8829fc76a..a63613cf886aa 100644
--- a/options/locale/locale_fr-FR.ini
+++ b/options/locale/locale_fr-FR.ini
@@ -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_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_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_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
@@ -469,7 +469,7 @@ sspi_auth_failed=Échec de l'authentification SSPI
password_pwned=Le mot de passe que vous avez choisi fait partit des mots de passe ayant fuité 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
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
[mail]
@@ -818,7 +818,7 @@ manage_ssh_keys=Gérer les clés SSH
manage_ssh_principals=Gérer les certificats principaux SSH
manage_gpg_keys=Gérer les clés GPG
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.
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=Besoin d'aide ? Consultez le guide de GitHub pour créer vos propres clés SSH ou résoudre les problèmes courants 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_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 WebAuthn Authenticator.
+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 WebAuthn Authenticator.
webauthn_register_key=Ajouter une clé de sécurité
webauthn_nickname=Pseudonyme
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.subscribe=S’abonner
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.pin_comment=a é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.deploy_keys=Clés 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_info=Autoriser cette clé de déploiement à soumettre 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.deploy_key_content=Contenu
-settings.key_been_used=Une clef 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.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_desc=La suppression d'une clef de déploiement révoque son accès à ce dépôt. Continuer ?
+settings.key_been_used=Une clé de déploiement identique est déjà en cours d’utilisation.
+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.deploy_key_deletion=Supprimer une clé de déploiement
+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.branches=Branches
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.show_file_tree=Afficher 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.
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_surname=Attribut nom de famille
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.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
@@ -3240,7 +3243,7 @@ config.ssh_port=Port
config.ssh_listen_port=Port d'écoute
config.ssh_root_path=Emplacement racine
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_sizes=Tailles de clé minimales
diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini
index cf6c76a9dbfc0..ef486b9e7a703 100644
--- a/options/locale/locale_ga-IE.ini
+++ b/options/locale/locale_ga-IE.ini
@@ -244,6 +244,7 @@ license_desc=Téigh go bhfaighidh doiciméadúchán roimh aon socruithe a athrú.
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_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_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
template=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
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.
+no_branch=Níl aon bhrainsí ag an stóras seo.
code=Cód
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.subscribe=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.pin_comment=phionnáil 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.show_file_tree=Taispeáin 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.
release.releases=Eisiúintí
@@ -2860,6 +2868,9 @@ teams.invite.title=Tugadh cuireadh duit dul isteach i bhfoireann %s/etc/apk/repositories:
alpine.registry.key=Íoslódáil eochair RSA poiblí na clárlainne isteach san fhillteán /etc/apk/keys/
chun an síniú innéacs a fhíorú:
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.from_ref=Úsáid sreabhadh oibre ó
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.
diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini
index 1fcf6d59b6c90..391691ebf5df6 100644
--- a/options/locale/locale_id-ID.ini
+++ b/options/locale/locale_id-ID.ini
@@ -818,6 +818,7 @@ issues.attachment.open_tab=`Klik untuk melihat "%s" di tab baru`
issues.attachment.download=`Klik untuk mengunduh "%s"`
issues.subscribe=Berlangganan
issues.unsubscribe=Berhenti berlangganan
+issues.unpin=Lepas sematan
issues.delete=Hapus
diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini
index 8ee9112c349f4..e5f3d14115177 100644
--- a/options/locale/locale_ja-JP.ini
+++ b/options/locale/locale_ja-JP.ini
@@ -1015,6 +1015,7 @@ new_repo_helper=リポジトリには、プロジェクトのすべてのファ
owner=オーナー
owner_helper=リポジトリ数の上限により、一部の組織はドロップダウンに表示されない場合があります。
repo_name=リポジトリ名
+repo_name_helper=リポジトリ名は、短く、覚えやすく、他と重複しないキーワードを使用しましょう。 リポジトリ名を ".profile" または ".profile-private" にして README.md を追加すると、ユーザーや組織のプロフィールとなります。
repo_size=リポジトリサイズ
template=テンプレート
template_select=テンプレートを選択してください。
@@ -1641,7 +1642,7 @@ issues.attachment.open_tab=`クリックして新しいタブで "%s" を見る`
issues.attachment.download=`クリックして "%s" をダウンロード`
issues.subscribe=購読する
issues.unsubscribe=購読を解除
-issues.unpin_issue=イシューのピン留めを解除
+issues.unpin=ピン留め解除
issues.max_pinned=これ以上イシューをピン留めできません
issues.pin_comment=がピン留め %s
issues.unpin_comment=がピン留めを解除 %s
@@ -2852,6 +2853,8 @@ teams.invite.title=あなたは組織 %[2]s 内のチーム /etc/pacman.conf にリポジトリとアーキテクチャを含めてサーバーを追加します:
+arch.install=pacmanでパッケージを同期します:
arch.repository=リポジトリ情報
arch.repository.repositories=リポジトリ
arch.repository.architectures=Architectures
@@ -3712,6 +3717,7 @@ runners.status.active=稼働中
runners.status.offline=オフライン
runners.version=バージョン
runners.reset_registration_token=登録トークンをリセット
+runners.reset_registration_token_confirm=現在のトークンを無効にして、新しいトークンを生成しますか?
runners.reset_registration_token_success=ランナー登録トークンをリセットしました
runs.all_workflows=すべてのワークフロー
diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini
index 0dfc5683ecdbc..c90de9578b6e2 100644
--- a/options/locale/locale_lv-LV.ini
+++ b/options/locale/locale_lv-LV.ini
@@ -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.subscribe=Abonēt
issues.unsubscribe=Atrakstīties
-issues.unpin_issue=Atspraust problēmu
+issues.unpin=Atspraust
issues.max_pinned=Nevar piespraust vairāk problēmas
issues.pin_comment=piesprauda šo %s
issues.unpin_comment=atsprauda šo %s
diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini
index f0c034a1331f3..f42de9287ed7b 100644
--- a/options/locale/locale_pt-BR.ini
+++ b/options/locale/locale_pt-BR.ini
@@ -1491,7 +1491,7 @@ issues.attachment.open_tab=`Clique para ver "%s" em uma nova aba`
issues.attachment.download=`Clique para baixar "%s"`
issues.subscribe=Inscrever-se
issues.unsubscribe=Desinscrever
-issues.unpin_issue=Desfixar issue
+issues.unpin=Desfixar
issues.max_pinned=Você não pode fixar mais issues
issues.pin_comment=fixou isto %s
issues.unpin_comment=desafixou isto %s
diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini
index 824da09dda1ca..7b57e776d12d2 100644
--- a/options/locale/locale_pt-PT.ini
+++ b/options/locale/locale_pt-PT.ini
@@ -1651,7 +1651,7 @@ issues.attachment.open_tab=`Clique para ver "%s" num separador novo`
issues.attachment.download=`Clique para descarregar "%s"`
issues.subscribe=Subscrever
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.pin_comment=fixou isto %s
issues.unpin_comment=desafixou isto %s
diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini
index 027a2cb19d3b8..9c6c706288b86 100644
--- a/options/locale/locale_ru-RU.ini
+++ b/options/locale/locale_ru-RU.ini
@@ -1471,7 +1471,7 @@ issues.attachment.open_tab=`Нажмите, чтобы увидеть «%s» в
issues.attachment.download=`Нажмите, чтобы скачать «%s»`
issues.subscribe=Подписаться
issues.unsubscribe=Отказаться от подписки
-issues.unpin_issue=Открепить задачу
+issues.unpin=Открепить
issues.max_pinned=Нельзя закрепить больше задач
issues.pin_comment=закрепил(а) эту задачу %s
issues.unpin_comment=открепил(а) эту задачу %s
diff --git a/options/locale/locale_sk-SK.ini b/options/locale/locale_sk-SK.ini
index 43b190098ff93..cd2f9157559d4 100644
--- a/options/locale/locale_sk-SK.ini
+++ b/options/locale/locale_sk-SK.ini
@@ -1068,6 +1068,7 @@ issues.dismiss_review=Zamietnuť revíziu
issues.dismiss_review_warning=Naozaj chcete zrušiť túto revíziu?
issues.cancel=Zrušiť
issues.save=Uložiť
+issues.unpin=Odopnúť
diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini
index fb30ab3b67b6f..e939d9f04ea0a 100644
--- a/options/locale/locale_tr-TR.ini
+++ b/options/locale/locale_tr-TR.ini
@@ -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.subscribe=Abone Ol
issues.unsubscribe=Abonelikten Çık
-issues.unpin_issue=Konuyu Sabitlemeden Kaldır
+issues.unpin=Sabitlemeyi kaldır
issues.max_pinned=Daha fazla konuyu sabitleyemezsiniz
issues.pin_comment=%s sabitlendi
issues.unpin_comment=%s sabitlenmesi kaldırıldı
diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini
index 5e4723a4cd848..564e9f9d8df1a 100644
--- a/options/locale/locale_zh-CN.ini
+++ b/options/locale/locale_zh-CN.ini
@@ -1646,7 +1646,7 @@ issues.attachment.open_tab=`在新的标签页中查看 '%s'`
issues.attachment.download=`点击下载 '%s'`
issues.subscribe=订阅
issues.unsubscribe=取消订阅
-issues.unpin_issue=取消置顶
+issues.unpin=取消置顶
issues.max_pinned=您不能置顶更多工单
issues.pin_comment=于 %s 被置顶
issues.unpin_comment=于 %s 取消置顶
diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini
index 948b47bc9cb67..b4183aa70a07f 100644
--- a/options/locale/locale_zh-TW.ini
+++ b/options/locale/locale_zh-TW.ini
@@ -1640,7 +1640,7 @@ issues.attachment.open_tab=`在新分頁中查看「%s」`
issues.attachment.download=`點擊下載「%s」`
issues.subscribe=訂閱
issues.unsubscribe=取消訂閱
-issues.unpin_issue=取消固定問題
+issues.unpin=取消固定
issues.max_pinned=您不能固定更多問題
issues.pin_comment=固定於 %s
issues.unpin_comment=取消固定於 %s
diff --git a/routers/api/v1/repo/download.go b/routers/api/v1/repo/download.go
index a8a23c4a8d425..e6296c9fe7324 100644
--- a/routers/api/v1/repo/download.go
+++ b/routers/api/v1/repo/download.go
@@ -17,11 +17,11 @@ func DownloadArchive(ctx *context.APIContext) {
var tp git.ArchiveType
switch ballType := ctx.PathParam("ball_type"); ballType {
case "tarball":
- tp = git.TARGZ
+ tp = git.ArchiveTarGz
case "zipball":
- tp = git.ZIP
+ tp = git.ArchiveZip
case "bundle":
- tp = git.BUNDLE
+ tp = git.ArchiveBundle
default:
ctx.Error(http.StatusBadRequest, "", fmt.Sprintf("Unknown archive type: %s", ballType))
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 {
ctx.ServerError("NewRequest", err)
return
diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go
index 7c7f53a56520d..3eefd2ae29253 100644
--- a/routers/api/v1/repo/file.go
+++ b/routers/api/v1/repo/file.go
@@ -293,14 +293,7 @@ func GetArchive(ctx *context.APIContext) {
}
func archiveDownload(ctx *context.APIContext) {
- uri := 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)
+ aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"))
if err != nil {
if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
ctx.Error(http.StatusBadRequest, "unknown archive format", err)
diff --git a/routers/web/feed/branch.go b/routers/web/feed/branch.go
index 80ce2ad198bcd..6c4cc11ca0565 100644
--- a/routers/web/feed/branch.go
+++ b/routers/web/feed/branch.go
@@ -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)
- link := &feeds.Link{Href: repo.HTMLURL() + "/" + ctx.Repo.BranchNameSubURL()}
+ link := &feeds.Link{Href: repo.HTMLURL() + "/" + ctx.Repo.RefTypeNameSubURL()}
feed := &feeds.Feed{
Title: title,
diff --git a/routers/web/feed/file.go b/routers/web/feed/file.go
index 1ab768ff27fcb..518d995ccbcb7 100644
--- a/routers/web/feed/file.go
+++ b/routers/web/feed/file.go
@@ -24,7 +24,7 @@ func ShowFileFeed(ctx *context.Context, repo *repo.Repository, formatType string
}
commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(
git.CommitsByFileAndRangeOptions{
- Revision: ctx.Repo.RefName,
+ Revision: ctx.Repo.RefFullName.ShortName(), // FIXME: legacy code used ShortName
File: fileName,
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)
- 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{
Title: title,
diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go
index d8c2f442abdfa..31a6a577728a7 100644
--- a/routers/web/repo/blame.go
+++ b/routers/web/repo/blame.go
@@ -59,9 +59,9 @@ func RefBlame(ctx *context.Context) {
ShowFileViewTreeSidebar: showFileViewTreeSidebar,
}
- branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
+ branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
treeLink := branchLink
- rawLink := ctx.Repo.RepoLink + "/raw/" + ctx.Repo.BranchNameSubURL()
+ rawLink := ctx.Repo.RepoLink + "/raw/" + ctx.Repo.RefTypeNameSubURL()
if len(ctx.Repo.TreePath) > 0 {
treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go
index 5d58c64ec82e5..51d91b7d6a00a 100644
--- a/routers/web/repo/branch.go
+++ b/routers/web/repo/branch.go
@@ -185,7 +185,7 @@ func CreateBranch(ctx *context.Context) {
if ctx.HasError() {
ctx.Flash.Error(ctx.GetErrMsg())
- ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
+ ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL())
return
}
@@ -205,25 +205,25 @@ func CreateBranch(ctx *context.Context) {
if err != nil {
if release_service.IsErrProtectedTagName(err) {
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
}
if release_service.IsErrTagAlreadyExists(err) {
e := err.(release_service.ErrTagAlreadyExists)
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
}
if git_model.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) {
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
}
if git_model.IsErrBranchNameConflict(err) {
e := err.(git_model.ErrBranchNameConflict)
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
}
if git.IsErrPushRejected(err) {
@@ -242,7 +242,7 @@ func CreateBranch(ctx *context.Context) {
}
ctx.Flash.Error(flashError)
}
- ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
+ ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL())
return
}
diff --git a/routers/web/repo/cherry_pick.go b/routers/web/repo/cherry_pick.go
index 35f158df5258d..33d941c9d886c 100644
--- a/routers/web/repo/cherry_pick.go
+++ b/routers/web/repo/cherry_pick.go
@@ -57,7 +57,7 @@ func CherryPick(ctx *context.Context) {
ctx.Data["new_branch_name"] = GetUniquePatchBranchName(ctx)
ctx.Data["last_commit"] = ctx.Repo.CommitID
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)
}
@@ -85,7 +85,7 @@ func CherryPickPost(ctx *context.Context) {
ctx.Data["new_branch_name"] = form.NewBranchName
ctx.Data["last_commit"] = ctx.Repo.CommitID
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() {
ctx.HTML(200, tplCherryPick)
diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go
index 3655233312c34..b5498ccd2c901 100644
--- a/routers/web/repo/commit.go
+++ b/routers/web/repo/commit.go
@@ -191,7 +191,7 @@ func SearchCommits(ctx *context.Context) {
query := ctx.FormTrim("q")
if len(query) == 0 {
- ctx.Redirect(ctx.Repo.RepoLink + "/commits/" + ctx.Repo.BranchNameSubURL())
+ ctx.Redirect(ctx.Repo.RepoLink + "/commits/" + ctx.Repo.RefTypeNameSubURL())
return
}
@@ -222,7 +222,7 @@ func FileHistory(ctx *context.Context) {
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 {
ctx.ServerError("FileCommitsCount", err)
return
@@ -238,7 +238,7 @@ func FileHistory(ctx *context.Context) {
commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(
git.CommitsByFileAndRangeOptions{
- Revision: ctx.Repo.RefName,
+ Revision: ctx.Repo.RefFullName.ShortName(), // FIXME: legacy code used ShortName
File: fileName,
Page: page,
})
diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go
index 5fbdeee27e3a5..85f407ab8d795 100644
--- a/routers/web/repo/editor.go
+++ b/routers/web/repo/editor.go
@@ -180,7 +180,7 @@ func editFile(ctx *context.Context, isNewFile bool) {
ctx.Data["TreeNames"] = treeNames
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_message"] = ""
if canCommit {
@@ -428,7 +428,7 @@ func DiffPreviewPost(ctx *context.Context) {
// DeleteFile render delete file page
func DeleteFile(ctx *context.Context) {
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)
if treePath != ctx.Repo.TreePath {
@@ -462,7 +462,7 @@ func DeleteFilePost(ctx *context.Context) {
}
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["commit_summary"] = form.CommitSummary
ctx.Data["commit_message"] = form.CommitMessage
@@ -604,7 +604,7 @@ func UploadFile(ctx *context.Context) {
ctx.Data["TreeNames"] = treeNames
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_message"] = ""
if canCommit {
diff --git a/routers/web/repo/helper.go b/routers/web/repo/helper.go
index ed6216fa5ce2a..3bf064c1e386d 100644
--- a/routers/web/repo/helper.go
+++ b/routers/web/repo/helper.go
@@ -4,25 +4,14 @@
package repo
import (
- "net/url"
-
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/services/context"
)
func HandleGitError(ctx *context.Context, msg string, err error) {
if git.IsErrNotExist(err) {
- refType := ""
- switch {
- 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.Data["NotFoundPrompt"] = ctx.Locale.Tr("repo.tree_path_not_found", ctx.Repo.TreePath, ctx.Repo.RefTypeNameSubURL())
+ ctx.Data["NotFoundGoBackURL"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
ctx.NotFound(msg, err)
} else {
ctx.ServerError(msg, err)
diff --git a/routers/web/repo/middlewares.go b/routers/web/repo/middlewares.go
index 420931c5fb729..7518e6feae916 100644
--- a/routers/web/repo/middlewares.go
+++ b/routers/web/repo/middlewares.go
@@ -4,12 +4,9 @@
package repo
import (
- "fmt"
"strconv"
- system_model "code.gitea.io/gitea/models/system"
user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/services/context"
user_service "code.gitea.io/gitea/services/user"
@@ -22,12 +19,9 @@ func SetEditorconfigIfExists(ctx *context.Context) {
}
ec, _, err := ctx.Repo.GetEditorconfig()
-
- if err != nil && !git.IsErrNotExist(err) {
- description := fmt.Sprintf("Error while getting .editorconfig file: %v", err)
- if err := system_model.CreateRepositoryNotice(description); err != nil {
- ctx.ServerError("ErrCreatingReporitoryNotice", err)
- }
+ if err != nil {
+ // it used to check `!git.IsErrNotExist(err)` and create a system notice, but it is quite annoying and useless
+ // because network errors also happen frequently, so we just ignore it
return
}
diff --git a/routers/web/repo/packages.go b/routers/web/repo/packages.go
index 5dcfd0454c802..65a340a799700 100644
--- a/routers/web/repo/packages.go
+++ b/routers/web/repo/packages.go
@@ -62,9 +62,7 @@ func Packages(ctx *context.Context) {
ctx.Data["PackageType"] = packageType
ctx.Data["AvailableTypes"] = packages.TypeList
ctx.Data["HasPackages"] = hasPackages
- if ctx.Repo != nil {
- ctx.Data["CanWritePackages"] = ctx.IsUserRepoWriter([]unit.Type{unit.TypePackages}) || ctx.IsUserSiteAdmin()
- }
+ ctx.Data["CanWritePackages"] = ctx.Repo.CanWrite(unit.TypePackages) || ctx.IsUserSiteAdmin()
ctx.Data["PackageDescriptors"] = pds
ctx.Data["Total"] = total
ctx.Data["RepositoryAccessMap"] = map[int64]bool{ctx.Repo.Repository.ID: true} // There is only the current repository
diff --git a/routers/web/repo/patch.go b/routers/web/repo/patch.go
index 1807cf31a1280..4d47a705d6e94 100644
--- a/routers/web/repo/patch.go
+++ b/routers/web/repo/patch.go
@@ -37,7 +37,7 @@ func NewDiffPatch(ctx *context.Context) {
ctx.Data["new_branch_name"] = GetUniquePatchBranchName(ctx)
ctx.Data["last_commit"] = ctx.Repo.CommitID
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)
}
@@ -52,7 +52,7 @@ func NewDiffPatchPost(ctx *context.Context) {
branchName = form.NewBranchName
}
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["commit_summary"] = form.CommitSummary
ctx.Data["commit_message"] = form.CommitMessage
diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go
index 5b099fe8d4fa3..53655703fcb9f 100644
--- a/routers/web/repo/release.go
+++ b/routers/web/repo/release.go
@@ -435,19 +435,19 @@ func NewReleasePost(ctx *context.Context) {
if release_service.IsErrTagAlreadyExists(err) {
e := err.(release_service.ErrTagAlreadyExists)
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
}
if release_service.IsErrInvalidTagName(err) {
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
}
if release_service.IsErrProtectedTagName(err) {
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
}
diff --git a/routers/web/repo/render.go b/routers/web/repo/render.go
index 856425ae355c5..069bf6f6bfa4c 100644
--- a/routers/web/repo/render.go
+++ b/routers/web/repo/render.go
@@ -58,7 +58,7 @@ func RenderFile(ctx *context.Context) {
}
rctx := renderhelper.NewRenderContextRepoFile(ctx, ctx.Repo.Repository, renderhelper.RepoFileOptions{
- CurrentRefPath: ctx.Repo.BranchNameSubURL(),
+ CurrentRefPath: ctx.Repo.RefTypeNameSubURL(),
CurrentTreePath: path.Dir(ctx.Repo.TreePath),
}).WithRelativePath(ctx.Repo.TreePath).WithInStandalonePage(true)
diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go
index 6e9a8ea756ca1..84a86e96359e4 100644
--- a/routers/web/repo/repo.go
+++ b/routers/web/repo/repo.go
@@ -465,13 +465,7 @@ func RedirectDownload(ctx *context.Context) {
// Download an archive of a repository
func Download(ctx *context.Context) {
- uri := 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)
+ aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"))
if err != nil {
if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
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
// kind of drop it on the floor if this is the case.
func InitiateDownload(ctx *context.Context) {
- uri := 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)
+ aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"))
if err != nil {
- ctx.ServerError("archiver_service.NewRequest", err)
+ ctx.Error(http.StatusBadRequest, "invalid archive request")
return
}
if aReq == nil {
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index 7ae812d6452be..550f1203fdc94 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -244,7 +244,7 @@ func LastCommit(ctx *context.Context) {
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.HTML(http.StatusOK, tplRepoViewList)
@@ -302,7 +302,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri
return nil
}
- branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
+ branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
treeLink := branchLink
if len(ctx.Repo.TreePath) > 0 {
diff --git a/routers/web/repo/view_file.go b/routers/web/repo/view_file.go
index 17c2821824339..0b4381edfb057 100644
--- a/routers/web/repo/view_file.go
+++ b/routers/web/repo/view_file.go
@@ -42,10 +42,10 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
}
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["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)
if err != nil {
@@ -92,7 +92,7 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
isDisplayingRendered := !isDisplayingSource
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()
@@ -170,9 +170,9 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
ctx.Data["IsMarkup"] = true
ctx.Data["MarkupType"] = markupType
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{
- CurrentRefPath: ctx.Repo.BranchNameSubURL(),
+ CurrentRefPath: ctx.Repo.RefTypeNameSubURL(),
CurrentTreePath: path.Dir(ctx.Repo.TreePath),
}).
WithMarkupType(markupType).
@@ -262,7 +262,7 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
ctx.Data["MarkupType"] = markupType
rctx := renderhelper.NewRenderContextRepoFile(ctx, ctx.Repo.Repository, renderhelper.RepoFileOptions{
- CurrentRefPath: ctx.Repo.BranchNameSubURL(),
+ CurrentRefPath: ctx.Repo.RefTypeNameSubURL(),
CurrentTreePath: path.Dir(ctx.Repo.TreePath),
}).
WithMarkupType(markupType).
diff --git a/routers/web/repo/view_home.go b/routers/web/repo/view_home.go
index 929a77b6ab0d8..fc2adf29af678 100644
--- a/routers/web/repo/view_home.go
+++ b/routers/web/repo/view_home.go
@@ -137,7 +137,7 @@ func prepareToRenderDirectory(ctx *context.Context) {
if ctx.Repo.TreePath != "" {
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)
@@ -361,7 +361,7 @@ func Home(ctx *context.Context) {
// prepare the tree path
var treeNames, paths []string
- branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
+ branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL()
treeLink := branchLink
if ctx.Repo.TreePath != "" {
treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
diff --git a/routers/web/repo/view_readme.go b/routers/web/repo/view_readme.go
index 5bd39de96315d..48befe47f8e0e 100644
--- a/routers/web/repo/view_readme.go
+++ b/routers/web/repo/view_readme.go
@@ -189,7 +189,7 @@ func prepareToRenderReadmeFile(ctx *context.Context, subfolder string, readmeFil
ctx.Data["MarkupType"] = markupType
rctx := renderhelper.NewRenderContextRepoFile(ctx, ctx.Repo.Repository, renderhelper.RepoFileOptions{
- CurrentRefPath: ctx.Repo.BranchNameSubURL(),
+ CurrentRefPath: ctx.Repo.RefTypeNameSubURL(),
CurrentTreePath: path.Join(ctx.Repo.TreePath, subfolder),
}).
WithMarkupType(markupType).
diff --git a/services/context/context_model.go b/services/context/context_model.go
index 4f70aac51695a..3a1776102ff8e 100644
--- a/services/context/context_model.go
+++ b/services/context/context_model.go
@@ -3,27 +3,7 @@
package context
-import (
- "code.gitea.io/gitea/models/unit"
-)
-
// IsUserSiteAdmin returns true if current user is a site admin
func (ctx *Context) IsUserSiteAdmin() bool {
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
-}
diff --git a/services/context/repo.go b/services/context/repo.go
index 3e832333166e3..64a6aa42cd820 100644
--- a/services/context/repo.go
+++ b/services/context/repo.go
@@ -21,7 +21,6 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
unit_model "code.gitea.io/gitea/models/unit"
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/git"
"code.gitea.io/gitea/modules/gitrepo"
@@ -47,22 +46,27 @@ type PullRequest struct {
// Repository contains information to operate a repository
type Repository struct {
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
IsViewTag bool
IsViewCommit bool
- Repository *repo_model.Repository
- Owner *user_model.User
- Commit *git.Commit
- Tag *git.Tag
- GitRepo *git.Repository
- RefName string
- BranchName string
- TagName string
- TreePath string
- CommitID string
- RepoLink string
- CloneLink repo_model.CloneLink
+
+ RefFullName git.RefName
+ BranchName string
+ TagName string
+ TreePath string
+
+ // Commit it is always set to the commit for the branch or tag
+ Commit *git.Commit
+ CommitID string
+
CommitsCount int64
PullRequest *PullRequest
@@ -150,7 +154,7 @@ func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.Use
}, 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 {
// Checking for following:
// 1. Is timetracker enabled
@@ -200,8 +204,12 @@ func (r *Repository) GetCommitGraphsCount(ctx context.Context, hidePRRefs bool,
})
}
-// BranchNameSubURL sub-URL for the BranchName field
-func (r *Repository) BranchNameSubURL() string {
+// RefTypeNameSubURL makes a sub-url for the current ref (branch/tag/commit) field, for example:
+// * "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 {
case r.IsViewBranch:
return "branch/" + util.PathEscapeSegments(r.BranchName)
@@ -214,21 +222,6 @@ func (r *Repository) BranchNameSubURL() string {
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
// HEAD of the default repo branch.
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
func RepoAssignment(ctx *Context) {
- if _, repoAssignmentOnce := ctx.Data["repoAssignmentExecuted"]; repoAssignmentOnce {
- // FIXME: it should panic in dev/test modes to have a clear behavior
- if !setting.IsProd || setting.IsInTesting {
- panic("RepoAssignment should not be executed twice")
- }
- return
+ if ctx.Data["Repository"] != nil {
+ setting.PanicInDevOrTesting("RepoAssignment should not be executed twice")
}
- ctx.Data["repoAssignmentExecuted"] = true
-
- var (
- owner *user_model.User
- err error
- )
+ var err error
userName := ctx.PathParam("username")
repoName := ctx.PathParam("reponame")
repoName = strings.TrimSuffix(repoName, ".git")
if setting.Other.EnableFeed {
+ ctx.Data["EnableFeed"] = true
repoName = strings.TrimSuffix(repoName, ".rss")
repoName = strings.TrimSuffix(repoName, ".atom")
}
// Check if the user is the same as the repository owner
if ctx.IsSigned && ctx.Doer.LowerName == strings.ToLower(userName) {
- owner = ctx.Doer
+ ctx.Repo.Owner = ctx.Doer
} else {
- owner, err = user_model.GetUserByName(ctx, userName)
+ ctx.Repo.Owner, err = user_model.GetUserByName(ctx, userName)
if err != nil {
if user_model.IsErrUserNotExist(err) {
// go-get does not support redirects
@@ -448,10 +433,8 @@ func RepoAssignment(ctx *Context) {
return
}
}
- ctx.Repo.Owner = owner
- ctx.ContextUser = owner
+ ctx.ContextUser = ctx.Repo.Owner
ctx.Data["ContextUser"] = ctx.ContextUser
- ctx.Data["Username"] = ctx.Repo.Owner.Name
// redirect link to wiki
if strings.HasSuffix(repoName, ".wiki") {
@@ -474,10 +457,10 @@ func RepoAssignment(ctx *Context) {
}
// 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 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 {
RedirectToRepo(ctx.Base, redirectRepoID)
} else if repo_model.IsErrRedirectNotExist(err) {
@@ -494,7 +477,7 @@ func RepoAssignment(ctx *Context) {
}
return
}
- repo.Owner = owner
+ repo.Owner = ctx.Repo.Owner
repoAssignment(ctx, repo)
if ctx.Written() {
@@ -503,12 +486,7 @@ func RepoAssignment(ctx *Context) {
ctx.Repo.RepoLink = repo.Link()
ctx.Data["RepoLink"] = ctx.Repo.RepoLink
- ctx.Data["RepoRelPath"] = ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name
-
- if setting.Other.EnableFeed {
- ctx.Data["EnableFeed"] = true
- ctx.Data["FeedURL"] = ctx.Repo.RepoLink
- }
+ ctx.Data["FeedURL"] = ctx.Repo.RepoLink
unit, err := ctx.Repo.Repository.GetUnit(ctx, unit_model.TypeExternalTracker)
if err == nil {
@@ -535,12 +513,9 @@ func RepoAssignment(ctx *Context) {
return
}
- ctx.Data["Title"] = owner.Name + "/" + repo.Name
+ ctx.Data["Title"] = repo.Owner.Name + "/" + repo.Name
ctx.Data["Repository"] = repo
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["CanWriteIssues"] = ctx.Repo.CanWrite(unit_model.TypeIssues)
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
if ctx.Repo.Repository.IsBeingCreated() || ctx.Repo.Repository.IsBroken() {
- ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
if !isHomeOrSettings {
ctx.Redirect(ctx.Repo.RepoLink)
}
@@ -616,9 +590,7 @@ func RepoAssignment(ctx *Context) {
}
if ctx.Repo.GitRepo != nil {
- if !setting.IsProd || setting.IsInTesting {
- panic("RepoAssignment: GitRepo should be nil")
- }
+ setting.PanicInDevOrTesting("RepoAssignment: GitRepo should be nil")
_ = ctx.Repo.GitRepo.Close()
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") {
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.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
// Only allow access to base of repo or settings
if !isHomeOrSettings {
ctx.Redirect(ctx.Repo.RepoLink)
@@ -641,7 +612,6 @@ func RepoAssignment(ctx *Context) {
// Stop at this point when the repo is empty.
if ctx.Repo.Repository.IsEmpty {
- ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch
return
}
@@ -667,22 +637,6 @@ func RepoAssignment(ctx *Context) {
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.
canPush := ctx.Repo.CanWrite(unit_model.TypeCode) ||
(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" {
- 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)
ctx.Data["GoDocDirectory"] = fullURLPrefix + "{/dir}"
ctx.Data["GoDocFile"] = fullURLPrefix + "{/dir}/{file}#L{line}"
@@ -871,26 +825,39 @@ type RepoRefByTypeOptions struct {
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
// of repository reference
func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func(*Context) {
opt := util.OptionalArg(opts)
return func(ctx *Context) {
+ var err error
refType := detectRefType
// Empty repository does not have reference information.
if ctx.Repo.Repository.IsEmpty {
// assume the user is viewing the (non-existent) default branch
ctx.Repo.IsViewBranch = true
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"] = ""
return
}
- var (
- refName string
- err error
- )
-
if ctx.Repo.GitRepo == nil {
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
if err != nil {
@@ -900,22 +867,23 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func
}
// Get default branch.
+ var refShortName string
reqPath := ctx.PathParam("*")
if reqPath == "" {
- refName = ctx.Repo.Repository.DefaultBranch
- if !ctx.Repo.GitRepo.IsBranchExist(refName) {
+ refShortName = ctx.Repo.Repository.DefaultBranch
+ if !ctx.Repo.GitRepo.IsBranchExist(refShortName) {
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 1)
if err == nil && len(brs) != 0 {
- refName = brs[0].Name
+ refShortName = brs[0].Name
} else if len(brs) == 0 {
log.Error("No branches in non-empty repository %s", ctx.Repo.GitRepo.Path)
} else {
log.Error("GetBranches error: %v", err)
}
}
- ctx.Repo.RefName = refName
- ctx.Repo.BranchName = refName
- ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
+ ctx.Repo.RefFullName = git.RefNameFromBranch(refShortName)
+ ctx.Repo.BranchName = refShortName
+ ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refShortName)
if err == nil {
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") {
@@ -929,35 +897,37 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func
} else { // there is a path in request
guessLegacyPath := refType == RepoRefUnknown
if guessLegacyPath {
- refName, refType = getRefNameLegacy(ctx.Base, ctx.Repo, reqPath, "")
+ refShortName, refType = getRefNameLegacy(ctx.Base, ctx.Repo, reqPath, "")
} 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)
if isRenamedBranch && has {
renamedBranchName := ctx.Data["RenamedBranchName"].(string)
- ctx.Flash.Info(ctx.Tr("repo.branch.renamed", refName, renamedBranchName))
- link := setting.AppSubURL + strings.Replace(ctx.Req.URL.EscapedPath(), util.PathEscapeSegments(refName), util.PathEscapeSegments(renamedBranchName), 1)
+ ctx.Flash.Info(ctx.Tr("repo.branch.renamed", refShortName, renamedBranchName))
+ link := setting.AppSubURL + strings.Replace(ctx.Req.URL.EscapedPath(), util.PathEscapeSegments(refShortName), util.PathEscapeSegments(renamedBranchName), 1)
ctx.Redirect(link)
return
}
- if refType == RepoRefBranch && ctx.Repo.GitRepo.IsBranchExist(refName) {
+ if refType == RepoRefBranch && ctx.Repo.GitRepo.IsBranchExist(refShortName) {
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 {
ctx.ServerError("GetBranchCommit", err)
return
}
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.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 git.IsErrNotExist(err) {
ctx.NotFound("GetTagCommit", err)
@@ -967,25 +937,26 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func
return
}
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.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 {
ctx.NotFound("GetCommit", err)
return
}
// If short commit ID add canonical link header
- if len(refName) < 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))
+ if len(refShortName) < ctx.Repo.GetObjectFormat().FullLength() {
+ 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))
}
} else {
if opt.IgnoreNotExistErr {
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
}
@@ -995,24 +966,26 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func
redirect := path.Join(
ctx.Repo.RepoLink,
util.PathEscapeSegments(prefix),
- ctx.Repo.BranchNameSubURL(),
+ ctx.Repo.RefTypeNameSubURL(),
util.PathEscapeSegments(ctx.Repo.TreePath))
ctx.Redirect(redirect)
return
}
}
- ctx.Data["BranchName"] = ctx.Repo.BranchName
- ctx.Data["RefName"] = ctx.Repo.RefName
- 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["RefFullName"] = ctx.Repo.RefFullName
+ ctx.Data["RefTypeNameSubURL"] = ctx.Repo.RefTypeNameSubURL()
ctx.Data["TreePath"] = ctx.Repo.TreePath
+
ctx.Data["IsViewBranch"] = ctx.Repo.IsViewBranch
+ ctx.Data["BranchName"] = ctx.Repo.BranchName
+
ctx.Data["IsViewTag"] = ctx.Repo.IsViewTag
+ ctx.Data["TagName"] = ctx.Repo.TagName
+
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.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount()
diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go
index 948222a436cc6..24605cfae055a 100644
--- a/services/mirror/mirror_pull.go
+++ b/services/mirror/mirror_pull.go
@@ -87,6 +87,7 @@ type mirrorSyncResult struct {
/*
// * [new tag] v0.1.8 -> v0.1.8
// * [new branch] master -> origin/master
+// * [new ref] refs/pull/2/head -> refs/pull/2/head"
// - [deleted] (none) -> origin/test // delete a branch
// - [deleted] (none) -> 1 // delete a tag
// 957a993..a87ba5f test -> origin/test
@@ -117,6 +118,11 @@ func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult {
refName: git.RefNameFromBranch(refName),
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
isTag := !strings.HasPrefix(refName, remoteName+"/")
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])
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{
- refName: git.RefNameFromBranch(strings.TrimPrefix(refName, remoteName+"/")),
+ refName: refFullName,
oldCommitID: shas[0],
newCommitID: shas[1],
})
diff --git a/services/repository/archiver/archiver.go b/services/repository/archiver/archiver.go
index e1addbed335cb..d39acc080d584 100644
--- a/services/repository/archiver/archiver.go
+++ b/services/repository/archiver/archiver.go
@@ -31,19 +31,20 @@ import (
// handle elsewhere.
type ArchiveRequest struct {
RepoID int64
- refName string
Type git.ArchiveType
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
type ErrUnknownArchiveFormat struct {
- RequestFormat string
+ RequestNameType string
}
// Error implements error
func (err ErrUnknownArchiveFormat) Error() string {
- return fmt.Sprintf("unknown format: %s", err.RequestFormat)
+ return fmt.Sprintf("unknown format: %s", err.RequestNameType)
}
// 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.
type RepoRefNotFoundError struct {
- RefName string
+ RefShortName string
}
// Error implements error.
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 {
@@ -67,43 +68,23 @@ func (e RepoRefNotFoundError) Is(err error) bool {
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
// resulting ArchiveRequest is suitable for being passed to Await()
// 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) {
- if fileType < git.ZIP || fileType > git.BUNDLE {
- return nil, ErrUnknownArchiveFormat{RequestFormat: fileType.String()}
- }
-
- r := &ArchiveRequest{
- RepoID: repoID,
- refName: refName,
- Type: fileType,
+func NewRequest(repoID int64, repo *git.Repository, archiveRefExt string) (*ArchiveRequest, error) {
+ // here the archiveRefShortName is not a clear ref, it could be a tag, branch or commit id
+ archiveRefShortName, archiveType := git.SplitArchiveNameType(archiveRefExt)
+ if archiveType == git.ArchiveUnknown {
+ return nil, ErrUnknownArchiveFormat{archiveRefExt}
}
// Get corresponding commit.
- commitID, err := repo.ConvertToGitID(r.refName)
+ commitID, err := repo.ConvertToGitID(archiveRefShortName)
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()
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
// caller to create this request.
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
-// 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
// 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
@@ -208,8 +189,8 @@ func doArchive(ctx context.Context, r *ArchiveRequest) (*repo_model.RepoArchiver
rd, w := io.Pipe()
defer func() {
- w.Close()
- rd.Close()
+ _ = w.Close()
+ _ = rd.Close()
}()
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)
@@ -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(
ctx,
archiver.CommitID,
diff --git a/services/repository/archiver/archiver_test.go b/services/repository/archiver/archiver_test.go
index 1d0c6e513d836..522f90558a728 100644
--- a/services/repository/archiver/archiver_test.go
+++ b/services/repository/archiver/archiver_test.go
@@ -9,7 +9,6 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/services/contexttest"
_ "code.gitea.io/gitea/models/actions"
@@ -31,47 +30,47 @@ func TestArchive_Basic(t *testing.T) {
contexttest.LoadGitRepo(t, ctx)
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.NotNil(t, bogusReq)
assert.EqualValues(t, firstCommit+".zip", bogusReq.GetArchiveName())
// Check a series of bogus requests.
// 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.Nil(t, bogusReq)
// 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.Nil(t, bogusReq)
// 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.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.NotNil(t, bogusReq)
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.NotNil(t, bogusReq)
assert.EqualValues(t, "test-archive.zip", bogusReq.GetArchiveName())
// 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.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.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.NotNil(t, secondReq)
@@ -91,7 +90,7 @@ func TestArchive_Basic(t *testing.T) {
// Sleep two seconds to make sure the queue doesn't change.
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)
// 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
@@ -106,12 +105,12 @@ func TestArchive_Basic(t *testing.T) {
// Now we'll submit a request and TimedWaitForCompletion twice, before and
// after we release it. We should trigger both the timeout and non-timeout
// 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.NotNil(t, 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)
// 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
@@ -129,6 +128,6 @@ func TestArchive_Basic(t *testing.T) {
}
func TestErrUnknownArchiveFormat(t *testing.T) {
- err := ErrUnknownArchiveFormat{RequestFormat: "master"}
+ err := ErrUnknownArchiveFormat{RequestNameType: "xxx"}
assert.ErrorIs(t, err, ErrUnknownArchiveFormat{})
}
diff --git a/templates/repo/blame.tmpl b/templates/repo/blame.tmpl
index 62d1bbf2ba7c4..f8bd22074f490 100644
--- a/templates/repo/blame.tmpl
+++ b/templates/repo/blame.tmpl
@@ -1,5 +1,5 @@
{{if or .UsesIgnoreRevs .FaultyIgnoreRevsFile}}
- {{$revsFileLink := URLJoin .RepoLink "src" .BranchNameSubURL "/.git-blame-ignore-revs"}}
+ {{$revsFileLink := URLJoin .RepoLink "src" .RefTypeNameSubURL "/.git-blame-ignore-revs"}}
{{if .UsesIgnoreRevs}}
diff --git a/templates/repo/branch/list.tmpl b/templates/repo/branch/list.tmpl
index cb504e2b75e18..25614d0df409f 100644
--- a/templates/repo/branch/list.tmpl
+++ b/templates/repo/branch/list.tmpl
@@ -42,7 +42,7 @@
{{end}}
{{if .EnableFeed}}
- {{svg "octicon-rss"}}
+ {{svg "octicon-rss"}}
{{end}}
{{if not $.DisableDownloadSourceArchives}}
@@ -162,7 +162,7 @@
{{end}}
{{if $.EnableFeed}}
-
{{svg "octicon-rss"}}
+
{{svg "octicon-rss"}}
{{end}}
{{if and (not .DBBranch.IsDeleted) (not $.DisableDownloadSourceArchives)}}
diff --git a/templates/repo/clone_panel.tmpl b/templates/repo/clone_panel.tmpl
index d3496bdb73a04..c1c2c87b75561 100644
--- a/templates/repo/clone_panel.tmpl
+++ b/templates/repo/clone_panel.tmpl
@@ -32,12 +32,14 @@
{{end}}
- {{if and (not $.DisableDownloadSourceArchives) $.RefName}}
+ {{if and (not $.DisableDownloadSourceArchives) $.RefFullName}}
{{end}}
{{end}}
diff --git a/templates/repo/commits_table.tmpl b/templates/repo/commits_table.tmpl
index 91fc1c2faede2..a0c5eacdd4b00 100644
--- a/templates/repo/commits_table.tmpl
+++ b/templates/repo/commits_table.tmpl
@@ -19,7 +19,7 @@
{{if .PageIsCommits}}