* Refactor repo.isBare to repo.isEmpty #5629 Signed-off-by: Andrew Thornton <art27@cantab.net> * Remove Sync calltags/v1.9.0-dev
"code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
) | ) | ||||
func TestBareRepo(t *testing.T) { | |||||
func TestEmptyRepo(t *testing.T) { | |||||
prepareTestEnv(t) | prepareTestEnv(t) | ||||
subpaths := []string{ | subpaths := []string{ | ||||
"commits/master", | "commits/master", | ||||
"commit/1ae57b34ccf7e18373", | "commit/1ae57b34ccf7e18373", | ||||
"graph", | "graph", | ||||
} | } | ||||
bareRepo := models.AssertExistsAndLoadBean(t, &models.Repository{}, models.Cond("is_bare = ?", true)).(*models.Repository) | |||||
owner := models.AssertExistsAndLoadBean(t, &models.User{ID: bareRepo.OwnerID}).(*models.User) | |||||
emptyRepo := models.AssertExistsAndLoadBean(t, &models.Repository{}, models.Cond("is_empty = ?", true)).(*models.Repository) | |||||
owner := models.AssertExistsAndLoadBean(t, &models.User{ID: emptyRepo.OwnerID}).(*models.User) | |||||
for _, subpath := range subpaths { | for _, subpath := range subpaths { | ||||
req := NewRequestf(t, "GET", "/%s/%s/%s", owner.Name, bareRepo.Name, subpath) | |||||
req := NewRequestf(t, "GET", "/%s/%s/%s", owner.Name, emptyRepo.Name, subpath) | |||||
MakeRequest(t, req, http.StatusNotFound) | MakeRequest(t, req, http.StatusNotFound) | ||||
} | } | ||||
} | } |
refName := git.RefEndName(opts.RefFullName) | refName := git.RefEndName(opts.RefFullName) | ||||
// Change default branch and bare status only if pushed ref is non-empty branch. | |||||
if repo.IsBare && opts.NewCommitID != git.EmptySHA && strings.HasPrefix(opts.RefFullName, git.BranchPrefix) { | |||||
// Change default branch and empty status only if pushed ref is non-empty branch. | |||||
if repo.IsEmpty && opts.NewCommitID != git.EmptySHA && strings.HasPrefix(opts.RefFullName, git.BranchPrefix) { | |||||
repo.DefaultBranch = refName | repo.DefaultBranch = refName | ||||
repo.IsBare = false | |||||
repo.IsEmpty = false | |||||
} | } | ||||
// Change repository bare status and update last updated time. | |||||
// Change repository empty status and update last updated time. | |||||
if err = UpdateRepository(repo, false); err != nil { | if err = UpdateRepository(repo, false); err != nil { | ||||
return fmt.Errorf("UpdateRepository: %v", err) | return fmt.Errorf("UpdateRepository: %v", err) | ||||
} | } |
owner_id: 2 | owner_id: 2 | ||||
lower_name: repo15 | lower_name: repo15 | ||||
name: repo15 | name: repo15 | ||||
is_bare: true | |||||
is_empty: true | |||||
- | - | ||||
id: 16 | id: 16 |
NewMigration("add pull request rebase with merge commit", addPullRequestRebaseWithMerge), | NewMigration("add pull request rebase with merge commit", addPullRequestRebaseWithMerge), | ||||
// v77 -> v78 | // v77 -> v78 | ||||
NewMigration("add theme to users", addUserDefaultTheme), | NewMigration("add theme to users", addUserDefaultTheme), | ||||
// v78 -> v79 | |||||
NewMigration("rename repo is_bare to repo is_empty", renameRepoIsBareToIsEmpty), | |||||
} | } | ||||
// Migrate database to current version | // Migrate database to current version |
// Copyright 2019 The Gitea Authors. All rights reserved. | |||||
// Use of this source code is governed by a MIT-style | |||||
// license that can be found in the LICENSE file. | |||||
package migrations | |||||
import ( | |||||
"fmt" | |||||
"strings" | |||||
"code.gitea.io/gitea/models" | |||||
"github.com/go-xorm/xorm" | |||||
) | |||||
func renameRepoIsBareToIsEmpty(x *xorm.Engine) error { | |||||
type Repository struct { | |||||
ID int64 `xorm:"pk autoincr"` | |||||
IsBare bool | |||||
IsEmpty bool `xorm:"INDEX"` | |||||
} | |||||
sess := x.NewSession() | |||||
defer sess.Close() | |||||
if err := sess.Begin(); err != nil { | |||||
return err | |||||
} | |||||
var err error | |||||
if models.DbCfg.Type == "mssql" { | |||||
_, err = sess.Query("EXEC sp_rename 'repository.is_bare', 'is_empty', 'COLUMN'") | |||||
} else { | |||||
_, err = sess.Query("ALTER TABLE \"repository\" RENAME COLUMN \"is_bare\" TO \"is_empty\";") | |||||
} | |||||
if err != nil { | |||||
if strings.Contains(err.Error(), "no such column") { | |||||
return nil | |||||
} | |||||
return fmt.Errorf("select repositories: %v", err) | |||||
} | |||||
return sess.Commit() | |||||
} |
NumReleases int `xorm:"-"` | NumReleases int `xorm:"-"` | ||||
IsPrivate bool `xorm:"INDEX"` | IsPrivate bool `xorm:"INDEX"` | ||||
IsBare bool `xorm:"INDEX"` | |||||
IsEmpty bool `xorm:"INDEX"` | |||||
IsMirror bool `xorm:"INDEX"` | IsMirror bool `xorm:"INDEX"` | ||||
*Mirror `xorm:"-"` | *Mirror `xorm:"-"` | ||||
FullName: repo.FullName(), | FullName: repo.FullName(), | ||||
Description: repo.Description, | Description: repo.Description, | ||||
Private: repo.IsPrivate, | Private: repo.IsPrivate, | ||||
Empty: repo.IsBare, | |||||
Empty: repo.IsEmpty, | |||||
Size: int(repo.Size / 1024), | Size: int(repo.Size / 1024), | ||||
Fork: repo.IsFork, | Fork: repo.IsFork, | ||||
Parent: parent, | Parent: parent, | ||||
// CanEnablePulls returns true if repository meets the requirements of accepting pulls. | // CanEnablePulls returns true if repository meets the requirements of accepting pulls. | ||||
func (repo *Repository) CanEnablePulls() bool { | func (repo *Repository) CanEnablePulls() bool { | ||||
return !repo.IsMirror && !repo.IsBare | |||||
return !repo.IsMirror && !repo.IsEmpty | |||||
} | } | ||||
// AllowsPulls returns true if repository meets the requirements of accepting pulls and has them enabled. | // AllowsPulls returns true if repository meets the requirements of accepting pulls and has them enabled. | ||||
_, stderr, err := com.ExecCmdDir(repoPath, "git", "log", "-1") | _, stderr, err := com.ExecCmdDir(repoPath, "git", "log", "-1") | ||||
if err != nil { | if err != nil { | ||||
if strings.Contains(stderr, "fatal: bad default revision 'HEAD'") { | if strings.Contains(stderr, "fatal: bad default revision 'HEAD'") { | ||||
repo.IsBare = true | |||||
repo.IsEmpty = true | |||||
} else { | } else { | ||||
return repo, fmt.Errorf("check bare: %v - %s", err, stderr) | |||||
return repo, fmt.Errorf("check empty: %v - %s", err, stderr) | |||||
} | } | ||||
} | } | ||||
if !repo.IsBare { | |||||
if !repo.IsEmpty { | |||||
// Try to get HEAD branch and set it as default branch. | // Try to get HEAD branch and set it as default branch. | ||||
gitRepo, err := git.OpenRepository(repoPath) | gitRepo, err := git.OpenRepository(repoPath) | ||||
if err != nil { | if err != nil { | ||||
repo, err = CleanUpMigrateInfo(repo) | repo, err = CleanUpMigrateInfo(repo) | ||||
} | } | ||||
if err != nil && !repo.IsBare { | |||||
if err != nil && !repo.IsEmpty { | |||||
UpdateRepoIndexer(repo) | UpdateRepoIndexer(repo) | ||||
} | } | ||||
return fmt.Errorf("initRepository: path already exists: %s", repoPath) | return fmt.Errorf("initRepository: path already exists: %s", repoPath) | ||||
} | } | ||||
// Init bare new repository. | |||||
// Init git bare new repository. | |||||
if err = git.InitRepository(repoPath, true); err != nil { | if err = git.InitRepository(repoPath, true); err != nil { | ||||
return fmt.Errorf("InitRepository: %v", err) | return fmt.Errorf("InitRepository: %v", err) | ||||
} else if err = createDelegateHooks(repoPath); err != nil { | } else if err = createDelegateHooks(repoPath); err != nil { | ||||
} | } | ||||
if !opts.AutoInit { | if !opts.AutoInit { | ||||
repo.IsBare = true | |||||
repo.IsEmpty = true | |||||
} | } | ||||
repo.DefaultBranch = "master" | repo.DefaultBranch = "master" |
func ReferencesGitRepo() macaron.Handler { | func ReferencesGitRepo() macaron.Handler { | ||||
return func(ctx *APIContext) { | return func(ctx *APIContext) { | ||||
// Empty repository does not have reference information. | // Empty repository does not have reference information. | ||||
if ctx.Repo.Repository.IsBare { | |||||
if ctx.Repo.Repository.IsEmpty { | |||||
return | return | ||||
} | } | ||||
ctx.Repo.Repository = repo | ctx.Repo.Repository = repo | ||||
ctx.Data["RepoName"] = ctx.Repo.Repository.Name | ctx.Data["RepoName"] = ctx.Repo.Repository.Name | ||||
ctx.Data["IsBareRepo"] = ctx.Repo.Repository.IsBare | |||||
ctx.Data["IsEmptyRepo"] = ctx.Repo.Repository.IsEmpty | |||||
} | } | ||||
// RepoIDAssignment returns a macaron handler which assigns the repo to the context. | // RepoIDAssignment returns a macaron handler which assigns the repo to the context. | ||||
ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.ID, repo.ID) | ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.ID, repo.ID) | ||||
} | } | ||||
// repo is bare and display enable | |||||
if ctx.Repo.Repository.IsBare { | |||||
// repo is empty and display enable | |||||
if ctx.Repo.Repository.IsEmpty { | |||||
ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch | ctx.Data["BranchName"] = ctx.Repo.Repository.DefaultBranch | ||||
return | return | ||||
} | } | ||||
func RepoRefByType(refType RepoRefType) macaron.Handler { | func RepoRefByType(refType RepoRefType) macaron.Handler { | ||||
return func(ctx *Context) { | return func(ctx *Context) { | ||||
// Empty repository does not have reference information. | // Empty repository does not have reference information. | ||||
if ctx.Repo.Repository.IsBare { | |||||
if ctx.Repo.Repository.IsEmpty { | |||||
return | return | ||||
} | } | ||||
ctx.ServerError("GetBranches", err) | ctx.ServerError("GetBranches", err) | ||||
return | return | ||||
} else if len(brs) == 0 { | } else if len(brs) == 0 { | ||||
err = fmt.Errorf("No branches in non-bare repository %s", | |||||
err = fmt.Errorf("No branches in non-empty repository %s", | |||||
ctx.Repo.GitRepo.Path) | ctx.Repo.GitRepo.Path) | ||||
ctx.ServerError("GetBranches", err) | ctx.ServerError("GetBranches", err) | ||||
return | return |
clone_this_repo=Naklonovat tento repozitář | clone_this_repo=Naklonovat tento repozitář | ||||
create_new_repo_command=Vytvořit nový repozitář na příkazové řádce | create_new_repo_command=Vytvořit nový repozitář na příkazové řádce | ||||
push_exist_repo=Nahrání existujícího repozitáře z příkazové řádky | push_exist_repo=Nahrání existujícího repozitáře z příkazové řádky | ||||
bare_message=Tento repozitář nemá žádný obsah. | |||||
empty_message=Tento repozitář nemá žádný obsah. | |||||
code=Zdrojový kód | code=Zdrojový kód | ||||
code.desc=Přístup ke zdrojovým kódům, souborům, revizím a větvím. | code.desc=Přístup ke zdrojovým kódům, souborům, revizím a větvím. |
clone_this_repo=Dieses Repository klonen | clone_this_repo=Dieses Repository klonen | ||||
create_new_repo_command=Erstelle ein neues Repository von der Kommandozeile aus | create_new_repo_command=Erstelle ein neues Repository von der Kommandozeile aus | ||||
push_exist_repo=Bestehendes Repository via Kommandozeile pushen | push_exist_repo=Bestehendes Repository via Kommandozeile pushen | ||||
bare_message=Dieses Repository hat noch keinen Inhalt. | |||||
empty_message=Dieses Repository hat noch keinen Inhalt. | |||||
code=Code | code=Code | ||||
code.desc=Zugriff auf Quellcode, Dateien, Commits und Branches. | code.desc=Zugriff auf Quellcode, Dateien, Commits und Branches. |
clone_this_repo = Clone this repository | clone_this_repo = Clone this repository | ||||
create_new_repo_command = Creating a new repository on the command line | create_new_repo_command = Creating a new repository on the command line | ||||
push_exist_repo = Pushing an existing repository from the command line | push_exist_repo = Pushing an existing repository from the command line | ||||
bare_message = This repository does not contain any content. | |||||
empty_message = This repository does not contain any content. | |||||
code = Code | code = Code | ||||
code.desc = Access source code, files, commits and branches. | code.desc = Access source code, files, commits and branches. |
clone_this_repo=Clonar este repositorio | clone_this_repo=Clonar este repositorio | ||||
create_new_repo_command=Crear un nuevo repositorio desde línea de comandos | create_new_repo_command=Crear un nuevo repositorio desde línea de comandos | ||||
push_exist_repo=Hacer push de un repositorio existente desde línea de comandos | push_exist_repo=Hacer push de un repositorio existente desde línea de comandos | ||||
bare_message=Este repositorio no contiene ningún contenido. | |||||
empty_message=Este repositorio no contiene ningún contenido. | |||||
code=Código | code=Código | ||||
branch=Rama | branch=Rama |
clone_this_repo=Cloner ce dépôt | clone_this_repo=Cloner ce dépôt | ||||
create_new_repo_command=Création d'un nouveau dépôt en ligne de commande | create_new_repo_command=Création d'un nouveau dépôt en ligne de commande | ||||
push_exist_repo=Soumission d'un dépôt existant par ligne de commande | push_exist_repo=Soumission d'un dépôt existant par ligne de commande | ||||
bare_message=Ce dépôt ne contient aucune information. | |||||
empty_message=Ce dépôt ne contient aucune information. | |||||
code=Code | code=Code | ||||
code.desc=Accéder au code source, fichiers, révisions et branches. | code.desc=Accéder au code source, fichiers, révisions et branches. |
clone_this_repo=Tároló klónozása | clone_this_repo=Tároló klónozása | ||||
create_new_repo_command=Egy új tároló létrehozása a parancssorból | create_new_repo_command=Egy új tároló létrehozása a parancssorból | ||||
push_exist_repo=Meglévő tároló feltöltése parancssorból | push_exist_repo=Meglévő tároló feltöltése parancssorból | ||||
bare_message=A tároló nem tartalmaz semmit, üres. | |||||
empty_message=A tároló nem tartalmaz semmit, üres. | |||||
code=Kód | code=Kód | ||||
branch=Ág | branch=Ág |
clone_this_repo=Klon repositori ini | clone_this_repo=Klon repositori ini | ||||
create_new_repo_command=Membuat repositori baru pada baris perintah | create_new_repo_command=Membuat repositori baru pada baris perintah | ||||
push_exist_repo=Mendorong sebuah repositori yang ada di baris perintah | push_exist_repo=Mendorong sebuah repositori yang ada di baris perintah | ||||
bare_message=Repositori ini tidak berisi konten apapun. | |||||
empty_message=Repositori ini tidak berisi konten apapun. | |||||
code=Kode | code=Kode | ||||
branch=Cabang | branch=Cabang |
clone_this_repo=Clona questo repository | clone_this_repo=Clona questo repository | ||||
create_new_repo_command=Creazione di un nuovo repository da riga di comando | create_new_repo_command=Creazione di un nuovo repository da riga di comando | ||||
push_exist_repo=Push di un repository esistente da riga di comando | push_exist_repo=Push di un repository esistente da riga di comando | ||||
bare_message=Questo repository non contiene alcun contenuto. | |||||
empty_message=Questo repository non contiene alcun contenuto. | |||||
code=Codice | code=Codice | ||||
code.desc=Accedi al codice sorgente, file, commits e branches. | code.desc=Accedi al codice sorgente, file, commits e branches. |
clone_this_repo=このリポジトリのクローンを作成 | clone_this_repo=このリポジトリのクローンを作成 | ||||
create_new_repo_command=コマンドラインから新しいリポジトリを作成 | create_new_repo_command=コマンドラインから新しいリポジトリを作成 | ||||
push_exist_repo=コマンドラインから既存のリポジトリをプッシュ | push_exist_repo=コマンドラインから既存のリポジトリをプッシュ | ||||
bare_message=このリポジトリには内容がありません。 | |||||
empty_message=このリポジトリには内容がありません。 | |||||
code=コード | code=コード | ||||
code.desc=ソースコード、ファイル、コミット、ブランチにアクセス。 | code.desc=ソースコード、ファイル、コミット、ブランチにアクセス。 |
clone_this_repo=이 저장소 복제 | clone_this_repo=이 저장소 복제 | ||||
create_new_repo_command=커맨드 라인에서 새 레포리지터리 생성 | create_new_repo_command=커맨드 라인에서 새 레포리지터리 생성 | ||||
push_exist_repo=커맨드라인에서 기존 레포지터리 푸시 | push_exist_repo=커맨드라인에서 기존 레포지터리 푸시 | ||||
bare_message=이 레포지터리에는 아무것도 없습니다. | |||||
empty_message=이 레포지터리에는 아무것도 없습니다. | |||||
code=코드 | code=코드 | ||||
branch=브렌치 | branch=브렌치 |
clone_this_repo=Klonēt šo repozitoriju | clone_this_repo=Klonēt šo repozitoriju | ||||
create_new_repo_command=Izveidot jaunu repozitoriju komandrindā | create_new_repo_command=Izveidot jaunu repozitoriju komandrindā | ||||
push_exist_repo=Nosūtīt izmaiņas no komandrindas eksistējošam repozitorijam | push_exist_repo=Nosūtīt izmaiņas no komandrindas eksistējošam repozitorijam | ||||
bare_message=Repozitorijs ir tukšs. | |||||
empty_message=Repozitorijs ir tukšs. | |||||
code=Kods | code=Kods | ||||
code.desc=Piekļūt pirmkodam, failiem, revīzijām un atzariem. | code.desc=Piekļūt pirmkodam, failiem, revīzijām un atzariem. |
clone_this_repo=Kloon deze repository | clone_this_repo=Kloon deze repository | ||||
create_new_repo_command=Maak een nieuwe repository aan vanaf de console | create_new_repo_command=Maak een nieuwe repository aan vanaf de console | ||||
push_exist_repo=Push een bestaande repositorie vanaf de console | push_exist_repo=Push een bestaande repositorie vanaf de console | ||||
bare_message=Deze repository bevat geen inhoud. | |||||
empty_message=Deze repository bevat geen inhoud. | |||||
code=Code | code=Code | ||||
branch=Branch | branch=Branch |
clone_this_repo=Klonuj repozytorium | clone_this_repo=Klonuj repozytorium | ||||
create_new_repo_command=Tworzenie nowego repozytorium z linii poleceń | create_new_repo_command=Tworzenie nowego repozytorium z linii poleceń | ||||
push_exist_repo=Wypychanie istniejącego repozytorium z linii poleceń | push_exist_repo=Wypychanie istniejącego repozytorium z linii poleceń | ||||
bare_message=Repozytorium jest puste. | |||||
empty_message=Repozytorium jest puste. | |||||
code=Kod | code=Kod | ||||
branch=Gałąź | branch=Gałąź |
clone_this_repo=Clonar este repositório | clone_this_repo=Clonar este repositório | ||||
create_new_repo_command=Criando um novo repositório por linha de comando | create_new_repo_command=Criando um novo repositório por linha de comando | ||||
push_exist_repo=Realizando push para um repositório existente por linha de comando | push_exist_repo=Realizando push para um repositório existente por linha de comando | ||||
bare_message=Este repositório está vazio. | |||||
empty_message=Este repositório está vazio. | |||||
code=Código | code=Código | ||||
code.desc=Acesso a código-fonte, arquivos, commits e branches. | code.desc=Acesso a código-fonte, arquivos, commits e branches. |
clone_this_repo=Клонировать репозиторий | clone_this_repo=Клонировать репозиторий | ||||
create_new_repo_command=Создать новый репозиторий из командной строки | create_new_repo_command=Создать новый репозиторий из командной строки | ||||
push_exist_repo=Push существующего репозитория из командной строки | push_exist_repo=Push существующего репозитория из командной строки | ||||
bare_message=В репозитории нет файлов. | |||||
empty_message=В репозитории нет файлов. | |||||
code=Код | code=Код | ||||
code.desc=Исходный код, файлы, коммиты и ветки. | code.desc=Исходный код, файлы, коммиты и ветки. |
clone_this_repo=Klona detta repo | clone_this_repo=Klona detta repo | ||||
create_new_repo_command=Skapa en ny utvecklingskatalog på kommandoraden | create_new_repo_command=Skapa en ny utvecklingskatalog på kommandoraden | ||||
push_exist_repo=Pusha en existerande utvecklingskatalog från kommandoraden | push_exist_repo=Pusha en existerande utvecklingskatalog från kommandoraden | ||||
bare_message=Denna utvecklingskatalog är tom. | |||||
empty_message=Denna utvecklingskatalog är tom. | |||||
code=Kod | code=Kod | ||||
code.desc=Se källkod, filer, commits och brancher. | code.desc=Se källkod, filer, commits och brancher. |
clone_this_repo=Bu depoyu klonla | clone_this_repo=Bu depoyu klonla | ||||
create_new_repo_command=Komut satırında yeni bir depo oluşturuluyor | create_new_repo_command=Komut satırında yeni bir depo oluşturuluyor | ||||
push_exist_repo=Komut satırından mevcut bir depo itiliyor | push_exist_repo=Komut satırından mevcut bir depo itiliyor | ||||
bare_message=Bu depo herhangi bir içerik içermiyor. | |||||
empty_message=Bu depo herhangi bir içerik içermiyor. | |||||
code=Kod | code=Kod | ||||
branch=Dal | branch=Dal |
clone_this_repo=Кнонувати цей репозиторій | clone_this_repo=Кнонувати цей репозиторій | ||||
create_new_repo_command=Створити новий репозиторій з командного рядка | create_new_repo_command=Створити новий репозиторій з командного рядка | ||||
push_exist_repo=Опублікувати існуючий репозиторій з командного рядка | push_exist_repo=Опублікувати існуючий репозиторій з командного рядка | ||||
bare_message=Цей репозиторій порожній. | |||||
empty_message=Цей репозиторій порожній. | |||||
code=Код | code=Код | ||||
code.desc=Доступ до коду, файлів, комітів та гілок. | code.desc=Доступ до коду, файлів, комітів та гілок. |
clone_this_repo=克隆当前仓库 | clone_this_repo=克隆当前仓库 | ||||
create_new_repo_command=从命令行创建一个新的仓库 | create_new_repo_command=从命令行创建一个新的仓库 | ||||
push_exist_repo=从命令行推送已经创建的仓库 | push_exist_repo=从命令行推送已经创建的仓库 | ||||
bare_message=这个家伙很懒,什么都没有推送。 | |||||
empty_message=这个家伙很懒,什么都没有推送。 | |||||
code=代码 | code=代码 | ||||
code.desc=查看源码、文件、提交和分支。 | code.desc=查看源码、文件、提交和分支。 |
clone_this_repo=複製當前儲存庫 | clone_this_repo=複製當前儲存庫 | ||||
create_new_repo_command=從命令列建立新儲存庫。 | create_new_repo_command=從命令列建立新儲存庫。 | ||||
push_exist_repo=從命令列推送已存在的儲存庫 | push_exist_repo=從命令列推送已存在的儲存庫 | ||||
bare_message=此儲存庫未包含任何內容。 | |||||
empty_message=此儲存庫未包含任何內容。 | |||||
code=程式碼 | code=程式碼 | ||||
branch=分支 | branch=分支 |
clone_this_repo=複製此儲存庫 | clone_this_repo=複製此儲存庫 | ||||
create_new_repo_command=從命令列建立新儲存庫。 | create_new_repo_command=從命令列建立新儲存庫。 | ||||
push_exist_repo=從命令行推送已經建立的儲存庫 | push_exist_repo=從命令行推送已經建立的儲存庫 | ||||
bare_message=此儲存庫未包含任何內容。 | |||||
empty_message=此儲存庫未包含任何內容。 | |||||
code=程式碼 | code=程式碼 | ||||
branch=分支 | branch=分支 |
// responses: | // responses: | ||||
// 200: | // 200: | ||||
// description: success | // description: success | ||||
if ctx.Repo.Repository.IsBare { | |||||
if ctx.Repo.Repository.IsEmpty { | |||||
ctx.Status(404) | ctx.Status(404) | ||||
return | return | ||||
} | } |
return nil | return nil | ||||
} | } | ||||
if forkRepo.IsBare || !perm.CanRead(models.UnitTypeCode) { | |||||
if forkRepo.IsEmpty || !perm.CanRead(models.UnitTypeCode) { | |||||
ctx.NotFound("getForkRepository", nil) | ctx.NotFound("getForkRepository", nil) | ||||
return nil | return nil | ||||
} | } |
tplMigrate base.TplName = "repo/migrate" | tplMigrate base.TplName = "repo/migrate" | ||||
) | ) | ||||
// MustBeNotBare render when a repo is a bare git dir | |||||
func MustBeNotBare(ctx *context.Context) { | |||||
if ctx.Repo.Repository.IsBare { | |||||
ctx.NotFound("MustBeNotBare", nil) | |||||
// MustBeNotEmpty render when a repo is a empty git dir | |||||
func MustBeNotEmpty(ctx *context.Context) { | |||||
if ctx.Repo.Repository.IsEmpty { | |||||
ctx.NotFound("MustBeNotEmpty", nil) | |||||
} | } | ||||
} | } | ||||
) | ) | ||||
const ( | const ( | ||||
tplRepoBARE base.TplName = "repo/bare" | |||||
tplRepoHome base.TplName = "repo/home" | |||||
tplWatchers base.TplName = "repo/watchers" | |||||
tplForks base.TplName = "repo/forks" | |||||
tplRepoEMPTY base.TplName = "repo/empty" | |||||
tplRepoHome base.TplName = "repo/home" | |||||
tplWatchers base.TplName = "repo/watchers" | |||||
tplForks base.TplName = "repo/forks" | |||||
) | ) | ||||
func renderDirectory(ctx *context.Context, treeLink string) { | func renderDirectory(ctx *context.Context, treeLink string) { | ||||
func renderCode(ctx *context.Context) { | func renderCode(ctx *context.Context) { | ||||
ctx.Data["PageIsViewCode"] = true | ctx.Data["PageIsViewCode"] = true | ||||
if ctx.Repo.Repository.IsBare { | |||||
ctx.HTML(200, tplRepoBARE) | |||||
if ctx.Repo.Repository.IsEmpty { | |||||
ctx.HTML(200, tplRepoEMPTY) | |||||
return | return | ||||
} | } | ||||
}, reqSignIn) | }, reqSignIn) | ||||
// ***** Release Attachment Download without Signin | // ***** Release Attachment Download without Signin | ||||
m.Get("/:username/:reponame/releases/download/:vTag/:fileName", ignSignIn, context.RepoAssignment(), repo.MustBeNotBare, repo.RedirectDownload) | |||||
m.Get("/:username/:reponame/releases/download/:vTag/:fileName", ignSignIn, context.RepoAssignment(), repo.MustBeNotEmpty, repo.RedirectDownload) | |||||
m.Group("/:username/:reponame", func() { | m.Group("/:username/:reponame", func() { | ||||
m.Group("/settings", func() { | m.Group("/settings", func() { | ||||
m.Combo("").Get(repo.ProtectedBranch).Post(repo.ProtectedBranchPost) | m.Combo("").Get(repo.ProtectedBranch).Post(repo.ProtectedBranchPost) | ||||
m.Combo("/*").Get(repo.SettingsProtectedBranch). | m.Combo("/*").Get(repo.SettingsProtectedBranch). | ||||
Post(bindIgnErr(auth.ProtectBranchForm{}), repo.SettingsProtectedBranchPost) | Post(bindIgnErr(auth.ProtectBranchForm{}), repo.SettingsProtectedBranchPost) | ||||
}, repo.MustBeNotBare) | |||||
}, repo.MustBeNotEmpty) | |||||
m.Group("/hooks", func() { | m.Group("/hooks", func() { | ||||
m.Get("", repo.Webhooks) | m.Get("", repo.Webhooks) | ||||
m.Post("/upload-file", repo.UploadFileToServer) | m.Post("/upload-file", repo.UploadFileToServer) | ||||
m.Post("/upload-remove", bindIgnErr(auth.RemoveUploadFileForm{}), repo.RemoveUploadFileFromServer) | m.Post("/upload-remove", bindIgnErr(auth.RemoveUploadFileForm{}), repo.RemoveUploadFileFromServer) | ||||
}, context.RepoRef(), repo.MustBeEditable, repo.MustBeAbleToUpload) | }, context.RepoRef(), repo.MustBeEditable, repo.MustBeAbleToUpload) | ||||
}, reqRepoCodeWriter, repo.MustBeNotBare) | |||||
}, reqRepoCodeWriter, repo.MustBeNotEmpty) | |||||
m.Group("/branches", func() { | m.Group("/branches", func() { | ||||
m.Group("/_new/", func() { | m.Group("/_new/", func() { | ||||
}, bindIgnErr(auth.NewBranchForm{})) | }, bindIgnErr(auth.NewBranchForm{})) | ||||
m.Post("/delete", repo.DeleteBranchPost) | m.Post("/delete", repo.DeleteBranchPost) | ||||
m.Post("/restore", repo.RestoreBranchPost) | m.Post("/restore", repo.RestoreBranchPost) | ||||
}, reqRepoCodeWriter, repo.MustBeNotBare) | |||||
}, reqRepoCodeWriter, repo.MustBeNotEmpty) | |||||
}, reqSignIn, context.RepoAssignment(), context.UnitTypes()) | }, reqSignIn, context.RepoAssignment(), context.UnitTypes()) | ||||
// Releases | // Releases | ||||
m.Group("/:username/:reponame", func() { | m.Group("/:username/:reponame", func() { | ||||
m.Group("/releases", func() { | m.Group("/releases", func() { | ||||
m.Get("/", repo.MustBeNotBare, repo.Releases) | |||||
}, repo.MustBeNotBare, context.RepoRef()) | |||||
m.Get("/", repo.MustBeNotEmpty, repo.Releases) | |||||
}, repo.MustBeNotEmpty, context.RepoRef()) | |||||
m.Group("/releases", func() { | m.Group("/releases", func() { | ||||
m.Get("/new", repo.NewRelease) | m.Get("/new", repo.NewRelease) | ||||
m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost) | m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost) | ||||
m.Post("/delete", repo.DeleteRelease) | m.Post("/delete", repo.DeleteRelease) | ||||
}, reqSignIn, repo.MustBeNotBare, reqRepoReleaseWriter, context.RepoRef()) | |||||
}, reqSignIn, repo.MustBeNotEmpty, reqRepoReleaseWriter, context.RepoRef()) | |||||
m.Group("/releases", func() { | m.Group("/releases", func() { | ||||
m.Get("/edit/*", repo.EditRelease) | m.Get("/edit/*", repo.EditRelease) | ||||
m.Post("/edit/*", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost) | m.Post("/edit/*", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost) | ||||
}, reqSignIn, repo.MustBeNotBare, reqRepoReleaseWriter, func(ctx *context.Context) { | |||||
}, reqSignIn, repo.MustBeNotEmpty, reqRepoReleaseWriter, func(ctx *context.Context) { | |||||
var err error | var err error | ||||
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) | ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) | ||||
if err != nil { | if err != nil { | ||||
m.Group("/activity", func() { | m.Group("/activity", func() { | ||||
m.Get("", repo.Activity) | m.Get("", repo.Activity) | ||||
m.Get("/:period", repo.Activity) | m.Get("/:period", repo.Activity) | ||||
}, context.RepoRef(), repo.MustBeNotBare, context.RequireRepoReaderOr(models.UnitTypePullRequests, models.UnitTypeIssues, models.UnitTypeReleases)) | |||||
}, context.RepoRef(), repo.MustBeNotEmpty, context.RequireRepoReaderOr(models.UnitTypePullRequests, models.UnitTypeIssues, models.UnitTypeReleases)) | |||||
m.Get("/archive/*", repo.MustBeNotBare, reqRepoCodeReader, repo.Download) | |||||
m.Get("/archive/*", repo.MustBeNotEmpty, reqRepoCodeReader, repo.Download) | |||||
m.Group("/branches", func() { | m.Group("/branches", func() { | ||||
m.Get("", repo.Branches) | m.Get("", repo.Branches) | ||||
}, repo.MustBeNotBare, context.RepoRef(), reqRepoCodeReader) | |||||
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader) | |||||
m.Group("/pulls/:index", func() { | m.Group("/pulls/:index", func() { | ||||
m.Get(".diff", repo.DownloadPullDiff) | m.Get(".diff", repo.DownloadPullDiff) | ||||
m.Get("/blob/:sha", context.RepoRefByType(context.RepoRefBlob), repo.DownloadByID) | m.Get("/blob/:sha", context.RepoRefByType(context.RepoRefBlob), repo.DownloadByID) | ||||
// "/*" route is deprecated, and kept for backward compatibility | // "/*" route is deprecated, and kept for backward compatibility | ||||
m.Get("/*", context.RepoRefByType(context.RepoRefLegacy), repo.SingleDownload) | m.Get("/*", context.RepoRefByType(context.RepoRefLegacy), repo.SingleDownload) | ||||
}, repo.MustBeNotBare, reqRepoCodeReader) | |||||
}, repo.MustBeNotEmpty, reqRepoCodeReader) | |||||
m.Group("/commits", func() { | m.Group("/commits", func() { | ||||
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.RefCommits) | m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.RefCommits) | ||||
m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.RefCommits) | m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.RefCommits) | ||||
// "/*" route is deprecated, and kept for backward compatibility | // "/*" route is deprecated, and kept for backward compatibility | ||||
m.Get("/*", context.RepoRefByType(context.RepoRefLegacy), repo.RefCommits) | m.Get("/*", context.RepoRefByType(context.RepoRefLegacy), repo.RefCommits) | ||||
}, repo.MustBeNotBare, reqRepoCodeReader) | |||||
}, repo.MustBeNotEmpty, reqRepoCodeReader) | |||||
m.Group("", func() { | m.Group("", func() { | ||||
m.Get("/graph", repo.Graph) | m.Get("/graph", repo.Graph) | ||||
m.Get("/commit/:sha([a-f0-9]{7,40})$", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.Diff) | m.Get("/commit/:sha([a-f0-9]{7,40})$", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.Diff) | ||||
}, repo.MustBeNotBare, context.RepoRef(), reqRepoCodeReader) | |||||
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader) | |||||
m.Group("/src", func() { | m.Group("/src", func() { | ||||
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.Home) | m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.Home) | ||||
m.Get("/forks", repo.Forks) | m.Get("/forks", repo.Forks) | ||||
}, context.RepoRef(), reqRepoCodeReader) | }, context.RepoRef(), reqRepoCodeReader) | ||||
m.Get("/commit/:sha([a-f0-9]{7,40})\\.:ext(patch|diff)", | m.Get("/commit/:sha([a-f0-9]{7,40})\\.:ext(patch|diff)", | ||||
repo.MustBeNotBare, reqRepoCodeReader, repo.RawDiff) | |||||
repo.MustBeNotEmpty, reqRepoCodeReader, repo.RawDiff) | |||||
m.Get("/compare/:before([a-z0-9]{40})\\.\\.\\.:after([a-z0-9]{40})", repo.SetEditorconfigIfExists, | m.Get("/compare/:before([a-z0-9]{40})\\.\\.\\.:after([a-z0-9]{40})", repo.SetEditorconfigIfExists, | ||||
repo.SetDiffViewStyle, repo.MustBeNotBare, reqRepoCodeReader, repo.CompareDiff) | |||||
repo.SetDiffViewStyle, repo.MustBeNotEmpty, reqRepoCodeReader, repo.CompareDiff) | |||||
}, ignSignIn, context.RepoAssignment(), context.UnitTypes()) | }, ignSignIn, context.RepoAssignment(), context.UnitTypes()) | ||||
m.Group("/:username/:reponame", func() { | m.Group("/:username/:reponame", func() { | ||||
m.Get("/stars", repo.Stars) | m.Get("/stars", repo.Stars) |
</div> | </div> | ||||
{{else}} | {{else}} | ||||
<div class="ui segment center"> | <div class="ui segment center"> | ||||
{{.i18n.Tr "repo.bare_message"}} | |||||
{{.i18n.Tr "repo.empty_message"}} | |||||
</div> | </div> | ||||
{{end}} | {{end}} | ||||
</div> | </div> |
{{.NumStars}} | {{.NumStars}} | ||||
</a> | </a> | ||||
</div> | </div> | ||||
{{if and (not .IsBare) ($.Permission.CanRead $.UnitTypeCode)}} | |||||
{{if and (not .IsEmpty) ($.Permission.CanRead $.UnitTypeCode)}} | |||||
<div class="ui compact labeled button" tabindex="0"> | <div class="ui compact labeled button" tabindex="0"> | ||||
<a class="ui compact button {{if or (not $.IsSigned) (not $.CanSignedUserFork)}}poping up{{end}}" {{if $.CanSignedUserFork}}href="{{AppSubUrl}}/repo/fork/{{.ID}}"{{else if $.IsSigned}} data-content="{{$.i18n.Tr "repo.fork_from_self"}}" {{ else }} data-content="{{$.i18n.Tr "repo.fork_guest_user" }}" href="{{AppSubUrl}}/user/login?redirect_to={{AppSubUrl}}/repo/fork/{{.ID}}" {{end}} data-position="top center" data-variation="tiny"> | <a class="ui compact button {{if or (not $.IsSigned) (not $.CanSignedUserFork)}}poping up{{end}}" {{if $.CanSignedUserFork}}href="{{AppSubUrl}}/repo/fork/{{.ID}}"{{else if $.IsSigned}} data-content="{{$.i18n.Tr "repo.fork_from_self"}}" {{ else }} data-content="{{$.i18n.Tr "repo.fork_guest_user" }}" href="{{AppSubUrl}}/user/login?redirect_to={{AppSubUrl}}/repo/fork/{{.ID}}" {{end}} data-position="top center" data-variation="tiny"> | ||||
<i class="octicon octicon-repo-forked"></i>{{$.i18n.Tr "repo.fork"}} | <i class="octicon octicon-repo-forked"></i>{{$.i18n.Tr "repo.fork"}} | ||||
</a> | </a> | ||||
{{end}} | {{end}} | ||||
{{if and (.Permission.CanRead $.UnitTypeReleases) (not .IsBareRepo) }} | |||||
{{if and (.Permission.CanRead $.UnitTypeReleases) (not .IsEmptyRepo) }} | |||||
<a class="{{if .PageIsReleaseList}}active{{end}} item" href="{{.RepoLink}}/releases"> | <a class="{{if .PageIsReleaseList}}active{{end}} item" href="{{.RepoLink}}/releases"> | ||||
<i class="octicon octicon-tag"></i> {{.i18n.Tr "repo.releases"}} <span class="ui {{if not .Repository.NumReleases}}gray{{else}}blue{{end}} small label">{{.Repository.NumReleases}}</span> | <i class="octicon octicon-tag"></i> {{.i18n.Tr "repo.releases"}} <span class="ui {{if not .Repository.NumReleases}}gray{{else}}blue{{end}} small label">{{.Repository.NumReleases}}</span> | ||||
</a> | </a> | ||||
</a> | </a> | ||||
{{end}} | {{end}} | ||||
{{if and (.Permission.CanReadAny $.UnitTypePullRequests $.UnitTypeIssues $.UnitTypeReleases) (not .IsBareRepo)}} | |||||
{{if and (.Permission.CanReadAny $.UnitTypePullRequests $.UnitTypeIssues $.UnitTypeReleases) (not .IsEmptyRepo)}} | |||||
<a class="{{if .PageIsActivity}}active{{end}} item" href="{{.RepoLink}}/activity"> | <a class="{{if .PageIsActivity}}active{{end}} item" href="{{.RepoLink}}/activity"> | ||||
<i class="octicon octicon-pulse"></i> {{.i18n.Tr "repo.activity"}} | <i class="octicon octicon-pulse"></i> {{.i18n.Tr "repo.activity"}} | ||||
</a> | </a> |
<form class="ui form" action="{{.Link}}" method="post"> | <form class="ui form" action="{{.Link}}" method="post"> | ||||
{{.CsrfTokenHtml}} | {{.CsrfTokenHtml}} | ||||
<input type="hidden" name="action" value="default_branch"> | <input type="hidden" name="action" value="default_branch"> | ||||
{{if not .Repository.IsBare}} | |||||
{{if not .Repository.IsEmpty}} | |||||
<div class="required inline field"> | <div class="required inline field"> | ||||
<div class="ui dropdown selection" tabindex="0"> | <div class="ui dropdown selection" tabindex="0"> | ||||
<select name="branch"> | <select name="branch"> |
<a class="{{if .PageIsSettingsCollaboration}}active{{end}} item" href="{{.RepoLink}}/settings/collaboration"> | <a class="{{if .PageIsSettingsCollaboration}}active{{end}} item" href="{{.RepoLink}}/settings/collaboration"> | ||||
{{.i18n.Tr "repo.settings.collaboration"}} | {{.i18n.Tr "repo.settings.collaboration"}} | ||||
</a> | </a> | ||||
{{if not .Repository.IsBare}} | |||||
{{if not .Repository.IsEmpty}} | |||||
<a class="{{if .PageIsSettingsBranches}}active{{end}} item" href="{{.RepoLink}}/settings/branches"> | <a class="{{if .PageIsSettingsBranches}}active{{end}} item" href="{{.RepoLink}}/settings/branches"> | ||||
{{.i18n.Tr "repo.settings.branches"}} | {{.i18n.Tr "repo.settings.branches"}} | ||||
</a> | </a> |
<div class="ui segment sub-menu"> | <div class="ui segment sub-menu"> | ||||
<div class="ui two horizontal center link list"> | <div class="ui two horizontal center link list"> | ||||
{{if and (.Permission.CanRead $.UnitTypeCode) (not .IsBareRepo)}} | |||||
{{if and (.Permission.CanRead $.UnitTypeCode) (not .IsEmptyRepo)}} | |||||
<div class="item{{if .PageIsCommits}} active{{end}}"> | <div class="item{{if .PageIsCommits}} active{{end}}"> | ||||
<a href="{{.RepoLink}}/commits{{if .IsViewBranch}}/branch{{else if .IsViewTag}}/tag{{else if .IsViewCommit}}/commit{{end}}/{{EscapePound .BranchName}}"><i class="octicon octicon-history"></i> <b>{{.CommitsCount}}</b> {{.i18n.Tr (TrN .i18n.Lang .CommitsCount "repo.commit" "repo.commits") }}</a> | <a href="{{.RepoLink}}/commits{{if .IsViewBranch}}/branch{{else if .IsViewTag}}/tag{{else if .IsViewCommit}}/commit{{end}}/{{EscapePound .BranchName}}"><i class="octicon octicon-history"></i> <b>{{.CommitsCount}}</b> {{.i18n.Tr (TrN .i18n.Lang .CommitsCount "repo.commit" "repo.commits") }}</a> | ||||
</div> | </div> | ||||
{{end}} | {{end}} | ||||
{{if and (.Permission.CanRead $.UnitTypeCode) (not .IsBareRepo) }} | |||||
{{if and (.Permission.CanRead $.UnitTypeCode) (not .IsEmptyRepo) }} | |||||
<div class="item{{if .PageIsBranches}} active{{end}}"> | <div class="item{{if .PageIsBranches}} active{{end}}"> | ||||
<a href="{{.RepoLink}}/branches/"><i class="octicon octicon-git-branch"></i> <b>{{.BranchesCount}}</b> {{.i18n.Tr (TrN .i18n.Lang .BranchesCount "repo.branch" "repo.branches") }}</a> | <a href="{{.RepoLink}}/branches/"><i class="octicon octicon-git-branch"></i> <b>{{.BranchesCount}}</b> {{.i18n.Tr (TrN .i18n.Lang .BranchesCount "repo.branch" "repo.branches") }}</a> | ||||
</div> | </div> |