mirror of https://github.com/go-gitea/gitea
Merge remote-tracking branch 'upstream/main' into sync-issue-pr-and-more
This commit is contained in:
commit
aa7f59e5fc
16
.drone.yml
16
.drone.yml
|
@ -19,7 +19,7 @@ volumes:
|
|||
|
||||
steps:
|
||||
- name: deps-frontend
|
||||
image: node:16
|
||||
image: node:18
|
||||
pull: always
|
||||
commands:
|
||||
- make deps-frontend
|
||||
|
@ -34,7 +34,7 @@ steps:
|
|||
path: /go
|
||||
|
||||
- name: lint-frontend
|
||||
image: node:16
|
||||
image: node:18
|
||||
commands:
|
||||
- make lint-frontend
|
||||
depends_on: [deps-frontend]
|
||||
|
@ -82,7 +82,7 @@ steps:
|
|||
path: /go
|
||||
|
||||
- name: checks-frontend
|
||||
image: node:16
|
||||
image: node:18
|
||||
commands:
|
||||
- make checks-frontend
|
||||
depends_on: [deps-frontend]
|
||||
|
@ -97,13 +97,13 @@ steps:
|
|||
path: /go
|
||||
|
||||
- name: test-frontend
|
||||
image: node:16
|
||||
image: node:18
|
||||
commands:
|
||||
- make test-frontend
|
||||
depends_on: [lint-frontend]
|
||||
|
||||
- name: build-frontend
|
||||
image: node:16
|
||||
image: node:18
|
||||
commands:
|
||||
- make frontend
|
||||
depends_on: [test-frontend]
|
||||
|
@ -634,7 +634,7 @@ steps:
|
|||
- git fetch --tags --force
|
||||
|
||||
- name: deps-frontend
|
||||
image: node:16
|
||||
image: node:18
|
||||
pull: always
|
||||
commands:
|
||||
- make deps-frontend
|
||||
|
@ -652,6 +652,7 @@ steps:
|
|||
image: techknowlogick/xgo:go-1.18.x
|
||||
pull: always
|
||||
commands:
|
||||
# Upgrade to node 18 once https://github.com/techknowlogick/xgo/issues/163 is resolved
|
||||
- curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs
|
||||
- export PATH=$PATH:$GOPATH/bin
|
||||
- make release
|
||||
|
@ -753,7 +754,7 @@ steps:
|
|||
- git fetch --tags --force
|
||||
|
||||
- name: deps-frontend
|
||||
image: node:16
|
||||
image: node:18
|
||||
pull: always
|
||||
commands:
|
||||
- make deps-frontend
|
||||
|
@ -771,6 +772,7 @@ steps:
|
|||
image: techknowlogick/xgo:go-1.18.x
|
||||
pull: always
|
||||
commands:
|
||||
# Upgrade to node 18 once https://github.com/techknowlogick/xgo/issues/163 is resolved
|
||||
- curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs
|
||||
- export PATH=$PATH:$GOPATH/bin
|
||||
- make release
|
||||
|
|
|
@ -11,13 +11,8 @@ parserOptions:
|
|||
plugins:
|
||||
- eslint-plugin-unicorn
|
||||
- eslint-plugin-import
|
||||
- eslint-plugin-vue
|
||||
- eslint-plugin-html
|
||||
- eslint-plugin-jquery
|
||||
|
||||
extends:
|
||||
- plugin:vue/recommended
|
||||
|
||||
env:
|
||||
es2022: true
|
||||
node: true
|
||||
|
@ -25,18 +20,11 @@ env:
|
|||
globals:
|
||||
__webpack_public_path__: true
|
||||
|
||||
settings:
|
||||
html/html-extensions: [".tmpl"]
|
||||
|
||||
overrides:
|
||||
- files: ["web_src/**/*.js", "web_src/**/*.vue", "templates/**/*.tmpl"]
|
||||
- files: ["web_src/**/*.js", "docs/**/*.js"]
|
||||
env:
|
||||
browser: true
|
||||
node: false
|
||||
- files: ["templates/**/*.tmpl"]
|
||||
rules:
|
||||
no-tabs: [0]
|
||||
indent: [2, tab, {SwitchCase: 1}]
|
||||
- files: ["web_src/**/*worker.js"]
|
||||
env:
|
||||
worker: true
|
||||
|
@ -502,11 +490,6 @@ rules:
|
|||
use-isnan: [2]
|
||||
valid-typeof: [2, {requireStringLiterals: true}]
|
||||
vars-on-top: [0]
|
||||
vue/attributes-order: [0]
|
||||
vue/component-definition-name-casing: [0]
|
||||
vue/html-closing-bracket-spacing: [0]
|
||||
vue/max-attributes-per-line: [0]
|
||||
vue/one-component-per-file: [0]
|
||||
wrap-iife: [2, inside]
|
||||
wrap-regex: [0]
|
||||
yield-star-spacing: [2, after]
|
||||
|
|
8
Makefile
8
Makefile
|
@ -201,9 +201,9 @@ help:
|
|||
|
||||
.PHONY: go-check
|
||||
go-check:
|
||||
$(eval MIN_GO_VERSION_STR := $(shell grep -Eo '^go\s+[0-9]+\.[0-9.]+' go.mod | cut -d' ' -f2))
|
||||
$(eval MIN_GO_VERSION := $(shell printf "%03d%03d%03d" $(shell echo '$(MIN_GO_VERSION_STR)' | tr '.' ' ')))
|
||||
$(eval GO_VERSION := $(shell printf "%03d%03d%03d" $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9.]+' | tr '.' ' ');))
|
||||
$(eval MIN_GO_VERSION_STR := $(shell grep -Eo '^go\s+[0-9]+\.[0-9]+' go.mod | cut -d' ' -f2))
|
||||
$(eval MIN_GO_VERSION := $(shell printf "%03d%03d" $(shell echo '$(MIN_GO_VERSION_STR)' | tr '.' ' ')))
|
||||
$(eval GO_VERSION := $(shell printf "%03d%03d" $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9]+' | tr '.' ' ');))
|
||||
@if [ "$(GO_VERSION)" -lt "$(MIN_GO_VERSION)" ]; then \
|
||||
echo "Gitea requires Go $(MIN_GO_VERSION_STR) or greater to build. You can get it at https://go.dev/dl/"; \
|
||||
exit 1; \
|
||||
|
@ -310,7 +310,7 @@ lint: lint-frontend lint-backend
|
|||
|
||||
.PHONY: lint-frontend
|
||||
lint-frontend: node_modules
|
||||
npx eslint --color --max-warnings=0 web_src/js build templates *.config.js docs/assets/js
|
||||
npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js
|
||||
npx stylelint --color --max-warnings=0 web_src/less
|
||||
npx spectral lint -q -F hint $(SWAGGER_SPEC)
|
||||
|
||||
|
|
16
README.md
16
README.md
|
@ -45,21 +45,21 @@
|
|||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="README_ZH.md">View the chinese version of this document</a>
|
||||
<a href="README_ZH.md">View this document in Chinese</a>
|
||||
</p>
|
||||
|
||||
## Purpose
|
||||
|
||||
The goal of this project is to make the easiest, fastest, and most
|
||||
painless way of setting up a self-hosted Git service.
|
||||
Using Go, this can be done with an independent binary distribution across
|
||||
**all platforms** which Go supports, including Linux, macOS, and Windows
|
||||
on x86, amd64, ARM and PowerPC architectures.
|
||||
Want to try it before doing anything else?
|
||||
Do it [with the online demo](https://try.gitea.io/)!
|
||||
|
||||
As Gitea is written in Go, it works across **all** the platforms and
|
||||
architectures that are supported by Go, including Linux, macOS, and
|
||||
Windows on x86, amd64, ARM and PowerPC architectures.
|
||||
You can try it out using [the online demo](https://try.gitea.io/).
|
||||
This project has been
|
||||
[forked](https://blog.gitea.io/2016/12/welcome-to-gitea/) from
|
||||
[Gogs](https://gogs.io) since 2016.11 but changed a lot.
|
||||
[Gogs](https://gogs.io) since November of 2016, but a lot has changed.
|
||||
|
||||
## Building
|
||||
|
||||
|
@ -114,7 +114,7 @@ For more information and instructions about how to install Gitea, please look at
|
|||
If you have questions that are not covered by the documentation, you can get in contact with us on our [Discord server](https://discord.gg/Gitea) or create a post in the [discourse forum](https://discourse.gitea.io/).
|
||||
|
||||
We maintain a list of Gitea-related projects at [gitea/awesome-gitea](https://gitea.com/gitea/awesome-gitea).
|
||||
The hugo-based documentation theme is hosted at [gitea/theme](https://gitea.com/gitea/theme).
|
||||
The Hugo-based documentation theme is hosted at [gitea/theme](https://gitea.com/gitea/theme).
|
||||
The official Gitea CLI is developed at [gitea/tea](https://gitea.com/gitea/tea).
|
||||
|
||||
## Authors
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="README.md">View the english version of this document</a>
|
||||
<a href="README.md">View this document in English</a>
|
||||
</p>
|
||||
|
||||
## 目标
|
||||
|
|
|
@ -157,6 +157,10 @@ var (
|
|||
Name: "email,e",
|
||||
Usage: "Email of the user to delete",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "purge",
|
||||
Usage: "Purge user, all their repositories, organizations and comments",
|
||||
},
|
||||
},
|
||||
Action: runDeleteUser,
|
||||
}
|
||||
|
@ -675,7 +679,7 @@ func runDeleteUser(c *cli.Context) error {
|
|||
return fmt.Errorf("The user %s does not match the provided id %d", user.Name, c.Int64("id"))
|
||||
}
|
||||
|
||||
return user_service.DeleteUser(user)
|
||||
return user_service.DeleteUser(ctx, user, c.Bool("purge"))
|
||||
}
|
||||
|
||||
func runGenerateAccessToken(c *cli.Context) error {
|
||||
|
|
|
@ -7,6 +7,8 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/convert"
|
||||
|
@ -15,6 +17,7 @@ import (
|
|||
base "code.gitea.io/gitea/modules/migration"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/services/migrations"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
|
@ -159,9 +162,23 @@ func runDumpRepository(ctx *cli.Context) error {
|
|||
}
|
||||
}
|
||||
|
||||
// the repo_dir will be removed if error occurs in DumpRepository
|
||||
// make sure the directory doesn't exist or is empty, prevent from deleting user files
|
||||
repoDir := ctx.String("repo_dir")
|
||||
if exists, err := util.IsExist(repoDir); err != nil {
|
||||
return fmt.Errorf("unable to stat repo_dir %q: %v", repoDir, err)
|
||||
} else if exists {
|
||||
if isDir, _ := util.IsDir(repoDir); !isDir {
|
||||
return fmt.Errorf("repo_dir %q already exists but it's not a directory", repoDir)
|
||||
}
|
||||
if dir, _ := os.ReadDir(repoDir); len(dir) > 0 {
|
||||
return fmt.Errorf("repo_dir %q is not empty", repoDir)
|
||||
}
|
||||
}
|
||||
|
||||
if err := migrations.DumpRepository(
|
||||
context.Background(),
|
||||
ctx.String("repo_dir"),
|
||||
repoDir,
|
||||
ctx.String("owner_name"),
|
||||
opts,
|
||||
); err != nil {
|
||||
|
|
|
@ -24,7 +24,7 @@ embedded assets. This can be different for older releases.
|
|||
|
||||
## Download
|
||||
|
||||
Choose the file matching the destination platform from the [downloads page](https://dl.gitea.io/gitea/), copy the URL and replace the URL within the commands below:
|
||||
Choose the file matching your platform from the [downloads page](https://dl.gitea.io/gitea/), copy the URL and replace the URL within the commands below:
|
||||
|
||||
```sh
|
||||
wget -O gitea https://dl.gitea.io/gitea/{{< version >}}/gitea-{{< version >}}-linux-amd64
|
||||
|
@ -56,7 +56,8 @@ Check that Git is installed on the server. If it is not, install it first. Gitea
|
|||
git --version
|
||||
```
|
||||
|
||||
Create user to run Gitea (ex. `git`)
|
||||
Create a user to run Gitea (e.g. `git`)
|
||||
|
||||
```sh
|
||||
adduser \
|
||||
--system \
|
||||
|
@ -79,29 +80,39 @@ chown root:git /etc/gitea
|
|||
chmod 770 /etc/gitea
|
||||
```
|
||||
|
||||
**NOTE:** `/etc/gitea` is temporary set with write rights for user `git` so that Web installer could write configuration file. After installation is done, it is recommended to set rights to read-only using:
|
||||
```
|
||||
**NOTE:** `/etc/gitea` is temporarily set with write permissions for user `git` so that the web installer can write the configuration file. After the installation is finished, it is recommended to set permissions to read-only using:
|
||||
|
||||
```sh
|
||||
chmod 750 /etc/gitea
|
||||
chmod 640 /etc/gitea/app.ini
|
||||
```
|
||||
If you don't want the web installer to be able to write the config file at all, it is also possible to make the config file read-only for the Gitea user (owner/group `root:git`, mode `0640`), and set `INSTALL_LOCK = true`. In that case all database configuration details must be set beforehand in the config file, as well as the `SECRET_KEY` and `INTERNAL_TOKEN` values. See the [command line documentation]({{< relref "doc/usage/command-line.en-us.md" >}}) for information on using `gitea generate secret INTERNAL_TOKEN`.
|
||||
|
||||
If you don't want the web installer to be able to write to the config file, it is possible to make the config file read-only for the Gitea user (owner/group `root:git`, mode `0640`) however you will need to edit your config file manually to:
|
||||
|
||||
* Set `INSTALL_LOCK= true`,
|
||||
* Ensure all database configuration details are set correctly
|
||||
* Ensure that the `SECRET_KEY` and `INTERNAL_TOKEN` values are set. (You may want to use the `gitea generate secret` to generate these secret keys.)
|
||||
* Ensure that any other secret keys you need are set.
|
||||
|
||||
See the [command line documentation]({{< relref "doc/usage/command-line.en-us.md" >}}) for information on using `gitea generate secret`.
|
||||
|
||||
### Configure Gitea's working directory
|
||||
|
||||
**NOTE:** If you plan on running Gitea as a Linux service, you can skip this step as the service file allows you to set `WorkingDirectory`. Otherwise, consider setting this environment variable (semi-)permanently so that Gitea consistently uses the correct working directory.
|
||||
```
|
||||
**NOTE:** If you plan on running Gitea as a Linux service, you can skip this step, as the service file allows you to set `WorkingDirectory`. Otherwise, consider setting this environment variable (semi-)permanently so that Gitea consistently uses the correct working directory.
|
||||
|
||||
```sh
|
||||
export GITEA_WORK_DIR=/var/lib/gitea/
|
||||
```
|
||||
|
||||
### Copy Gitea binary to global location
|
||||
### Copy the Gitea binary to a global location
|
||||
|
||||
```
|
||||
```sh
|
||||
cp gitea /usr/local/bin/gitea
|
||||
```
|
||||
|
||||
## Running Gitea
|
||||
|
||||
After the above steps, two options to run Gitea are:
|
||||
After you complete the above steps, you can run Gitea two ways:
|
||||
|
||||
### 1. Creating a service file to start Gitea automatically (recommended)
|
||||
|
||||
|
@ -109,32 +120,31 @@ See how to create [Linux service]({{< relref "run-as-service-in-ubuntu.en-us.md"
|
|||
|
||||
### 2. Running from command-line/terminal
|
||||
|
||||
```
|
||||
```sh
|
||||
GITEA_WORK_DIR=/var/lib/gitea/ /usr/local/bin/gitea web -c /etc/gitea/app.ini
|
||||
```
|
||||
|
||||
## Updating to a new version
|
||||
|
||||
You can update to a new version of Gitea by stopping Gitea, replacing the binary at `/usr/local/bin/gitea` and restarting the instance.
|
||||
The binary file name should not be changed during the update to avoid problems
|
||||
in existing repositories.
|
||||
The binary file name should not be changed during the update to avoid problems in existing repositories.
|
||||
|
||||
It is recommended you do a [backup]({{< relref "doc/usage/backup-and-restore.en-us.md" >}}) before updating your installation.
|
||||
It is recommended that you make a [backup]({{< relref "doc/usage/backup-and-restore.en-us.md" >}}) before updating your installation.
|
||||
|
||||
If you have carried out the installation steps as described above, the binary should
|
||||
have the generic name `gitea`. Do not change this, i.e. to include the version number.
|
||||
|
||||
### 1. Restarting Gitea with systemd (recommended)
|
||||
|
||||
As explained before, we recommend to use systemd as service manager. In this case ```systemctl restart gitea``` should be enough.
|
||||
As we explained before, we recommend to use systemd as the service manager. In this case, `systemctl restart gitea` should be fine.
|
||||
|
||||
### 2. Restarting Gitea without systemd
|
||||
|
||||
To restart your Gitea instance, we recommend to use SIGHUP signal. If you know your Gitea PID use ```kill -1 $GITEA_PID``` otherwise you can use ```killall -1 gitea``` or ```pkill -1 gitea```
|
||||
To restart your Gitea instance, we recommend to use SIGHUP signal. If you know your Gitea PID, use `kill -1 $GITEA_PID`, otherwise you can use `killall -1 gitea`.
|
||||
|
||||
To gracefully stop the Gitea instance, a simple ```kill $GITEA_PID``` or ```killall gitea``` is enough.
|
||||
To gracefully stop the Gitea instance, a simple `kill $GITEA_PID` or `killall gitea` is enough.
|
||||
|
||||
**NOTE:** We don't recommend to use SIGKILL signal (know also as `-9`), you may be forcefully stopping some of Gitea internal tasks and it will not gracefully stop (tasks in queues, indexers processes, etc.)
|
||||
**NOTE:** We don't recommend to use the SIGKILL signal (`-9`); you may be forcefully stopping some of Gitea's internal tasks, and it will not gracefully stop (tasks in queues, indexers, etc.)
|
||||
|
||||
See below for troubleshooting instructions to repair broken repositories after
|
||||
an update of your Gitea version.
|
||||
|
@ -144,31 +154,31 @@ an update of your Gitea version.
|
|||
### Old glibc versions
|
||||
|
||||
Older Linux distributions (such as Debian 7 and CentOS 6) may not be able to load the
|
||||
Gitea binary, usually producing an error such as ```./gitea: /lib/x86_64-linux-gnu/libc.so.6:
|
||||
version `GLIBC\_2.14' not found (required by ./gitea)```. This is due to the integrated
|
||||
Gitea binary, usually producing an error such as `./gitea: /lib/x86_64-linux-gnu/libc.so.6:
|
||||
version 'GLIBC\_2.14' not found (required by ./gitea)`. This is due to the integrated
|
||||
SQLite support in the binaries provided by dl.gitea.io. In this situation, it is usually
|
||||
possible to [install from source]({{< relref "from-source.en-us.md" >}}) without SQLite
|
||||
support.
|
||||
possible to [install from source]({{< relref "from-source.en-us.md" >}}), without including
|
||||
SQLite support.
|
||||
|
||||
### Running Gitea on another port
|
||||
|
||||
For errors like `702 runWeb()] [E] Failed to start server: listen tcp 0.0.0.0:3000:
|
||||
bind: address already in use` Gitea needs to be started on another free port. This
|
||||
bind: address already in use`, Gitea needs to be started on another free port. This
|
||||
is possible using `./gitea web -p $PORT`. It's possible another instance of Gitea
|
||||
is already running.
|
||||
|
||||
### Running Gitea on Raspbian
|
||||
|
||||
As of v1.8, there is a problem with the arm7 version of Gitea and it doesn't run on Raspberry Pi and similar devices.
|
||||
As of v1.8, there is a problem with the arm7 version of Gitea, and it doesn't run on Raspberry Pis and similar devices.
|
||||
|
||||
It is therefore recommended to switch to the arm6 version which has been tested and shown to work on Raspberry Pi and similar devices.
|
||||
It is recommended to switch to the arm6 version, which has been tested and shown to work on Raspberry Pis and similar devices.
|
||||
|
||||
<!---
|
||||
please remove after fixing the arm7 bug
|
||||
--->
|
||||
### Git error after updating to a new version of Gitea
|
||||
|
||||
If the binary file name has been changed during the update to a new version of Gitea,
|
||||
If during the update, the binary file name has been changed to a new version of Gitea,
|
||||
Git Hooks in existing repositories will not work any more. In that case, a Git
|
||||
error will be displayed when pushing to the repository.
|
||||
|
||||
|
@ -181,9 +191,9 @@ binary.
|
|||
|
||||
To solve this, go to the admin options and run the task `Resynchronize pre-receive,
|
||||
update and post-receive hooks of all repositories` to update all hooks to contain
|
||||
the new binary path. Please note that this overwrite all Git Hooks including ones
|
||||
the new binary path. Please note that this overwrites all Git Hooks, including ones
|
||||
with customizations made.
|
||||
|
||||
If you aren't using the built-in to Gitea SSH server you will also need to re-write
|
||||
If you aren't using the Gitea built-in SSH server, you will also need to re-write
|
||||
the authorized key file by running the `Update the '.ssh/authorized_keys' file with
|
||||
Gitea SSH keys.` task in the admin options.
|
||||
|
|
|
@ -17,9 +17,12 @@ blog post to read about the justification for a fork.
|
|||
## Purpose
|
||||
|
||||
The goal of this project is to provide the easiest, fastest, and most painless way of setting
|
||||
up a self-hosted Git service. With Go, this can be done with an independent binary distribution
|
||||
across all platforms and architectures that Go supports. This support includes Linux, macOS, and
|
||||
Windows, on architectures like amd64, i386, ARM, PowerPC, and others.
|
||||
up a self-hosted Git service.
|
||||
|
||||
With Go, this can be done platform-independently across
|
||||
**all platforms** which Go supports, including Linux, macOS, and Windows,
|
||||
on x86, amd64, ARM and PowerPC architectures.
|
||||
You can try it out using [the online demo](https://try.gitea.io/).
|
||||
|
||||
## Features
|
||||
|
||||
|
@ -268,8 +271,8 @@ Windows, on architectures like amd64, i386, ARM, PowerPC, and others.
|
|||
- Gitea should be run with a dedicated non-root system account on UNIX-type systems.
|
||||
- Note: Gitea manages the `~/.ssh/authorized_keys` file. Running Gitea as a regular user could break that user's ability to log in.
|
||||
- [Git](https://git-scm.com/) version 2.0.0 or later is required.
|
||||
- [Git Large File Storage](https://git-lfs.github.com/) will be available if enabled when Git >= 2.1.2.
|
||||
- Git commit-graph rendering will be enabled automatically when Git >= 2.18.
|
||||
- [Git Large File Storage](https://git-lfs.github.com/) will be available if enabled and if your Git version is >= 2.1.2
|
||||
- Git commit-graph rendering will be enabled automatically if your Git version is >= 2.18
|
||||
|
||||
## Browser Support
|
||||
|
||||
|
|
2
go.mod
2
go.mod
|
@ -104,7 +104,7 @@ require (
|
|||
mvdan.cc/xurls/v2 v2.4.0
|
||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251
|
||||
xorm.io/builder v0.3.11
|
||||
xorm.io/xorm v1.3.1
|
||||
xorm.io/xorm v1.3.2-0.20220714055524-c3bce556200f
|
||||
)
|
||||
|
||||
require (
|
||||
|
|
4
go.sum
4
go.sum
|
@ -2423,5 +2423,5 @@ strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:
|
|||
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/builder v0.3.11 h1:naLkJitGyYW7ZZdncsh/JW+HF4HshmvTHTyUyPwJS00=
|
||||
xorm.io/builder v0.3.11/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/xorm v1.3.1 h1:z5egKrDoOLqZFhMjcGF4FBHiTmE5/feQoHclfhNidfM=
|
||||
xorm.io/xorm v1.3.1/go.mod h1:9NbjqdnjX6eyjRRhh01GHm64r6N9shTb/8Ak3YRt8Nw=
|
||||
xorm.io/xorm v1.3.2-0.20220714055524-c3bce556200f h1:3NvNsM4lnttTsHpk8ODHqrwN1MCEjsO3bD/rpd8A47k=
|
||||
xorm.io/xorm v1.3.2-0.20220714055524-c3bce556200f/go.mod h1:9NbjqdnjX6eyjRRhh01GHm64r6N9shTb/8Ak3YRt8Nw=
|
||||
|
|
|
@ -76,7 +76,7 @@ func TestAdminDeleteUser(t *testing.T) {
|
|||
req := NewRequestWithValues(t, "POST", "/admin/users/8/delete", map[string]string{
|
||||
"_csrf": csrf,
|
||||
})
|
||||
session.MakeRequest(t, req, http.StatusOK)
|
||||
session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
|
||||
assertUserDeleted(t, 8)
|
||||
unittest.CheckConsistencyFor(t, &user_model.User{})
|
||||
|
|
|
@ -188,8 +188,13 @@ func initIntegrationTest() {
|
|||
|
||||
switch {
|
||||
case setting.Database.UseMySQL:
|
||||
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/",
|
||||
setting.Database.User, setting.Database.Passwd, setting.Database.Host))
|
||||
connType := "tcp"
|
||||
if len(setting.Database.Host) > 0 && setting.Database.Host[0] == '/' { // looks like a unix socket
|
||||
connType = "unix"
|
||||
}
|
||||
|
||||
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@%s(%s)/",
|
||||
setting.Database.User, setting.Database.Passwd, connType, setting.Database.Host))
|
||||
defer db.Close()
|
||||
if err != nil {
|
||||
log.Fatal("sql.Open: %v", err)
|
||||
|
|
|
@ -105,7 +105,11 @@ func doAPICreateCommitStatus(ctx APITestContext, commitID string, status api.Com
|
|||
}
|
||||
}
|
||||
|
||||
func TestPullCreate_EmptyChangesWithCommits(t *testing.T) {
|
||||
func TestPullCreate_EmptyChangesWithDifferentCommits(t *testing.T) {
|
||||
// Merge must continue if commits SHA are different, even if content is same
|
||||
// Reason: gitflow and merging master back into develop, where is high possiblity, there are no changes
|
||||
// but just commit saying "Merge branch". And this meta commit can be also tagged,
|
||||
// so we need to have this meta commit also in develop branch.
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
session := loginUser(t, "user1")
|
||||
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
|
||||
|
@ -126,6 +130,28 @@ func TestPullCreate_EmptyChangesWithCommits(t *testing.T) {
|
|||
doc := NewHTMLParser(t, resp.Body)
|
||||
|
||||
text := strings.TrimSpace(doc.doc.Find(".merge-section").Text())
|
||||
assert.Contains(t, text, "This branch is equal with the target branch.")
|
||||
assert.Contains(t, text, "This pull request can be merged automatically.")
|
||||
})
|
||||
}
|
||||
|
||||
func TestPullCreate_EmptyChangesWithSameCommits(t *testing.T) {
|
||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||
session := loginUser(t, "user1")
|
||||
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
|
||||
testCreateBranch(t, session, "user1", "repo1", "branch/master", "status1", http.StatusSeeOther)
|
||||
url := path.Join("user1", "repo1", "compare", "master...status1")
|
||||
req := NewRequestWithValues(t, "POST", url,
|
||||
map[string]string{
|
||||
"_csrf": GetCSRF(t, session, url),
|
||||
"title": "pull request from status1",
|
||||
},
|
||||
)
|
||||
session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
req = NewRequest(t, "GET", "/user1/repo1/pulls/1")
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
doc := NewHTMLParser(t, resp.Body)
|
||||
|
||||
text := strings.TrimSpace(doc.doc.Find(".merge-section").Text())
|
||||
assert.Contains(t, text, "This branch is already included in the target branch. There is nothing to merge.")
|
||||
})
|
||||
}
|
||||
|
|
|
@ -242,7 +242,7 @@ func (issues IssueList) loadAssignees(ctx context.Context) error {
|
|||
}
|
||||
rows, err := db.GetEngine(ctx).Table("issue_assignees").
|
||||
Join("INNER", "`user`", "`user`.id = `issue_assignees`.assignee_id").
|
||||
In("`issue_assignees`.issue_id", issueIDs[:limit]).
|
||||
In("`issue_assignees`.issue_id", issueIDs[:limit]).OrderBy(user_model.GetOrderByName()).
|
||||
Rows(new(AssigneeIssue))
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"code.gitea.io/gitea/models/db"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
@ -107,6 +108,7 @@ func (label *Label) CalOpenOrgIssues(repoID, labelID int64) {
|
|||
counts, _ := CountIssuesByRepo(&IssuesOptions{
|
||||
RepoID: repoID,
|
||||
LabelIDs: []int64{labelID},
|
||||
IsClosed: util.OptionalBoolFalse,
|
||||
})
|
||||
|
||||
for _, count := range counts {
|
||||
|
|
|
@ -122,6 +122,7 @@ const (
|
|||
PullRequestStatusManuallyMerged
|
||||
PullRequestStatusError
|
||||
PullRequestStatusEmpty
|
||||
PullRequestStatusAncestor
|
||||
)
|
||||
|
||||
// PullRequestFlow the flow of pull request
|
||||
|
@ -423,6 +424,11 @@ func (pr *PullRequest) IsEmpty() bool {
|
|||
return pr.Status == PullRequestStatusEmpty
|
||||
}
|
||||
|
||||
// IsAncestor returns true if the Head Commit of this PR is an ancestor of the Base Commit
|
||||
func (pr *PullRequest) IsAncestor() bool {
|
||||
return pr.Status == PullRequestStatusAncestor
|
||||
}
|
||||
|
||||
// SetMerged sets a pull request to merged and closes the corresponding issue
|
||||
func (pr *PullRequest) SetMerged(ctx context.Context) (bool, error) {
|
||||
if pr.HasMerged {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
"code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
|
|
|
@ -81,5 +81,6 @@ func GetTeamsWithAccessToRepo(ctx context.Context, orgID, repoID int64, mode per
|
|||
Join("INNER", "team_repo", "team_repo.team_id = team.id").
|
||||
And("team_repo.org_id = ?", orgID).
|
||||
And("team_repo.repo_id = ?", repoID).
|
||||
OrderBy("name").
|
||||
Find(&teams)
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ func getVersionByNameAndVersion(ctx context.Context, ownerID int64, packageType
|
|||
ExactMatch: true,
|
||||
Value: version,
|
||||
},
|
||||
IsInternal: isInternal,
|
||||
IsInternal: util.OptionalBoolOf(isInternal),
|
||||
Paginator: db.NewAbsoluteListOptions(0, 1),
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -171,7 +171,7 @@ type PackageSearchOptions struct {
|
|||
Name SearchValue // only results with the specific name are found
|
||||
Version SearchValue // only results with the specific version are found
|
||||
Properties map[string]string // only results are found which contain all listed version properties with the specific value
|
||||
IsInternal bool
|
||||
IsInternal util.OptionalBool
|
||||
HasFileWithName string // only results are found which are associated with a file with the specific name
|
||||
HasFiles util.OptionalBool // only results are found which have associated files
|
||||
Sort string
|
||||
|
@ -179,7 +179,10 @@ type PackageSearchOptions struct {
|
|||
}
|
||||
|
||||
func (opts *PackageSearchOptions) toConds() builder.Cond {
|
||||
var cond builder.Cond = builder.Eq{"package_version.is_internal": opts.IsInternal}
|
||||
cond := builder.NewCond()
|
||||
if !opts.IsInternal.IsNone() {
|
||||
cond = builder.Eq{"package_version.is_internal": opts.IsInternal.IsTrue()}
|
||||
}
|
||||
|
||||
if opts.OwnerID != 0 {
|
||||
cond = cond.And(builder.Eq{"package.owner_id": opts.OwnerID})
|
||||
|
|
|
@ -330,3 +330,40 @@ func DeleteProjectByIDCtx(ctx context.Context, id int64) error {
|
|||
|
||||
return updateRepositoryProjectCount(ctx, p.RepoID)
|
||||
}
|
||||
|
||||
func DeleteProjectByRepoIDCtx(ctx context.Context, repoID int64) error {
|
||||
switch {
|
||||
case setting.Database.UseSQLite3:
|
||||
if _, err := db.GetEngine(ctx).Exec("DELETE FROM project_issue WHERE project_issue.id IN (SELECT project_issue.id FROM project_issue INNER JOIN project WHERE project.id = project_issue.project_id AND project.repo_id = ?)", repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.GetEngine(ctx).Exec("DELETE FROM project_board WHERE project_board.id IN (SELECT project_board.id FROM project_board INNER JOIN project WHERE project.id = project_board.project_id AND project.repo_id = ?)", repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.GetEngine(ctx).Table("project").Where("repo_id = ? ", repoID).Delete(&Project{}); err != nil {
|
||||
return err
|
||||
}
|
||||
case setting.Database.UsePostgreSQL:
|
||||
if _, err := db.GetEngine(ctx).Exec("DELETE FROM project_issue USING project WHERE project.id = project_issue.project_id AND project.repo_id = ? ", repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.GetEngine(ctx).Exec("DELETE FROM project_board USING project WHERE project.id = project_board.project_id AND project.repo_id = ? ", repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.GetEngine(ctx).Table("project").Where("repo_id = ? ", repoID).Delete(&Project{}); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
if _, err := db.GetEngine(ctx).Exec("DELETE project_issue FROM project_issue INNER JOIN project ON project.id = project_issue.project_id WHERE project.repo_id = ? ", repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.GetEngine(ctx).Exec("DELETE project_board FROM project_board INNER JOIN project ON project.id = project_board.project_id WHERE project.repo_id = ? ", repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.GetEngine(ctx).Table("project").Where("repo_id = ? ", repoID).Delete(&Project{}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return updateRepositoryProjectCount(ctx, repoID)
|
||||
}
|
||||
|
|
|
@ -342,16 +342,8 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
|
|||
}
|
||||
}
|
||||
|
||||
projects, _, err := project_model.GetProjects(ctx, project_model.SearchOptions{
|
||||
RepoID: repoID,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("get projects: %v", err)
|
||||
}
|
||||
for i := range projects {
|
||||
if err := project_model.DeleteProjectByIDCtx(ctx, projects[i].ID); err != nil {
|
||||
return fmt.Errorf("delete project [%d]: %v", projects[i].ID, err)
|
||||
}
|
||||
if err := project_model.DeleteProjectByRepoIDCtx(ctx, repoID); err != nil {
|
||||
return fmt.Errorf("unable to delete projects for repo[%d]: %v", repoID, err)
|
||||
}
|
||||
|
||||
// Remove LFS objects
|
||||
|
|
|
@ -109,7 +109,7 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us
|
|||
// and just waste 1 unit is cheaper than re-allocate memory once.
|
||||
users := make([]*user_model.User, 0, len(userIDs)+1)
|
||||
if len(userIDs) > 0 {
|
||||
if err = e.In("id", userIDs).Find(&users); err != nil {
|
||||
if err = e.In("id", userIDs).OrderBy(user_model.GetOrderByName()).Find(&users); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
@ -168,5 +168,5 @@ func GetReviewers(ctx context.Context, repo *Repository, doerID, posterID int64)
|
|||
}
|
||||
|
||||
users := make([]*user_model.User, 0, 8)
|
||||
return users, db.GetEngine(ctx).Where(cond).OrderBy("name").Find(&users)
|
||||
return users, db.GetEngine(ctx).Where(cond).OrderBy(user_model.GetOrderByName()).Find(&users)
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import (
|
|||
)
|
||||
|
||||
// DeleteUser deletes models associated to an user.
|
||||
func DeleteUser(ctx context.Context, u *user_model.User) (err error) {
|
||||
func DeleteUser(ctx context.Context, u *user_model.User, purge bool) (err error) {
|
||||
e := db.GetEngine(ctx)
|
||||
|
||||
// ***** START: Watch *****
|
||||
|
@ -95,8 +95,8 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
if setting.Service.UserDeleteWithCommentsMaxTime != 0 &&
|
||||
u.CreatedUnix.AsTime().Add(setting.Service.UserDeleteWithCommentsMaxTime).After(time.Now()) {
|
||||
if purge || (setting.Service.UserDeleteWithCommentsMaxTime != 0 &&
|
||||
u.CreatedUnix.AsTime().Add(setting.Service.UserDeleteWithCommentsMaxTime).After(time.Now())) {
|
||||
|
||||
// Delete Comments
|
||||
const batchSize = 50
|
||||
|
|
|
@ -1314,3 +1314,10 @@ func IsUserVisibleToViewer(ctx context.Context, u, viewer *User) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func GetOrderByName() string {
|
||||
if setting.UI.DefaultShowFullName {
|
||||
return "full_name, name"
|
||||
}
|
||||
return "name"
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"code.gitea.io/gitea/models/perm"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
|
||||
// Organization contains organization context
|
||||
|
@ -69,6 +70,20 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
|
|||
return
|
||||
}
|
||||
org := ctx.Org.Organization
|
||||
|
||||
// Handle Visibility
|
||||
if org.Visibility != structs.VisibleTypePublic && !ctx.IsSigned {
|
||||
// We must be signed in to see limited or private organizations
|
||||
ctx.NotFound("OrgAssignment", err)
|
||||
return
|
||||
}
|
||||
|
||||
if org.Visibility == structs.VisibleTypePrivate {
|
||||
requireMember = true
|
||||
} else if ctx.IsSigned && ctx.Doer.IsRestricted {
|
||||
requireMember = true
|
||||
}
|
||||
|
||||
ctx.ContextUser = org.AsUser()
|
||||
ctx.Data["Org"] = org
|
||||
|
||||
|
|
|
@ -78,6 +78,8 @@ func innerToRepo(repo *repo_model.Repository, mode perm.AccessMode, isParent boo
|
|||
allowRebase := false
|
||||
allowRebaseMerge := false
|
||||
allowSquash := false
|
||||
allowRebaseUpdate := false
|
||||
defaultDeleteBranchAfterMerge := false
|
||||
defaultMergeStyle := repo_model.MergeStyleMerge
|
||||
if unit, err := repo.GetUnit(unit_model.TypePullRequests); err == nil {
|
||||
config := unit.PullRequestsConfig()
|
||||
|
@ -87,6 +89,8 @@ func innerToRepo(repo *repo_model.Repository, mode perm.AccessMode, isParent boo
|
|||
allowRebase = config.AllowRebase
|
||||
allowRebaseMerge = config.AllowRebaseMerge
|
||||
allowSquash = config.AllowSquash
|
||||
allowRebaseUpdate = config.AllowRebaseUpdate
|
||||
defaultDeleteBranchAfterMerge = config.DefaultDeleteBranchAfterMerge
|
||||
defaultMergeStyle = config.GetDefaultMergeStyle()
|
||||
}
|
||||
hasProjects := false
|
||||
|
@ -133,54 +137,56 @@ func innerToRepo(repo *repo_model.Repository, mode perm.AccessMode, isParent boo
|
|||
repoAPIURL := repo.APIURL()
|
||||
|
||||
return &api.Repository{
|
||||
ID: repo.ID,
|
||||
Owner: ToUserWithAccessMode(repo.Owner, mode),
|
||||
Name: repo.Name,
|
||||
FullName: repo.FullName(),
|
||||
Description: repo.Description,
|
||||
Private: repo.IsPrivate,
|
||||
Template: repo.IsTemplate,
|
||||
Empty: repo.IsEmpty,
|
||||
Archived: repo.IsArchived,
|
||||
Size: int(repo.Size / 1024),
|
||||
Fork: repo.IsFork,
|
||||
Parent: parent,
|
||||
Mirror: repo.IsMirror,
|
||||
HTMLURL: repo.HTMLURL(),
|
||||
SSHURL: cloneLink.SSH,
|
||||
CloneURL: cloneLink.HTTPS,
|
||||
OriginalURL: repo.SanitizedOriginalURL(),
|
||||
Website: repo.Website,
|
||||
Language: language,
|
||||
LanguagesURL: repoAPIURL + "/languages",
|
||||
Stars: repo.NumStars,
|
||||
Forks: repo.NumForks,
|
||||
Watchers: repo.NumWatches,
|
||||
OpenIssues: repo.NumOpenIssues,
|
||||
OpenPulls: repo.NumOpenPulls,
|
||||
Releases: int(numReleases),
|
||||
DefaultBranch: repo.DefaultBranch,
|
||||
Created: repo.CreatedUnix.AsTime(),
|
||||
Updated: repo.UpdatedUnix.AsTime(),
|
||||
Permissions: permission,
|
||||
HasIssues: hasIssues,
|
||||
ExternalTracker: externalTracker,
|
||||
InternalTracker: internalTracker,
|
||||
HasWiki: hasWiki,
|
||||
HasProjects: hasProjects,
|
||||
ExternalWiki: externalWiki,
|
||||
HasPullRequests: hasPullRequests,
|
||||
IgnoreWhitespaceConflicts: ignoreWhitespaceConflicts,
|
||||
AllowMerge: allowMerge,
|
||||
AllowRebase: allowRebase,
|
||||
AllowRebaseMerge: allowRebaseMerge,
|
||||
AllowSquash: allowSquash,
|
||||
DefaultMergeStyle: string(defaultMergeStyle),
|
||||
AvatarURL: repo.AvatarLink(),
|
||||
Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate,
|
||||
MirrorInterval: mirrorInterval,
|
||||
MirrorUpdated: mirrorUpdated,
|
||||
RepoTransfer: transfer,
|
||||
ID: repo.ID,
|
||||
Owner: ToUserWithAccessMode(repo.Owner, mode),
|
||||
Name: repo.Name,
|
||||
FullName: repo.FullName(),
|
||||
Description: repo.Description,
|
||||
Private: repo.IsPrivate,
|
||||
Template: repo.IsTemplate,
|
||||
Empty: repo.IsEmpty,
|
||||
Archived: repo.IsArchived,
|
||||
Size: int(repo.Size / 1024),
|
||||
Fork: repo.IsFork,
|
||||
Parent: parent,
|
||||
Mirror: repo.IsMirror,
|
||||
HTMLURL: repo.HTMLURL(),
|
||||
SSHURL: cloneLink.SSH,
|
||||
CloneURL: cloneLink.HTTPS,
|
||||
OriginalURL: repo.SanitizedOriginalURL(),
|
||||
Website: repo.Website,
|
||||
Language: language,
|
||||
LanguagesURL: repoAPIURL + "/languages",
|
||||
Stars: repo.NumStars,
|
||||
Forks: repo.NumForks,
|
||||
Watchers: repo.NumWatches,
|
||||
OpenIssues: repo.NumOpenIssues,
|
||||
OpenPulls: repo.NumOpenPulls,
|
||||
Releases: int(numReleases),
|
||||
DefaultBranch: repo.DefaultBranch,
|
||||
Created: repo.CreatedUnix.AsTime(),
|
||||
Updated: repo.UpdatedUnix.AsTime(),
|
||||
Permissions: permission,
|
||||
HasIssues: hasIssues,
|
||||
ExternalTracker: externalTracker,
|
||||
InternalTracker: internalTracker,
|
||||
HasWiki: hasWiki,
|
||||
HasProjects: hasProjects,
|
||||
ExternalWiki: externalWiki,
|
||||
HasPullRequests: hasPullRequests,
|
||||
IgnoreWhitespaceConflicts: ignoreWhitespaceConflicts,
|
||||
AllowMerge: allowMerge,
|
||||
AllowRebase: allowRebase,
|
||||
AllowRebaseMerge: allowRebaseMerge,
|
||||
AllowSquash: allowSquash,
|
||||
AllowRebaseUpdate: allowRebaseUpdate,
|
||||
DefaultDeleteBranchAfterMerge: defaultDeleteBranchAfterMerge,
|
||||
DefaultMergeStyle: string(defaultMergeStyle),
|
||||
AvatarURL: repo.AvatarLink(),
|
||||
Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate,
|
||||
MirrorInterval: mirrorInterval,
|
||||
MirrorUpdated: mirrorUpdated,
|
||||
RepoTransfer: transfer,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ func toUser(user *user_model.User, signed, authed bool) *api.User {
|
|||
// only site admin will get these information and possibly user himself
|
||||
if authed {
|
||||
result.IsAdmin = user.IsAdmin
|
||||
result.LoginName = user.LoginName
|
||||
result.LastLogin = user.LastLoginUnix.AsTime()
|
||||
result.Language = user.Language
|
||||
result.IsActive = user.IsActive
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
)
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"path"
|
||||
"sort"
|
||||
|
@ -62,9 +63,10 @@ func LogNameStatusRepo(ctx context.Context, repository, head, treepath string, p
|
|||
})
|
||||
if err != nil {
|
||||
_ = stdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
|
||||
} else {
|
||||
_ = stdoutWriter.Close()
|
||||
return
|
||||
}
|
||||
|
||||
_ = stdoutWriter.Close()
|
||||
}()
|
||||
|
||||
// For simplicities sake we'll us a buffered reader to read from the cat-file --batch
|
||||
|
@ -354,7 +356,7 @@ heaploop:
|
|||
}
|
||||
current, err := g.Next(treepath, path2idx, changed, maxpathlen)
|
||||
if err != nil {
|
||||
if err == context.DeadlineExceeded {
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
break heaploop
|
||||
}
|
||||
g.Close()
|
||||
|
|
|
@ -7,6 +7,7 @@ package git
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
@ -72,7 +73,14 @@ func (repo *Repository) SetDefaultBranch(name string) error {
|
|||
// GetDefaultBranch gets default branch of repository.
|
||||
func (repo *Repository) GetDefaultBranch() (string, error) {
|
||||
stdout, _, err := NewCommand(repo.Ctx, "symbolic-ref", "HEAD").RunStdString(&RunOpts{Dir: repo.Path})
|
||||
return stdout, err
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
stdout = strings.TrimSpace(stdout)
|
||||
if !strings.HasPrefix(stdout, BranchPrefix) {
|
||||
return "", errors.New("the HEAD is not a branch: " + stdout)
|
||||
}
|
||||
return strings.TrimPrefix(stdout, BranchPrefix), nil
|
||||
}
|
||||
|
||||
// GetBranch returns a branch by it's name
|
||||
|
|
|
@ -85,6 +85,12 @@ func createDefaultPolicy() *bluemonday.Policy {
|
|||
// Allow icons, emojis, chroma syntax and keyword markup on span
|
||||
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^((icon(\s+[\p{L}\p{N}_-]+)+)|(emoji))$|^([a-z][a-z0-9]{0,2})$|^` + keywordClass + `$`)).OnElements("span")
|
||||
|
||||
// Allow 'style' attribute on text elements.
|
||||
policy.AllowAttrs("style").OnElements("span", "p")
|
||||
|
||||
// Allow 'color' property for the style attribute on text elements.
|
||||
policy.AllowStyles("color").OnElements("span", "p")
|
||||
|
||||
// Allow generally safe attributes
|
||||
generalSafeAttrs := []string{
|
||||
"abbr", "accept", "accept-charset",
|
||||
|
|
|
@ -45,6 +45,14 @@ func Test_Sanitizer(t *testing.T) {
|
|||
`<input type="checkbox" disabled=""/>unchecked`, `<input type="checkbox" disabled=""/>unchecked`,
|
||||
`<span class="emoji dropdown">NAUGHTY</span>`, `<span>NAUGHTY</span>`,
|
||||
`<span class="emoji">contents</span>`, `<span class="emoji">contents</span>`,
|
||||
|
||||
// Color property
|
||||
`<span style="color: red">Hello World</span>`, `<span style="color: red">Hello World</span>`,
|
||||
`<p style="color: red">Hello World</p>`, `<p style="color: red">Hello World</p>`,
|
||||
`<code style="color: red">Hello World</code>`, `<code>Hello World</code>`,
|
||||
`<span style="bad-color: red">Hello World</span>`, `<span>Hello World</span>`,
|
||||
`<p style="bad-color: red">Hello World</p>`, `<p>Hello World</p>`,
|
||||
`<code style="bad-color: red">Hello World</code>`, `<code>Hello World</code>`,
|
||||
}
|
||||
|
||||
for i := 0; i < len(testCases); i += 2 {
|
||||
|
|
|
@ -77,24 +77,26 @@ type Repository struct {
|
|||
// swagger:strfmt date-time
|
||||
Created time.Time `json:"created_at"`
|
||||
// swagger:strfmt date-time
|
||||
Updated time.Time `json:"updated_at"`
|
||||
Permissions *Permission `json:"permissions,omitempty"`
|
||||
HasIssues bool `json:"has_issues"`
|
||||
InternalTracker *InternalTracker `json:"internal_tracker,omitempty"`
|
||||
ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"`
|
||||
HasWiki bool `json:"has_wiki"`
|
||||
ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"`
|
||||
HasPullRequests bool `json:"has_pull_requests"`
|
||||
HasProjects bool `json:"has_projects"`
|
||||
IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"`
|
||||
AllowMerge bool `json:"allow_merge_commits"`
|
||||
AllowRebase bool `json:"allow_rebase"`
|
||||
AllowRebaseMerge bool `json:"allow_rebase_explicit"`
|
||||
AllowSquash bool `json:"allow_squash_merge"`
|
||||
DefaultMergeStyle string `json:"default_merge_style"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
Internal bool `json:"internal"`
|
||||
MirrorInterval string `json:"mirror_interval"`
|
||||
Updated time.Time `json:"updated_at"`
|
||||
Permissions *Permission `json:"permissions,omitempty"`
|
||||
HasIssues bool `json:"has_issues"`
|
||||
InternalTracker *InternalTracker `json:"internal_tracker,omitempty"`
|
||||
ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"`
|
||||
HasWiki bool `json:"has_wiki"`
|
||||
ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"`
|
||||
HasPullRequests bool `json:"has_pull_requests"`
|
||||
HasProjects bool `json:"has_projects"`
|
||||
IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"`
|
||||
AllowMerge bool `json:"allow_merge_commits"`
|
||||
AllowRebase bool `json:"allow_rebase"`
|
||||
AllowRebaseMerge bool `json:"allow_rebase_explicit"`
|
||||
AllowSquash bool `json:"allow_squash_merge"`
|
||||
AllowRebaseUpdate bool `json:"allow_rebase_update"`
|
||||
DefaultDeleteBranchAfterMerge bool `json:"default_delete_branch_after_merge"`
|
||||
DefaultMergeStyle string `json:"default_merge_style"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
Internal bool `json:"internal"`
|
||||
MirrorInterval string `json:"mirror_interval"`
|
||||
// swagger:strfmt date-time
|
||||
MirrorUpdated time.Time `json:"mirror_updated,omitempty"`
|
||||
RepoTransfer *RepoTransfer `json:"repo_transfer"`
|
||||
|
|
|
@ -17,6 +17,9 @@ type User struct {
|
|||
ID int64 `json:"id"`
|
||||
// the user's username
|
||||
UserName string `json:"login"`
|
||||
// the user's authentication sign-in name.
|
||||
// default: empty
|
||||
LoginName string `json:"login_name"`
|
||||
// the user's full name
|
||||
FullName string `json:"full_name"`
|
||||
// swagger:strfmt email
|
||||
|
|
|
@ -897,7 +897,6 @@ form.name_pattern_not_allowed=Vzor „%s“ není povolený v názvu repozitář
|
|||
need_auth=Ověření
|
||||
migrate_options=Možnosti migrace
|
||||
migrate_service=Migrační služba
|
||||
migrate_options_mirror_helper=Tento repozitář bude <span class="text blue">zrcadlem</span>
|
||||
migrate_options_lfs=Migrovat LFS soubory
|
||||
migrate_options_lfs_endpoint.label=Koncový bod LFS
|
||||
migrate_options_lfs_endpoint.description=Migrace se pokusí použít váš vzdálený Git pro <a target="_blank" rel="noopener noreferrer" href="%s">určení LFS serveru</a>. Můžete také zadat vlastní koncový bod, pokud jsou data LFS repozitáře uložena někde jinde.
|
||||
|
@ -1462,7 +1461,6 @@ pulls.remove_prefix=Odstranit prefix <strong>%s</strong>
|
|||
pulls.data_broken=Tento požadavek na natažení je rozbitý kvůli chybějícím informacím o rozštěpení.
|
||||
pulls.files_conflicted=Tento požadavek na natažení obsahuje změny, které kolidují s cílovou větví.
|
||||
pulls.is_checking=Právě probíhá kontrola konfliktů při sloučení. Zkuste to za chvíli.
|
||||
pulls.is_empty=Tato větev je stejná jako cílová větev.
|
||||
pulls.required_status_check_failed=Některé požadované kontroly nebyly úspěšné.
|
||||
pulls.required_status_check_missing=Některé požadované kontroly chybí.
|
||||
pulls.required_status_check_administrator=Jako administrátor stále můžete sloučit tento požadavek na natažení.
|
||||
|
|
|
@ -930,7 +930,6 @@ form.name_pattern_not_allowed='%s' ist nicht erlaubt für Repository-Namen.
|
|||
need_auth=Authentifizierung
|
||||
migrate_options=Migrationsoptionen
|
||||
migrate_service=Migrationsdienst
|
||||
migrate_options_mirror_helper=Dieses Repository wird ein <span class="text blue">Mirror</span> sein
|
||||
migrate_options_lfs=LFS-Dateien migrieren
|
||||
migrate_options_lfs_endpoint.label=LFS-Endpunkt
|
||||
migrate_options_lfs_endpoint.description=Migration wird versuchen, über den entfernten Git-Server <a target="_blank" rel="noopener noreferrer" href="%s">den LFS-Server zu bestimmen</a>. Du kannst auch einen eigenen Endpunkt angeben, wenn die LFS-Dateien woanders gespeichert werden.
|
||||
|
@ -1529,7 +1528,6 @@ pulls.remove_prefix=<strong>%s</strong> Präfix entfernen
|
|||
pulls.data_broken=Dieser Pull-Requests ist kaputt, da Fork-Informationen gelöscht wurden.
|
||||
pulls.files_conflicted=Dieser Pull-Request hat Änderungen, die im Widerspruch zum Ziel-Branch stehen.
|
||||
pulls.is_checking=Die Konfliktprüfung läuft noch. Bitte aktualisiere die Seite in wenigen Augenblicken.
|
||||
pulls.is_empty=Dieser Branch ist gleich mit dem Zielbranch.
|
||||
pulls.required_status_check_failed=Einige erforderliche Prüfungen waren nicht erfolgreich.
|
||||
pulls.required_status_check_missing=Einige erforderliche Prüfungen fehlen.
|
||||
pulls.required_status_check_administrator=Als Administrator kannst du diesen Pull-Request weiterhin zusammenführen.
|
||||
|
|
|
@ -930,7 +930,6 @@ form.name_pattern_not_allowed=Το μοτίβο '%s' δεν επιτρέπετα
|
|||
need_auth=Εξουσιοδότηση
|
||||
migrate_options=Επιλογές Μεταφοράς
|
||||
migrate_service=Υπηρεσία Μεταφοράς
|
||||
migrate_options_mirror_helper=Αυτό το αποθετήριο θα είναι ένα <span class="text blue">είδωλο</span>
|
||||
migrate_options_lfs=Μεταφορά αρχείων LFS
|
||||
migrate_options_lfs_endpoint.label=LFS Endpoint
|
||||
migrate_options_lfs_endpoint.description=Η μεταφορά θα προσπαθήσει να χρησιμοποιήσει το Git remote για να <a target="_blank" rel="noopener noreferrer" href="%s">καθορίσει τον διακομιστή LFS</a>. Μπορείτε επίσης να καθορίσετε ένα δικό σας endpoint αν τα δεδομένα LFS του αποθετηρίου αποθηκεύονται κάπου αλλού.
|
||||
|
@ -1529,7 +1528,6 @@ pulls.remove_prefix=Αφαίρεση <strong>%s</strong> προθέματος
|
|||
pulls.data_broken=Αυτό το pull request είναι κατεστραμμένο λόγω των πληροφοριών του fork που λείπουν.
|
||||
pulls.files_conflicted=Αυτό το pull request περιέχει αλλαγές που συγκρούονται με το κλάδο προορισμού.
|
||||
pulls.is_checking=Ο έλεγχος συγκρούσεων κατά την συγχώνευση είναι σε εξέλιξη. Δοκιμάστε ξανά σε λίγα λεπτά.
|
||||
pulls.is_empty=Αυτός ο κλάδος είναι ίσος με τον κλάδο-στόχο.
|
||||
pulls.required_status_check_failed=Ορισμένοι απαιτούμενοι έλεγχοι δεν ήταν επιτυχείς.
|
||||
pulls.required_status_check_missing=Λείπουν ορισμένοι απαιτούμενοι έλεγχοι.
|
||||
pulls.required_status_check_administrator=Ως διαχειριστής, μπορείτε ακόμα να συγχωνεύσετε αυτό το pull request.
|
||||
|
|
|
@ -1532,7 +1532,8 @@ pulls.remove_prefix = Remove <strong>%s</strong> prefix
|
|||
pulls.data_broken = This pull request is broken due to missing fork information.
|
||||
pulls.files_conflicted = This pull request has changes conflicting with the target branch.
|
||||
pulls.is_checking = "Merge conflict checking is in progress. Try again in few moments."
|
||||
pulls.is_empty = "This branch is equal with the target branch."
|
||||
pulls.is_ancestor = "This branch is already included in the target branch. There is nothing to merge."
|
||||
pulls.is_empty = "The changes on this branch are already on the target branch. This will be an empty commit."
|
||||
pulls.required_status_check_failed = Some required checks were not successful.
|
||||
pulls.required_status_check_missing = Some required checks are missing.
|
||||
pulls.required_status_check_administrator = As an administrator, you may still merge this pull request.
|
||||
|
@ -2539,6 +2540,8 @@ users.delete_account = Delete User Account
|
|||
users.cannot_delete_self = "You cannot delete yourself"
|
||||
users.still_own_repo = This user still owns one or more repositories. Delete or transfer these repositories first.
|
||||
users.still_has_org = This user is a member of an organization. Remove the user from any organizations first.
|
||||
users.purge = Purge User
|
||||
users.purge_help = Forcibly delete user and any repositories, organizations, and packages owned by the user. All comments will be deleted too.
|
||||
users.still_own_packages = This user still owns one or more packages. Delete these packages first.
|
||||
users.deletion_success = The user account has been deleted.
|
||||
users.reset_2fa = Reset 2FA
|
||||
|
|
|
@ -932,7 +932,6 @@ form.name_pattern_not_allowed=El patrón '%s' no está permitido en un nombre de
|
|||
need_auth=Autorización
|
||||
migrate_options=Opciones de migración
|
||||
migrate_service=Servicio de Migración
|
||||
migrate_options_mirror_helper=Este repositorio será uno <span class="text blue">replicado</span>
|
||||
migrate_options_lfs=Migrar archivos LFS
|
||||
migrate_options_lfs_endpoint.label=Punto final de LFS
|
||||
migrate_options_lfs_endpoint.description=Migración intentará usar su mando Git para <a target="_blank" rel="noopener noreferrer" href="%s">determinar el servidor LFS</a>. También puede especificar un punto final personalizado si los datos LFS del repositorio se almacenan en otro lugar.
|
||||
|
@ -1531,7 +1530,6 @@ pulls.remove_prefix=Eliminar prefijo <strong>%s</strong>
|
|||
pulls.data_broken=Este pull request está rota debido a que falta información del fork.
|
||||
pulls.files_conflicted=Este pull request tiene cambios en conflicto con la rama de destino.
|
||||
pulls.is_checking=La comprobación de conflicto de fusión está en progreso. Inténtalo de nuevo en unos momentos.
|
||||
pulls.is_empty=Esta rama es igual a la rama objetivo.
|
||||
pulls.required_status_check_failed=Algunos controles requeridos no han tenido éxito.
|
||||
pulls.required_status_check_missing=Faltan algunos controles necesarios.
|
||||
pulls.required_status_check_administrator=Como administrador, aún puede fusionar este Pull Request.
|
||||
|
|
|
@ -863,7 +863,6 @@ form.name_pattern_not_allowed=الگوی %s در نام مخزن مجاز نیس
|
|||
need_auth=دسترسی
|
||||
migrate_options=تنظیمات مهاجرت
|
||||
migrate_service=سرویس مهاجرت
|
||||
migrate_options_mirror_helper=این مخزن یک <span class="text blue">آینه</span> خواهد بود
|
||||
migrate_options_lfs=مهاجرت فایلهای LFS
|
||||
migrate_options_lfs_endpoint.label=نشانهای پایانی LFS
|
||||
migrate_options_lfs_endpoint.description=Migration سعی خواهد کرد از کنترل از راه دور Git شما برای <a target="_blank" rel="noopener noreferrer" href="%s">تعیین سرور LFS</a> استفاده کند. همچنین اگر داده های LFS مخزن در جای دیگری ذخیره شده باشد، می توانید یک نقطه پایانی سفارشی را مشخص کنید.
|
||||
|
@ -1411,7 +1410,6 @@ pulls.remove_prefix=حذف پیشوند <strong>%s</strong>
|
|||
pulls.data_broken=این تقاضای واکشی به دلیل از دست رفتن اطلاعات انشعاب با شکست مواجه شد.
|
||||
pulls.files_conflicted=این تقاضای واکشی دارای تغییراتی است که با شاخه هدف تداخل دارد.
|
||||
pulls.is_checking=در حال پردازش تداخل در ادغام میباشد. لطفاً لحظاتی بعد امتحان کنید.
|
||||
pulls.is_empty=این شاخه با شاخه مقصد برابر است.
|
||||
pulls.required_status_check_failed=برخی بررسی های ضروری موفقیت آمیز نبود.
|
||||
pulls.required_status_check_missing=برخی بررسی های موردنیاز از قلم افتاده است.
|
||||
pulls.required_status_check_administrator=مثل یک مدیر، ممکن است شما این تقاضای واکشی را مسکوت بگذارید.
|
||||
|
|
|
@ -867,7 +867,6 @@ form.name_pattern_not_allowed="%s" n'est pas autorisé dans un nom de dépôt.
|
|||
need_auth=Autorisation
|
||||
migrate_options=Options de migration
|
||||
migrate_service=Service de migration
|
||||
migrate_options_mirror_helper=Ce dépôt sera un <span class="text blue">miroir</span>
|
||||
migrate_options_lfs=Migrer les fichiers LFS
|
||||
migrate_options_lfs_endpoint.label=Point d'accès LFS
|
||||
migrate_options_lfs_endpoint.description=La migration va tenter d'utiliser votre dépôt Git distant pour <a target="_blank" rel="noopener noreferrer" href="%s">déterminer le serveur LFS</a>. Vous pouvez également spécifier un point d'accès personnalisé si les données LFS du dépôt sont stockées ailleurs.
|
||||
|
@ -1405,7 +1404,6 @@ pulls.remove_prefix=Enlever le préfixe <strong>%s</strong>
|
|||
pulls.data_broken=Cette demande de fusion est impossible par manque d'informations de bifurcation.
|
||||
pulls.files_conflicted=Cette demande d'ajout contient des modifications en conflit avec la branche ciblée.
|
||||
pulls.is_checking=Vérification des conflits de fusion en cours. Réessayez dans quelques instants.
|
||||
pulls.is_empty=Cette branche est identique à la branche cible.
|
||||
pulls.required_status_check_failed=Certains contrôles requis n'ont pas réussi.
|
||||
pulls.required_status_check_missing=Certains contrôles requis sont manquants.
|
||||
pulls.required_status_check_administrator=En tant qu'administrateur, vous pouvez toujours fusionner cette requête de pull.
|
||||
|
|
|
@ -736,7 +736,6 @@ form.name_pattern_not_allowed=Il modello '%s' non è consentito come nome di un
|
|||
|
||||
migrate_options=Opzioni di migrazione
|
||||
migrate_service=Servizio migrazione
|
||||
migrate_options_mirror_helper=Questo repository sarà un <span class="text blue">mirror</span>
|
||||
migrate_items=Elementi di migrazione
|
||||
migrate_items_wiki=Wiki
|
||||
migrate_items_milestones=Milestone
|
||||
|
|
|
@ -861,7 +861,9 @@ default_branch=デフォルトブランチ
|
|||
default_branch_helper=デフォルトブランチはプルリクエストとコードコミットのベースブランチとなります。
|
||||
mirror_prune=Prune
|
||||
mirror_prune_desc=不要になった古いリモートトラッキング参照を削除
|
||||
mirror_interval=ミラー間隔 (有効な時間の単位は'h'、'm'、's')。 定期的な同期を無効にする場合は0。(最小間隔: %s)
|
||||
mirror_interval_invalid=ミラー間隔が不正です。
|
||||
mirror_sync_on_commit=コミットがプッシュされたときに同期
|
||||
mirror_address=クローンするURL
|
||||
mirror_address_desc=必要な資格情報は「認証」セクションに設定してください。
|
||||
mirror_address_url_invalid=入力したURLは無効です。 URLの構成要素はすべて正しくエスケープする必要があります。
|
||||
|
@ -930,7 +932,7 @@ form.name_pattern_not_allowed='%s' の形式はリポジトリ名に使用でき
|
|||
need_auth=認証
|
||||
migrate_options=移行オプション
|
||||
migrate_service=移行するサービス
|
||||
migrate_options_mirror_helper=このリポジトリを<span class="text blue">ミラー</span>にする
|
||||
migrate_options_mirror_helper=このリポジトリをミラーにする
|
||||
migrate_options_lfs=LFS ファイルのマイグレート
|
||||
migrate_options_lfs_endpoint.label=LFS エンドポイント
|
||||
migrate_options_lfs_endpoint.description=マイグレーションでは、リモート側のGitをもとに<a target="_blank" rel="noopener noreferrer" href="%s">LFSサーバーを決定</a>しようとします。 リポジトリのLFSデータがほかの場所に保存されている場合は、独自のエンドポイントを指定することができます。
|
||||
|
@ -1301,6 +1303,7 @@ issues.previous=前ページ
|
|||
issues.next=次ページ
|
||||
issues.open_title=オープン
|
||||
issues.closed_title=クローズ
|
||||
issues.draft_title=ドラフト
|
||||
issues.num_comments=%d件のコメント
|
||||
issues.commented_at=`が <a href="#%s">%s</a> にコメント`
|
||||
issues.delete_comment_confirm=このコメントを削除してよろしいですか?
|
||||
|
@ -1529,7 +1532,6 @@ pulls.remove_prefix=先頭の <strong>%s</strong> を除去
|
|||
pulls.data_broken=このプルリクエストは、フォークの情報が見つからないため壊れています。
|
||||
pulls.files_conflicted=このプルリクエストは、ターゲットブランチと競合する変更を含んでいます。
|
||||
pulls.is_checking=マージのコンフリクトを確認中です。 少し待ってからもう一度実行してください。
|
||||
pulls.is_empty=このブランチの内容はターゲットブランチと同じです。
|
||||
pulls.required_status_check_failed=いくつかの必要なステータスチェックが成功していません。
|
||||
pulls.required_status_check_missing=必要なステータスチェックが見つかりません。
|
||||
pulls.required_status_check_administrator=管理者であるため、このプルリクエストをマージすることは可能です。
|
||||
|
|
|
@ -930,7 +930,6 @@ form.name_pattern_not_allowed=Repozitorija nosaukums '%s' nav atļauts.
|
|||
need_auth=Autorizācija
|
||||
migrate_options=Migrācijas opcijas
|
||||
migrate_service=Migrācijas serviss
|
||||
migrate_options_mirror_helper=Šis repozitorijs būs <span class="text blue">spogulis</span>
|
||||
migrate_options_lfs=Migrēt LFS failus
|
||||
migrate_options_lfs_endpoint.label=LFS galapunkts
|
||||
migrate_options_lfs_endpoint.description=Migrācija mēģinās izmantot attālināto URL, lai <a target="_blank" rel="noopener noreferrer" href="%s">noteiktu LFS serveri</a>. Var norādīt arī citu galapunktu, ja repozitorija LFS dati ir izvietoti citā vietā.
|
||||
|
@ -1529,7 +1528,6 @@ pulls.remove_prefix=Noņemt <strong>%s</strong> prefiksu
|
|||
pulls.data_broken=Izmaiņu pieprasījums ir bojāts, jo dzēsta informācija no atdalītā repozitorija.
|
||||
pulls.files_conflicted=Šīs izmaiņu pieprasījuma izmaiņas konfliktē ar mērķa atzaru.
|
||||
pulls.is_checking=Notiek konfliktu pārbaude, mirkli uzgaidiet un atjaunojiet lapu.
|
||||
pulls.is_empty=Šis atzars ir vienāds ar mērķa atzaru.
|
||||
pulls.required_status_check_failed=Dažas no pārbaudēm nebija veiksmīgas.
|
||||
pulls.required_status_check_missing=Trūkst dažu obligāto pārbaužu.
|
||||
pulls.required_status_check_administrator=Kā administrators Jūs varat sapludināt šo izmaiņu pieprasījumu.
|
||||
|
|
|
@ -754,7 +754,6 @@ form.name_pattern_not_allowed=Het patroon '%s' is niet toegestaan in de naam van
|
|||
|
||||
migrate_options=Migratie opties
|
||||
migrate_service=Migratie Service
|
||||
migrate_options_mirror_helper=Deze repository zal een <span class="text blue">kopie</span> zijn
|
||||
migrate_items=Migratie Items
|
||||
migrate_items_wiki=Wiki
|
||||
migrate_items_milestones=Mijlpalen
|
||||
|
|
|
@ -870,7 +870,6 @@ form.name_pattern_not_allowed=Wzór "%s" nie jest dozwolony w nazwie repozytoriu
|
|||
need_auth=Autoryzacja
|
||||
migrate_options=Opcje migracji
|
||||
migrate_service=Usługa migracji
|
||||
migrate_options_mirror_helper=To repozytorium będzie <span class="text blue">kopią lustrzaną</span>
|
||||
migrate_options_lfs=Migruj pliki LFS
|
||||
migrate_options_lfs_endpoint.label=Punkt końcowy LFS
|
||||
migrate_options_lfs_endpoint.description=Migracja spróbuje użyć Git remote, aby <a target="_blank" rel="noopener noreferrer" href="%s">określić serwer LFS</a>. Możesz również określić niestandardowy punkt końcowy, jeśli dane repozytorium LFS są przechowywane gdzieś indziej.
|
||||
|
@ -1389,7 +1388,6 @@ pulls.remove_prefix=Usuń <strong>%s</strong> prefiks
|
|||
pulls.data_broken=Ten Pull Request jest uszkodzony ze względu na brakujące informacje o forku.
|
||||
pulls.files_conflicted=Ten Pull Request zawiera zmiany konfliktujące z docelową gałęzią.
|
||||
pulls.is_checking=Sprawdzanie konfliktów ze scalaniem w toku. Spróbuj ponownie za chwilę.
|
||||
pulls.is_empty=Ten branch jest równy z docelowym branch'em.
|
||||
pulls.required_status_check_failed=Niektóre kontrole stanów nie były pomyślne.
|
||||
pulls.required_status_check_missing=Brakuje pewnych wymaganych etapów.
|
||||
pulls.required_status_check_administrator=Jako administrator, możesz wciąż scalić ten Pull Request.
|
||||
|
|
|
@ -862,6 +862,7 @@ default_branch_helper=O branch padrão é o branch base para pull requests e com
|
|||
mirror_prune=Varrer
|
||||
mirror_prune_desc=Remover referências obsoletas de controle remoto
|
||||
mirror_interval_invalid=O intervalo do espelhamento não é válido.
|
||||
mirror_sync_on_commit=Sincronizar quando commits forem enviados
|
||||
mirror_address=Clonar de URL
|
||||
mirror_address_desc=Coloque todas as credenciais necessárias na seção de autorização.
|
||||
mirror_address_url_invalid=A url fornecida é inválida. Você deve escapar todos os componentes da url corretamente.
|
||||
|
@ -930,7 +931,7 @@ form.name_pattern_not_allowed=O padrão de '%s' não é permitido em um nome de
|
|||
need_auth=Autorização
|
||||
migrate_options=Opções de Migração
|
||||
migrate_service=Serviço de Migração
|
||||
migrate_options_mirror_helper=Este repositório será um <span class="text blue">espelho</span>
|
||||
migrate_options_mirror_helper=Este repositório será um espelho
|
||||
migrate_options_lfs=Migrar arquivos LFS
|
||||
migrate_options_lfs_endpoint.label=Destino LFS
|
||||
migrate_options_lfs_endpoint.description=A migração tentará usar seu controle remoto Git para <a target="_blank" rel="noopener noreferrer" href="%s">determinar o servidor LFS</a>. Você também pode especificar um destino personalizado se os dados do repositório LFS forem armazenados em outro lugar.
|
||||
|
@ -1301,6 +1302,7 @@ issues.previous=Anterior
|
|||
issues.next=Próximo
|
||||
issues.open_title=Aberto
|
||||
issues.closed_title=Fechado
|
||||
issues.draft_title=Rascunho
|
||||
issues.num_comments=%d comentários
|
||||
issues.commented_at=`comentou <a href="#%s">%s</a>`
|
||||
issues.delete_comment_confirm=Tem certeza que deseja excluir este comentário?
|
||||
|
@ -1491,6 +1493,7 @@ pulls.new=Novo pull request
|
|||
pulls.view=Ver Pull Request
|
||||
pulls.compare_changes=Novo pull request
|
||||
pulls.allow_edits_from_maintainers=Permitir edições de mantenedores
|
||||
pulls.allow_edits_from_maintainers_desc=Usuários com acesso de gravação para o branch base também podem fazer push para este branch
|
||||
pulls.allow_edits_from_maintainers_err=Falha na atualização
|
||||
pulls.compare_changes_desc=Selecione o branch de destino (push) e o branch de origem (pull) para o merge.
|
||||
pulls.has_viewed_file=Visto
|
||||
|
@ -1528,7 +1531,6 @@ pulls.remove_prefix=Remover o prefixo <strong>%s</strong>
|
|||
pulls.data_broken=Este pull request está quebrado devido a falta de informação do fork.
|
||||
pulls.files_conflicted=Este pull request tem alterações conflitantes com o branch de destino.
|
||||
pulls.is_checking=Verificação de conflitos do merge está em andamento. Tente novamente em alguns momentos.
|
||||
pulls.is_empty=Este branch é igual ao branch de destino.
|
||||
pulls.required_status_check_failed=Algumas verificações necessárias não foram bem sucedidas.
|
||||
pulls.required_status_check_missing=Estão faltando algumas verificações necessárias.
|
||||
pulls.required_status_check_administrator=Como administrador, você ainda pode aplicar o merge deste pull request.
|
||||
|
@ -1596,9 +1598,13 @@ pulls.merge_instruction_step1_desc=No repositório do seu projeto, crie um novo
|
|||
pulls.merge_instruction_step2_desc=Faça merge das alterações e atualize no Gitea.
|
||||
|
||||
pulls.auto_merge_button_when_succeed=(Quando a verificação for bem-sucedida)
|
||||
pulls.auto_merge_newly_scheduled=O merge do pull request foi agendado para quando todas as verificações forem bem-sucedidas.
|
||||
|
||||
pulls.auto_merge_cancel_schedule=Cancelar merge automático
|
||||
|
||||
|
||||
|
||||
pulls.delete.title=Excluir este pull request?
|
||||
pulls.delete.text=Você realmente deseja excluir este pull request? (Isto irá remover permanentemente todo o conteúdo. Considere fechá-la em vez disso, se você pretende mantê-la arquivado)
|
||||
|
||||
milestones.new=Novo marco
|
||||
milestones.closed=Fechado %s
|
||||
|
@ -2269,6 +2275,8 @@ topic.done=Feito
|
|||
topic.count_prompt=Você não pode selecionar mais de 25 tópicos
|
||||
topic.format_prompt=Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
|
||||
|
||||
find_file.go_to_file=Ir para arquivo
|
||||
find_file.no_matching=Nenhum arquivo correspondente encontrado
|
||||
|
||||
error.csv.too_large=Não é possível renderizar este arquivo porque ele é muito grande.
|
||||
error.csv.unexpected=Não é possível renderizar este arquivo porque ele contém um caractere inesperado na linha %d e coluna %d.
|
||||
|
|
|
@ -932,7 +932,7 @@ form.name_pattern_not_allowed=O padrão '%s' não é permitido no nome de um rep
|
|||
need_auth=Autorização
|
||||
migrate_options=Opções de migração
|
||||
migrate_service=Serviço de migração
|
||||
migrate_options_mirror_helper=Este repositório irá ser uma <span class="text blue">réplica</span>
|
||||
migrate_options_mirror_helper=Este repositório irá ser uma réplica
|
||||
migrate_options_lfs=Migrar ficheiros LFS
|
||||
migrate_options_lfs_endpoint.label=Destino LFS
|
||||
migrate_options_lfs_endpoint.description=A migração irá tentar usar o seu controlo remoto do Git para <a target="_blank" rel="noopener noreferrer" href="%s">determinar o servidor LFS</a>. Também pode especificar um destino personalizado se os dados do repositório LFS forem armazenados noutro lugar.
|
||||
|
@ -1532,7 +1532,8 @@ pulls.remove_prefix=Remover o prefixo <strong>%s</strong>
|
|||
pulls.data_broken=Este pedido de integração está danificado devido à falta de informação da derivação.
|
||||
pulls.files_conflicted=Este pedido de integração contém modificações que entram em conflito com o ramo de destino.
|
||||
pulls.is_checking=Está em andamento uma verificação de conflitos na integração. Tente novamente daqui a alguns momentos.
|
||||
pulls.is_empty=Este ramo é igual ao ramo de destino.
|
||||
pulls.is_ancestor=Este ramo já está incluído no ramo de destino. Não há nada a integrar.
|
||||
pulls.is_empty=As modificações feitas neste ramo já existem no ramo de destino. Este cometimento ficará vazio.
|
||||
pulls.required_status_check_failed=Algumas das verificações obrigatórias não foram bem sucedidas.
|
||||
pulls.required_status_check_missing=Estão faltando algumas verificações necessárias.
|
||||
pulls.required_status_check_administrator=Uma vez que é administrador, ainda pode realizar a integração deste pedido.
|
||||
|
@ -2539,6 +2540,8 @@ users.delete_account=Eliminar conta de utilizador
|
|||
users.cannot_delete_self=Não se pode eliminar a si próprio
|
||||
users.still_own_repo=Este utilizador ainda possui um ou mais repositórios. Elimine ou transfira esses repositórios primeiro.
|
||||
users.still_has_org=Este utilizador é membro de uma organização. Remova, primeiro, o utilizador de todas as organizações.
|
||||
users.purge=Eliminar utilizador
|
||||
users.purge_help=Eliminar o utilizador à força, juntamente com todos os seus repositórios, organizações e pacotes. Também serão eliminados todos os seus comentários.
|
||||
users.still_own_packages=Este utilizador ainda possui um ou mais pacotes. Elimine esses pacotes primeiro.
|
||||
users.deletion_success=A conta de utilizador foi eliminada.
|
||||
users.reset_2fa=Reinicializar a autenticação em dois passos
|
||||
|
|
|
@ -918,7 +918,6 @@ form.name_pattern_not_allowed=Шаблон имени репозитория '%s
|
|||
need_auth=Авторизация
|
||||
migrate_options=Параметры миграции
|
||||
migrate_service=Сервис миграции
|
||||
migrate_options_mirror_helper=Этот репозиторий будет <span class="text blue">зеркалом</span>
|
||||
migrate_options_lfs=Перенос LFS файлов
|
||||
migrate_options_lfs_endpoint.label=LFS Endpoint
|
||||
migrate_options_lfs_endpoint.description=Миграция попытается использовать ваш Git удаленно, чтобы <a target="_blank" rel="noopener noreferrer" href="%s">определить сервер LFS</a>. Вы также можете указать пользовательскую конечную точку, если данные хранятся в другом месте.
|
||||
|
@ -1481,7 +1480,6 @@ pulls.remove_prefix=Удалить <strong>%s</strong> префикс
|
|||
pulls.data_broken=Содержимое этого запроса было нарушено вследствие удаления информации форка.
|
||||
pulls.files_conflicted=Этот запрос на слияние имеет изменения конфликтующие с целевой веткой.
|
||||
pulls.is_checking=Продолжается проверка конфликтов, пожалуйста обновите страницу несколько позже.
|
||||
pulls.is_empty=Ветвь идентична с целевой.
|
||||
pulls.required_status_check_failed=Некоторые необходимые проверки не были пройдены.
|
||||
pulls.required_status_check_missing=Отсутствуют некоторые обязательные проверки.
|
||||
pulls.required_status_check_administrator=Как администратор, вы все равно можете принять этот запрос на слияние.
|
||||
|
|
|
@ -1355,7 +1355,6 @@ pulls.remove_prefix=<strong>%s</strong> උපසර්ගය ඉවත් ක
|
|||
pulls.data_broken=අතුරුදහන් වූ දෙබලක තොරතුරු හේතුවෙන් මෙම අදින්න ඉල්ලීම කැඩී ඇත.
|
||||
pulls.files_conflicted=මෙම අදින්න ඉල්ලීම ඉලක්කගත ශාඛාව සමග එකිනෙකට වෙනස් වෙනස්කම් ඇත.
|
||||
pulls.is_checking=ගැටුම් පරීක්ෂා කිරීම ඒකාබද්ධ කිරීම ක්රියාත්මක වෙමින් පවතී. සුළු මොහොතකින් නැවත උත්සාහ කරන්න.
|
||||
pulls.is_empty=මෙම ශාඛාව ඉලක්කගත ශාඛාව සමග සමාන වේ.
|
||||
pulls.required_status_check_failed=සමහර අවශ්ය චෙක්පත් සාර්ථක නොවීය.
|
||||
pulls.required_status_check_missing=සමහර අවශ්ය චෙක්පත් අස්ථානගත වී ඇත.
|
||||
pulls.required_status_check_administrator=පරිපාලකයෙකු ලෙස, ඔබ තවමත් මෙම අදින්න ඉල්ලීම ඒකාබද්ධ කළ හැකිය.
|
||||
|
|
|
@ -700,7 +700,6 @@ form.name_pattern_not_allowed=Mönstret '%s' är otillåtet i ett utvecklingskat
|
|||
|
||||
migrate_options=Migrationsalternativ
|
||||
migrate_service=Migreringstjänst
|
||||
migrate_options_mirror_helper=Denna utvecklingskatalog kommer att vara en <span class="text blue">spegel</span>
|
||||
migrate_items=Migrationsobjekt
|
||||
migrate_items_wiki=Wiki
|
||||
migrate_items_milestones=Milstenar
|
||||
|
|
|
@ -846,7 +846,6 @@ form.name_pattern_not_allowed='%s' deseni, depo adı için geçerli değildir.
|
|||
need_auth=Yetkilendirme
|
||||
migrate_options=Göç Seçenekleri
|
||||
migrate_service=Göç Hizmeti
|
||||
migrate_options_mirror_helper=Bu depo bir <span class="text blue">yansı</span> olacaktır
|
||||
migrate_options_lfs=LFS dosyalarını taşı
|
||||
migrate_options_lfs_endpoint.label=LFS Uç Noktası
|
||||
migrate_options_lfs_endpoint.description=Taşıma, <a target="_blank" rel="noopener noreferrer" href="%s"> LFS sunucusunu belirlemek</a> için Git uzak sunucusunu kullanmaya çalışacak. Eğer LFS veri deposu başka yerdeyse özel bir uç nokta da belirtebilirsiniz.
|
||||
|
@ -1370,7 +1369,6 @@ pulls.remove_prefix=<strong>%s</strong> ön ekini kaldır
|
|||
pulls.data_broken=Bu değişiklik isteği, çatallama bilgilerinin eksik olması nedeniyle bozuldu.
|
||||
pulls.files_conflicted=Bu değişiklik isteğinde, hedef dalla çakışan değişiklikler var.
|
||||
pulls.is_checking=Birleştirme çakışması denetimi devam ediyor. Birkaç dakika sonra tekrar deneyin.
|
||||
pulls.is_empty=Bu dal, hedef dalla eşittir.
|
||||
pulls.required_status_check_failed=Bazı gerekli denetimler başarılı olmadı.
|
||||
pulls.required_status_check_missing=Gerekli bazı kontroller eksik.
|
||||
pulls.required_status_check_administrator=Yönetici olarak, bu değişiklik isteğini yine de birleştirebilirsiniz.
|
||||
|
|
|
@ -870,7 +870,6 @@ form.name_pattern_not_allowed=Шаблон '%s' не дозволено в на
|
|||
need_auth=Авторизація
|
||||
migrate_options=Параметри міграції
|
||||
migrate_service=Сервіс міграції
|
||||
migrate_options_mirror_helper=Цей репозиторій буде <span class="text blue">дзеркалом</span>
|
||||
migrate_options_lfs=Перенесення LFS файлів
|
||||
migrate_options_lfs_endpoint.label=Кінцева точка LFS
|
||||
migrate_options_lfs_endpoint.description=Міграція буде намагатися використовувати ваш Git віддалено, щоб <a target="_blank" rel="noopener noreferrer" href="%s">визначати LFS сервер</a>. Ви також можете вказати свою кінцеву точку, якщо дані репозиторію LFS зберігаються в іншому місці.
|
||||
|
@ -1419,7 +1418,6 @@ pulls.remove_prefix=Видалити префікс <strong>%s</strong>
|
|||
pulls.data_broken=Зміст цього запиту було порушено внаслідок видалення інформації Форком. Цей запит тягнеться через відсутність інформації про вилучення.
|
||||
pulls.files_conflicted=Цей запит має зміни, що конфліктують з цільовою гілкою.
|
||||
pulls.is_checking=Триває перевірка конфліктів, будь ласка обновіть сторінку дещо пізніше.
|
||||
pulls.is_empty=Ця гілка ідентична з цільовою гілкою.
|
||||
pulls.required_status_check_failed=Деякі необхідні перевірки виконані з помилками.
|
||||
pulls.required_status_check_missing=Декілька з необхідних перевірок відсутні.
|
||||
pulls.required_status_check_administrator=Як адміністратор ви все одно можете об'єднати цей запит на злиття.
|
||||
|
|
|
@ -932,7 +932,6 @@ form.name_pattern_not_allowed=仓库名称中不允许使用模式 "%s"。
|
|||
need_auth=授权
|
||||
migrate_options=迁移选项
|
||||
migrate_service=迁移服务
|
||||
migrate_options_mirror_helper=该仓库将是一个 <span class="text blue">镜像</span>
|
||||
migrate_options_lfs=迁移 LFS 文件
|
||||
migrate_options_lfs_endpoint.label=LFS 网址
|
||||
migrate_options_lfs_endpoint.description=迁移将尝试使用你的 Git remote 来 <a target="_blank" rel="noopener noreferrer" href="%s">确定 LFS 服务器</a>。如果仓库 LFS 数据存储在其他位置,你还可以指定自定义网址。
|
||||
|
@ -1532,7 +1531,6 @@ pulls.remove_prefix=删除 <strong>%s</strong> 前缀
|
|||
pulls.data_broken=此合并请求因为派生仓库信息缺失而中断。
|
||||
pulls.files_conflicted=此合并请求有变更与目标分支冲突。
|
||||
pulls.is_checking=正在进行合并冲突检测,请稍后再试。
|
||||
pulls.is_empty=此分支与目标分支相同。
|
||||
pulls.required_status_check_failed=一些必要的检查没有成功
|
||||
pulls.required_status_check_missing=缺少一些必要的检查。
|
||||
pulls.required_status_check_administrator=作为管理员,您仍可合并此合并请求
|
||||
|
|
|
@ -861,7 +861,9 @@ default_branch=預設分支
|
|||
default_branch_helper=預設分支是合併請求和提交程式碼的基礎分支。
|
||||
mirror_prune=裁減
|
||||
mirror_prune_desc=刪除過時的遠端追蹤參考
|
||||
mirror_interval=鏡像間隔 (有效時間單位為 'h'、'm'、's'),設為 0 以停用定期同步。(最小間隔: %s)
|
||||
mirror_interval_invalid=鏡像週期無效
|
||||
mirror_sync_on_commit=推送提交後進行同步
|
||||
mirror_address=從 URL Clone
|
||||
mirror_address_desc=在授權資訊中填入必要的資料。
|
||||
mirror_address_url_invalid=提供的網址無效。請檢查您輸入的網址是否正確。
|
||||
|
@ -930,7 +932,6 @@ form.name_pattern_not_allowed=儲存庫名稱不可包含字元「%s」。
|
|||
need_auth=授權
|
||||
migrate_options=遷移選項
|
||||
migrate_service=遷移服務
|
||||
migrate_options_mirror_helper=將此儲存庫設定為<span class="text blue">鏡像儲存庫</span>
|
||||
migrate_options_lfs=遷移 LFS 檔案
|
||||
migrate_options_lfs_endpoint.label=LFS 端點
|
||||
migrate_options_lfs_endpoint.description=遷移將會嘗試使用您的 Git Remote 來<a target="_blank" rel="noopener noreferrer" href="%s">確認 LFS 伺服器</a>。如果存儲庫的 LFS 資料放在其他地方,您也可以指定自訂的端點。
|
||||
|
@ -1301,6 +1302,7 @@ issues.previous=上一頁
|
|||
issues.next=下一頁
|
||||
issues.open_title=開放中
|
||||
issues.closed_title=已關閉
|
||||
issues.draft_title=草稿
|
||||
issues.num_comments=%d 則留言
|
||||
issues.commented_at=`已留言 <a href="#%s"> %s</a>`
|
||||
issues.delete_comment_confirm=您確定要刪除這則留言嗎?
|
||||
|
@ -1529,7 +1531,6 @@ pulls.remove_prefix=移除 <strong>%s</strong> 前綴
|
|||
pulls.data_broken=此合併請求已損毀,因為遺失 Fork 資訊。
|
||||
pulls.files_conflicted=此合併請求有變更和目標分支衝突。
|
||||
pulls.is_checking=正在進行合併衝突檢查,請稍後再試。
|
||||
pulls.is_empty=此分支與目標分支相同。
|
||||
pulls.required_status_check_failed=未通過某些必要的檢查。
|
||||
pulls.required_status_check_missing=遺失某些必要的檢查。
|
||||
pulls.required_status_check_administrator=身為系統管理員,您依然可以進行合併。
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
"@happy-dom/jest-environment": "4.0.1",
|
||||
"@stoplight/spectral-cli": "6.4.1",
|
||||
"eslint": "8.15.0",
|
||||
"eslint-plugin-html": "6.2.0",
|
||||
"eslint-plugin-import": "2.26.0",
|
||||
"eslint-plugin-jquery": "1.5.1",
|
||||
"eslint-plugin-unicorn": "42.0.0",
|
||||
|
@ -61,7 +60,7 @@
|
|||
"updates": "13.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
"node": ">= 14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ampproject/remapping": {
|
||||
|
@ -4839,18 +4838,6 @@
|
|||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/entities": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
|
||||
"integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/envinfo": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
|
||||
|
@ -5231,15 +5218,6 @@
|
|||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-html": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.2.0.tgz",
|
||||
"integrity": "sha512-vi3NW0E8AJombTvt8beMwkL1R/fdRWl4QSNRNMhVQKWm36/X0KF0unGNAY4mqUF06mnwVWZcIcerrCnfn9025g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"htmlparser2": "^7.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-import": {
|
||||
"version": "2.26.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz",
|
||||
|
@ -6262,25 +6240,6 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/htmlparser2": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz",
|
||||
"integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
"https://github.com/fb55/htmlparser2?sponsor=1",
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^4.2.2",
|
||||
"domutils": "^2.8.0",
|
||||
"entities": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/http-basic": {
|
||||
"version": "8.1.3",
|
||||
"resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz",
|
||||
|
@ -16221,12 +16180,6 @@
|
|||
"tapable": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
|
||||
"integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
|
||||
"dev": true
|
||||
},
|
||||
"envinfo": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
|
||||
|
@ -16519,15 +16472,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"eslint-plugin-html": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.2.0.tgz",
|
||||
"integrity": "sha512-vi3NW0E8AJombTvt8beMwkL1R/fdRWl4QSNRNMhVQKWm36/X0KF0unGNAY4mqUF06mnwVWZcIcerrCnfn9025g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"htmlparser2": "^7.1.2"
|
||||
}
|
||||
},
|
||||
"eslint-plugin-import": {
|
||||
"version": "2.26.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz",
|
||||
|
@ -17317,18 +17261,6 @@
|
|||
"integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==",
|
||||
"dev": true
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz",
|
||||
"integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^4.2.2",
|
||||
"domutils": "^2.8.0",
|
||||
"entities": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"http-basic": {
|
||||
"version": "8.1.3",
|
||||
"resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz",
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"private": true,
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
"node": ">= 14.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@claviska/jquery-minicolors": "2.3.6",
|
||||
|
@ -47,7 +47,6 @@
|
|||
"@happy-dom/jest-environment": "4.0.1",
|
||||
"@stoplight/spectral-cli": "6.4.1",
|
||||
"eslint": "8.15.0",
|
||||
"eslint-plugin-html": "6.2.0",
|
||||
"eslint-plugin-import": "2.26.0",
|
||||
"eslint-plugin-jquery": "1.5.1",
|
||||
"eslint-plugin-unicorn": "42.0.0",
|
||||
|
|
|
@ -316,7 +316,7 @@ func DeleteUser(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
if err := user_service.DeleteUser(ctx.ContextUser); err != nil {
|
||||
if err := user_service.DeleteUser(ctx, ctx.ContextUser, ctx.FormBool("purge")); err != nil {
|
||||
if models.IsErrUserOwnRepos(err) ||
|
||||
models.IsErrUserHasOrgs(err) ||
|
||||
models.IsErrUserOwnPackages(err) {
|
||||
|
|
|
@ -224,6 +224,7 @@ func CreateRelease(ctx *context.APIContext) {
|
|||
rel.IsTag = false
|
||||
rel.Repo = ctx.Repo.Repository
|
||||
rel.Publisher = ctx.Doer
|
||||
rel.Target = form.Target
|
||||
|
||||
if err = release_service.UpdateRelease(ctx.Doer, ctx.Repo.GitRepo, rel, nil, nil, nil); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateRelease", err)
|
||||
|
|
|
@ -240,6 +240,7 @@ func DeleteTopic(ctx *context.APIContext) {
|
|||
|
||||
if topic == nil {
|
||||
ctx.NotFound()
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
|
|
|
@ -141,7 +141,6 @@ func GlobalInitInstalled(ctx context.Context) {
|
|||
mustInit(repo_service.Init)
|
||||
|
||||
// Booting long running goroutines.
|
||||
cron.NewContext(ctx)
|
||||
issue_indexer.InitIssueIndexer(false)
|
||||
code_indexer.Init()
|
||||
mustInit(stats_indexer.Init)
|
||||
|
@ -160,6 +159,9 @@ func GlobalInitInstalled(ctx context.Context) {
|
|||
|
||||
auth.Init()
|
||||
svg.Init()
|
||||
|
||||
// Finally start up the cron
|
||||
cron.NewContext(ctx)
|
||||
}
|
||||
|
||||
// NormalRoutes represents non install routes
|
||||
|
|
|
@ -419,29 +419,21 @@ func DeleteUser(ctx *context.Context) {
|
|||
// admin should not delete themself
|
||||
if u.ID == ctx.Doer.ID {
|
||||
ctx.Flash.Error(ctx.Tr("admin.users.cannot_delete_self"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")),
|
||||
})
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")))
|
||||
return
|
||||
}
|
||||
|
||||
if err = user_service.DeleteUser(u); err != nil {
|
||||
if err = user_service.DeleteUser(ctx, u, ctx.FormBool("purge")); err != nil {
|
||||
switch {
|
||||
case models.IsErrUserOwnRepos(err):
|
||||
ctx.Flash.Error(ctx.Tr("admin.users.still_own_repo"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")),
|
||||
})
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")))
|
||||
case models.IsErrUserHasOrgs(err):
|
||||
ctx.Flash.Error(ctx.Tr("admin.users.still_has_org"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")),
|
||||
})
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")))
|
||||
case models.IsErrUserOwnPackages(err):
|
||||
ctx.Flash.Error(ctx.Tr("admin.users.still_own_packages"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": setting.AppSubURL + "/admin/users/" + ctx.Params(":userid"),
|
||||
})
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/users/" + ctx.Params(":userid"))
|
||||
default:
|
||||
ctx.ServerError("DeleteUser", err)
|
||||
}
|
||||
|
@ -450,9 +442,7 @@ func DeleteUser(ctx *context.Context) {
|
|||
log.Trace("Account deleted by admin (%s): %s", ctx.Doer.Name, u.Name)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("admin.users.deletion_success"))
|
||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||
"redirect": setting.AppSubURL + "/admin/users",
|
||||
})
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/users")
|
||||
}
|
||||
|
||||
// AvatarPost response for change user's avatar request
|
||||
|
|
|
@ -39,11 +39,6 @@ func Home(ctx *context.Context) {
|
|||
|
||||
org := ctx.Org.Organization
|
||||
|
||||
if !organization.HasOrgOrUserVisible(ctx, org.AsUser(), ctx.Doer) {
|
||||
ctx.NotFound("HasOrgOrUserVisible", nil)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["PageIsUserProfile"] = true
|
||||
ctx.Data["Title"] = org.DisplayName()
|
||||
if len(org.Description) != 0 {
|
||||
|
|
|
@ -854,15 +854,15 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri
|
|||
}
|
||||
ctx.Data["LatestCommitVerification"] = verification
|
||||
ctx.Data["LatestCommitUser"] = user_model.ValidateCommitWithEmail(latestCommit)
|
||||
}
|
||||
|
||||
statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, ctx.Repo.Commit.ID.String(), db.ListOptions{})
|
||||
if err != nil {
|
||||
log.Error("GetLatestCommitStatus: %v", err)
|
||||
}
|
||||
statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, latestCommit.ID.String(), db.ListOptions{})
|
||||
if err != nil {
|
||||
log.Error("GetLatestCommitStatus: %v", err)
|
||||
}
|
||||
|
||||
ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(statuses)
|
||||
ctx.Data["LatestCommitStatuses"] = statuses
|
||||
ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(statuses)
|
||||
ctx.Data["LatestCommitStatuses"] = statuses
|
||||
}
|
||||
|
||||
branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
|
||||
treeLink := branchLink
|
||||
|
|
|
@ -248,7 +248,7 @@ func DeleteAccount(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
if err := user.DeleteUser(ctx.Doer); err != nil {
|
||||
if err := user.DeleteUser(ctx, ctx.Doer, false); err != nil {
|
||||
switch {
|
||||
case models.IsErrUserOwnRepos(err):
|
||||
ctx.Flash.Error(ctx.Tr("form.still_own_repo"))
|
||||
|
|
|
@ -610,6 +610,12 @@ func RegisterRoutes(m *web.Route) {
|
|||
}
|
||||
|
||||
// ***** START: Organization *****
|
||||
m.Group("/org", func() {
|
||||
m.Group("/{org}", func() {
|
||||
m.Get("/members", org.Members)
|
||||
}, context.OrgAssignment())
|
||||
}, ignSignIn)
|
||||
|
||||
m.Group("/org", func() {
|
||||
m.Group("", func() {
|
||||
m.Get("/create", org.Create)
|
||||
|
@ -625,7 +631,6 @@ func RegisterRoutes(m *web.Route) {
|
|||
m.Get("/pulls/{team}", user.Pulls)
|
||||
m.Get("/milestones", reqMilestonesDashboardPageEnabled, user.Milestones)
|
||||
m.Get("/milestones/{team}", reqMilestonesDashboardPageEnabled, user.Milestones)
|
||||
m.Get("/members", org.Members)
|
||||
m.Post("/members/action/{action}", org.MembersAction)
|
||||
m.Get("/teams", org.Teams)
|
||||
}, context.OrgAssignment(true, false, true))
|
||||
|
|
|
@ -59,7 +59,7 @@ func cleanupExpiredUploadedBlobs(ctx context.Context, olderThan time.Duration) e
|
|||
ExactMatch: true,
|
||||
Value: container_model.UploadVersion,
|
||||
},
|
||||
IsInternal: true,
|
||||
IsInternal: util.OptionalBoolTrue,
|
||||
HasFiles: util.OptionalBoolFalse,
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
packages_model "code.gitea.io/gitea/models/packages"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
@ -451,3 +452,30 @@ func GetPackageFileStream(ctx context.Context, pf *packages_model.PackageFile) (
|
|||
}
|
||||
return s, pf, err
|
||||
}
|
||||
|
||||
// RemoveAllPackages for User
|
||||
func RemoveAllPackages(ctx context.Context, userID int64) (int, error) {
|
||||
count := 0
|
||||
for {
|
||||
pkgVersions, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
|
||||
Paginator: &db.ListOptions{
|
||||
PageSize: repo_model.RepositoryListDefaultPageSize,
|
||||
Page: 1,
|
||||
},
|
||||
OwnerID: userID,
|
||||
})
|
||||
if err != nil {
|
||||
return count, fmt.Errorf("GetOwnedPackages[%d]: %w", userID, err)
|
||||
}
|
||||
if len(pkgVersions) == 0 {
|
||||
break
|
||||
}
|
||||
for _, pv := range pkgVersions {
|
||||
if err := DeletePackageVersionAndReferences(ctx, pv); err != nil {
|
||||
return count, fmt.Errorf("unable to delete package %d:%s[%d]. Error: %w", pv.PackageID, pv.Version, pv.ID, err)
|
||||
}
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *acce
|
|||
return ErrIsWorkInProgress
|
||||
}
|
||||
|
||||
if !pr.CanAutoMerge() {
|
||||
if !pr.CanAutoMerge() && !pr.IsEmpty() {
|
||||
return ErrNotMergableState
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,14 @@ func TestPatch(pr *issues_model.PullRequest) error {
|
|||
}
|
||||
}
|
||||
pr.MergeBase = strings.TrimSpace(pr.MergeBase)
|
||||
if pr.HeadCommitID, err = gitRepo.GetRefCommitID(git.BranchPrefix + "tracking"); err != nil {
|
||||
return fmt.Errorf("GetBranchCommitID: can't find commit ID for head: %w", err)
|
||||
}
|
||||
|
||||
if pr.HeadCommitID == pr.MergeBase {
|
||||
pr.Status = issues_model.PullRequestStatusAncestor
|
||||
return nil
|
||||
}
|
||||
|
||||
// 2. Check for conflicts
|
||||
if conflicts, err := checkConflicts(ctx, pr, gitRepo, tmpBasePath); err != nil || conflicts || pr.Status == issues_model.PullRequestStatusEmpty {
|
||||
|
|
|
@ -143,8 +143,6 @@ func adoptRepository(ctx context.Context, repoPath string, u *user_model.User, r
|
|||
return fmt.Errorf("setDefaultBranch: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
repo.DefaultBranch = strings.TrimPrefix(repo.DefaultBranch, git.BranchPrefix)
|
||||
}
|
||||
branches, _, _ := gitRepo.GetBranchNames(0, 0)
|
||||
found := false
|
||||
|
|
|
@ -21,19 +21,116 @@ import (
|
|||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/avatar"
|
||||
"code.gitea.io/gitea/modules/eventsource"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/services/packages"
|
||||
)
|
||||
|
||||
// DeleteUser completely and permanently deletes everything of a user,
|
||||
// but issues/comments/pulls will be kept and shown as someone has been deleted,
|
||||
// unless the user is younger than USER_DELETE_WITH_COMMENTS_MAX_DAYS.
|
||||
func DeleteUser(u *user_model.User) error {
|
||||
func DeleteUser(ctx context.Context, u *user_model.User, purge bool) error {
|
||||
if u.IsOrganization() {
|
||||
return fmt.Errorf("%s is an organization not a user", u.Name)
|
||||
}
|
||||
|
||||
if purge {
|
||||
// Disable the user first
|
||||
// NOTE: This is deliberately not within a transaction as it must disable the user immediately to prevent any further action by the user to be purged.
|
||||
if err := user_model.UpdateUserCols(ctx, &user_model.User{
|
||||
ID: u.ID,
|
||||
IsActive: false,
|
||||
IsRestricted: true,
|
||||
IsAdmin: false,
|
||||
ProhibitLogin: true,
|
||||
Passwd: "",
|
||||
Salt: "",
|
||||
PasswdHashAlgo: "",
|
||||
MaxRepoCreation: 0,
|
||||
}, "is_active", "is_restricted", "is_admin", "prohibit_login", "max_repo_creation", "passwd", "salt", "passwd_hash_algo"); err != nil {
|
||||
return fmt.Errorf("unable to disable user: %s[%d] prior to purge. UpdateUserCols: %w", u.Name, u.ID, err)
|
||||
}
|
||||
|
||||
// Force any logged in sessions to log out
|
||||
// FIXME: We also need to tell the session manager to log them out too.
|
||||
eventsource.GetManager().SendMessage(u.ID, &eventsource.Event{
|
||||
Name: "logout",
|
||||
})
|
||||
|
||||
// Delete all repos belonging to this user
|
||||
// Now this is not within a transaction because there are internal transactions within the DeleteRepository
|
||||
// BUT: the db will still be consistent even if a number of repos have already been deleted.
|
||||
// And in fact we want to capture any repositories that are being created in other transactions in the meantime
|
||||
//
|
||||
// An alternative option here would be write a DeleteAllRepositoriesForUserID function which would delete all of the repos
|
||||
// but such a function would likely get out of date
|
||||
for {
|
||||
repos, _, err := repo_model.GetUserRepositories(&repo_model.SearchRepoOptions{
|
||||
ListOptions: db.ListOptions{
|
||||
PageSize: repo_model.RepositoryListDefaultPageSize,
|
||||
Page: 1,
|
||||
},
|
||||
Private: true,
|
||||
OwnerID: u.ID,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("SearchRepositoryByName: %v", err)
|
||||
}
|
||||
if len(repos) == 0 {
|
||||
break
|
||||
}
|
||||
for _, repo := range repos {
|
||||
if err := models.DeleteRepository(u, u.ID, repo.ID); err != nil {
|
||||
return fmt.Errorf("unable to delete repository %s for %s[%d]. Error: %v", repo.Name, u.Name, u.ID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove from Organizations and delete last owner organizations
|
||||
// Now this is not within a transaction because there are internal transactions within the DeleteOrganization
|
||||
// BUT: the db will still be consistent even if a number of organizations memberships and organizations have already been deleted
|
||||
// And in fact we want to capture any organization additions that are being created in other transactions in the meantime
|
||||
//
|
||||
// An alternative option here would be write a function which would delete all organizations but it seems
|
||||
// but such a function would likely get out of date
|
||||
for {
|
||||
orgs, err := organization.FindOrgs(organization.FindOrgOptions{
|
||||
ListOptions: db.ListOptions{
|
||||
PageSize: repo_model.RepositoryListDefaultPageSize,
|
||||
Page: 1,
|
||||
},
|
||||
UserID: u.ID,
|
||||
IncludePrivate: true,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to find org list for %s[%d]. Error: %v", u.Name, u.ID, err)
|
||||
}
|
||||
if len(orgs) == 0 {
|
||||
break
|
||||
}
|
||||
for _, org := range orgs {
|
||||
if err := models.RemoveOrgUser(org.ID, u.ID); err != nil {
|
||||
if organization.IsErrLastOrgOwner(err) {
|
||||
err = organization.DeleteOrganization(ctx, org)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to remove user %s[%d] from org %s[%d]. Error: %v", u.Name, u.ID, org.Name, org.ID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete Packages
|
||||
if setting.Packages.Enabled {
|
||||
if _, err := packages.RemoveAllPackages(ctx, u.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx, committer, err := db.TxContext()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -41,7 +138,8 @@ func DeleteUser(u *user_model.User) error {
|
|||
defer committer.Close()
|
||||
|
||||
// Note: A user owns any repository or belongs to any organization
|
||||
// cannot perform delete operation.
|
||||
// cannot perform delete operation. This causes a race with the purge above
|
||||
// however consistency requires that we ensure that this is the case
|
||||
|
||||
// Check ownership of repository.
|
||||
count, err := repo_model.CountRepositories(ctx, repo_model.CountRepositoryOptions{OwnerID: u.ID})
|
||||
|
@ -66,7 +164,7 @@ func DeleteUser(u *user_model.User) error {
|
|||
return models.ErrUserOwnPackages{UID: u.ID}
|
||||
}
|
||||
|
||||
if err := models.DeleteUser(ctx, u); err != nil {
|
||||
if err := models.DeleteUser(ctx, u, purge); err != nil {
|
||||
return fmt.Errorf("DeleteUser: %v", err)
|
||||
}
|
||||
|
||||
|
@ -117,7 +215,7 @@ func DeleteInactiveUsers(ctx context.Context, olderThan time.Duration) error {
|
|||
return db.ErrCancelledf("Before delete inactive user %s", u.Name)
|
||||
default:
|
||||
}
|
||||
if err := DeleteUser(u); err != nil {
|
||||
if err := DeleteUser(ctx, u, false); err != nil {
|
||||
// Ignore users that were set inactive by admin.
|
||||
if models.IsErrUserOwnRepos(err) || models.IsErrUserHasOrgs(err) || models.IsErrUserOwnPackages(err) {
|
||||
continue
|
||||
|
|
|
@ -33,7 +33,7 @@ func TestDeleteUser(t *testing.T) {
|
|||
ownedRepos := make([]*repo_model.Repository, 0, 10)
|
||||
assert.NoError(t, db.GetEngine(db.DefaultContext).Find(&ownedRepos, &repo_model.Repository{OwnerID: userID}))
|
||||
if len(ownedRepos) > 0 {
|
||||
err := DeleteUser(user)
|
||||
err := DeleteUser(db.DefaultContext, user, false)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, models.IsErrUserOwnRepos(err))
|
||||
return
|
||||
|
@ -47,7 +47,7 @@ func TestDeleteUser(t *testing.T) {
|
|||
return
|
||||
}
|
||||
}
|
||||
assert.NoError(t, DeleteUser(user))
|
||||
assert.NoError(t, DeleteUser(db.DefaultContext, user, false))
|
||||
unittest.AssertNotExistsBean(t, &user_model.User{ID: userID})
|
||||
unittest.CheckConsistencyFor(t, &user_model.User{}, &repo_model.Repository{})
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ func TestDeleteUser(t *testing.T) {
|
|||
test(11)
|
||||
|
||||
org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
|
||||
assert.Error(t, DeleteUser(org))
|
||||
assert.Error(t, DeleteUser(db.DefaultContext, org, false))
|
||||
}
|
||||
|
||||
func TestCreateUser(t *testing.T) {
|
||||
|
@ -72,7 +72,7 @@ func TestCreateUser(t *testing.T) {
|
|||
|
||||
assert.NoError(t, user_model.CreateUser(user))
|
||||
|
||||
assert.NoError(t, DeleteUser(user))
|
||||
assert.NoError(t, DeleteUser(db.DefaultContext, user, false))
|
||||
}
|
||||
|
||||
func TestCreateUser_Issue5882(t *testing.T) {
|
||||
|
@ -101,6 +101,6 @@ func TestCreateUser_Issue5882(t *testing.T) {
|
|||
|
||||
assert.Equal(t, !u.AllowCreateOrganization, v.disableOrgCreation)
|
||||
|
||||
assert.NoError(t, DeleteUser(v.user))
|
||||
assert.NoError(t, DeleteUser(db.DefaultContext, v.user, false))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@
|
|||
|
||||
<div class="field">
|
||||
<button class="ui green button">{{.locale.Tr "admin.users.update_profile"}}</button>
|
||||
<div class="ui red button delete-button" data-url="{{$.Link}}/delete" data-id="{{.User.ID}}">{{.locale.Tr "admin.users.delete_account"}}</div>
|
||||
<div class="ui red button show-modal" data-modal="#delete-user-modal" data-url="{{$.Link}}/delete" data-id="{{.User.ID}}">{{.locale.Tr "admin.users.delete_account"}}</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -196,7 +196,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui small basic delete modal">
|
||||
<div class="ui small basic delete modal" id="delete-user-modal">
|
||||
<div class="ui icon header">
|
||||
{{svg "octicon-trash"}}
|
||||
{{.locale.Tr "settings.delete_account_title"}}
|
||||
|
@ -204,6 +204,17 @@
|
|||
<div class="content">
|
||||
<p>{{.locale.Tr "settings.delete_account_desc"}}</p>
|
||||
</div>
|
||||
{{template "base/delete_modal_actions" .}}
|
||||
<form class="ui form" method="POST" action="{{.Link}}/delete">
|
||||
{{$.CsrfTokenHtml}}
|
||||
<input type="hidden" name="id">
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<label for="purge">{{.locale.Tr "admin.users.purge"}}</label>
|
||||
<input name="purge" type="checkbox">
|
||||
</div>
|
||||
<p class="help">{{.locale.Tr "admin.users.purge_help"}}</p>
|
||||
</div>
|
||||
{{template "base/delete_modal_actions" .}}
|
||||
</form>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
||||
|
|
|
@ -4,7 +4,6 @@ If you are customizing Gitea, please do not change this file.
|
|||
If you introduce mistakes in it, Gitea JavaScript code wouldn't run correctly.
|
||||
*/}}
|
||||
<script>
|
||||
<!-- /* eslint-disable */ -->
|
||||
window.addEventListener('error', function(e) {window._globalHandlerErrors=window._globalHandlerErrors||[]; window._globalHandlerErrors.push(e);});
|
||||
window.config = {
|
||||
appVer: '{{AppVer}}',
|
||||
|
|
|
@ -41,11 +41,9 @@
|
|||
{{end}}
|
||||
<h4 class="ui top attached header df">
|
||||
<strong class="f1">{{.locale.Tr "org.people"}}</strong>
|
||||
{{if .IsOrganizationMember}}
|
||||
<div class="ui">
|
||||
<a class="text grey dif ac" href="{{.OrgLink}}/members"><span>{{.Org.NumMembers}}</span> {{svg "octicon-chevron-right"}}</a>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="ui">
|
||||
<a class="text grey dif ac" href="{{.OrgLink}}/members"><span>{{.MembersTotal}}</span> {{svg "octicon-chevron-right"}}</a>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="ui attached segment members">
|
||||
{{$isMember := .IsOrganizationMember}}
|
||||
|
|
|
@ -195,12 +195,12 @@
|
|||
<i class="icon icon-octicon">{{svg "octicon-sync"}}</i>
|
||||
{{$.locale.Tr "repo.pulls.is_checking"}}
|
||||
</div>
|
||||
{{else if .Issue.PullRequest.IsEmpty}}
|
||||
{{else if .Issue.PullRequest.IsAncestor}}
|
||||
<div class="item">
|
||||
<i class="icon icon-octicon">{{svg "octicon-alert" 16}}</i>
|
||||
{{$.locale.Tr "repo.pulls.is_empty"}}
|
||||
{{$.locale.Tr "repo.pulls.is_ancestor"}}
|
||||
</div>
|
||||
{{else if .Issue.PullRequest.CanAutoMerge}}
|
||||
{{else if or .Issue.PullRequest.CanAutoMerge .Issue.PullRequest.IsEmpty}}
|
||||
{{if .IsBlockedByApprovals}}
|
||||
<div class="item">
|
||||
<i class="icon icon-octicon">{{svg "octicon-x"}}</i>
|
||||
|
@ -282,7 +282,6 @@
|
|||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{if and (gt .Issue.PullRequest.CommitsBehind 0) (not .Issue.IsClosed) (not .Issue.PullRequest.IsChecking) (not .IsPullFilesConflicted) (not .IsPullRequestBroken) (not $canAutoMerge)}}
|
||||
<div class="ui divider"></div>
|
||||
<div class="item item-section">
|
||||
|
@ -321,6 +320,14 @@
|
|||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .Issue.PullRequest.IsEmpty}}
|
||||
<div class="ui divider"></div>
|
||||
|
||||
<div class="item">
|
||||
<i class="icon icon-octicon">{{svg "octicon-alert" 16}}</i>
|
||||
{{$.locale.Tr "repo.pulls.is_empty"}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{if .AllowMerge}} {{/* user is allowed to merge */}}
|
||||
{{$prUnit := .Repository.MustGetUnit $.UnitTypePullRequests}}
|
||||
|
@ -333,7 +340,6 @@
|
|||
{{end}}
|
||||
<div class="ui divider"></div>
|
||||
<script>
|
||||
<!-- /* eslint-disable */ -->
|
||||
(() => {
|
||||
const defaultMergeTitle = {{.DefaultMergeMessage}};
|
||||
const defaultSquashMergeTitle = {{.DefaultSquashMergeMessage}};
|
||||
|
@ -348,6 +354,7 @@
|
|||
|
||||
'canMergeNow': {{$canMergeNow}},
|
||||
'allOverridableChecksOk': {{not $notAllOverridableChecksOk}},
|
||||
'emptyCommit': {{.Issue.PullRequest.IsEmpty}},
|
||||
'pullHeadCommitID': {{.PullHeadCommitID}},
|
||||
'isPullBranchDeletable': {{.IsPullBranchDeletable}},
|
||||
'defaultDeleteBranchAfterMerge': {{$prUnit.PullRequestsConfig.DefaultDeleteBranchAfterMerge}},
|
||||
|
|
|
@ -17713,6 +17713,10 @@
|
|||
"type": "boolean",
|
||||
"x-go-name": "AllowRebaseMerge"
|
||||
},
|
||||
"allow_rebase_update": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "AllowRebaseUpdate"
|
||||
},
|
||||
"allow_squash_merge": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "AllowSquash"
|
||||
|
@ -17738,6 +17742,10 @@
|
|||
"type": "string",
|
||||
"x-go-name": "DefaultBranch"
|
||||
},
|
||||
"default_delete_branch_after_merge": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "DefaultDeleteBranchAfterMerge"
|
||||
},
|
||||
"default_merge_style": {
|
||||
"type": "string",
|
||||
"x-go-name": "DefaultMergeStyle"
|
||||
|
@ -18479,6 +18487,12 @@
|
|||
"type": "string",
|
||||
"x-go-name": "UserName"
|
||||
},
|
||||
"login_name": {
|
||||
"description": "the user's authentication sign-in name.",
|
||||
"type": "string",
|
||||
"default": "empty",
|
||||
"x-go-name": "LoginName"
|
||||
},
|
||||
"prohibit_login": {
|
||||
"description": "Is user login prohibited",
|
||||
"type": "boolean",
|
||||
|
|
|
@ -109,15 +109,15 @@
|
|||
<div class="item">
|
||||
<div class="content">
|
||||
{{if .IsPrivate}}
|
||||
<span class="text gold iconFloat">{{svg "octicon-lock"}}</span>
|
||||
{{svg "octicon-lock" 16 "mr-2 iconFloat text gold"}}
|
||||
{{else if .IsFork}}
|
||||
<span class="iconFloat">{{svg "octicon-repo-forked"}}</span>
|
||||
{{svg "octicon-repo-forked" 16 "mr-2 iconFloat"}}
|
||||
{{else if .IsMirror}}
|
||||
<span class="iconFloat">{{svg "octicon-mirror"}}</span>
|
||||
{{svg "octicon-mirror" 16 "mr-2 iconFloat"}}
|
||||
{{else if .IsTemplate}}
|
||||
<span class="iconFloat">{{svg "octicon-repo-template"}}</span>
|
||||
{{svg "octicon-repo-template" 16 "mr-2 iconFloat"}}
|
||||
{{else}}
|
||||
<span class="iconFloat">{{svg "octicon-repo"}}</span>
|
||||
{{svg "octicon-repo" 16 "mr-2 iconFloat"}}
|
||||
{{end}}
|
||||
<a class="name" href="{{.Link}}">{{.OwnerName}}/{{.Name}}</a>
|
||||
<span>{{FileSize .Size}}</span>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
plugins:
|
||||
- eslint-plugin-vue
|
||||
|
||||
extends:
|
||||
- ../../../.eslintrc.yaml
|
||||
- plugin:vue/recommended
|
||||
|
||||
env:
|
||||
browser: true
|
||||
|
||||
rules:
|
||||
vue/attributes-order: [0]
|
||||
vue/component-definition-name-casing: [0]
|
||||
vue/html-closing-bracket-spacing: [0]
|
||||
vue/max-attributes-per-line: [0]
|
||||
vue/one-component-per-file: [0]
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
<div v-if="!showActionForm" class="df">
|
||||
<!-- the merge button -->
|
||||
<div class="ui buttons merge-button" :class="mergeButtonStyleClass" @click="toggleActionForm(true)" >
|
||||
<div class="ui buttons merge-button" :class="[mergeForm.emptyCommit ? 'grey' : mergeForm.allOverridableChecksOk ? 'green' : 'red']" @click="toggleActionForm(true)" >
|
||||
<button class="ui button">
|
||||
<svg-icon name="octicon-git-merge"/>
|
||||
<span class="button-text">
|
||||
|
|
Loading…
Reference in New Issue