Merge remote-tracking branch 'upstream/main' into issue-updates

This commit is contained in:
Anbraten 2024-01-30 16:03:23 +01:00
commit 4947abce8b
124 changed files with 631 additions and 509 deletions

View File

@ -110,7 +110,7 @@ See the [development setup instructions](https://docs.gitea.com/development/hack
### Backend ### Backend
Go dependencies are managed using [Go Modules](https://golang.org/cmd/go/#hdr-Module_maintenance). \ Go dependencies are managed using [Go Modules](https://go.dev/cmd/go/#hdr-Module_maintenance). \
You can find more details in the [go mod documentation](https://go.dev/ref/mod) and the [Go Modules Wiki](https://github.com/golang/go/wiki/Modules). You can find more details in the [go mod documentation](https://go.dev/ref/mod) and the [Go Modules Wiki](https://github.com/golang/go/wiki/Modules).
Pull requests should only modify `go.mod` and `go.sum` where it is related to your change, be it a bugfix or a new feature. \ Pull requests should only modify `go.mod` and `go.sum` where it is related to your change, be it a bugfix or a new feature. \

View File

@ -11,6 +11,7 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository" repo_module "code.gitea.io/gitea/modules/repository"
@ -122,7 +123,7 @@ func runRepoSyncReleases(_ *cli.Context) error {
log.Trace("Processing next %d repos of %d", len(repos), count) log.Trace("Processing next %d repos of %d", len(repos), count)
for _, repo := range repos { for _, repo := range repos {
log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RepoPath()) log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RepoPath())
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
log.Warn("OpenRepository: %v", err) log.Warn("OpenRepository: %v", err)
continue continue

View File

@ -431,7 +431,7 @@ SECRET_KEY =
;SECRET_KEY_URI = file:/etc/gitea/secret_key ;SECRET_KEY_URI = file:/etc/gitea/secret_key
;; ;;
;; Secret used to validate communication within Gitea binary. ;; Secret used to validate communication within Gitea binary.
INTERNAL_TOKEN= INTERNAL_TOKEN =
;; ;;
;; Alternative location to specify internal token, instead of this file; you cannot specify both this and INTERNAL_TOKEN, and must pick one ;; Alternative location to specify internal token, instead of this file; you cannot specify both this and INTERNAL_TOKEN, and must pick one
;INTERNAL_TOKEN_URI = file:/etc/gitea/internal_token ;INTERNAL_TOKEN_URI = file:/etc/gitea/internal_token
@ -524,7 +524,7 @@ INTERNAL_TOKEN=
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Enables OAuth2 provider ;; Enables OAuth2 provider
ENABLE = true ENABLED = true
;; ;;
;; Algorithm used to sign OAuth2 tokens. Valid values: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512, EdDSA ;; Algorithm used to sign OAuth2 tokens. Valid values: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512, EdDSA
;JWT_SIGNING_ALGORITHM = RS256 ;JWT_SIGNING_ALGORITHM = RS256

View File

@ -1107,7 +1107,7 @@ This section only does "set" config, a removed config key from this section won'
## OAuth2 (`oauth2`) ## OAuth2 (`oauth2`)
- `ENABLE`: **true**: Enables OAuth2 provider. - `ENABLED`: **true**: Enables OAuth2 provider.
- `ACCESS_TOKEN_EXPIRATION_TIME`: **3600**: Lifetime of an OAuth2 access token in seconds - `ACCESS_TOKEN_EXPIRATION_TIME`: **3600**: Lifetime of an OAuth2 access token in seconds
- `REFRESH_TOKEN_EXPIRATION_TIME`: **730**: Lifetime of an OAuth2 refresh token in hours - `REFRESH_TOKEN_EXPIRATION_TIME`: **730**: Lifetime of an OAuth2 refresh token in hours
- `INVALIDATE_REFRESH_TOKENS`: **false**: Check if refresh token has already been used - `INVALIDATE_REFRESH_TOKENS`: **false**: Check if refresh token has already been used

View File

@ -1043,7 +1043,7 @@ Gitea 创建以下非唯一队列:
## OAuth2 (`oauth2`) ## OAuth2 (`oauth2`)
- `ENABLE`: **true**启用OAuth2提供者。 - `ENABLED`: **true**启用OAuth2提供者。
- `ACCESS_TOKEN_EXPIRATION_TIME`**3600**OAuth2访问令牌的生命周期以秒为单位。 - `ACCESS_TOKEN_EXPIRATION_TIME`**3600**OAuth2访问令牌的生命周期以秒为单位。
- `REFRESH_TOKEN_EXPIRATION_TIME`**730**OAuth2刷新令牌的生命周期以小时为单位。 - `REFRESH_TOKEN_EXPIRATION_TIME`**730**OAuth2刷新令牌的生命周期以小时为单位。
- `INVALIDATE_REFRESH_TOKENS`**false**:检查刷新令牌是否已被使用。 - `INVALIDATE_REFRESH_TOKENS`**false**:检查刷新令牌是否已被使用。

View File

@ -29,9 +29,9 @@ GITEA_CUSTOM=/home/gitea/custom ./gitea web
* `GOOS` * `GOOS`
* `GOARCH` * `GOARCH`
* [`GOPATH`](https://golang.org/cmd/go/#hdr-GOPATH_environment_variable) * [`GOPATH`](https://go.dev/cmd/go/#hdr-GOPATH_environment_variable)
您可以在[官方文档](https://golang.org/cmd/go/#hdr-Environment_variables)中查阅这些配置参数的详细信息。 您可以在[官方文档](https://go.dev/cmd/go/#hdr-Environment_variables)中查阅这些配置参数的详细信息。
## Gitea 的文件目录 ## Gitea 的文件目录

View File

@ -85,7 +85,7 @@ Text and macros for the mail body
Specifying a _subject_ section is optional (and therefore also the dash line separator). When used, the separator between Specifying a _subject_ section is optional (and therefore also the dash line separator). When used, the separator between
_subject_ and _mail body_ templates requires at least three dashes; no other characters are allowed in the separator line. _subject_ and _mail body_ templates requires at least three dashes; no other characters are allowed in the separator line.
_Subject_ and _mail body_ are parsed by [Golang's template engine](https://golang.org/pkg/text/template/) and _Subject_ and _mail body_ are parsed by [Golang's template engine](https://go.dev/pkg/text/template/) and
are provided with a _metadata context_ assembled for each notification. The context contains the following elements: are provided with a _metadata context_ assembled for each notification. The context contains the following elements:
| Name | Type | Available | Usage | | Name | Type | Available | Usage |
@ -110,7 +110,7 @@ All names are case sensitive.
### The _subject_ part of the template ### The _subject_ part of the template
The template engine used for the mail _subject_ is golang's [`text/template`](https://golang.org/pkg/text/template/). The template engine used for the mail _subject_ is golang's [`text/template`](https://go.dev/pkg/text/template/).
Please refer to the linked documentation for details about its syntax. Please refer to the linked documentation for details about its syntax.
The _subject_ is built using the following steps: The _subject_ is built using the following steps:
@ -138,7 +138,7 @@ the two templates, even if a valid subject template is present.
### The _mail body_ part of the template ### The _mail body_ part of the template
The template engine used for the _mail body_ is golang's [`html/template`](https://golang.org/pkg/html/template/). The template engine used for the _mail body_ is golang's [`html/template`](https://go.dev/pkg/html/template/).
Please refer to the linked documentation for details about its syntax. Please refer to the linked documentation for details about its syntax.
The _mail body_ is parsed after the mail subject, so there is an additional _metadata_ field which is The _mail body_ is parsed after the mail subject, so there is an additional _metadata_ field which is
@ -146,7 +146,7 @@ the actual rendered subject, after all considerations.
The expected result is HTML (including structural elements like`<html>`, `<body>`, etc.). Styling The expected result is HTML (including structural elements like`<html>`, `<body>`, etc.). Styling
through `<style>` blocks, `class` and `style` attributes is possible. However, `html/template` through `<style>` blocks, `class` and `style` attributes is possible. However, `html/template`
does some [automatic escaping](https://golang.org/pkg/html/template/#hdr-Contexts) that should be considered. does some [automatic escaping](https://go.dev/pkg/html/template/#hdr-Contexts) that should be considered.
Attachments (such as images or external style sheets) are not supported. However, other templates can Attachments (such as images or external style sheets) are not supported. However, other templates can
be referenced too, for example to provide the contents of a `<style>` element in a centralized fashion. be referenced too, for example to provide the contents of a `<style>` element in a centralized fashion.

View File

@ -81,7 +81,7 @@ custom/templates/mail/pull/comment.tmpl
指定 _主题_ 部分是可选的因此也是虚线分隔符。在使用时_主题_ 和 _邮件正文_ 模板之间的分隔符需要至少三个虚线;分隔符行中不允许使用其他字符。 指定 _主题_ 部分是可选的因此也是虚线分隔符。在使用时_主题_ 和 _邮件正文_ 模板之间的分隔符需要至少三个虚线;分隔符行中不允许使用其他字符。
_主题_ 和 _邮件正文_ 由 [Golang的模板引擎](https://golang.org/pkg/text/template/) 解析,并提供了为每个通知组装的 _元数据上下文_。上下文包含以下元素: _主题_ 和 _邮件正文_ 由 [Golang的模板引擎](https://go.dev/pkg/text/template/) 解析,并提供了为每个通知组装的 _元数据上下文_。上下文包含以下元素:
| 名称 | 类型 | 可用性 | 用途 | | 名称 | 类型 | 可用性 | 用途 |
| -------------------- | ------------------ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | -------------------- | ------------------ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@ -105,7 +105,7 @@ _主题_ 和 _邮件正文_ 由 [Golang的模板引擎](https://golang.org/pkg/t
### 模板中的主题部分 ### 模板中的主题部分
用于邮件主题的模板引擎是 Golang 的 [`text/template`](https://golang.org/pkg/text/template/)。 用于邮件主题的模板引擎是 Golang 的 [`text/template`](https://go.dev/pkg/text/template/)。
有关语法的详细信息,请参阅链接的文档。 有关语法的详细信息,请参阅链接的文档。
主题构建的步骤如下: 主题构建的步骤如下:
@ -130,12 +130,12 @@ _主题_ 和 _邮件正文_ 由 [Golang的模板引擎](https://golang.org/pkg/t
### 模板中的邮件正文部分 ### 模板中的邮件正文部分
用于邮件正文的模板引擎是 Golang 的 [`html/template`](https://golang.org/pkg/html/template/)。 用于邮件正文的模板引擎是 Golang 的 [`html/template`](https://go.dev/pkg/html/template/)。
有关语法的详细信息,请参阅链接的文档。 有关语法的详细信息,请参阅链接的文档。
邮件正文在邮件主题之后进行解析,因此还有一个额外的 _元数据_ 字段,即在考虑所有情况之后实际呈现的主题。 邮件正文在邮件主题之后进行解析,因此还有一个额外的 _元数据_ 字段,即在考虑所有情况之后实际呈现的主题。
期望的结果是 HTML包括结构元素`<html>``<body>`等)。可以通过 `<style>` 块、`class``style` 属性进行样式设置。但是,`html/template` 会进行一些 [自动转义](https://golang.org/pkg/html/template/#hdr-Contexts),需要考虑这一点。 期望的结果是 HTML包括结构元素`<html>``<body>`等)。可以通过 `<style>` 块、`class``style` 属性进行样式设置。但是,`html/template` 会进行一些 [自动转义](https://go.dev/pkg/html/template/#hdr-Contexts),需要考虑这一点。
不支持附件(例如图像或外部样式表)。但是,也可以引用其他模板,例如以集中方式提供 `<style>` 元素的内容。外部模板必须放置在 `custom/mail` 下,并相对于该目录引用。例如,可以使用 `{{template styles/base}}` 包含 `custom/mail/styles/base.tmpl` 不支持附件(例如图像或外部样式表)。但是,也可以引用其他模板,例如以集中方式提供 `<style>` 元素的内容。外部模板必须放置在 `custom/mail` 下,并相对于该目录引用。例如,可以使用 `{{template styles/base}}` 包含 `custom/mail/styles/base.tmpl`

View File

@ -25,7 +25,7 @@ To get a quick working development environment you could use Gitpod.
## Installing go ## Installing go
You should [install go](https://golang.org/doc/install) and set up your go You should [install go](https://go.dev/doc/install) and set up your go
environment correctly. environment correctly.
Next, [install Node.js with npm](https://nodejs.org/en/download/) which is Next, [install Node.js with npm](https://nodejs.org/en/download/) which is

View File

@ -25,7 +25,7 @@ menu:
## 安装 Golang ## 安装 Golang
您需要 [安装 go]( https://golang.org/doc/install ) 并设置您的 go 环境。 您需要 [安装 go]( https://go.dev/doc/install ) 并设置您的 go 环境。
接下来,[使用 npm 安装 Node.js](https://nodejs.org/en/download/) ,这是构建 接下来,[使用 npm 安装 Node.js](https://nodejs.org/en/download/) ,这是构建
JavaScript 和 CSS 文件的必要工具。最低支持的 Node.js 版本是 @minNodeVersion@ JavaScript 和 CSS 文件的必要工具。最低支持的 Node.js 版本是 @minNodeVersion@

View File

@ -17,7 +17,7 @@ menu:
# Installation from source # Installation from source
You should [install go](https://golang.org/doc/install) and set up your go You should [install go](https://go.dev/doc/install) and set up your go
environment correctly. In particular, it is recommended to set the `$GOPATH` environment correctly. In particular, it is recommended to set the `$GOPATH`
environment variable and to add the go bin directory or directories environment variable and to add the go bin directory or directories
`${GOPATH//://bin:}/bin` to the `$PATH`. See the Go wiki entry for `${GOPATH//://bin:}/bin` to the `$PATH`. See the Go wiki entry for
@ -82,7 +82,7 @@ git checkout v@version@ # or git checkout pr-xyz
To build from source, the following programs must be present on the system: To build from source, the following programs must be present on the system:
- `go` @minGoVersion@ or higher, see [here](https://golang.org/dl/) - `go` @minGoVersion@ or higher, see [here](https://go.dev/dl/)
- `node` @minNodeVersion@ or higher with `npm`, see [here](https://nodejs.org/en/download/) - `node` @minNodeVersion@ or higher with `npm`, see [here](https://nodejs.org/en/download/)
- `make`, see [here](development/hacking-on-gitea.md#installing-make) - `make`, see [here](development/hacking-on-gitea.md#installing-make)
@ -119,7 +119,7 @@ TAGS="bindata sqlite sqlite_unlock_notify" make build
The `build` target is split into two sub-targets: The `build` target is split into two sub-targets:
- `make backend` which requires [Go @minGoVersion@](https://golang.org/dl/) or greater. - `make backend` which requires [Go @minGoVersion@](https://go.dev/dl/) or greater.
- `make frontend` which requires [Node.js @minNodeVersion@](https://nodejs.org/en/download/) or greater. - `make frontend` which requires [Node.js @minNodeVersion@](https://nodejs.org/en/download/) or greater.
If pre-built frontend files are present it is possible to only build the backend: If pre-built frontend files are present it is possible to only build the backend:
@ -165,7 +165,7 @@ Running `gitea help` will allow you to review what the computed settings will be
## Cross Build ## Cross Build
The `go` compiler toolchain supports cross-compiling to different architecture targets that are supported by the toolchain. See [`GOOS` and `GOARCH` environment variable](https://golang.org/doc/install/source#environment) for the list of supported targets. Cross compilation is helpful if you want to build Gitea for less-powerful systems (such as Raspberry Pi). The `go` compiler toolchain supports cross-compiling to different architecture targets that are supported by the toolchain. See [`GOOS` and `GOARCH` environment variable](https://go.dev/doc/install/source#environment) for the list of supported targets. Cross compilation is helpful if you want to build Gitea for less-powerful systems (such as Raspberry Pi).
To cross build Gitea with build tags (`TAGS`), you also need a C cross compiler which targets the same architecture as selected by the `GOOS` and `GOARCH` variables. For example, to cross build for Linux ARM64 (`GOOS=linux` and `GOARCH=arm64`), you need the `aarch64-unknown-linux-gnu-gcc` cross compiler. This is required because Gitea build tags uses `cgo`'s foreign-function interface (FFI). To cross build Gitea with build tags (`TAGS`), you also need a C cross compiler which targets the same architecture as selected by the `GOOS` and `GOARCH` variables. For example, to cross build for Linux ARM64 (`GOOS=linux` and `GOARCH=arm64`), you need the `aarch64-unknown-linux-gnu-gcc` cross compiler. This is required because Gitea build tags uses `cgo`'s foreign-function interface (FFI).

View File

@ -62,7 +62,7 @@ git checkout v@version@ # or git checkout pr-xyz
要从源代码进行构建,系统必须预先安装以下程序: 要从源代码进行构建,系统必须预先安装以下程序:
- `go` @minGoVersion@ 或更高版本,请参阅 [这里](https://golang.org/dl/) - `go` @minGoVersion@ 或更高版本,请参阅 [这里](https://go.dev/dl/)
- `node` @minNodeVersion@ 或更高版本,并且安装 `npm`, 请参阅 [这里](https://nodejs.org/zh-cn/download/) - `node` @minNodeVersion@ 或更高版本,并且安装 `npm`, 请参阅 [这里](https://nodejs.org/zh-cn/download/)
- `make`, 请参阅 [这里](development/hacking-on-gitea.md) - `make`, 请参阅 [这里](development/hacking-on-gitea.md)
@ -128,7 +128,7 @@ Gitea 将从`CustomPath`中查找许多信息。默认的,这会在运行 Gite
## 交叉编译 ## 交叉编译
`go`编译器工具链支持将代码交叉编译到不同的目标架构上。请参考[`GOOS`和`GOARCH`环境变量](https://golang.org/doc/install/source#environment) 以获取支持的目标列表。如果您想为性能较弱的系统(如树莓派)构建 Gitea交叉编译非常有用。 `go`编译器工具链支持将代码交叉编译到不同的目标架构上。请参考[`GOOS`和`GOARCH`环境变量](https://go.dev/doc/install/source#environment) 以获取支持的目标列表。如果您想为性能较弱的系统(如树莓派)构建 Gitea交叉编译非常有用。
要使用构建标签(`TAGS`进行交叉编译Gitea您还需要一个 C 交叉编译器,该编译器的目标架构与`GOOS``GOARCH`变量选择的架构相同。例如,要为 Linux ARM64`GOOS=linux``GOARCH=arm64`)进行交叉编译,您需要`aarch64-unknown-linux-gnu-gcc`交叉编译器。这是因为 Gitea 构建标签使用了`cgo`的外部函数接口FFI 要使用构建标签(`TAGS`进行交叉编译Gitea您还需要一个 C 交叉编译器,该编译器的目标架构与`GOOS``GOARCH`变量选择的架构相同。例如,要为 Linux ARM64`GOOS=linux``GOARCH=arm64`)进行交叉编译,您需要`aarch64-unknown-linux-gnu-gcc`交叉编译器。这是因为 Gitea 构建标签使用了`cgo`的外部函数接口FFI

View File

@ -19,3 +19,7 @@ To display a Markdown file in your Gitea user or organization profile page, crea
Gitea will automatically display the contents of the file on your profile, in a new "Overview" above your repositories. Gitea will automatically display the contents of the file on your profile, in a new "Overview" above your repositories.
Making the `.profile` repository private will hide the Profile README. Making the `.profile` repository private will hide the Profile README.
Example of user with `.profile/README.md`:
![profile readme screenshot](./profile-readme.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -14,6 +14,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"xorm.io/xorm" "xorm.io/xorm"
) )
@ -65,7 +66,7 @@ func GetActivityStats(ctx context.Context, repo *repo_model.Repository, timeFrom
return nil, fmt.Errorf("FillUnresolvedIssues: %w", err) return nil, fmt.Errorf("FillUnresolvedIssues: %w", err)
} }
if code { if code {
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath()) gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
if err != nil { if err != nil {
return nil, fmt.Errorf("OpenRepository: %w", err) return nil, fmt.Errorf("OpenRepository: %w", err)
} }
@ -82,7 +83,7 @@ func GetActivityStats(ctx context.Context, repo *repo_model.Repository, timeFrom
// GetActivityStatsTopAuthors returns top author stats for git commits for all branches // GetActivityStatsTopAuthors returns top author stats for git commits for all branches
func GetActivityStatsTopAuthors(ctx context.Context, repo *repo_model.Repository, timeFrom time.Time, count int) ([]*ActivityAuthorData, error) { func GetActivityStatsTopAuthors(ctx context.Context, repo *repo_model.Repository, timeFrom time.Time, count int) ([]*ActivityAuthorData, error) {
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath()) gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
if err != nil { if err != nil {
return nil, fmt.Errorf("OpenRepository: %w", err) return nil, fmt.Errorf("OpenRepository: %w", err)
} }

View File

@ -133,17 +133,21 @@ type FindOptionsOrder interface {
// Find represents a common find function which accept an options interface // Find represents a common find function which accept an options interface
func Find[T any](ctx context.Context, opts FindOptions) ([]*T, error) { func Find[T any](ctx context.Context, opts FindOptions) ([]*T, error) {
sess := GetEngine(ctx) sess := GetEngine(ctx).Where(opts.ToConds())
if joinOpt, ok := opts.(FindOptionsJoin); ok && len(joinOpt.ToJoins()) > 0 { if joinOpt, ok := opts.(FindOptionsJoin); ok {
for _, joinFunc := range joinOpt.ToJoins() { for _, joinFunc := range joinOpt.ToJoins() {
if err := joinFunc(sess); err != nil { if err := joinFunc(sess); err != nil {
return nil, err return nil, err
} }
} }
} }
if orderOpt, ok := opts.(FindOptionsOrder); ok {
if order := orderOpt.ToOrders(); order != "" {
sess.OrderBy(order)
}
}
sess = sess.Where(opts.ToConds())
page, pageSize := opts.GetPage(), opts.GetPageSize() page, pageSize := opts.GetPage(), opts.GetPageSize()
if !opts.IsListAll() && pageSize > 0 { if !opts.IsListAll() && pageSize > 0 {
if page == 0 { if page == 0 {
@ -151,9 +155,6 @@ func Find[T any](ctx context.Context, opts FindOptions) ([]*T, error) {
} }
sess.Limit(pageSize, (page-1)*pageSize) sess.Limit(pageSize, (page-1)*pageSize)
} }
if newOpt, ok := opts.(FindOptionsOrder); ok && newOpt.ToOrders() != "" {
sess.OrderBy(newOpt.ToOrders())
}
findPageSize := defaultFindSliceSize findPageSize := defaultFindSliceSize
if pageSize > 0 { if pageSize > 0 {
@ -168,8 +169,8 @@ func Find[T any](ctx context.Context, opts FindOptions) ([]*T, error) {
// Count represents a common count function which accept an options interface // Count represents a common count function which accept an options interface
func Count[T any](ctx context.Context, opts FindOptions) (int64, error) { func Count[T any](ctx context.Context, opts FindOptions) (int64, error) {
sess := GetEngine(ctx) sess := GetEngine(ctx).Where(opts.ToConds())
if joinOpt, ok := opts.(FindOptionsJoin); ok && len(joinOpt.ToJoins()) > 0 { if joinOpt, ok := opts.(FindOptionsJoin); ok {
for _, joinFunc := range joinOpt.ToJoins() { for _, joinFunc := range joinOpt.ToJoins() {
if err := joinFunc(sess); err != nil { if err := joinFunc(sess); err != nil {
return 0, err return 0, err
@ -178,7 +179,7 @@ func Count[T any](ctx context.Context, opts FindOptions) (int64, error) {
} }
var object T var object T
return sess.Where(opts.ToConds()).Count(&object) return sess.Count(&object)
} }
// FindAndCount represents a common findandcount function which accept an options interface // FindAndCount represents a common findandcount function which accept an options interface
@ -188,8 +189,17 @@ func FindAndCount[T any](ctx context.Context, opts FindOptions) ([]*T, int64, er
if !opts.IsListAll() && pageSize > 0 && page >= 1 { if !opts.IsListAll() && pageSize > 0 && page >= 1 {
sess.Limit(pageSize, (page-1)*pageSize) sess.Limit(pageSize, (page-1)*pageSize)
} }
if newOpt, ok := opts.(FindOptionsOrder); ok && newOpt.ToOrders() != "" { if joinOpt, ok := opts.(FindOptionsJoin); ok {
sess.OrderBy(newOpt.ToOrders()) for _, joinFunc := range joinOpt.ToJoins() {
if err := joinFunc(sess); err != nil {
return nil, 0, err
}
}
}
if orderOpt, ok := opts.(FindOptionsOrder); ok {
if order := orderOpt.ToOrders(); order != "" {
sess.OrderBy(order)
}
} }
findPageSize := defaultFindSliceSize findPageSize := defaultFindSliceSize

View File

@ -18,7 +18,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/references" "code.gitea.io/gitea/modules/references"
@ -762,8 +762,7 @@ func (c *Comment) LoadPushCommits(ctx context.Context) (err error) {
c.OldCommit = data.CommitIDs[0] c.OldCommit = data.CommitIDs[0]
c.NewCommit = data.CommitIDs[1] c.NewCommit = data.CommitIDs[1]
} else { } else {
repoPath := c.Issue.Repo.RepoPath() gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, c.Issue.Repo)
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repoPath)
if err != nil { if err != nil {
return err return err
} }

View File

@ -19,6 +19,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
@ -865,7 +866,7 @@ func PullRequestCodeOwnersReview(ctx context.Context, pull *Issue, pr *PullReque
return err return err
} }
repo, err := git.OpenRepository(ctx, pr.BaseRepo.RepoPath()) repo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
if err != nil { if err != nil {
return err return err
} }

View File

@ -196,6 +196,14 @@ func init() {
db.RegisterModel(new(Repository)) db.RegisterModel(new(Repository))
} }
func (repo *Repository) GetName() string {
return repo.Name
}
func (repo *Repository) GetOwnerName() string {
return repo.OwnerName
}
// SanitizedOriginalURL returns a sanitized OriginalURL // SanitizedOriginalURL returns a sanitized OriginalURL
func (repo *Repository) SanitizedOriginalURL() string { func (repo *Repository) SanitizedOriginalURL() string {
if repo.OriginalURL == "" { if repo.OriginalURL == "" {

View File

@ -22,17 +22,21 @@ import (
// UTF8BOM is the utf-8 byte-order marker // UTF8BOM is the utf-8 byte-order marker
var UTF8BOM = []byte{'\xef', '\xbb', '\xbf'} var UTF8BOM = []byte{'\xef', '\xbb', '\xbf'}
type ConvertOpts struct {
KeepBOM bool
}
// ToUTF8WithFallbackReader detects the encoding of content and converts to UTF-8 reader if possible // ToUTF8WithFallbackReader detects the encoding of content and converts to UTF-8 reader if possible
func ToUTF8WithFallbackReader(rd io.Reader) io.Reader { func ToUTF8WithFallbackReader(rd io.Reader, opts ConvertOpts) io.Reader {
buf := make([]byte, 2048) buf := make([]byte, 2048)
n, err := util.ReadAtMost(rd, buf) n, err := util.ReadAtMost(rd, buf)
if err != nil { if err != nil {
return io.MultiReader(bytes.NewReader(RemoveBOMIfPresent(buf[:n])), rd) return io.MultiReader(bytes.NewReader(MaybeRemoveBOM(buf[:n], opts)), rd)
} }
charsetLabel, err := DetectEncoding(buf[:n]) charsetLabel, err := DetectEncoding(buf[:n])
if err != nil || charsetLabel == "UTF-8" { if err != nil || charsetLabel == "UTF-8" {
return io.MultiReader(bytes.NewReader(RemoveBOMIfPresent(buf[:n])), rd) return io.MultiReader(bytes.NewReader(MaybeRemoveBOM(buf[:n], opts)), rd)
} }
encoding, _ := charset.Lookup(charsetLabel) encoding, _ := charset.Lookup(charsetLabel)
@ -42,20 +46,20 @@ func ToUTF8WithFallbackReader(rd io.Reader) io.Reader {
return transform.NewReader( return transform.NewReader(
io.MultiReader( io.MultiReader(
bytes.NewReader(RemoveBOMIfPresent(buf[:n])), bytes.NewReader(MaybeRemoveBOM(buf[:n], opts)),
rd, rd,
), ),
encoding.NewDecoder(), encoding.NewDecoder(),
) )
} }
// ToUTF8WithErr converts content to UTF8 encoding // ToUTF8 converts content to UTF8 encoding
func ToUTF8WithErr(content []byte) (string, error) { func ToUTF8(content []byte, opts ConvertOpts) (string, error) {
charsetLabel, err := DetectEncoding(content) charsetLabel, err := DetectEncoding(content)
if err != nil { if err != nil {
return "", err return "", err
} else if charsetLabel == "UTF-8" { } else if charsetLabel == "UTF-8" {
return string(RemoveBOMIfPresent(content)), nil return string(MaybeRemoveBOM(content, opts)), nil
} }
encoding, _ := charset.Lookup(charsetLabel) encoding, _ := charset.Lookup(charsetLabel)
@ -70,28 +74,22 @@ func ToUTF8WithErr(content []byte) (string, error) {
result = append(result, content[n:]...) result = append(result, content[n:]...)
} }
result = RemoveBOMIfPresent(result) result = MaybeRemoveBOM(result, opts)
return string(result), err return string(result), err
} }
// ToUTF8WithFallback detects the encoding of content and converts to UTF-8 if possible // ToUTF8WithFallback detects the encoding of content and converts to UTF-8 if possible
func ToUTF8WithFallback(content []byte) []byte { func ToUTF8WithFallback(content []byte, opts ConvertOpts) []byte {
bs, _ := io.ReadAll(ToUTF8WithFallbackReader(bytes.NewReader(content))) bs, _ := io.ReadAll(ToUTF8WithFallbackReader(bytes.NewReader(content), opts))
return bs return bs
} }
// ToUTF8 converts content to UTF8 encoding and ignore error
func ToUTF8(content string) string {
res, _ := ToUTF8WithErr([]byte(content))
return res
}
// ToUTF8DropErrors makes sure the return string is valid utf-8; attempts conversion if possible // ToUTF8DropErrors makes sure the return string is valid utf-8; attempts conversion if possible
func ToUTF8DropErrors(content []byte) []byte { func ToUTF8DropErrors(content []byte, opts ConvertOpts) []byte {
charsetLabel, err := DetectEncoding(content) charsetLabel, err := DetectEncoding(content)
if err != nil || charsetLabel == "UTF-8" { if err != nil || charsetLabel == "UTF-8" {
return RemoveBOMIfPresent(content) return MaybeRemoveBOM(content, opts)
} }
encoding, _ := charset.Lookup(charsetLabel) encoding, _ := charset.Lookup(charsetLabel)
@ -117,11 +115,14 @@ func ToUTF8DropErrors(content []byte) []byte {
} }
} }
return RemoveBOMIfPresent(decoded) return MaybeRemoveBOM(decoded, opts)
} }
// RemoveBOMIfPresent removes a UTF-8 BOM from a []byte // MaybeRemoveBOM removes a UTF-8 BOM from a []byte when opts.KeepBOM is false
func RemoveBOMIfPresent(content []byte) []byte { func MaybeRemoveBOM(content []byte, opts ConvertOpts) []byte {
if opts.KeepBOM {
return content
}
if len(content) > 2 && bytes.Equal(content[0:3], UTF8BOM) { if len(content) > 2 && bytes.Equal(content[0:3], UTF8BOM) {
return content[3:] return content[3:]
} }

View File

@ -30,15 +30,15 @@ func resetDefaultCharsetsOrder() {
} }
} }
func TestRemoveBOMIfPresent(t *testing.T) { func TestMaybeRemoveBOM(t *testing.T) {
res := RemoveBOMIfPresent([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}) res := MaybeRemoveBOM([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, ConvertOpts{})
assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, res) assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, res)
res = RemoveBOMIfPresent([]byte{0xef, 0xbb, 0xbf, 0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}) res = MaybeRemoveBOM([]byte{0xef, 0xbb, 0xbf, 0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, ConvertOpts{})
assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, res) assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, res)
} }
func TestToUTF8WithErr(t *testing.T) { func TestToUTF8(t *testing.T) {
resetDefaultCharsetsOrder() resetDefaultCharsetsOrder()
var res string var res string
var err error var err error
@ -47,53 +47,53 @@ func TestToUTF8WithErr(t *testing.T) {
// locale, so some conversions might behave differently. For that reason, we don't // locale, so some conversions might behave differently. For that reason, we don't
// depend on particular conversions but in expected behaviors. // depend on particular conversions but in expected behaviors.
res, err = ToUTF8WithErr([]byte{0x41, 0x42, 0x43}) res, err = ToUTF8([]byte{0x41, 0x42, 0x43}, ConvertOpts{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "ABC", res) assert.Equal(t, "ABC", res)
// "áéíóú" // "áéíóú"
res, err = ToUTF8WithErr([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}) res, err = ToUTF8([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, ConvertOpts{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, []byte(res)) assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, []byte(res))
// "áéíóú" // "áéíóú"
res, err = ToUTF8WithErr([]byte{ res, err = ToUTF8([]byte{
0xef, 0xbb, 0xbf, 0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xef, 0xbb, 0xbf, 0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3,
0xc3, 0xba, 0xc3, 0xba,
}) }, ConvertOpts{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, []byte(res)) assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, []byte(res))
res, err = ToUTF8WithErr([]byte{ res, err = ToUTF8([]byte{
0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63, 0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63,
0xF3, 0x6D, 0x6F, 0x20, 0xF1, 0x6F, 0x73, 0x41, 0x41, 0x41, 0x2e, 0xF3, 0x6D, 0x6F, 0x20, 0xF1, 0x6F, 0x73, 0x41, 0x41, 0x41, 0x2e,
}) }, ConvertOpts{})
assert.NoError(t, err) assert.NoError(t, err)
stringMustStartWith(t, "Hola,", res) stringMustStartWith(t, "Hola,", res)
stringMustEndWith(t, "AAA.", res) stringMustEndWith(t, "AAA.", res)
res, err = ToUTF8WithErr([]byte{ res, err = ToUTF8([]byte{
0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63, 0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63,
0xF3, 0x6D, 0x6F, 0x20, 0x07, 0xA4, 0x6F, 0x73, 0x41, 0x41, 0x41, 0x2e, 0xF3, 0x6D, 0x6F, 0x20, 0x07, 0xA4, 0x6F, 0x73, 0x41, 0x41, 0x41, 0x2e,
}) }, ConvertOpts{})
assert.NoError(t, err) assert.NoError(t, err)
stringMustStartWith(t, "Hola,", res) stringMustStartWith(t, "Hola,", res)
stringMustEndWith(t, "AAA.", res) stringMustEndWith(t, "AAA.", res)
res, err = ToUTF8WithErr([]byte{ res, err = ToUTF8([]byte{
0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63, 0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63,
0xF3, 0x6D, 0x6F, 0x20, 0x81, 0xA4, 0x6F, 0x73, 0x41, 0x41, 0x41, 0x2e, 0xF3, 0x6D, 0x6F, 0x20, 0x81, 0xA4, 0x6F, 0x73, 0x41, 0x41, 0x41, 0x2e,
}) }, ConvertOpts{})
assert.NoError(t, err) assert.NoError(t, err)
stringMustStartWith(t, "Hola,", res) stringMustStartWith(t, "Hola,", res)
stringMustEndWith(t, "AAA.", res) stringMustEndWith(t, "AAA.", res)
// Japanese (Shift-JIS) // Japanese (Shift-JIS)
// 日属秘ぞしちゅ。 // 日属秘ぞしちゅ。
res, err = ToUTF8WithErr([]byte{ res, err = ToUTF8([]byte{
0x93, 0xFA, 0x91, 0xAE, 0x94, 0xE9, 0x82, 0xBC, 0x82, 0xB5, 0x82, 0x93, 0xFA, 0x91, 0xAE, 0x94, 0xE9, 0x82, 0xBC, 0x82, 0xB5, 0x82,
0xBF, 0x82, 0xE3, 0x81, 0x42, 0xBF, 0x82, 0xE3, 0x81, 0x42,
}) }, ConvertOpts{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, []byte{ assert.Equal(t, []byte{
0xE6, 0x97, 0xA5, 0xE5, 0xB1, 0x9E, 0xE7, 0xA7, 0x98, 0xE3, 0xE6, 0x97, 0xA5, 0xE5, 0xB1, 0x9E, 0xE7, 0xA7, 0x98, 0xE3,
@ -101,7 +101,7 @@ func TestToUTF8WithErr(t *testing.T) {
}, },
[]byte(res)) []byte(res))
res, err = ToUTF8WithErr([]byte{0x00, 0x00, 0x00, 0x00}) res, err = ToUTF8([]byte{0x00, 0x00, 0x00, 0x00}, ConvertOpts{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, []byte{0x00, 0x00, 0x00, 0x00}, []byte(res)) assert.Equal(t, []byte{0x00, 0x00, 0x00, 0x00}, []byte(res))
} }
@ -109,22 +109,22 @@ func TestToUTF8WithErr(t *testing.T) {
func TestToUTF8WithFallback(t *testing.T) { func TestToUTF8WithFallback(t *testing.T) {
resetDefaultCharsetsOrder() resetDefaultCharsetsOrder()
// "ABC" // "ABC"
res := ToUTF8WithFallback([]byte{0x41, 0x42, 0x43}) res := ToUTF8WithFallback([]byte{0x41, 0x42, 0x43}, ConvertOpts{})
assert.Equal(t, []byte{0x41, 0x42, 0x43}, res) assert.Equal(t, []byte{0x41, 0x42, 0x43}, res)
// "áéíóú" // "áéíóú"
res = ToUTF8WithFallback([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}) res = ToUTF8WithFallback([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, ConvertOpts{})
assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, res) assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, res)
// UTF8 BOM + "áéíóú" // UTF8 BOM + "áéíóú"
res = ToUTF8WithFallback([]byte{0xef, 0xbb, 0xbf, 0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}) res = ToUTF8WithFallback([]byte{0xef, 0xbb, 0xbf, 0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, ConvertOpts{})
assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, res) assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, res)
// "Hola, así cómo ños" // "Hola, así cómo ños"
res = ToUTF8WithFallback([]byte{ res = ToUTF8WithFallback([]byte{
0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63, 0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63,
0xF3, 0x6D, 0x6F, 0x20, 0xF1, 0x6F, 0x73, 0xF3, 0x6D, 0x6F, 0x20, 0xF1, 0x6F, 0x73,
}) }, ConvertOpts{})
assert.Equal(t, []byte{ assert.Equal(t, []byte{
0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xC3, 0xAD, 0x20, 0x63, 0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xC3, 0xAD, 0x20, 0x63,
0xC3, 0xB3, 0x6D, 0x6F, 0x20, 0xC3, 0xB1, 0x6F, 0x73, 0xC3, 0xB3, 0x6D, 0x6F, 0x20, 0xC3, 0xB1, 0x6F, 0x73,
@ -133,126 +133,65 @@ func TestToUTF8WithFallback(t *testing.T) {
// "Hola, así cómo " // "Hola, así cómo "
minmatch := []byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xC3, 0xAD, 0x20, 0x63, 0xC3, 0xB3, 0x6D, 0x6F, 0x20} minmatch := []byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xC3, 0xAD, 0x20, 0x63, 0xC3, 0xB3, 0x6D, 0x6F, 0x20}
res = ToUTF8WithFallback([]byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63, 0xF3, 0x6D, 0x6F, 0x20, 0x07, 0xA4, 0x6F, 0x73}) res = ToUTF8WithFallback([]byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63, 0xF3, 0x6D, 0x6F, 0x20, 0x07, 0xA4, 0x6F, 0x73}, ConvertOpts{})
// Do not fail for differences in invalid cases, as the library might change the conversion criteria for those // Do not fail for differences in invalid cases, as the library might change the conversion criteria for those
assert.Equal(t, minmatch, res[0:len(minmatch)]) assert.Equal(t, minmatch, res[0:len(minmatch)])
res = ToUTF8WithFallback([]byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63, 0xF3, 0x6D, 0x6F, 0x20, 0x81, 0xA4, 0x6F, 0x73}) res = ToUTF8WithFallback([]byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63, 0xF3, 0x6D, 0x6F, 0x20, 0x81, 0xA4, 0x6F, 0x73}, ConvertOpts{})
// Do not fail for differences in invalid cases, as the library might change the conversion criteria for those // Do not fail for differences in invalid cases, as the library might change the conversion criteria for those
assert.Equal(t, minmatch, res[0:len(minmatch)]) assert.Equal(t, minmatch, res[0:len(minmatch)])
// Japanese (Shift-JIS) // Japanese (Shift-JIS)
// "日属秘ぞしちゅ。" // "日属秘ぞしちゅ。"
res = ToUTF8WithFallback([]byte{0x93, 0xFA, 0x91, 0xAE, 0x94, 0xE9, 0x82, 0xBC, 0x82, 0xB5, 0x82, 0xBF, 0x82, 0xE3, 0x81, 0x42}) res = ToUTF8WithFallback([]byte{0x93, 0xFA, 0x91, 0xAE, 0x94, 0xE9, 0x82, 0xBC, 0x82, 0xB5, 0x82, 0xBF, 0x82, 0xE3, 0x81, 0x42}, ConvertOpts{})
assert.Equal(t, []byte{ assert.Equal(t, []byte{
0xE6, 0x97, 0xA5, 0xE5, 0xB1, 0x9E, 0xE7, 0xA7, 0x98, 0xE3, 0xE6, 0x97, 0xA5, 0xE5, 0xB1, 0x9E, 0xE7, 0xA7, 0x98, 0xE3,
0x81, 0x9E, 0xE3, 0x81, 0x97, 0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x85, 0xE3, 0x80, 0x82, 0x81, 0x9E, 0xE3, 0x81, 0x97, 0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x85, 0xE3, 0x80, 0x82,
}, res) }, res)
res = ToUTF8WithFallback([]byte{0x00, 0x00, 0x00, 0x00}) res = ToUTF8WithFallback([]byte{0x00, 0x00, 0x00, 0x00}, ConvertOpts{})
assert.Equal(t, []byte{0x00, 0x00, 0x00, 0x00}, res) assert.Equal(t, []byte{0x00, 0x00, 0x00, 0x00}, res)
} }
func TestToUTF8(t *testing.T) {
resetDefaultCharsetsOrder()
// Note: golang compiler seems so behave differently depending on the current
// locale, so some conversions might behave differently. For that reason, we don't
// depend on particular conversions but in expected behaviors.
res := ToUTF8(string([]byte{0x41, 0x42, 0x43}))
assert.Equal(t, "ABC", res)
// "áéíóú"
res = ToUTF8(string([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}))
assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, []byte(res))
// BOM + "áéíóú"
res = ToUTF8(string([]byte{
0xef, 0xbb, 0xbf, 0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3,
0xc3, 0xba,
}))
assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, []byte(res))
// Latin1
// Hola, así cómo ños
res = ToUTF8(string([]byte{
0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63,
0xF3, 0x6D, 0x6F, 0x20, 0xF1, 0x6F, 0x73,
}))
assert.Equal(t, []byte{
0x48, 0x6f, 0x6c, 0x61, 0x2c, 0x20, 0x61, 0x73, 0xc3, 0xad, 0x20, 0x63,
0xc3, 0xb3, 0x6d, 0x6f, 0x20, 0xc3, 0xb1, 0x6f, 0x73,
}, []byte(res))
// Latin1
// Hola, así cómo \x07ños
res = ToUTF8(string([]byte{
0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63,
0xF3, 0x6D, 0x6F, 0x20, 0x07, 0xA4, 0x6F, 0x73,
}))
// Hola,
bytesMustStartWith(t, []byte{0x48, 0x6F, 0x6C, 0x61, 0x2C}, []byte(res))
// This test FAILS
// res = ToUTF8("Hola, así cómo \x81ños")
// Do not fail for differences in invalid cases, as the library might change the conversion criteria for those
// assert.Regexp(t, "^Hola, así cómo", res)
// Japanese (Shift-JIS)
// 日属秘ぞしちゅ。
res = ToUTF8(string([]byte{
0x93, 0xFA, 0x91, 0xAE, 0x94, 0xE9, 0x82, 0xBC, 0x82, 0xB5, 0x82,
0xBF, 0x82, 0xE3, 0x81, 0x42,
}))
assert.Equal(t, []byte{
0xE6, 0x97, 0xA5, 0xE5, 0xB1, 0x9E, 0xE7, 0xA7, 0x98, 0xE3,
0x81, 0x9E, 0xE3, 0x81, 0x97, 0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x85, 0xE3, 0x80, 0x82,
},
[]byte(res))
res = ToUTF8("\x00\x00\x00\x00")
assert.Equal(t, []byte{0x00, 0x00, 0x00, 0x00}, []byte(res))
}
func TestToUTF8DropErrors(t *testing.T) { func TestToUTF8DropErrors(t *testing.T) {
resetDefaultCharsetsOrder() resetDefaultCharsetsOrder()
// "ABC" // "ABC"
res := ToUTF8DropErrors([]byte{0x41, 0x42, 0x43}) res := ToUTF8DropErrors([]byte{0x41, 0x42, 0x43}, ConvertOpts{})
assert.Equal(t, []byte{0x41, 0x42, 0x43}, res) assert.Equal(t, []byte{0x41, 0x42, 0x43}, res)
// "áéíóú" // "áéíóú"
res = ToUTF8DropErrors([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}) res = ToUTF8DropErrors([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, ConvertOpts{})
assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, res) assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, res)
// UTF8 BOM + "áéíóú" // UTF8 BOM + "áéíóú"
res = ToUTF8DropErrors([]byte{0xef, 0xbb, 0xbf, 0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}) res = ToUTF8DropErrors([]byte{0xef, 0xbb, 0xbf, 0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, ConvertOpts{})
assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, res) assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, res)
// "Hola, así cómo ños" // "Hola, así cómo ños"
res = ToUTF8DropErrors([]byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63, 0xF3, 0x6D, 0x6F, 0x20, 0xF1, 0x6F, 0x73}) res = ToUTF8DropErrors([]byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63, 0xF3, 0x6D, 0x6F, 0x20, 0xF1, 0x6F, 0x73}, ConvertOpts{})
assert.Equal(t, []byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73}, res[:8]) assert.Equal(t, []byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73}, res[:8])
assert.Equal(t, []byte{0x73}, res[len(res)-1:]) assert.Equal(t, []byte{0x73}, res[len(res)-1:])
// "Hola, así cómo " // "Hola, así cómo "
minmatch := []byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xC3, 0xAD, 0x20, 0x63, 0xC3, 0xB3, 0x6D, 0x6F, 0x20} minmatch := []byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xC3, 0xAD, 0x20, 0x63, 0xC3, 0xB3, 0x6D, 0x6F, 0x20}
res = ToUTF8DropErrors([]byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63, 0xF3, 0x6D, 0x6F, 0x20, 0x07, 0xA4, 0x6F, 0x73}) res = ToUTF8DropErrors([]byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63, 0xF3, 0x6D, 0x6F, 0x20, 0x07, 0xA4, 0x6F, 0x73}, ConvertOpts{})
// Do not fail for differences in invalid cases, as the library might change the conversion criteria for those // Do not fail for differences in invalid cases, as the library might change the conversion criteria for those
assert.Equal(t, minmatch, res[0:len(minmatch)]) assert.Equal(t, minmatch, res[0:len(minmatch)])
res = ToUTF8DropErrors([]byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63, 0xF3, 0x6D, 0x6F, 0x20, 0x81, 0xA4, 0x6F, 0x73}) res = ToUTF8DropErrors([]byte{0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63, 0xF3, 0x6D, 0x6F, 0x20, 0x81, 0xA4, 0x6F, 0x73}, ConvertOpts{})
// Do not fail for differences in invalid cases, as the library might change the conversion criteria for those // Do not fail for differences in invalid cases, as the library might change the conversion criteria for those
assert.Equal(t, minmatch, res[0:len(minmatch)]) assert.Equal(t, minmatch, res[0:len(minmatch)])
// Japanese (Shift-JIS) // Japanese (Shift-JIS)
// "日属秘ぞしちゅ。" // "日属秘ぞしちゅ。"
res = ToUTF8DropErrors([]byte{0x93, 0xFA, 0x91, 0xAE, 0x94, 0xE9, 0x82, 0xBC, 0x82, 0xB5, 0x82, 0xBF, 0x82, 0xE3, 0x81, 0x42}) res = ToUTF8DropErrors([]byte{0x93, 0xFA, 0x91, 0xAE, 0x94, 0xE9, 0x82, 0xBC, 0x82, 0xB5, 0x82, 0xBF, 0x82, 0xE3, 0x81, 0x42}, ConvertOpts{})
assert.Equal(t, []byte{ assert.Equal(t, []byte{
0xE6, 0x97, 0xA5, 0xE5, 0xB1, 0x9E, 0xE7, 0xA7, 0x98, 0xE3, 0xE6, 0x97, 0xA5, 0xE5, 0xB1, 0x9E, 0xE7, 0xA7, 0x98, 0xE3,
0x81, 0x9E, 0xE3, 0x81, 0x97, 0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x85, 0xE3, 0x80, 0x82, 0x81, 0x9E, 0xE3, 0x81, 0x97, 0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x85, 0xE3, 0x80, 0x82,
}, res) }, res)
res = ToUTF8DropErrors([]byte{0x00, 0x00, 0x00, 0x00}) res = ToUTF8DropErrors([]byte{0x00, 0x00, 0x00, 0x00}, ConvertOpts{})
assert.Equal(t, []byte{0x00, 0x00, 0x00, 0x00}, res) assert.Equal(t, []byte{0x00, 0x00, 0x00, 0x00}, res)
} }
@ -302,10 +241,6 @@ func stringMustEndWith(t *testing.T, expected, value string) {
assert.Equal(t, expected, value[len(value)-len(expected):]) assert.Equal(t, expected, value[len(value)-len(expected):])
} }
func bytesMustStartWith(t *testing.T, expected, value []byte) {
assert.Equal(t, expected, value[:len(expected)])
}
func TestToUTF8WithFallbackReader(t *testing.T) { func TestToUTF8WithFallbackReader(t *testing.T) {
resetDefaultCharsetsOrder() resetDefaultCharsetsOrder()
@ -317,7 +252,7 @@ func TestToUTF8WithFallbackReader(t *testing.T) {
} }
input = input[:testLen] input = input[:testLen]
input += "// Выключаем" input += "// Выключаем"
rd := ToUTF8WithFallbackReader(bytes.NewReader([]byte(input))) rd := ToUTF8WithFallbackReader(bytes.NewReader([]byte(input)), ConvertOpts{})
r, _ := io.ReadAll(rd) r, _ := io.ReadAll(rd)
assert.EqualValuesf(t, input, string(r), "testing string len=%d", testLen) assert.EqualValuesf(t, input, string(r), "testing string len=%d", testLen)
} }

View File

@ -11,11 +11,11 @@ import (
"net/url" "net/url"
"strings" "strings"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
mc "code.gitea.io/gitea/modules/cache" mc "code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/httpcache"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -224,7 +224,7 @@ func APIContexter() func(http.Handler) http.Handler {
defer baseCleanUp() defer baseCleanUp()
ctx.Base.AppendContextValue(apiContextKey, ctx) ctx.Base.AppendContextValue(apiContextKey, ctx)
ctx.Base.AppendContextValueFunc(git.RepositoryContextKey, func() any { return ctx.Repo.GitRepo }) ctx.Base.AppendContextValueFunc(gitrepo.RepositoryContextKey, func() any { return ctx.Repo.GitRepo })
// If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid. // If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid.
if ctx.Req.Method == "POST" && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") { if ctx.Req.Method == "POST" && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") {
@ -278,10 +278,9 @@ func ReferencesGitRepo(allowEmpty ...bool) func(ctx *APIContext) (cancel context
// For API calls. // For API calls.
if ctx.Repo.GitRepo == nil { if ctx.Repo.GitRepo == nil {
repoPath := repo_model.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
gitRepo, err := git.OpenRepository(ctx, repoPath)
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "RepoRef Invalid repo "+repoPath, err) ctx.Error(http.StatusInternalServerError, fmt.Sprintf("Open Repository %v failed", ctx.Repo.Repository.FullName()), err)
return cancel return cancel
} }
ctx.Repo.GitRepo = gitRepo ctx.Repo.GitRepo = gitRepo

View File

@ -17,7 +17,7 @@ import (
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
mc "code.gitea.io/gitea/modules/cache" mc "code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/httpcache"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/templates"
@ -163,7 +163,7 @@ func Contexter() func(next http.Handler) http.Handler {
ctx.Data["PageData"] = ctx.PageData ctx.Data["PageData"] = ctx.PageData
ctx.Base.AppendContextValue(WebContextKey, ctx) ctx.Base.AppendContextValue(WebContextKey, ctx)
ctx.Base.AppendContextValueFunc(git.RepositoryContextKey, func() any { return ctx.Repo.GitRepo }) ctx.Base.AppendContextValueFunc(gitrepo.RepositoryContextKey, func() any { return ctx.Repo.GitRepo })
ctx.Csrf = PrepareCSRFProtector(csrfOpts, ctx) ctx.Csrf = PrepareCSRFProtector(csrfOpts, ctx)

View File

@ -23,6 +23,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
code_indexer "code.gitea.io/gitea/modules/indexer/code" code_indexer "code.gitea.io/gitea/modules/indexer/code"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository" repo_module "code.gitea.io/gitea/modules/repository"
@ -633,7 +634,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
return nil return nil
} }
gitRepo, err := git.OpenRepository(ctx, repo_model.RepoPath(userName, repoName)) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "repository does not exist") || strings.Contains(err.Error(), "no such file or directory") { if strings.Contains(err.Error(), "repository does not exist") || strings.Contains(err.Error(), "no such file or directory") {
log.Error("Repository %-v has a broken repository on the file system: %s Error: %v", ctx.Repo.Repository, ctx.Repo.Repository.RepoPath(), err) log.Error("Repository %-v has a broken repository on the file system: %s Error: %v", ctx.Repo.Repository, ctx.Repo.Repository.RepoPath(), err)
@ -645,7 +646,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
} }
return nil return nil
} }
ctx.ServerError("RepoAssignment Invalid repo "+repo_model.RepoPath(userName, repoName), err) ctx.ServerError("RepoAssignment Invalid repo "+repo.FullName(), err)
return nil return nil
} }
if ctx.Repo.GitRepo != nil { if ctx.Repo.GitRepo != nil {
@ -920,10 +921,9 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
) )
if ctx.Repo.GitRepo == nil { if ctx.Repo.GitRepo == nil {
repoPath := repo_model.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) ctx.Repo.GitRepo, err = gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
ctx.Repo.GitRepo, err = git.OpenRepository(ctx, repoPath)
if err != nil { if err != nil {
ctx.ServerError("RepoRef Invalid repo "+repoPath, err) ctx.ServerError(fmt.Sprintf("Open Repository %v failed", ctx.Repo.Repository.FullName()), err)
return nil return nil
} }
// We opened it, we should close it // We opened it, we should close it

View File

@ -18,7 +18,7 @@ import (
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/modules/translation"
"code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/modules/web/middleware"
@ -107,7 +107,7 @@ func LoadRepoCommit(t *testing.T, ctx gocontext.Context) {
assert.FailNow(t, "context is not *context.Context or *context.APIContext") assert.FailNow(t, "context is not *context.Context or *context.APIContext")
} }
gitRepo, err := git.OpenRepository(ctx, repo.Repository.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo.Repository)
assert.NoError(t, err) assert.NoError(t, err)
defer gitRepo.Close() defer gitRepo.Close()
branch, err := gitRepo.GetHEADBranch() branch, err := gitRepo.GetHEADBranch()
@ -137,7 +137,7 @@ func LoadUser(t *testing.T, ctx gocontext.Context, userID int64) {
func LoadGitRepo(t *testing.T, ctx *context.Context) { func LoadGitRepo(t *testing.T, ctx *context.Context) {
assert.NoError(t, ctx.Repo.Repository.LoadOwner(ctx)) assert.NoError(t, ctx.Repo.Repository.LoadOwner(ctx))
var err error var err error
ctx.Repo.GitRepo, err = git.OpenRepository(ctx, ctx.Repo.Repository.RepoPath()) ctx.Repo.GitRepo, err = gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
assert.NoError(t, err) assert.NoError(t, err)
} }

View File

@ -3,48 +3,4 @@
package git package git
import (
"context"
"io"
)
var isGogit bool var isGogit bool
// contextKey is a value for use with context.WithValue.
type contextKey struct {
name string
}
// RepositoryContextKey is a context key. It is used with context.Value() to get the current Repository for the context
var RepositoryContextKey = &contextKey{"repository"}
// RepositoryFromContext attempts to get the repository from the context
func RepositoryFromContext(ctx context.Context, path string) *Repository {
value := ctx.Value(RepositoryContextKey)
if value == nil {
return nil
}
if repo, ok := value.(*Repository); ok && repo != nil {
if repo.Path == path {
return repo
}
}
return nil
}
type nopCloser func()
func (nopCloser) Close() error { return nil }
// RepositoryFromContextOrOpen attempts to get the repository from the context or just opens it
func RepositoryFromContextOrOpen(ctx context.Context, path string) (*Repository, io.Closer, error) {
gitRepo := RepositoryFromContext(ctx, path)
if gitRepo != nil {
return gitRepo, nopCloser(nil), nil
}
gitRepo, err := OpenRepository(ctx, path)
return gitRepo, gitRepo, err
}

View File

@ -86,29 +86,6 @@ func (repo *Repository) GetBranch(branch string) (*Branch, error) {
}, nil }, nil
} }
// GetBranchesByPath returns a branch by it's path
// if limit = 0 it will not limit
func GetBranchesByPath(ctx context.Context, path string, skip, limit int) ([]*Branch, int, error) {
gitRepo, err := OpenRepository(ctx, path)
if err != nil {
return nil, 0, err
}
defer gitRepo.Close()
return gitRepo.GetBranches(skip, limit)
}
// GetBranchCommitID returns a branch commit ID by its name
func GetBranchCommitID(ctx context.Context, path, branch string) (string, error) {
gitRepo, err := OpenRepository(ctx, path)
if err != nil {
return "", err
}
defer gitRepo.Close()
return gitRepo.GetBranchCommitID(branch)
}
// GetBranches returns a slice of *git.Branch // GetBranches returns a slice of *git.Branch
func (repo *Repository) GetBranches(skip, limit int) ([]*Branch, int, error) { func (repo *Repository) GetBranches(skip, limit int) ([]*Branch, int, error) {
brs, countAll, err := repo.GetBranchNames(skip, limit) brs, countAll, err := repo.GetBranchNames(skip, limit)

View File

@ -7,7 +7,6 @@
package git package git
import ( import (
"context"
"sort" "sort"
"strings" "strings"
@ -95,34 +94,6 @@ func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) {
return branchNames, len(branchData), nil return branchNames, len(branchData), nil
} }
// WalkReferences walks all the references from the repository
// refType should be empty, ObjectTag or ObjectBranch. All other values are equivalent to empty.
func WalkReferences(ctx context.Context, repoPath string, walkfn func(sha1, refname string) error) (int, error) {
repo := RepositoryFromContext(ctx, repoPath)
if repo == nil {
var err error
repo, err = OpenRepository(ctx, repoPath)
if err != nil {
return 0, err
}
defer repo.Close()
}
i := 0
iter, err := repo.gogitRepo.References()
if err != nil {
return i, err
}
defer iter.Close()
err = iter.ForEach(func(ref *plumbing.Reference) error {
err := walkfn(ref.Hash().String(), string(ref.Name()))
i++
return err
})
return i, err
}
// WalkReferences walks all the references from the repository // WalkReferences walks all the references from the repository
func (repo *Repository) WalkReferences(arg ObjectType, skip, limit int, walkfn func(sha1, refname string) error) (int, error) { func (repo *Repository) WalkReferences(arg ObjectType, skip, limit int, walkfn func(sha1, refname string) error) (int, error) {
i := 0 i := 0

View File

@ -65,11 +65,6 @@ func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) {
return callShowRef(repo.Ctx, repo.Path, BranchPrefix, TrustedCmdArgs{BranchPrefix, "--sort=-committerdate"}, skip, limit) return callShowRef(repo.Ctx, repo.Path, BranchPrefix, TrustedCmdArgs{BranchPrefix, "--sort=-committerdate"}, skip, limit)
} }
// WalkReferences walks all the references from the repository
func WalkReferences(ctx context.Context, repoPath string, walkfn func(sha1, refname string) error) (int, error) {
return walkShowRef(ctx, repoPath, nil, 0, 0, walkfn)
}
// WalkReferences walks all the references from the repository // WalkReferences walks all the references from the repository
// refType should be empty, ObjectTag or ObjectBranch. All other values are equivalent to empty. // refType should be empty, ObjectTag or ObjectBranch. All other values are equivalent to empty.
func (repo *Repository) WalkReferences(refType ObjectType, skip, limit int, walkfn func(sha1, refname string) error) (int, error) { func (repo *Repository) WalkReferences(refType ObjectType, skip, limit int, walkfn func(sha1, refname string) error) (int, error) {
@ -81,12 +76,12 @@ func (repo *Repository) WalkReferences(refType ObjectType, skip, limit int, walk
args = TrustedCmdArgs{BranchPrefix, "--sort=-committerdate"} args = TrustedCmdArgs{BranchPrefix, "--sort=-committerdate"}
} }
return walkShowRef(repo.Ctx, repo.Path, args, skip, limit, walkfn) return WalkShowRef(repo.Ctx, repo.Path, args, skip, limit, walkfn)
} }
// callShowRef return refs, if limit = 0 it will not limit // callShowRef return refs, if limit = 0 it will not limit
func callShowRef(ctx context.Context, repoPath, trimPrefix string, extraArgs TrustedCmdArgs, skip, limit int) (branchNames []string, countAll int, err error) { func callShowRef(ctx context.Context, repoPath, trimPrefix string, extraArgs TrustedCmdArgs, skip, limit int) (branchNames []string, countAll int, err error) {
countAll, err = walkShowRef(ctx, repoPath, extraArgs, skip, limit, func(_, branchName string) error { countAll, err = WalkShowRef(ctx, repoPath, extraArgs, skip, limit, func(_, branchName string) error {
branchName = strings.TrimPrefix(branchName, trimPrefix) branchName = strings.TrimPrefix(branchName, trimPrefix)
branchNames = append(branchNames, branchName) branchNames = append(branchNames, branchName)
@ -95,7 +90,7 @@ func callShowRef(ctx context.Context, repoPath, trimPrefix string, extraArgs Tru
return branchNames, countAll, err return branchNames, countAll, err
} }
func walkShowRef(ctx context.Context, repoPath string, extraArgs TrustedCmdArgs, skip, limit int, walkfn func(sha1, refname string) error) (countAll int, err error) { func WalkShowRef(ctx context.Context, repoPath string, extraArgs TrustedCmdArgs, skip, limit int, walkfn func(sha1, refname string) error) (countAll int, err error) {
stdoutReader, stdoutWriter := io.Pipe() stdoutReader, stdoutWriter := io.Pipe()
defer func() { defer func() {
_ = stdoutReader.Close() _ = stdoutReader.Close()
@ -189,7 +184,7 @@ func walkShowRef(ctx context.Context, repoPath string, extraArgs TrustedCmdArgs,
// GetRefsBySha returns all references filtered with prefix that belong to a sha commit hash // GetRefsBySha returns all references filtered with prefix that belong to a sha commit hash
func (repo *Repository) GetRefsBySha(sha, prefix string) ([]string, error) { func (repo *Repository) GetRefsBySha(sha, prefix string) ([]string, error) {
var revList []string var revList []string
_, err := walkShowRef(repo.Ctx, repo.Path, nil, 0, 0, func(walkSha, refname string) error { _, err := WalkShowRef(repo.Ctx, repo.Path, nil, 0, 0, func(walkSha, refname string) error {
if walkSha == sha && strings.HasPrefix(refname, prefix) { if walkSha == sha && strings.HasPrefix(refname, prefix) {
revList = append(revList, refname) revList = append(revList, refname)
} }

32
modules/gitrepo/branch.go Normal file
View File

@ -0,0 +1,32 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package gitrepo
import (
"context"
"code.gitea.io/gitea/modules/git"
)
// GetBranchesByPath returns a branch by its path
// if limit = 0 it will not limit
func GetBranchesByPath(ctx context.Context, repo Repository, skip, limit int) ([]*git.Branch, int, error) {
gitRepo, err := OpenRepository(ctx, repo)
if err != nil {
return nil, 0, err
}
defer gitRepo.Close()
return gitRepo.GetBranches(skip, limit)
}
func GetBranchCommitID(ctx context.Context, repo Repository, branch string) (string, error) {
gitRepo, err := OpenRepository(ctx, repo)
if err != nil {
return "", err
}
defer gitRepo.Close()
return gitRepo.GetBranchCommitID(branch)
}

103
modules/gitrepo/gitrepo.go Normal file
View File

@ -0,0 +1,103 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package gitrepo
import (
"context"
"io"
"path/filepath"
"strings"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
)
type Repository interface {
GetName() string
GetOwnerName() string
}
func repoPath(repo Repository) string {
return filepath.Join(setting.RepoRootPath, strings.ToLower(repo.GetOwnerName()), strings.ToLower(repo.GetName())+".git")
}
func wikiPath(repo Repository) string {
return filepath.Join(setting.RepoRootPath, strings.ToLower(repo.GetOwnerName()), strings.ToLower(repo.GetName())+".wiki.git")
}
// OpenRepository opens the repository at the given relative path with the provided context.
func OpenRepository(ctx context.Context, repo Repository) (*git.Repository, error) {
return git.OpenRepository(ctx, repoPath(repo))
}
func OpenWikiRepository(ctx context.Context, repo Repository) (*git.Repository, error) {
return git.OpenRepository(ctx, wikiPath(repo))
}
// contextKey is a value for use with context.WithValue.
type contextKey struct {
name string
}
// RepositoryContextKey is a context key. It is used with context.Value() to get the current Repository for the context
var RepositoryContextKey = &contextKey{"repository"}
// RepositoryFromContext attempts to get the repository from the context
func repositoryFromContext(ctx context.Context, repo Repository) *git.Repository {
value := ctx.Value(RepositoryContextKey)
if value == nil {
return nil
}
if gitRepo, ok := value.(*git.Repository); ok && gitRepo != nil {
if gitRepo.Path == repoPath(repo) {
return gitRepo
}
}
return nil
}
type nopCloser func()
func (nopCloser) Close() error { return nil }
// RepositoryFromContextOrOpen attempts to get the repository from the context or just opens it
func RepositoryFromContextOrOpen(ctx context.Context, repo Repository) (*git.Repository, io.Closer, error) {
gitRepo := repositoryFromContext(ctx, repo)
if gitRepo != nil {
return gitRepo, nopCloser(nil), nil
}
gitRepo, err := OpenRepository(ctx, repo)
return gitRepo, gitRepo, err
}
// repositoryFromContextPath attempts to get the repository from the context
func repositoryFromContextPath(ctx context.Context, path string) *git.Repository {
value := ctx.Value(RepositoryContextKey)
if value == nil {
return nil
}
if repo, ok := value.(*git.Repository); ok && repo != nil {
if repo.Path == path {
return repo
}
}
return nil
}
// RepositoryFromContextOrOpenPath attempts to get the repository from the context or just opens it
// Deprecated: Use RepositoryFromContextOrOpen instead
func RepositoryFromContextOrOpenPath(ctx context.Context, path string) (*git.Repository, io.Closer, error) {
gitRepo := repositoryFromContextPath(ctx, path)
if gitRepo != nil {
return gitRepo, nopCloser(nil), nil
}
gitRepo, err := git.OpenRepository(ctx, path)
return gitRepo, gitRepo, err
}

View File

@ -0,0 +1,40 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
//go:build gogit
package gitrepo
import (
"context"
"github.com/go-git/go-git/v5/plumbing"
)
// WalkReferences walks all the references from the repository
// refname is empty, ObjectTag or ObjectBranch. All other values should be treated as equivalent to empty.
func WalkReferences(ctx context.Context, repo Repository, walkfn func(sha1, refname string) error) (int, error) {
gitRepo := repositoryFromContext(ctx, repo)
if gitRepo == nil {
var err error
gitRepo, err = OpenRepository(ctx, repo)
if err != nil {
return 0, err
}
defer gitRepo.Close()
}
i := 0
iter, err := gitRepo.GoGitRepo().References()
if err != nil {
return i, err
}
defer iter.Close()
err = iter.ForEach(func(ref *plumbing.Reference) error {
err := walkfn(ref.Hash().String(), string(ref.Name()))
i++
return err
})
return i, err
}

View File

@ -0,0 +1,17 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
//go:build !gogit
package gitrepo
import (
"context"
"code.gitea.io/gitea/modules/git"
)
// WalkReferences walks all the references from the repository
func WalkReferences(ctx context.Context, repo Repository, walkfn func(sha1, refname string) error) (int, error) {
return git.WalkShowRef(ctx, repoPath(repo), nil, 0, 0, walkfn)
}

View File

@ -59,7 +59,7 @@ func checkIfNoneMatchIsValid(req *http.Request, etag string) bool {
ifNoneMatch := req.Header.Get("If-None-Match") ifNoneMatch := req.Header.Get("If-None-Match")
if len(ifNoneMatch) > 0 { if len(ifNoneMatch) > 0 {
for _, item := range strings.Split(ifNoneMatch, ",") { for _, item := range strings.Split(ifNoneMatch, ",") {
item = strings.TrimSpace(item) item = strings.TrimPrefix(strings.TrimSpace(item), "W/") // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag#directives
if item == etag { if item == etag {
return true return true
} }

View File

@ -174,7 +174,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
return batch.Index(id, &RepoIndexerData{ return batch.Index(id, &RepoIndexerData{
RepoID: repo.ID, RepoID: repo.ID,
CommitID: commitSha, CommitID: commitSha,
Content: string(charset.ToUTF8DropErrors(fileContents)), Content: string(charset.ToUTF8DropErrors(fileContents, charset.ConvertOpts{})),
Language: analyze.GetCodeLanguage(update.Filename, fileContents), Language: analyze.GetCodeLanguage(update.Filename, fileContents),
UpdatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC(),
}) })

View File

@ -135,7 +135,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
Id(id). Id(id).
Doc(map[string]any{ Doc(map[string]any{
"repo_id": repo.ID, "repo_id": repo.ID,
"content": string(charset.ToUTF8DropErrors(fileContents)), "content": string(charset.ToUTF8DropErrors(fileContents, charset.ConvertOpts{})),
"commit_id": sha, "commit_id": sha,
"language": analyze.GetCodeLanguage(update.Filename, fileContents), "language": analyze.GetCodeLanguage(update.Filename, fileContents),
"updated_at": timeutil.TimeStampNow(), "updated_at": timeutil.TimeStampNow(),

View File

@ -8,6 +8,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
@ -35,7 +36,7 @@ func (db *DBIndexer) Index(id int64) error {
return err return err
} }
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
if err.Error() == "no such file or directory" { if err.Error() == "no such file or directory" {
return nil return nil

View File

@ -11,6 +11,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
) )
@ -24,9 +25,9 @@ func SyncRepoBranches(ctx context.Context, repoID, doerID int64) (int64, error)
log.Debug("SyncRepoBranches: in Repo[%d:%s]", repo.ID, repo.FullName()) log.Debug("SyncRepoBranches: in Repo[%d:%s]", repo.ID, repo.FullName())
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
log.Error("OpenRepository[%s]: %w", repo.RepoPath(), err) log.Error("OpenRepository[%s]: %w", repo.FullName(), err)
return 0, err return 0, err
} }
defer gitRepo.Close() defer gitRepo.Close()

View File

@ -19,6 +19,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
@ -223,8 +224,7 @@ func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *r
} }
} }
// FIXME: fix the hash if err := git.InitRepository(ctx, tmpDir, false, templateRepo.ObjectFormatName); err != nil {
if err := git.InitRepository(ctx, tmpDir, false, git.Sha1ObjectFormat.Name()); err != nil {
return err return err
} }
@ -271,7 +271,7 @@ func generateGitContent(ctx context.Context, repo, templateRepo, generateRepo *r
repo.DefaultBranch = templateRepo.DefaultBranch repo.DefaultBranch = templateRepo.DefaultBranch
} }
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
return fmt.Errorf("openRepository: %w", err) return fmt.Errorf("openRepository: %w", err)
} }
@ -338,6 +338,7 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ
IsFsckEnabled: templateRepo.IsFsckEnabled, IsFsckEnabled: templateRepo.IsFsckEnabled,
TemplateID: templateRepo.ID, TemplateID: templateRepo.ID,
TrustModel: templateRepo.TrustModel, TrustModel: templateRepo.TrustModel,
ObjectFormatName: templateRepo.ObjectFormatName,
} }
if err = CreateRepositoryByExample(ctx, doer, owner, generateRepo, false, false); err != nil { if err = CreateRepositoryByExample(ctx, doer, owner, generateRepo, false, false); err != nil {
@ -357,8 +358,7 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ
} }
} }
// FIXME - fix the hash if err = CheckInitRepository(ctx, owner.Name, generateRepo.Name, generateRepo.ObjectFormatName); err != nil {
if err = CheckInitRepository(ctx, owner.Name, generateRepo.Name, git.Sha1ObjectFormat.Name()); err != nil {
return generateRepo, err return generateRepo, err
} }

View File

@ -19,6 +19,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/migration" "code.gitea.io/gitea/modules/migration"
@ -291,7 +292,7 @@ func SyncRepoTags(ctx context.Context, repoID int64) error {
return err return err
} }
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
return err return err
} }

View File

@ -93,7 +93,7 @@ func parseScopes(sec ConfigSection, name string) []string {
} }
var OAuth2 = struct { var OAuth2 = struct {
Enable bool Enabled bool
AccessTokenExpirationTime int64 AccessTokenExpirationTime int64
RefreshTokenExpirationTime int64 RefreshTokenExpirationTime int64
InvalidateRefreshTokens bool InvalidateRefreshTokens bool
@ -103,7 +103,7 @@ var OAuth2 = struct {
MaxTokenLength int MaxTokenLength int
DefaultApplications []string DefaultApplications []string
}{ }{
Enable: true, Enabled: true,
AccessTokenExpirationTime: 3600, AccessTokenExpirationTime: 3600,
RefreshTokenExpirationTime: 730, RefreshTokenExpirationTime: 730,
InvalidateRefreshTokens: false, InvalidateRefreshTokens: false,
@ -114,16 +114,23 @@ var OAuth2 = struct {
} }
func loadOAuth2From(rootCfg ConfigProvider) { func loadOAuth2From(rootCfg ConfigProvider) {
if err := rootCfg.Section("oauth2").MapTo(&OAuth2); err != nil { sec := rootCfg.Section("oauth2")
log.Fatal("Failed to OAuth2 settings: %v", err) if err := sec.MapTo(&OAuth2); err != nil {
log.Fatal("Failed to map OAuth2 settings: %v", err)
return return
} }
if !OAuth2.Enable { // Handle the rename of ENABLE to ENABLED
deprecatedSetting(rootCfg, "oauth2", "ENABLE", "oauth2", "ENABLED", "v1.23.0")
if sec.HasKey("ENABLE") && !sec.HasKey("ENABLED") {
OAuth2.Enabled = sec.Key("ENABLE").MustBool(OAuth2.Enabled)
}
if !OAuth2.Enabled {
return return
} }
OAuth2.JWTSecretBase64 = loadSecret(rootCfg.Section("oauth2"), "JWT_SECRET_URI", "JWT_SECRET") OAuth2.JWTSecretBase64 = loadSecret(sec, "JWT_SECRET_URI", "JWT_SECRET")
if !filepath.IsAbs(OAuth2.JWTSigningPrivateKeyFile) { if !filepath.IsAbs(OAuth2.JWTSigningPrivateKeyFile) {
OAuth2.JWTSigningPrivateKeyFile = filepath.Join(AppDataPath, OAuth2.JWTSigningPrivateKeyFile) OAuth2.JWTSigningPrivateKeyFile = filepath.Join(AppDataPath, OAuth2.JWTSigningPrivateKeyFile)

View File

@ -0,0 +1,6 @@
--- Optional exception to the license ---
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into a machine-executable object form of such
source code, you may redistribute such embedded portions in such object form
without including the above copyright and permission notices.

View File

@ -186,7 +186,7 @@ app_desc = A painless, self-hosted Git service
install = Easy to install install = Easy to install
install_desc = Simply <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.com/installation/install-from-binary">run the binary</a> for your platform, ship it with <a target="_blank" rel="noopener noreferrer" href="https://github.com/go-gitea/gitea/tree/master/docker">Docker</a>, or get it <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.com/installation/install-from-package">packaged</a>. install_desc = Simply <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.com/installation/install-from-binary">run the binary</a> for your platform, ship it with <a target="_blank" rel="noopener noreferrer" href="https://github.com/go-gitea/gitea/tree/master/docker">Docker</a>, or get it <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.com/installation/install-from-package">packaged</a>.
platform = Cross-platform platform = Cross-platform
platform_desc = Gitea runs anywhere <a target="_blank" rel="noopener noreferrer" href="http://golang.org/">Go</a> can compile for: Windows, macOS, Linux, ARM, etc. Choose the one you love! platform_desc = Gitea runs anywhere <a target="_blank" rel="noopener noreferrer" href="https://go.dev/">Go</a> can compile for: Windows, macOS, Linux, ARM, etc. Choose the one you love!
lightweight = Lightweight lightweight = Lightweight
lightweight_desc = Gitea has low minimal requirements and can run on an inexpensive Raspberry Pi. Save your machine energy! lightweight_desc = Gitea has low minimal requirements and can run on an inexpensive Raspberry Pi. Save your machine energy!
license = Open Source license = Open Source

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" class="gitea-google__svg gitea-google__gitea-google svg gitea-google" viewBox="0 0 48 48" width="16" height="16"><defs><path id="gitea-google__a" d="M44.5 20H24v8.5h11.8C34.7 33.9 30.1 37 24 37c-7.2 0-13-5.8-13-13s5.8-13 13-13c3.1 0 5.9 1.1 8.1 2.9l6.4-6.4C34.6 4.1 29.6 2 24 2 11.8 2 2 11.8 2 24s9.8 22 22 22c11 0 21-8 21-22 0-1.3-.2-2.7-.5-4"/></defs><clipPath id="gitea-google__b"><use xlink:href="#gitea-google__a" overflow="visible"/></clipPath><path fill="#FBBC05" d="M0 37V11l17 13z" clip-path="url(#gitea-google__b)"/><path fill="#EA4335" d="m0 11 17 13 7-6.1L48 14V0H0z" clip-path="url(#gitea-google__b)"/><path fill="#34A853" d="m0 37 30-23 7.9 1L48 0v48H0z" clip-path="url(#gitea-google__b)"/><path fill="#4285F4" d="M48 48 17 24l-4-3 35-10z" clip-path="url(#gitea-google__b)"/></svg> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="gitea-google__svg gitea-google__gitea-google svg gitea-google" viewBox="0 0 24 24" width="16" height="16"><path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09"/><path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23"/><path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22z"/><path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53"/><path fill="none" d="M1 1h22v22H1z"/></svg>

Before

Width:  |  Height:  |  Size: 897 B

After

Width:  |  Height:  |  Size: 821 B

View File

@ -16,6 +16,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
repo_module "code.gitea.io/gitea/modules/repository" repo_module "code.gitea.io/gitea/modules/repository"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
@ -643,7 +644,7 @@ func CreateBranchProtection(ctx *context.APIContext) {
} else { } else {
if !isPlainRule { if !isPlainRule {
if ctx.Repo.GitRepo == nil { if ctx.Repo.GitRepo == nil {
ctx.Repo.GitRepo, err = git.OpenRepository(ctx, ctx.Repo.Repository.RepoPath()) ctx.Repo.GitRepo, err = gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err) ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return return
@ -920,7 +921,7 @@ func EditBranchProtection(ctx *context.APIContext) {
} else { } else {
if !isPlainRule { if !isPlainRule {
if ctx.Repo.GitRepo == nil { if ctx.Repo.GitRepo == nil {
ctx.Repo.GitRepo, err = git.OpenRepository(ctx, ctx.Repo.Repository.RepoPath()) ctx.Repo.GitRepo, err = gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err) ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return return

View File

@ -21,6 +21,7 @@ import (
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/httpcache"
"code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@ -279,9 +280,8 @@ func GetArchive(ctx *context.APIContext) {
// "404": // "404":
// "$ref": "#/responses/notFound" // "$ref": "#/responses/notFound"
repoPath := repo_model.RepoPath(ctx.Params(":username"), ctx.Params(":reponame"))
if ctx.Repo.GitRepo == nil { if ctx.Repo.GitRepo == nil {
gitRepo, err := git.OpenRepository(ctx, repoPath) gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err) ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return return

View File

@ -23,6 +23,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
@ -906,9 +907,9 @@ func MergePullRequest(ctx *context.APIContext) {
if ctx.Repo != nil && ctx.Repo.Repository != nil && ctx.Repo.Repository.ID == pr.HeadRepoID && ctx.Repo.GitRepo != nil { if ctx.Repo != nil && ctx.Repo.Repository != nil && ctx.Repo.Repository.ID == pr.HeadRepoID && ctx.Repo.GitRepo != nil {
headRepo = ctx.Repo.GitRepo headRepo = ctx.Repo.GitRepo
} else { } else {
headRepo, err = git.OpenRepository(ctx, pr.HeadRepo.RepoPath()) headRepo, err = gitrepo.OpenRepository(ctx, pr.HeadRepo)
if err != nil { if err != nil {
ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.RepoPath()), err) ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.FullName()), err)
return return
} }
defer headRepo.Close() defer headRepo.Close()
@ -1004,7 +1005,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
headRepo = ctx.Repo.Repository headRepo = ctx.Repo.Repository
headGitRepo = ctx.Repo.GitRepo headGitRepo = ctx.Repo.GitRepo
} else { } else {
headGitRepo, err = git.OpenRepository(ctx, repo_model.RepoPath(headUser.Name, headRepo.Name)) headGitRepo, err = gitrepo.OpenRepository(ctx, headRepo)
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err) ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return nil, nil, nil, nil, "", "" return nil, nil, nil, nil, "", ""
@ -1308,7 +1309,7 @@ func GetPullRequestCommits(ctx *context.APIContext) {
} }
var prInfo *git.CompareInfo var prInfo *git.CompareInfo
baseGitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, pr.BaseRepo.RepoPath()) baseGitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pr.BaseRepo)
if err != nil { if err != nil {
ctx.ServerError("OpenRepository", err) ctx.ServerError("OpenRepository", err)
return return

View File

@ -13,7 +13,7 @@ import (
access_model "code.gitea.io/gitea/models/perm/access" access_model "code.gitea.io/gitea/models/perm/access"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils" "code.gitea.io/gitea/routers/api/v1/utils"
@ -329,8 +329,7 @@ func CreatePullReview(ctx *context.APIContext) {
// if CommitID is empty, set it as lastCommitID // if CommitID is empty, set it as lastCommitID
if opts.CommitID == "" { if opts.CommitID == "" {
gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pr.Issue.Repo)
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, pr.Issue.Repo.RepoPath())
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "git.OpenRepository", err) ctx.Error(http.StatusInternalServerError, "git.OpenRepository", err)
return return

View File

@ -21,6 +21,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/label" "code.gitea.io/gitea/modules/label"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository" repo_module "code.gitea.io/gitea/modules/repository"
@ -718,7 +719,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
if ctx.Repo.GitRepo == nil && !repo.IsEmpty { if ctx.Repo.GitRepo == nil && !repo.IsEmpty {
var err error var err error
ctx.Repo.GitRepo, err = git.OpenRepository(ctx, ctx.Repo.Repository.RepoPath()) ctx.Repo.GitRepo, err = gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "Unable to OpenRepository", err) ctx.Error(http.StatusInternalServerError, "Unable to OpenRepository", err)
return err return err

View File

@ -12,6 +12,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
@ -475,7 +476,7 @@ func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error)
// findWikiRepoCommit opens the wiki repo and returns the latest commit, writing to context on error. // findWikiRepoCommit opens the wiki repo and returns the latest commit, writing to context on error.
// The caller is responsible for closing the returned repo again // The caller is responsible for closing the returned repo again
func findWikiRepoCommit(ctx *context.APIContext) (*git.Repository, *git.Commit) { func findWikiRepoCommit(ctx *context.APIContext) (*git.Repository, *git.Commit) {
wikiRepo, err := git.OpenRepository(ctx, ctx.Repo.Repository.WikiPath()) wikiRepo, err := gitrepo.OpenWikiRepository(ctx, ctx.Repo.Repository)
if err != nil { if err != nil {
if git.IsErrNotExist(err) || err.Error() == "no such file or directory" { if git.IsErrNotExist(err) || err.Error() == "no such file or directory" {

View File

@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
) )
@ -79,7 +80,7 @@ func ConvertToObjectID(ctx gocontext.Context, repo *context.Repository, commitID
} }
} }
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.Repository.RepoPath()) gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo.Repository)
if err != nil { if err != nil {
return objectFormat.EmptyObjectID(), fmt.Errorf("RepositoryFromContextOrOpen: %w", err) return objectFormat.EmptyObjectID(), fmt.Errorf("RepositoryFromContextOrOpen: %w", err)
} }

View File

@ -10,7 +10,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
gitea_context "code.gitea.io/gitea/modules/context" gitea_context "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/private"
) )
@ -28,7 +28,7 @@ func RepoAssignment(ctx *gitea_context.PrivateContext) context.CancelFunc {
return nil return nil
} }
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
log.Error("Failed to open repository: %s/%s Error: %v", ownerName, repoName, err) log.Error("Failed to open repository: %s/%s Error: %v", ownerName, repoName, err)
ctx.JSON(http.StatusInternalServerError, private.Response{ ctx.JSON(http.StatusInternalServerError, private.Response{

View File

@ -22,6 +22,7 @@ import (
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitgraph" "code.gitea.io/gitea/modules/gitgraph"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -279,7 +280,7 @@ func Diff(ctx *context.Context) {
) )
if ctx.Data["PageIsWiki"] != nil { if ctx.Data["PageIsWiki"] != nil {
gitRepo, err = git.OpenRepository(ctx, ctx.Repo.Repository.WikiPath()) gitRepo, err = gitrepo.OpenWikiRepository(ctx, ctx.Repo.Repository)
if err != nil { if err != nil {
ctx.ServerError("Repo.GitRepo.GetCommit", err) ctx.ServerError("Repo.GitRepo.GetCommit", err)
return return
@ -384,7 +385,7 @@ func Diff(ctx *context.Context) {
Metas: ctx.Repo.Repository.ComposeMetas(ctx), Metas: ctx.Repo.Repository.ComposeMetas(ctx),
GitRepo: ctx.Repo.GitRepo, GitRepo: ctx.Repo.GitRepo,
Ctx: ctx, Ctx: ctx,
}, template.HTMLEscapeString(string(charset.ToUTF8WithFallback(note.Message)))) }, template.HTMLEscapeString(string(charset.ToUTF8WithFallback(note.Message, charset.ConvertOpts{}))))
if err != nil { if err != nil {
ctx.ServerError("RenderCommitMessage", err) ctx.ServerError("RenderCommitMessage", err)
return return
@ -404,7 +405,7 @@ func Diff(ctx *context.Context) {
func RawDiff(ctx *context.Context) { func RawDiff(ctx *context.Context) {
var gitRepo *git.Repository var gitRepo *git.Repository
if ctx.Data["PageIsWiki"] != nil { if ctx.Data["PageIsWiki"] != nil {
wikiRepo, err := git.OpenRepository(ctx, ctx.Repo.Repository.WikiPath()) wikiRepo, err := gitrepo.OpenWikiRepository(ctx, ctx.Repo.Repository)
if err != nil { if err != nil {
ctx.ServerError("OpenRepository", err) ctx.ServerError("OpenRepository", err)
return return

View File

@ -28,6 +28,7 @@ import (
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
csv_module "code.gitea.io/gitea/modules/csv" csv_module "code.gitea.io/gitea/modules/csv"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -142,7 +143,7 @@ func setCsvCompareContext(ctx *context.Context) {
return nil, nil, err return nil, nil, err
} }
csvReader, err := csv_module.CreateReaderAndDetermineDelimiter(ctx, charset.ToUTF8WithFallbackReader(reader)) csvReader, err := csv_module.CreateReaderAndDetermineDelimiter(ctx, charset.ToUTF8WithFallbackReader(reader, charset.ConvertOpts{}))
return csvReader, reader, err return csvReader, reader, err
} }
@ -408,7 +409,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo {
ci.HeadRepo = ctx.Repo.Repository ci.HeadRepo = ctx.Repo.Repository
ci.HeadGitRepo = ctx.Repo.GitRepo ci.HeadGitRepo = ctx.Repo.GitRepo
} else if has { } else if has {
ci.HeadGitRepo, err = git.OpenRepository(ctx, ci.HeadRepo.RepoPath()) ci.HeadGitRepo, err = gitrepo.OpenRepository(ctx, ci.HeadRepo)
if err != nil { if err != nil {
ctx.ServerError("OpenRepository", err) ctx.ServerError("OpenRepository", err)
return nil return nil
@ -688,7 +689,7 @@ func PrepareCompareDiff(
} }
func getBranchesAndTagsForRepo(ctx gocontext.Context, repo *repo_model.Repository) (branches, tags []string, err error) { func getBranchesAndTagsForRepo(ctx gocontext.Context, repo *repo_model.Repository) (branches, tags []string, err error) {
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -876,7 +877,7 @@ func ExcerptBlob(ctx *context.Context) {
gitRepo := ctx.Repo.GitRepo gitRepo := ctx.Repo.GitRepo
if ctx.FormBool("wiki") { if ctx.FormBool("wiki") {
var err error var err error
gitRepo, err = git.OpenRepository(ctx, ctx.Repo.Repository.WikiPath()) gitRepo, err = gitrepo.OpenWikiRepository(ctx, ctx.Repo.Repository)
if err != nil { if err != nil {
ctx.ServerError("OpenRepository", err) ctx.ServerError("OpenRepository", err)
return return

View File

@ -166,8 +166,8 @@ func editFile(ctx *context.Context, isNewFile bool) {
} }
buf = append(buf, d...) buf = append(buf, d...)
if content, err := charset.ToUTF8WithErr(buf); err != nil { if content, err := charset.ToUTF8(buf, charset.ConvertOpts{KeepBOM: true}); err != nil {
log.Error("ToUTF8WithErr: %v", err) log.Error("ToUTF8: %v", err)
ctx.Data["FileContent"] = string(buf) ctx.Data["FileContent"] = string(buf)
} else { } else {
ctx.Data["FileContent"] = content ctx.Data["FileContent"] = content

View File

@ -9,6 +9,7 @@ import (
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/contexttest"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -66,7 +67,7 @@ func TestGetClosestParentWithFiles(t *testing.T) {
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
branch := repo.DefaultBranch branch := repo.DefaultBranch
gitRepo, _ := git.OpenRepository(git.DefaultContext, repo.RepoPath()) gitRepo, _ := gitrepo.OpenRepository(git.DefaultContext, repo)
defer gitRepo.Close() defer gitRepo.Close()
commit, _ := gitRepo.GetBranchCommit(branch) commit, _ := gitRepo.GetBranchCommit(branch)
var expectedTreePath string // Should return the root dir, empty string, since there are no subdirs in this repo var expectedTreePath string // Should return the root dir, empty string, since there are no subdirs in this repo

View File

@ -8,10 +8,15 @@ import (
"strconv" "strconv"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
) )
const (
tplWatching base.TplName = "repo/issue/view_content/watching"
)
// IssueWatch sets issue watching // IssueWatch sets issue watching
func IssueWatch(ctx *context.Context) { func IssueWatch(ctx *context.Context) {
issue := GetActionIssue(ctx) issue := GetActionIssue(ctx)
@ -52,5 +57,7 @@ func IssueWatch(ctx *context.Context) {
return return
} }
ctx.Redirect(issue.Link()) ctx.Data["Issue"] = issue
ctx.Data["IssueWatch"] = &issues_model.IssueWatch{IsWatching: watch}
ctx.HTML(http.StatusOK, tplWatching)
} }

View File

@ -29,6 +29,7 @@ import (
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
issue_template "code.gitea.io/gitea/modules/issue/template" issue_template "code.gitea.io/gitea/modules/issue/template"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -530,7 +531,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
if pull.BaseRepoID == ctx.Repo.Repository.ID && ctx.Repo.GitRepo != nil { if pull.BaseRepoID == ctx.Repo.Repository.ID && ctx.Repo.GitRepo != nil {
baseGitRepo = ctx.Repo.GitRepo baseGitRepo = ctx.Repo.GitRepo
} else { } else {
baseGitRepo, err := git.OpenRepository(ctx, pull.BaseRepo.RepoPath()) baseGitRepo, err := gitrepo.OpenRepository(ctx, pull.BaseRepo)
if err != nil { if err != nil {
ctx.ServerError("OpenRepository", err) ctx.ServerError("OpenRepository", err)
return nil return nil
@ -582,7 +583,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
var headBranchSha string var headBranchSha string
// HeadRepo may be missing // HeadRepo may be missing
if pull.HeadRepo != nil { if pull.HeadRepo != nil {
headGitRepo, err := git.OpenRepository(ctx, pull.HeadRepo.RepoPath()) headGitRepo, err := gitrepo.OpenRepository(ctx, pull.HeadRepo)
if err != nil { if err != nil {
ctx.ServerError("OpenRepository", err) ctx.ServerError("OpenRepository", err)
return nil return nil
@ -1314,9 +1315,9 @@ func MergePullRequest(ctx *context.Context) {
if ctx.Repo != nil && ctx.Repo.Repository != nil && pr.HeadRepoID == ctx.Repo.Repository.ID && ctx.Repo.GitRepo != nil { if ctx.Repo != nil && ctx.Repo.Repository != nil && pr.HeadRepoID == ctx.Repo.Repository.ID && ctx.Repo.GitRepo != nil {
headRepo = ctx.Repo.GitRepo headRepo = ctx.Repo.GitRepo
} else { } else {
headRepo, err = git.OpenRepository(ctx, pr.HeadRepo.RepoPath()) headRepo, err = gitrepo.OpenRepository(ctx, pr.HeadRepo)
if err != nil { if err != nil {
ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.RepoPath()), err) ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.FullName()), err)
return return
} }
defer headRepo.Close() defer headRepo.Close()
@ -1537,9 +1538,9 @@ func CleanUpPullRequest(ctx *context.Context) {
gitBaseRepo = ctx.Repo.GitRepo gitBaseRepo = ctx.Repo.GitRepo
} else { } else {
// If not just open it // If not just open it
gitBaseRepo, err = git.OpenRepository(ctx, pr.BaseRepo.RepoPath()) gitBaseRepo, err = gitrepo.OpenRepository(ctx, pr.BaseRepo)
if err != nil { if err != nil {
ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.BaseRepo.RepoPath()), err) ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.BaseRepo.FullName()), err)
return return
} }
defer gitBaseRepo.Close() defer gitBaseRepo.Close()
@ -1552,9 +1553,9 @@ func CleanUpPullRequest(ctx *context.Context) {
gitRepo = ctx.Repo.GitRepo gitRepo = ctx.Repo.GitRepo
} else if pr.BaseRepoID != pr.HeadRepoID { } else if pr.BaseRepoID != pr.HeadRepoID {
// Otherwise just load it up // Otherwise just load it up
gitRepo, err = git.OpenRepository(ctx, pr.HeadRepo.RepoPath()) gitRepo, err = gitrepo.OpenRepository(ctx, pr.HeadRepo)
if err != nil { if err != nil {
ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.RepoPath()), err) ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.FullName()), err)
return return
} }
defer gitRepo.Close() defer gitRepo.Close()

View File

@ -43,7 +43,7 @@ func RenderFile(ctx *context.Context) {
st := typesniffer.DetectContentType(buf) st := typesniffer.DetectContentType(buf)
isTextFile := st.IsText() isTextFile := st.IsText()
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc)) rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{})
if markupType := markup.Type(blob.Name()); markupType == "" { if markupType := markup.Type(blob.Name()); markupType == "" {
if isTextFile { if isTextFile {

View File

@ -303,7 +303,7 @@ func LFSFileGet(ctx *context.Context) {
break break
} }
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc)) rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{})
// Building code view blocks with line number on server side. // Building code view blocks with line number on server side.
escapedContent := &bytes.Buffer{} escapedContent := &bytes.Buffer{}

View File

@ -303,7 +303,7 @@ func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.Tr
return return
} }
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc)) rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{})
if markupType := markup.Type(readmeFile.Name()); markupType != "" { if markupType := markup.Type(readmeFile.Name()); markupType != "" {
ctx.Data["IsMarkup"] = true ctx.Data["IsMarkup"] = true
@ -492,7 +492,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
break break
} }
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc)) rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{})
shouldRenderSource := ctx.FormString("display") == "source" shouldRenderSource := ctx.FormString("display") == "source"
readmeExist := util.IsReadmeFileName(blob.Name()) readmeExist := util.IsReadmeFileName(blob.Name())

View File

@ -20,6 +20,7 @@ import (
"code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/charset"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/markup/markdown"
@ -92,7 +93,7 @@ func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error)
} }
func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) { func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) {
wikiRepo, err := git.OpenRepository(ctx, ctx.Repo.Repository.WikiPath()) wikiRepo, err := gitrepo.OpenWikiRepository(ctx, ctx.Repo.Repository)
if err != nil { if err != nil {
ctx.ServerError("OpenRepository", err) ctx.ServerError("OpenRepository", err)
return nil, nil, err return nil, nil, err

View File

@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/contexttest"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/forms"
wiki_service "code.gitea.io/gitea/services/wiki" wiki_service "code.gitea.io/gitea/services/wiki"
@ -26,7 +27,7 @@ const (
) )
func wikiEntry(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) *git.TreeEntry { func wikiEntry(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) *git.TreeEntry {
wikiRepo, err := git.OpenRepository(git.DefaultContext, repo.WikiPath()) wikiRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo)
assert.NoError(t, err) assert.NoError(t, err)
defer wikiRepo.Close() defer wikiRepo.Close()
commit, err := wikiRepo.GetBranchCommit("master") commit, err := wikiRepo.GetBranchCommit("master")

View File

@ -13,6 +13,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/markup/markdown"
@ -90,7 +91,7 @@ func FindUserProfileReadme(ctx *context.Context, doer *user_model.User) (profile
if err == nil { if err == nil {
perm, err := access_model.GetUserRepoPermission(ctx, profileDbRepo, doer) perm, err := access_model.GetUserRepoPermission(ctx, profileDbRepo, doer)
if err == nil && !profileDbRepo.IsEmpty && perm.CanRead(unit.TypeCode) { if err == nil && !profileDbRepo.IsEmpty && perm.CanRead(unit.TypeCode) {
if profileGitRepo, err = git.OpenRepository(ctx, profileDbRepo.RepoPath()); err != nil { if profileGitRepo, err = gitrepo.OpenRepository(ctx, profileDbRepo); err != nil {
log.Error("FindUserProfileReadme failed to OpenRepository: %v", err) log.Error("FindUserProfileReadme failed to OpenRepository: %v", err)
} else { } else {
if commit, err := profileGitRepo.GetBranchCommit(profileDbRepo.DefaultBranch); err != nil { if commit, err := profileGitRepo.GetBranchCommit(profileDbRepo.DefaultBranch); err != nil {

View File

@ -14,6 +14,7 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@ -26,6 +27,10 @@ import (
shared_user "code.gitea.io/gitea/routers/web/shared/user" shared_user "code.gitea.io/gitea/routers/web/shared/user"
) )
const (
tplProfileBigAvatar base.TplName = "shared/user/profile_big_avatar"
)
// OwnerProfile render profile page for a user or a organization (aka, repo owner) // OwnerProfile render profile page for a user or a organization (aka, repo owner)
func OwnerProfile(ctx *context.Context) { func OwnerProfile(ctx *context.Context) {
if strings.Contains(ctx.Req.Header.Get("Accept"), "application/rss+xml") { if strings.Contains(ctx.Req.Header.Get("Accept"), "application/rss+xml") {
@ -309,8 +314,10 @@ func Action(ctx *context.Context) {
if err != nil { if err != nil {
log.Error("Failed to apply action %q: %v", ctx.FormString("action"), err) log.Error("Failed to apply action %q: %v", ctx.FormString("action"), err)
ctx.JSONError(fmt.Sprintf("Action %q failed", ctx.FormString("action"))) ctx.Error(http.StatusBadRequest, fmt.Sprintf("Action %q failed", ctx.FormString("action")))
return return
} }
ctx.JSONOK()
shared_user.PrepareContextForProfileBigAvatar(ctx)
ctx.HTML(http.StatusOK, tplProfileBigAvatar)
} }

View File

@ -95,9 +95,9 @@ func loadApplicationsData(ctx *context.Context) {
return return
} }
ctx.Data["Tokens"] = tokens ctx.Data["Tokens"] = tokens
ctx.Data["EnableOAuth2"] = setting.OAuth2.Enable ctx.Data["EnableOAuth2"] = setting.OAuth2.Enabled
ctx.Data["IsAdmin"] = ctx.Doer.IsAdmin ctx.Data["IsAdmin"] = ctx.Doer.IsAdmin
if setting.OAuth2.Enable { if setting.OAuth2.Enabled {
ctx.Data["Applications"], err = db.Find[auth_model.OAuth2Application](ctx, auth_model.FindOAuth2ApplicationsOptions{ ctx.Data["Applications"], err = db.Find[auth_model.OAuth2Application](ctx, auth_model.FindOAuth2ApplicationsOptions{
OwnerID: ctx.Doer.ID, OwnerID: ctx.Doer.ID,
}) })

View File

@ -305,7 +305,7 @@ func registerRoutes(m *web.Route) {
validation.AddBindingRules() validation.AddBindingRules()
linkAccountEnabled := func(ctx *context.Context) { linkAccountEnabled := func(ctx *context.Context) {
if !setting.Service.EnableOpenIDSignIn && !setting.Service.EnableOpenIDSignUp && !setting.OAuth2.Enable { if !setting.Service.EnableOpenIDSignIn && !setting.Service.EnableOpenIDSignUp && !setting.OAuth2.Enabled {
ctx.Error(http.StatusForbidden) ctx.Error(http.StatusForbidden)
return return
} }
@ -771,7 +771,7 @@ func registerRoutes(m *web.Route) {
m.Post("/delete", admin.DeleteApplication) m.Post("/delete", admin.DeleteApplication)
}) })
}, func(ctx *context.Context) { }, func(ctx *context.Context) {
if !setting.OAuth2.Enable { if !setting.OAuth2.Enabled {
ctx.Error(http.StatusForbidden) ctx.Error(http.StatusForbidden)
return return
} }
@ -782,7 +782,7 @@ func registerRoutes(m *web.Route) {
addSettingsRunnersRoutes() addSettingsRunnersRoutes()
addSettingsVariablesRoutes() addSettingsVariablesRoutes()
}) })
}, adminReq, ctxDataSet("EnableOAuth2", setting.OAuth2.Enable, "EnablePackages", setting.Packages.Enabled)) }, adminReq, ctxDataSet("EnableOAuth2", setting.OAuth2.Enabled, "EnablePackages", setting.Packages.Enabled))
// ***** END: Admin ***** // ***** END: Admin *****
m.Group("", func() { m.Group("", func() {
@ -894,7 +894,7 @@ func registerRoutes(m *web.Route) {
m.Post("/delete", org.DeleteOAuth2Application) m.Post("/delete", org.DeleteOAuth2Application)
}) })
}, func(ctx *context.Context) { }, func(ctx *context.Context) {
if !setting.OAuth2.Enable { if !setting.OAuth2.Enabled {
ctx.Error(http.StatusForbidden) ctx.Error(http.StatusForbidden)
return return
} }
@ -946,7 +946,7 @@ func registerRoutes(m *web.Route) {
m.Post("/rebuild", org.RebuildCargoIndex) m.Post("/rebuild", org.RebuildCargoIndex)
}) })
}, packagesEnabled) }, packagesEnabled)
}, ctxDataSet("EnableOAuth2", setting.OAuth2.Enable, "EnablePackages", setting.Packages.Enabled, "PageIsOrgSettings", true)) }, ctxDataSet("EnableOAuth2", setting.OAuth2.Enabled, "EnablePackages", setting.Packages.Enabled, "PageIsOrgSettings", true))
}, context.OrgAssignment(true, true)) }, context.OrgAssignment(true, true))
}, reqSignIn) }, reqSignIn)
// ***** END: Organization ***** // ***** END: Organization *****

View File

@ -20,6 +20,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
actions_module "code.gitea.io/gitea/modules/actions" actions_module "code.gitea.io/gitea/modules/actions"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -128,7 +129,7 @@ func notify(ctx context.Context, input *notifyInput) error {
return nil return nil
} }
gitRepo, err := git.OpenRepository(context.Background(), input.Repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(context.Background(), input.Repo)
if err != nil { if err != nil {
return fmt.Errorf("git.OpenRepository: %w", err) return fmt.Errorf("git.OpenRepository: %w", err)
} }

View File

@ -13,8 +13,10 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git" git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -167,7 +169,8 @@ Loop:
} }
// SignWikiCommit determines if we should sign the commits to this repository wiki // SignWikiCommit determines if we should sign the commits to this repository wiki
func SignWikiCommit(ctx context.Context, repoWikiPath string, u *user_model.User) (bool, string, *git.Signature, error) { func SignWikiCommit(ctx context.Context, repo *repo_model.Repository, u *user_model.User) (bool, string, *git.Signature, error) {
repoWikiPath := repo.WikiPath()
rules := signingModeFromStrings(setting.Repository.Signing.Wiki) rules := signingModeFromStrings(setting.Repository.Signing.Wiki)
signingKey, sig := SigningKey(ctx, repoWikiPath) signingKey, sig := SigningKey(ctx, repoWikiPath)
if signingKey == "" { if signingKey == "" {
@ -201,7 +204,7 @@ Loop:
return false, "", nil, &ErrWontSign{twofa} return false, "", nil, &ErrWontSign{twofa}
} }
case parentSigned: case parentSigned:
gitRepo, err := git.OpenRepository(ctx, repoWikiPath) gitRepo, err := gitrepo.OpenWikiRepository(ctx, repo)
if err != nil { if err != nil {
return false, "", nil, err return false, "", nil, err
} }

View File

@ -17,6 +17,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
@ -111,7 +112,7 @@ func MergeScheduledPullRequest(ctx context.Context, sha string, repo *repo_model
} }
func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model.Repository, filter func(*issues_model.PullRequest) bool) (map[int64]*issues_model.PullRequest, error) { func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model.Repository, filter func(*issues_model.PullRequest) bool) (map[int64]*issues_model.PullRequest, error) {
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -190,7 +191,7 @@ func handlePull(pullID int64, sha string) {
return return
} }
headGitRepo, err := git.OpenRepository(ctx, pr.HeadRepo.RepoPath()) headGitRepo, err := gitrepo.OpenRepository(ctx, pr.HeadRepo)
if err != nil { if err != nil {
log.Error("OpenRepository %-v: %v", pr.HeadRepo, err) log.Error("OpenRepository %-v: %v", pr.HeadRepo, err)
return return
@ -246,7 +247,7 @@ func handlePull(pullID int64, sha string) {
return return
} }
baseGitRepo, err = git.OpenRepository(ctx, pr.BaseRepo.RepoPath()) baseGitRepo, err = gitrepo.OpenRepository(ctx, pr.BaseRepo)
if err != nil { if err != nil {
log.Error("OpenRepository %-v: %v", pr.BaseRepo, err) log.Error("OpenRepository %-v: %v", pr.BaseRepo, err)
return return

View File

@ -12,6 +12,7 @@ import (
access_model "code.gitea.io/gitea/models/perm/access" access_model "code.gitea.io/gitea/models/perm/access"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
) )
@ -101,7 +102,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
apiPullRequest.Closed = pr.Issue.ClosedUnix.AsTimePtr() apiPullRequest.Closed = pr.Issue.ClosedUnix.AsTimePtr()
} }
gitRepo, err := git.OpenRepository(ctx, pr.BaseRepo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
if err != nil { if err != nil {
log.Error("OpenRepository[%s]: %v", pr.BaseRepo.RepoPath(), err) log.Error("OpenRepository[%s]: %v", pr.BaseRepo.RepoPath(), err)
return nil return nil
@ -127,7 +128,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
} }
if pr.Flow == issues_model.PullRequestFlowAGit { if pr.Flow == issues_model.PullRequestFlowAGit {
gitRepo, err := git.OpenRepository(ctx, pr.BaseRepo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
if err != nil { if err != nil {
log.Error("OpenRepository[%s]: %v", pr.GetGitRefName(), err) log.Error("OpenRepository[%s]: %v", pr.GetGitRefName(), err)
return nil return nil
@ -154,7 +155,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
apiPullRequest.Head.RepoID = pr.HeadRepo.ID apiPullRequest.Head.RepoID = pr.HeadRepo.ID
apiPullRequest.Head.Repository = ToRepo(ctx, pr.HeadRepo, p) apiPullRequest.Head.Repository = ToRepo(ctx, pr.HeadRepo, p)
headGitRepo, err := git.OpenRepository(ctx, pr.HeadRepo.RepoPath()) headGitRepo, err := gitrepo.OpenRepository(ctx, pr.HeadRepo)
if err != nil { if err != nil {
log.Error("OpenRepository[%s]: %v", pr.HeadRepo.RepoPath(), err) log.Error("OpenRepository[%s]: %v", pr.HeadRepo.RepoPath(), err)
return nil return nil
@ -190,7 +191,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
} }
if len(apiPullRequest.Head.Sha) == 0 && len(apiPullRequest.Head.Ref) != 0 { if len(apiPullRequest.Head.Sha) == 0 && len(apiPullRequest.Head.Ref) != 0 {
baseGitRepo, err := git.OpenRepository(ctx, pr.BaseRepo.RepoPath()) baseGitRepo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
if err != nil { if err != nil {
log.Error("OpenRepository[%s]: %v", pr.BaseRepo.RepoPath(), err) log.Error("OpenRepository[%s]: %v", pr.BaseRepo.RepoPath(), err)
return nil return nil

View File

@ -16,6 +16,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -91,7 +92,7 @@ func checkEnablePushOptions(ctx context.Context, logger log.Logger, autofix bool
if err := iterateRepositories(ctx, func(repo *repo_model.Repository) error { if err := iterateRepositories(ctx, func(repo *repo_model.Repository) error {
numRepos++ numRepos++
r, err := git.OpenRepository(ctx, repo.RepoPath()) r, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
return err return err
} }

View File

@ -21,6 +21,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
base_module "code.gitea.io/gitea/modules/base" base_module "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/label" "code.gitea.io/gitea/modules/label"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
base "code.gitea.io/gitea/modules/migration" base "code.gitea.io/gitea/modules/migration"
@ -139,7 +140,7 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate
if err != nil { if err != nil {
return err return err
} }
g.gitRepo, err = git.OpenRepository(g.ctx, r.RepoPath()) g.gitRepo, err = gitrepo.OpenRepository(g.ctx, r)
return err return err
} }

View File

@ -19,6 +19,7 @@ import (
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
base "code.gitea.io/gitea/modules/migration" base "code.gitea.io/gitea/modules/migration"
@ -249,7 +250,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
Author: &signature, Author: &signature,
Message: "Initial Commit", Message: "Initial Commit",
})) }))
fromGitRepo, err := git.OpenRepository(git.DefaultContext, fromRepo.RepoPath()) fromGitRepo, err := gitrepo.OpenRepository(git.DefaultContext, fromRepo)
assert.NoError(t, err) assert.NoError(t, err)
defer fromGitRepo.Close() defer fromGitRepo.Close()
baseSHA, err := fromGitRepo.GetBranchCommitID(baseRef) baseSHA, err := fromGitRepo.GetBranchCommitID(baseRef)
@ -292,7 +293,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
Author: &signature, Author: &signature,
Message: "branch2 commit", Message: "branch2 commit",
})) }))
forkGitRepo, err := git.OpenRepository(git.DefaultContext, forkRepo.RepoPath()) forkGitRepo, err := gitrepo.OpenRepository(git.DefaultContext, forkRepo)
assert.NoError(t, err) assert.NoError(t, err)
defer forkGitRepo.Close() defer forkGitRepo.Close()
forkHeadSHA, err := forkGitRepo.GetBranchCommitID(forkHeadRef) forkHeadSHA, err := forkGitRepo.GetBranchCommitID(forkHeadRef)

View File

@ -13,6 +13,7 @@ import (
system_model "code.gitea.io/gitea/models/system" system_model "code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
@ -300,7 +301,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
log.Error("SyncMirrors [repo: %-v]: %v", m.Repo, err) log.Error("SyncMirrors [repo: %-v]: %v", m.Repo, err)
} }
gitRepo, err := git.OpenRepository(ctx, repoPath) gitRepo, err := gitrepo.OpenRepository(ctx, m.Repo)
if err != nil { if err != nil {
log.Error("SyncMirrors [repo: %-v]: failed to OpenRepository: %v", m.Repo, err) log.Error("SyncMirrors [repo: %-v]: failed to OpenRepository: %v", m.Repo, err)
return nil, false return nil, false
@ -396,7 +397,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
} }
log.Trace("SyncMirrors [repo: %-v]: invalidating mirror branch caches...", m.Repo) log.Trace("SyncMirrors [repo: %-v]: invalidating mirror branch caches...", m.Repo)
branches, _, err := git.GetBranchesByPath(ctx, m.Repo.RepoPath(), 0, 0) branches, _, err := gitrepo.GetBranchesByPath(ctx, m.Repo, 0, 0)
if err != nil { if err != nil {
log.Error("SyncMirrors [repo: %-v]: failed to GetBranches: %v", m.Repo, err) log.Error("SyncMirrors [repo: %-v]: failed to GetBranches: %v", m.Repo, err)
return nil, false return nil, false
@ -453,7 +454,7 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool {
log.Trace("SyncMirrors [repo: %-v]: no branches updated", m.Repo) log.Trace("SyncMirrors [repo: %-v]: no branches updated", m.Repo)
} else { } else {
log.Trace("SyncMirrors [repo: %-v]: %d branches updated", m.Repo, len(results)) log.Trace("SyncMirrors [repo: %-v]: %d branches updated", m.Repo, len(results))
gitRepo, err = git.OpenRepository(ctx, m.Repo.RepoPath()) gitRepo, err = gitrepo.OpenRepository(ctx, m.Repo)
if err != nil { if err != nil {
log.Error("SyncMirrors [repo: %-v]: unable to OpenRepository: %v", m.Repo, err) log.Error("SyncMirrors [repo: %-v]: unable to OpenRepository: %v", m.Repo, err)
return false return false

View File

@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
@ -131,7 +132,11 @@ func SyncPushMirror(ctx context.Context, mirrorID int64) bool {
func runPushSync(ctx context.Context, m *repo_model.PushMirror) error { func runPushSync(ctx context.Context, m *repo_model.PushMirror) error {
timeout := time.Duration(setting.Git.Timeout.Mirror) * time.Second timeout := time.Duration(setting.Git.Timeout.Mirror) * time.Second
performPush := func(path string) error { performPush := func(repo *repo_model.Repository, isWiki bool) error {
path := repo.RepoPath()
if isWiki {
path = repo.WikiPath()
}
remoteURL, err := git.GetRemoteURL(ctx, path, m.RemoteName) remoteURL, err := git.GetRemoteURL(ctx, path, m.RemoteName)
if err != nil { if err != nil {
log.Error("GetRemoteAddress(%s) Error %v", path, err) log.Error("GetRemoteAddress(%s) Error %v", path, err)
@ -141,7 +146,12 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error {
if setting.LFS.StartServer { if setting.LFS.StartServer {
log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo) log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo)
gitRepo, err := git.OpenRepository(ctx, path) var gitRepo *git.Repository
if isWiki {
gitRepo, err = gitrepo.OpenWikiRepository(ctx, repo)
} else {
gitRepo, err = gitrepo.OpenRepository(ctx, repo)
}
if err != nil { if err != nil {
log.Error("OpenRepository: %v", err) log.Error("OpenRepository: %v", err)
return errors.New("Unexpected error") return errors.New("Unexpected error")
@ -171,16 +181,15 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error {
return nil return nil
} }
err := performPush(m.Repo.RepoPath()) err := performPush(m.Repo, false)
if err != nil { if err != nil {
return err return err
} }
if m.Repo.HasWiki() { if m.Repo.HasWiki() {
wikiPath := m.Repo.WikiPath() _, err := git.GetRemoteAddress(ctx, m.Repo.WikiPath(), m.RemoteName)
_, err := git.GetRemoteAddress(ctx, wikiPath, m.RemoteName)
if err == nil { if err == nil {
err := performPush(wikiPath) err := performPush(m.Repo, true)
if err != nil { if err != nil {
return err return err
} }

View File

@ -20,6 +20,7 @@ import (
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
@ -215,7 +216,7 @@ func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Com
return nil, fmt.Errorf("GetFullCommitID(%s) in %s: %w", prHeadRef, pr.BaseRepo.FullName(), err) return nil, fmt.Errorf("GetFullCommitID(%s) in %s: %w", prHeadRef, pr.BaseRepo.FullName(), err)
} }
gitRepo, err := git.OpenRepository(ctx, pr.BaseRepo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
if err != nil { if err != nil {
return nil, fmt.Errorf("%-v OpenRepository: %w", pr.BaseRepo, err) return nil, fmt.Errorf("%-v OpenRepository: %w", pr.BaseRepo, err)
} }

View File

@ -9,7 +9,7 @@ import (
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
) )
@ -17,8 +17,7 @@ import (
// isForcePush will be true if oldCommit isn't on the branch // isForcePush will be true if oldCommit isn't on the branch
// Commit on baseBranch will skip // Commit on baseBranch will skip
func getCommitIDsFromRepo(ctx context.Context, repo *repo_model.Repository, oldCommitID, newCommitID, baseBranch string) (commitIDs []string, isForcePush bool, err error) { func getCommitIDsFromRepo(ctx context.Context, repo *repo_model.Repository, oldCommitID, newCommitID, baseBranch string) (commitIDs []string, isForcePush bool, err error) {
repoPath := repo.RepoPath() gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repoPath)
if err != nil { if err != nil {
return nil, false, err return nil, false, err
} }

View File

@ -11,6 +11,7 @@ import (
git_model "code.gitea.io/gitea/models/git" git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
@ -116,7 +117,7 @@ func GetPullRequestCommitStatusState(ctx context.Context, pr *issues_model.PullR
} }
// check if all required status checks are successful // check if all required status checks are successful
headGitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, pr.HeadRepo.RepoPath()) headGitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pr.HeadRepo)
if err != nil { if err != nil {
return "", errors.Wrap(err, "OpenRepository") return "", errors.Wrap(err, "OpenRepository")
} }

View File

@ -9,6 +9,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
) )
@ -57,7 +58,7 @@ func doMergeRebaseFastForward(ctx *mergeContext) error {
} }
// Original repo to read template from. // Original repo to read template from.
baseGitRepo, err := git.OpenRepository(ctx, ctx.pr.BaseRepo.RepoPath()) baseGitRepo, err := gitrepo.OpenRepository(ctx, ctx.pr.BaseRepo)
if err != nil { if err != nil {
log.Error("Unable to get Git repo for rebase: %v", err) log.Error("Unable to get Git repo for rebase: %v", err)
return err return err

View File

@ -10,6 +10,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
) )
@ -24,7 +25,7 @@ func getAuthorSignatureSquash(ctx *mergeContext) (*git.Signature, error) {
// Try to get an signature from the same user in one of the commits, as the // Try to get an signature from the same user in one of the commits, as the
// poster email might be private or commits might have a different signature // poster email might be private or commits might have a different signature
// than the primary email address of the poster. // than the primary email address of the poster.
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, ctx.tmpBasePath) gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpenPath(ctx, ctx.tmpBasePath)
if err != nil { if err != nil {
log.Error("%-v Unable to open base repository: %v", ctx.pr, err) log.Error("%-v Unable to open base repository: %v", ctx.pr, err)
return nil, err return nil, err

View File

@ -19,6 +19,7 @@ import (
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
@ -35,7 +36,7 @@ func DownloadDiffOrPatch(ctx context.Context, pr *issues_model.PullRequest, w io
return err return err
} }
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, pr.BaseRepo.RepoPath()) gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pr.BaseRepo)
if err != nil { if err != nil {
return fmt.Errorf("OpenRepository: %w", err) return fmt.Errorf("OpenRepository: %w", err)
} }

View File

@ -23,6 +23,7 @@ import (
"code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/container"
gitea_context "code.gitea.io/gitea/modules/context" gitea_context "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@ -62,7 +63,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *iss
assigneeCommentMap := make(map[int64]*issues_model.Comment) assigneeCommentMap := make(map[int64]*issues_model.Comment)
// add first push codes comment // add first push codes comment
baseGitRepo, err := git.OpenRepository(ctx, pr.BaseRepo.RepoPath()) baseGitRepo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
if err != nil { if err != nil {
return err return err
} }
@ -269,9 +270,9 @@ func checkForInvalidation(ctx context.Context, requests issues_model.PullRequest
if err != nil { if err != nil {
return fmt.Errorf("GetRepositoryByIDCtx: %w", err) return fmt.Errorf("GetRepositoryByIDCtx: %w", err)
} }
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
return fmt.Errorf("git.OpenRepository: %w", err) return fmt.Errorf("gitrepo.OpenRepository: %w", err)
} }
go func() { go func() {
// FIXME: graceful: We need to tell the manager we're doing something... // FIXME: graceful: We need to tell the manager we're doing something...
@ -614,7 +615,7 @@ func CloseBranchPulls(ctx context.Context, doer *user_model.User, repoID int64,
// CloseRepoBranchesPulls close all pull requests which head branches are in the given repository, but only whose base repo is not in the given repository // CloseRepoBranchesPulls close all pull requests which head branches are in the given repository, but only whose base repo is not in the given repository
func CloseRepoBranchesPulls(ctx context.Context, doer *user_model.User, repo *repo_model.Repository) error { func CloseRepoBranchesPulls(ctx context.Context, doer *user_model.User, repo *repo_model.Repository) error {
branches, _, err := git.GetBranchesByPath(ctx, repo.RepoPath(), 0, 0) branches, _, err := gitrepo.GetBranchesByPath(ctx, repo, 0, 0)
if err != nil { if err != nil {
return err return err
} }
@ -671,7 +672,7 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequ
} }
} }
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, pr.HeadRepo.RepoPath()) gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pr.HeadRepo)
if err != nil { if err != nil {
log.Error("Unable to open head repository: Error: %v", err) log.Error("Unable to open head repository: Error: %v", err)
return "" return ""
@ -845,7 +846,7 @@ func GetIssuesAllCommitStatus(ctx context.Context, issues issues_model.IssueList
} }
gitRepo, ok := gitRepos[issue.RepoID] gitRepo, ok := gitRepos[issue.RepoID]
if !ok { if !ok {
gitRepo, err = git.OpenRepository(ctx, issue.Repo.RepoPath()) gitRepo, err = gitrepo.OpenRepository(ctx, issue.Repo)
if err != nil { if err != nil {
log.Error("Cannot open git repository %-v for issue #%d[%d]. Error: %v", issue.Repo, issue.Index, issue.ID, err) log.Error("Cannot open git repository %-v for issue #%d[%d]. Error: %v", issue.Repo, issue.Index, issue.ID, err)
continue continue
@ -882,7 +883,7 @@ func IsHeadEqualWithBranch(ctx context.Context, pr *issues_model.PullRequest, br
if err = pr.LoadBaseRepo(ctx); err != nil { if err = pr.LoadBaseRepo(ctx); err != nil {
return false, err return false, err
} }
baseGitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, pr.BaseRepo.RepoPath()) baseGitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pr.BaseRepo)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -902,7 +903,7 @@ func IsHeadEqualWithBranch(ctx context.Context, pr *issues_model.PullRequest, br
} else { } else {
var closer io.Closer var closer io.Closer
headGitRepo, closer, err = git.RepositoryFromContextOrOpen(ctx, pr.HeadRepo.RepoPath()) headGitRepo, closer, err = gitrepo.RepositoryFromContextOrOpen(ctx, pr.HeadRepo)
if err != nil { if err != nil {
return false, err return false, err
} }

View File

@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -41,7 +42,7 @@ func TestPullRequest_GetDefaultMergeMessage_InternalTracker(t *testing.T) {
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext)) assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
gitRepo, err := git.OpenRepository(git.DefaultContext, pr.BaseRepo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, pr.BaseRepo)
assert.NoError(t, err) assert.NoError(t, err)
defer gitRepo.Close() defer gitRepo.Close()
@ -71,7 +72,7 @@ func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) {
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2, BaseRepo: baseRepo}) pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2, BaseRepo: baseRepo})
assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext)) assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
gitRepo, err := git.OpenRepository(git.DefaultContext, pr.BaseRepo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, pr.BaseRepo)
assert.NoError(t, err) assert.NoError(t, err)
defer gitRepo.Close() defer gitRepo.Close()

View File

@ -16,6 +16,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
@ -170,7 +171,7 @@ func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_mo
if err := pr.LoadBaseRepo(ctx); err != nil { if err := pr.LoadBaseRepo(ctx); err != nil {
return nil, fmt.Errorf("LoadBaseRepo: %w", err) return nil, fmt.Errorf("LoadBaseRepo: %w", err)
} }
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, pr.BaseRepo.RepoPath()) gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pr.BaseRepo)
if err != nil { if err != nil {
return nil, fmt.Errorf("RepositoryFromContextOrOpen: %w", err) return nil, fmt.Errorf("RepositoryFromContextOrOpen: %w", err)
} }

View File

@ -16,6 +16,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/repository"
@ -168,7 +169,7 @@ func CreateNewTag(ctx context.Context, doer *user_model.User, repo *repo_model.R
} }
} }
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath()) gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
if err != nil { if err != nil {
return err return err
} }

View File

@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/services/attachment" "code.gitea.io/gitea/services/attachment"
_ "code.gitea.io/gitea/models/actions" _ "code.gitea.io/gitea/models/actions"
@ -29,9 +30,8 @@ func TestRelease_Create(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repoPath := repo_model.RepoPath(user.Name, repo.Name)
gitRepo, err := git.OpenRepository(git.DefaultContext, repoPath) gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo)
assert.NoError(t, err) assert.NoError(t, err)
defer gitRepo.Close() defer gitRepo.Close()
@ -135,9 +135,8 @@ func TestRelease_Update(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repoPath := repo_model.RepoPath(user.Name, repo.Name)
gitRepo, err := git.OpenRepository(git.DefaultContext, repoPath) gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo)
assert.NoError(t, err) assert.NoError(t, err)
defer gitRepo.Close() defer gitRepo.Close()
@ -278,9 +277,8 @@ func TestRelease_createTag(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repoPath := repo_model.RepoPath(user.Name, repo.Name)
gitRepo, err := git.OpenRepository(git.DefaultContext, repoPath) gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo)
assert.NoError(t, err) assert.NoError(t, err)
defer gitRepo.Close() defer gitRepo.Close()

View File

@ -17,6 +17,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository" repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -126,7 +127,7 @@ func adoptRepository(ctx context.Context, repoPath string, u *user_model.User, r
repo.IsEmpty = false repo.IsEmpty = false
// Don't bother looking this repo in the context it won't be there // Don't bother looking this repo in the context it won't be there
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
return fmt.Errorf("openRepository: %w", err) return fmt.Errorf("openRepository: %w", err)
} }

View File

@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/process"
@ -209,7 +210,7 @@ func doArchive(ctx context.Context, r *ArchiveRequest) (*repo_model.RepoArchiver
return nil, fmt.Errorf("archiver.LoadRepo failed: %w", err) return nil, fmt.Errorf("archiver.LoadRepo failed: %w", err)
} }
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -17,6 +17,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/queue" "code.gitea.io/gitea/modules/queue"
@ -160,7 +161,7 @@ func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *g
if pr.HasMerged { if pr.HasMerged {
baseGitRepo, ok := repoIDToGitRepo[pr.BaseRepoID] baseGitRepo, ok := repoIDToGitRepo[pr.BaseRepoID]
if !ok { if !ok {
baseGitRepo, err = git.OpenRepository(ctx, pr.BaseRepo.RepoPath()) baseGitRepo, err = gitrepo.OpenRepository(ctx, pr.BaseRepo)
if err != nil { if err != nil {
return nil, fmt.Errorf("OpenRepository: %v", err) return nil, fmt.Errorf("OpenRepository: %v", err)
} }
@ -190,13 +191,9 @@ func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *g
}, nil }, nil
} }
func GetBranchCommitID(ctx context.Context, repo *repo_model.Repository, branch string) (string, error) {
return git.GetBranchCommitID(ctx, repo.RepoPath(), branch)
}
// checkBranchName validates branch name with existing repository branches // checkBranchName validates branch name with existing repository branches
func checkBranchName(ctx context.Context, repo *repo_model.Repository, name string) error { func checkBranchName(ctx context.Context, repo *repo_model.Repository, name string) error {
_, err := git.WalkReferences(ctx, repo.RepoPath(), func(_, refName string) error { _, err := gitrepo.WalkReferences(ctx, repo, func(_, refName string) error {
branchRefName := strings.TrimPrefix(refName, git.BranchPrefix) branchRefName := strings.TrimPrefix(refName, git.BranchPrefix)
switch { switch {
case branchRefName == name: case branchRefName == name:

View File

@ -16,6 +16,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/options" "code.gitea.io/gitea/modules/options"
repo_module "code.gitea.io/gitea/modules/repository" repo_module "code.gitea.io/gitea/modules/repository"
@ -175,7 +176,7 @@ func initRepository(ctx context.Context, repoPath string, u *user_model.User, re
if len(opts.DefaultBranch) > 0 { if len(opts.DefaultBranch) > 0 {
repo.DefaultBranch = opts.DefaultBranch repo.DefaultBranch = opts.DefaultBranch
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
return fmt.Errorf("openRepository: %w", err) return fmt.Errorf("openRepository: %w", err)
} }

View File

@ -12,6 +12,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/services/automerge" "code.gitea.io/gitea/services/automerge"
) )
@ -23,7 +24,7 @@ func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creato
repoPath := repo.RepoPath() repoPath := repo.RepoPath()
// confirm that commit is exist // confirm that commit is exist
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath()) gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
if err != nil { if err != nil {
return fmt.Errorf("OpenRepository[%s]: %w", repoPath, err) return fmt.Errorf("OpenRepository[%s]: %w", repoPath, err)
} }

View File

@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
@ -58,7 +59,7 @@ func GetContentsOrList(ctx context.Context, repo *repo_model.Repository, treePat
} }
treePath = cleanTreePath treePath = cleanTreePath
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath()) gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -133,7 +134,7 @@ func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref
} }
treePath = cleanTreePath treePath = cleanTreePath
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath()) gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -6,10 +6,9 @@ package files
import ( import (
"testing" "testing"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/contexttest"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
_ "code.gitea.io/gitea/models/actions" _ "code.gitea.io/gitea/models/actions"
@ -235,7 +234,7 @@ func TestGetBlobBySHA(t *testing.T) {
ctx.SetParams(":id", "1") ctx.SetParams(":id", "1")
ctx.SetParams(":sha", sha) ctx.SetParams(":sha", sha)
gitRepo, err := git.OpenRepository(ctx, repo_model.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)) gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
if err != nil { if err != nil {
t.Fail() t.Fail()
} }

View File

@ -8,7 +8,7 @@ import (
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/contexttest" "code.gitea.io/gitea/modules/contexttest"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
@ -109,7 +109,7 @@ func TestGetFileResponseFromCommit(t *testing.T) {
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
branch := repo.DefaultBranch branch := repo.DefaultBranch
treePath := "README.md" treePath := "README.md"
gitRepo, _ := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, _ := gitrepo.OpenRepository(ctx, repo)
defer gitRepo.Close() defer gitRepo.Close()
commit, _ := gitRepo.GetBranchCommit(branch) commit, _ := gitRepo.GetBranchCommit(branch)
expectedFileResponse := getExpectedFileResponse() expectedFileResponse := getExpectedFileResponse()

View File

@ -13,6 +13,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
asymkey_service "code.gitea.io/gitea/services/asymkey" asymkey_service "code.gitea.io/gitea/services/asymkey"
@ -42,7 +43,7 @@ func (opts *ApplyDiffPatchOptions) Validate(ctx context.Context, repo *repo_mode
opts.NewBranch = opts.OldBranch opts.NewBranch = opts.OldBranch
} }
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath()) gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
if err != nil { if err != nil {
return err return err
} }

View File

@ -16,6 +16,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -78,7 +79,7 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use
opts.NewBranch = opts.OldBranch opts.NewBranch = opts.OldBranch
} }
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath()) gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -14,6 +14,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository" repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
@ -167,7 +168,7 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
return fmt.Errorf("createDelegateHooks: %w", err) return fmt.Errorf("createDelegateHooks: %w", err)
} }
gitRepo, err := git.OpenRepository(txCtx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(txCtx, repo)
if err != nil { if err != nil {
return fmt.Errorf("OpenRepository: %w", err) return fmt.Errorf("OpenRepository: %w", err)
} }
@ -190,7 +191,7 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
log.Error("Copy language stat from oldRepo failed: %v", err) log.Error("Copy language stat from oldRepo failed: %v", err)
} }
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
log.Error("Open created git repository failed: %v", err) log.Error("Open created git repository failed: %v", err)
} else { } else {

View File

@ -10,7 +10,7 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository" repo_module "code.gitea.io/gitea/modules/repository"
@ -52,13 +52,13 @@ func SyncRepositoryHooks(ctx context.Context) error {
// GenerateGitHooks generates git hooks from a template repository // GenerateGitHooks generates git hooks from a template repository
func GenerateGitHooks(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error { func GenerateGitHooks(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error {
generateGitRepo, err := git.OpenRepository(ctx, generateRepo.RepoPath()) generateGitRepo, err := gitrepo.OpenRepository(ctx, generateRepo)
if err != nil { if err != nil {
return err return err
} }
defer generateGitRepo.Close() defer generateGitRepo.Close()
templateGitRepo, err := git.OpenRepository(ctx, templateRepo.RepoPath()) templateGitRepo, err := gitrepo.OpenRepository(ctx, templateRepo)
if err != nil { if err != nil {
return err return err
} }

View File

@ -12,6 +12,7 @@ import (
git_model "code.gitea.io/gitea/models/git" git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -69,7 +70,7 @@ func GarbageCollectLFSMetaObjectsForRepo(ctx context.Context, repo *repo_model.R
} }
}() }()
gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) gitRepo, err := gitrepo.OpenRepository(ctx, repo)
if err != nil { if err != nil {
log.Error("Unable to open git repository %-v: %v", repo, err) log.Error("Unable to open git repository %-v: %v", repo, err)
return err return err

Some files were not shown because too many files have changed in this diff Show More