diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 3343af95a975..bc98f4ca17ad 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -211,8 +211,6 @@ RUN_MODE = ; prod ;; Enables git-lfs support. true or false, default is false. ;LFS_START_SERVER = false ;; -;; Where your lfs files reside, default is data/lfs. -;LFS_CONTENT_PATH = data/lfs ;; ;; LFS authentication secret, change this yourself LFS_JWT_SECRET = @@ -2183,6 +2181,9 @@ PATH = ;; ;[lfs] ;STORAGE_TYPE = local +;; +;; Where your lfs files reside, default is data/lfs. +;PATH = data/lfs ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docker/root/etc/templates/app.ini b/docker/root/etc/templates/app.ini index c5212a935894..7e8aa0bd0a62 100644 --- a/docker/root/etc/templates/app.ini +++ b/docker/root/etc/templates/app.ini @@ -20,7 +20,6 @@ DISABLE_SSH = $DISABLE_SSH SSH_PORT = $SSH_PORT SSH_LISTEN_PORT = $SSH_LISTEN_PORT LFS_START_SERVER = $LFS_START_SERVER -LFS_CONTENT_PATH = /data/git/lfs [database] PATH = /data/gitea/gitea.db @@ -59,3 +58,6 @@ REVERSE_PROXY_TRUSTED_PROXIES = * [service] DISABLE_REGISTRATION = $DISABLE_REGISTRATION REQUIRE_SIGNIN_VIEW = $REQUIRE_SIGNIN_VIEW + +[lfs] +PATH = /data/git/lfs diff --git a/docker/rootless/etc/templates/app.ini b/docker/rootless/etc/templates/app.ini index 905b2adb339e..f106f01f5eb4 100644 --- a/docker/rootless/etc/templates/app.ini +++ b/docker/rootless/etc/templates/app.ini @@ -23,7 +23,6 @@ SSH_PORT = $SSH_PORT SSH_LISTEN_PORT = $SSH_LISTEN_PORT BUILTIN_SSH_SERVER_USER = $RUN_USER LFS_START_SERVER = $LFS_START_SERVER -LFS_CONTENT_PATH = $GITEA_WORK_DIR/git/lfs [database] PATH = $GITEA_WORK_DIR/data/gitea.db @@ -55,3 +54,6 @@ REVERSE_PROXY_TRUSTED_PROXIES = * [service] DISABLE_REGISTRATION = $DISABLE_REGISTRATION REQUIRE_SIGNIN_VIEW = $REQUIRE_SIGNIN_VIEW + +[lfs] +PATH = $GITEA_WORK_DIR/git/lfs diff --git a/docs/content/doc/installation/with-docker-rootless.en-us.md b/docs/content/doc/installation/with-docker-rootless.en-us.md index f28d506231ad..b5bc660afbc1 100644 --- a/docs/content/doc/installation/with-docker-rootless.en-us.md +++ b/docs/content/doc/installation/with-docker-rootless.en-us.md @@ -322,8 +322,15 @@ Match User git AuthorizedKeysCommand /usr/bin/docker exec -i gitea /usr/local/bin/gitea keys -c /etc/gitea/app.ini -e git -u %u -t %t -k %k ``` +(From 1.16.0 you will not need to set the `-c /etc/gitea/app.ini` option.) + All that is left to do is restart the SSH server: ```bash sudo systemctl restart sshd ``` + +**Notes** + +This isn't actually using the docker SSH - it is simply using the commands around it. +You could theoretically not run the internal SSH server. diff --git a/docs/content/doc/installation/with-docker.en-us.md b/docs/content/doc/installation/with-docker.en-us.md index 43a262c5936c..3462d8f377a1 100644 --- a/docs/content/doc/installation/with-docker.en-us.md +++ b/docs/content/doc/installation/with-docker.en-us.md @@ -307,77 +307,233 @@ To set required TOKEN and SECRET values, consider using Gitea's built-in [genera ## SSH Container Passthrough -Since SSH is running inside the container, SSH needs to be passed through from the host to the container if SSH support is desired. One option would be to run the container SSH on a non-standard port (or moving the host port to a non-standard port). Another option which might be more straightforward is to forward SSH connections from the host to the container. This setup is explained in the following. +Since SSH is running inside the container, SSH needs to be passed through from the host to the container if SSH support is desired. One option would be to run the container SSH on a non-standard port (or moving the host port to a non-standard port). Another option which might be more straightforward is to forward SSH connections from the host to the container. -This guide assumes that you have created a user on the host called `git` which shares the same `UID`/ `GID` as the container values `USER_UID`/ `USER_GID`. These values can be set as environment variables in the `docker-compose.yml`: +There are multiple ways of doing this - however, all of these require some information about the docker being passed to the host. -```bash -environment: - - USER_UID=1000 - - USER_GID=1000 -``` +### SSHing Shim (with authorized_keys) -Next mount `/home/git/.ssh` of the host into the container. Otherwise the SSH authentication cannot work inside the container. +The idea of this option is to use (essentially unchanged) the authorized_keys that gitea creates on the docker and simply shim the gitea binary the docker would use on the host to instead ssh into the docker ssh. -```bash -volumes: - - /home/git/.ssh/:/data/git/.ssh -``` +- To make the forwarding work, the SSH port of the container (22) needs to be mapped to the host port 2222 in `docker-compose.yml` . Since this port does not need to be exposed to the outside world, it can be mapped to the `localhost` of the host machine: -Now a SSH key pair needs to be created on the host. This key pair will be used to authenticate the `git` user on the host to the container. + ```yaml + ports: + # [...] + - "127.0.0.1:2222:22" + ``` -```bash -sudo -u git ssh-keygen -t rsa -b 4096 -C "Gitea Host Key" -``` +- Next on the host create the `git` user which shares the same `UID`/ `GID` as the container values `USER_UID`/ `USER_GID`. These values can be set as environment variables in the `docker-compose.yml`: + + ```yaml + environment: + - USER_UID=1000 + - USER_GID=1000 + ``` + +- Mount `/home/git/.ssh` of the host into the container. Otherwise the SSH authentication cannot work inside the container. + + ```yaml + volumes: + - /home/git/.ssh/:/data/git/.ssh + ``` + +- Now a SSH key pair needs to be created on the host. This key pair will be used to authenticate the `git` user on the host to the container. + + ```bash + sudo -u git ssh-keygen -t rsa -b 4096 -C "Gitea Host Key" + ``` + +- Please note depending on the local version of ssh you may want to consider using `-t ecdsa` here. + +- `/home/git/.ssh/authorized_keys` on the host now needs to be modified. It needs to act in the same way as `authorized_keys` within the Gitea container. Therefore add the public key of the key you created above ("Gitea Host Key") to `~/git/.ssh/authorized_keys`. + + ```bash + echo "$(cat /home/git/.ssh/id_rsa.pub)" >> /home/git/.ssh/authorized_keys + ``` + + Important: The pubkey from the `git` user needs to be added "as is" while all other pubkeys added via the Gitea web interface will be prefixed with `command="/usr [...]`. + + `/home/git/.ssh/authorized_keys` should then look somewhat like + + ```bash + # SSH pubkey from git user + ssh-rsa + + # other keys from users + command="/usr/local/bin/gitea --config=/data/gitea/conf/app.ini serv key-1",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty + ``` + +- The next step is to create the file that will issue the SSH forwarding from the host to the container. The name of this file depends on your version of Gitea: + + - For Gitea v1.16.0+: + + ```bash + cat <<"EOF" | sudo tee /usr/local/bin/gitea + #!/bin/sh + ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@" + EOF + chmod +x /usr/local/bin/gitea + ``` + + - For Gitea v1.15.x and earlier + + ```bash + cat <<"EOF" | sudo tee /app/gitea/gitea + #!/bin/sh + ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@" + EOF + sudo chmod +x /app/gitea/gitea + ``` + +Here is a detailed explanation what is happening when a SSH request is made: + +1. A SSH request is made against the host (usually port 22) using the `git` user, e.g. `git clone git@domain:user/repo.git`. +2. In `/home/git/.ssh/authorized_keys` , the command executes the `/usr/local/bin/gitea` script. +3. `/usr/local/bin/gitea` forwards the SSH request to port 2222 which is mapped to the SSH port (ssh 22) of the container. +4. Due to the existence of the public key of the `git` user in `/home/git/.ssh/authorized_keys` the authentication host → container succeeds and the SSH request get forwarded to Gitea running in the docker container. + +If a new SSH key is added in the Gitea web interface, it will be appended to `.ssh/authorized_keys` in the same way as the already existing key. + +**Notes** + +SSH container passthrough using `authorized_keys` will work only if + +- `opensshd` is used in the container +- if `AuthorizedKeysCommand` is _not used_ in combination with `SSH_CREATE_AUTHORIZED_KEYS_FILE=false` to disable authorized files key generation +- `LOCAL_ROOT_URL` is not changed (depending on the changes) + +### SSHing Shell (with authorized_keys) + +The idea of this option is to use (essentially unchanged) the authorized_keys that gitea creates on the docker and use a special shell for git user that uses ssh to shell to the docker git user. + +- In this case we setup as above except instead of creating `/usr/local/bin/gitea` or `/app/gitea/gitea` +we create a new shell for the git user: + + ```bash + cat <<"EOF" | sudo tee /home/git/ssh-shell + #!/bin/sh + shift + ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $@" + EOF + sudo chmod +x /home/git/ssh-shell + sudo usermod -s /home/git/ssh-shell git + ``` + + Be careful here - if you try to login as the git user in future you will ssh directly to the docker. + +Here is a detailed explanation what is happening when a SSH request is made: -In the next step a file named `/app/gitea/gitea` (with executable permissions) needs to be created on the host. This file will issue the SSH forwarding from the host to the container. Add the following contents to `/app/gitea/gitea`: +1. A SSH request is made against the host (usually port 22) using the `git` user, e.g. `git clone git@domain:user/repo.git`. +2. In `/home/git/.ssh/authorized_keys` , the command in the command portion is passed to the `ssh-shell` script +3. `ssh-shell` forwards the SSH request to port 2222 overriding whi is mapped to the SSH port (ssh 22) of the container. +4. Due to the existence of the public key of the `git` user in `/home/git/.ssh/authorized_keys` the authentication host → container succeeds and the SSH request get forwarded to Gitea running in the docker container. + +If a new SSH key is added in the Gitea web interface, it will be appended to `.ssh/authorized_keys` in the same way as the already existing key. + +**Notes** + +SSH container passthrough using `authorized_keys` will work only if + +- `opensshd` is used in the container +- if `AuthorizedKeysCommand` is _not used_ in combination with `SSH_CREATE_AUTHORIZED_KEYS_FILE=false` to disable authorized files key generation +- `LOCAL_ROOT_URL` is not changed (depending on the changes) + +### Docker Shell (with authorized_keys) + +Similar to the above ssh shell technique we can use a shell which simply uses `docker exec`: ```bash +cat <<"EOF" | sudo tee /home/git/docker-shell #!/bin/sh -ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@" +/usr/bin/docker exec -i --env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" gitea sh "$@" +EOF +sudo chmod +x /home/git/docker-shell +sudo usermod -s /home/git/docker-shell git ``` -Here you should also make sure that you've set the permission of `/app/gitea/gitea` correctly: +Note that `gitea` in the docker command above is the name of the container. If you named yours differently, don't forget to change that. The `git` user also have to have +permission to run `docker exec`. + +**Notes** + +Docker shell passthrough using `authorized_keys` will work only if + +- `opensshd` is used in the container +- if `AuthorizedKeysCommand` is _not used_ in combination with `SSH_CREATE_AUTHORIZED_KEYS_FILE=false` to disable authorized files key generation +- `LOCAL_ROOT_URL` is not changed (depending on the changes) + +A Docker execing shim could be created similarly to above. + +### Docker Shell with AuthorizedKeysCommand + +The AuthorizedKeysCommand route provides another option that does not require many changes to the compose file or the `authorized_keys` - but does require changes to the host `/etc/sshd_config`. + +- On the host create called `git` with permission to run `docker exec`. +- We will again assume that the Gitea container is called `gitea`. +- Modify the `git` user's shell to forward commands to the `sh` executable inside the container using `docker exec` as previously described: + + ```bash + cat <<"EOF" | sudo tee /home/git/docker-shell + #!/bin/sh + /usr/bin/docker exec -i --env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" gitea sh "$@" + EOF + sudo chmod +x /home/git/docker-shell + sudo usermod -s /home/git/docker-shell git + ``` + +Now all attempts to login as the `git` user will be forwarded to the docker - including the `SSH_ORIGINAL_COMMAND`. We now need to set-up SSH authenitication on the host. + +We will do this by leveraging the [SSH AuthorizedKeysCommand](https://docs.gitea.io/en-us/command-line/#keys) to match the keys against those accepted by Gitea. + +Add the following block to `/etc/ssh/sshd_config`, on the host: ```bash -sudo chmod +x /app/gitea/gitea +Match User git + AuthorizedKeysCommandUser git + AuthorizedKeysCommand /usr/bin/docker exec -i gitea /usr/local/bin/gitea keys -c /data/gitea/conf/app.ini -e git -u %u -t %t -k %k ``` -To make the forwarding work, the SSH port of the container (22) needs to be mapped to the host port 2222 in `docker-compose.yml` . Since this port does not need to be exposed to the outside world, it can be mapped to the `localhost` of the host machine: +(From 1.16.0 you will not need to set the `-c /data/gitea/conf/app.ini` option.) + +Finally restart the SSH server: ```bash -ports: - # [...] - - "127.0.0.1:2222:22" +sudo systemctl restart sshd ``` -In addition, `/home/git/.ssh/authorized_keys` on the host needs to be modified. It needs to act in the same way as `authorized_keys` within the Gitea container. Therefore add the public key of the key you created above ("Gitea Host Key") to `~/git/.ssh/authorized_keys`. -This can be done via `echo "$(cat /home/git/.ssh/id_rsa.pub)" >> /home/git/.ssh/authorized_keys`. -Important: The pubkey from the `git` user needs to be added "as is" while all other pubkeys added via the Gitea web interface will be prefixed with `command="/app [...]`. +**Notes** -The file should then look somewhat like +Docker shell passthrough using `AuthorizedKeysCommand` will work only if -```bash -# SSH pubkey from git user -ssh-rsa +- The host `git` user is allowed to run the `docker exec` command. + +A Docker execing shim could be created similarly to above. + +### SSH Shell with AuthorizedKeysCommand + +Create a key for the host `git` user as above, add it to the docker `/data/git/.ssh/authorized_keys` then finally create and set the `ssh-shell` as above. + +Add the following block to `/etc/ssh/sshd_config`, on the host: -# other keys from users -command="/app/gitea/gitea --config=/data/gitea/conf/app.ini serv key-1",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty +```bash +Match User git + AuthorizedKeysCommandUser git + AuthorizedKeysCommand ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 /usr/local/bin/gitea keys -c /data/gitea/conf/app.ini -e git -u %u -t %t -k %k ``` -Here is a detailed explanation what is happening when a SSH request is made: +(From 1.16.0 you will not need to set the `-c /data/gitea/conf/app.ini` option.) -1. A SSH request is made against the host (usually port 22) using the `git` user, e.g. `git clone git@domain:user/repo.git`. -2. In `/home/git/.ssh/authorized_keys` , the command executes the `/app/gitea/gitea` script. -3. `/app/gitea/gitea` forwards the SSH request to port 2222 which is mapped to the SSH port (22) of the container. -4. Due to the existence of the public key of the `git` user in `/home/git/.ssh/authorized_keys` the authentication host → container succeeds and the SSH request get forwarded to Gitea running in the docker container. +Finally restart the SSH server: -If a new SSH key is added in the Gitea web interface, it will be appended to `.ssh/authorized_keys` in the same way as the already existing key. +```bash +sudo systemctl restart sshd +``` **Notes** -SSH container passthrough will work only if +SSH container passthrough using `AuthorizedKeysCommand` will work only if -- `opensshd` is used in the container -- if `AuthorizedKeysCommand` is _not used_ in combination with `SSH_CREATE_AUTHORIZED_KEYS_FILE=false` to disable authorized files key generation -- `LOCAL_ROOT_URL` is not changed +- `opensshd` is running on the container + +SSHing shims could be created similarly to above. diff --git a/docs/content/doc/usage/git-lfs-support.md b/docs/content/doc/usage/git-lfs-support.md index a8f935de2bf0..8b2c997bf969 100644 --- a/docs/content/doc/usage/git-lfs-support.md +++ b/docs/content/doc/usage/git-lfs-support.md @@ -21,8 +21,10 @@ To use Gitea's built-in LFS support, you must update the `app.ini` file: [server] ; Enables git-lfs support. true or false, default is false. LFS_START_SERVER = true + +[lfs] ; Where your lfs files reside, default is data/lfs. -LFS_CONTENT_PATH = /home/gitea/data/lfs +PATH = /home/gitea/data/lfs ``` **Note**: LFS server support needs at least Git v2.1.2 installed on the server diff --git a/integrations/git_helper_for_declarative_test.go b/integrations/git_helper_for_declarative_test.go index b13c912fd79d..de96f633c042 100644 --- a/integrations/git_helper_for_declarative_test.go +++ b/integrations/git_helper_for_declarative_test.go @@ -122,6 +122,17 @@ func doGitClone(dstLocalPath string, u *url.URL) func(*testing.T) { } } +func doPartialGitClone(dstLocalPath string, u *url.URL) func(*testing.T) { + return func(t *testing.T) { + assert.NoError(t, git.CloneWithArgs(context.Background(), u.String(), dstLocalPath, allowLFSFilters(), git.CloneRepoOptions{ + Filter: "blob:none", + })) + exist, err := util.IsExist(filepath.Join(dstLocalPath, "README.md")) + assert.NoError(t, err) + assert.True(t, exist) + } +} + func doGitCloneFail(u *url.URL) func(*testing.T) { return func(t *testing.T) { tmpDir, err := os.MkdirTemp("", "doGitCloneFail") diff --git a/integrations/git_test.go b/integrations/git_test.go index 243cca2e55bd..93ff9d254338 100644 --- a/integrations/git_test.go +++ b/integrations/git_test.go @@ -69,6 +69,12 @@ func testGit(t *testing.T, u *url.URL) { t.Run("Clone", doGitClone(dstPath, u)) + dstPath2, err := os.MkdirTemp("", httpContext.Reponame) + assert.NoError(t, err) + defer util.RemoveAll(dstPath2) + + t.Run("Partial Clone", doPartialGitClone(dstPath2, u)) + little, big := standardCommitAndPushTest(t, dstPath) littleLFS, bigLFS := lfsCommitAndPushTest(t, dstPath) rawTest(t, &httpContext, little, big, littleLFS, bigLFS) diff --git a/integrations/mssql.ini.tmpl b/integrations/mssql.ini.tmpl index b9ed26dccd3f..e97174ee85a4 100644 --- a/integrations/mssql.ini.tmpl +++ b/integrations/mssql.ini.tmpl @@ -45,7 +45,6 @@ SSH_LISTEN_HOST = localhost SSH_PORT = 2201 START_SSH_SERVER = true LFS_START_SERVER = true -LFS_CONTENT_PATH = integrations/gitea-integration-mssql/data/lfs OFFLINE_MODE = false LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w APP_DATA_PATH = integrations/gitea-integration-mssql/data @@ -100,3 +99,6 @@ DISABLE_GIT_HOOKS = false INSTALL_LOCK = true SECRET_KEY = 9pCviYTWSb INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0OTU1NTE2MTh9.hhSVGOANkaKk3vfCd2jDOIww4pUk0xtg9JRde5UogyQ + +[lfs] +PATH = integrations/gitea-integration-mssql/data/lfs diff --git a/integrations/mysql8.ini.tmpl b/integrations/mysql8.ini.tmpl index 81a1d8836c32..606aa41d5ced 100644 --- a/integrations/mysql8.ini.tmpl +++ b/integrations/mysql8.ini.tmpl @@ -45,7 +45,6 @@ SSH_LISTEN_HOST = localhost SSH_PORT = 2204 START_SSH_SERVER = true LFS_START_SERVER = true -LFS_CONTENT_PATH = integrations/gitea-integration-mysql8/data/lfs OFFLINE_MODE = false LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w APP_DATA_PATH = integrations/gitea-integration-mysql8/data @@ -97,3 +96,6 @@ DISABLE_GIT_HOOKS = false INSTALL_LOCK = true SECRET_KEY = 9pCviYTWSb INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0OTU1NTE2MTh9.hhSVGOANkaKk3vfCd2jDOIww4pUk0xtg9JRde5UogyQ + +[lfs] +PATH = integrations/gitea-integration-mysql8/data/lfs diff --git a/integrations/pgsql.ini.tmpl b/integrations/pgsql.ini.tmpl index db1914a1bbc9..a325ea028656 100644 --- a/integrations/pgsql.ini.tmpl +++ b/integrations/pgsql.ini.tmpl @@ -46,7 +46,6 @@ SSH_LISTEN_HOST = localhost SSH_PORT = 2202 START_SSH_SERVER = true LFS_START_SERVER = true -LFS_CONTENT_PATH = integrations/gitea-integration-pgsql/data/lfs OFFLINE_MODE = false LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w APP_DATA_PATH = integrations/gitea-integration-pgsql/data @@ -101,3 +100,6 @@ DISABLE_GIT_HOOKS = false INSTALL_LOCK = true SECRET_KEY = 9pCviYTWSb INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0OTU1NTE2MTh9.hhSVGOANkaKk3vfCd2jDOIww4pUk0xtg9JRde5UogyQ + +[lfs] +PATH = integrations/gitea-integration-pgsql/data/lfs diff --git a/integrations/sqlite.ini.tmpl b/integrations/sqlite.ini.tmpl index 76d9420d817e..e82780ad8028 100644 --- a/integrations/sqlite.ini.tmpl +++ b/integrations/sqlite.ini.tmpl @@ -41,7 +41,6 @@ SSH_LISTEN_HOST = localhost SSH_PORT = 2203 START_SSH_SERVER = true LFS_START_SERVER = true -LFS_CONTENT_PATH = integrations/gitea-integration-sqlite/data/lfs OFFLINE_MODE = false LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w APP_DATA_PATH = integrations/gitea-integration-sqlite/data @@ -99,3 +98,6 @@ INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0OTI3OTU5ODN9.O [oauth2] JWT_SECRET = KZb_QLUd4fYVyxetjxC4eZkrBgWM2SndOOWDNtgUUko + +[lfs] +PATH = integrations/gitea-integration-sqlite/data/lfs diff --git a/modules/git/diff.go b/modules/git/diff.go index 38aefabf1a32..4723898e3741 100644 --- a/modules/git/diff.go +++ b/modules/git/diff.go @@ -81,7 +81,7 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff } stderr := new(bytes.Buffer) - cmd := NewCommandContextNoGlobals(repo.Ctx, args...) + cmd := NewCommandContext(repo.Ctx, args...) if err = cmd.RunWithContext(&RunContext{ Timeout: -1, Dir: repo.Path, diff --git a/modules/git/repo.go b/modules/git/repo.go index 6368c6459b50..5636405118fd 100644 --- a/modules/git/repo.go +++ b/modules/git/repo.go @@ -101,6 +101,7 @@ type CloneRepoOptions struct { Shared bool NoCheckout bool Depth int + Filter string } // Clone clones original repository to target path. @@ -136,7 +137,9 @@ func CloneWithArgs(ctx context.Context, from, to string, args []string, opts Clo if opts.Depth > 0 { cmd.AddArguments("--depth", strconv.Itoa(opts.Depth)) } - + if opts.Filter != "" { + cmd.AddArguments("--filter", opts.Filter) + } if len(opts.Branch) > 0 { cmd.AddArguments("-b", opts.Branch) } diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 0f7a098f1c45..abac0195f130 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -474,7 +474,7 @@ activity=Публічна активність followers=Читачі starred=Обрані Репозиторії watched=Відстежувані репозиторії -projects=Проекти +projects=Проєкт following=Читає follow=Підписатися unfollow=Відписатися @@ -524,6 +524,12 @@ continue=Продовжити cancel=Відмінити language=Мова ui=Тема +comment_type_group_label=Мітка +comment_type_group_milestone=Етап +comment_type_group_assignee=Виконавець +comment_type_group_title=Заголовок +comment_type_group_branch=Гілка +comment_type_group_project=Проєкт privacy=Приватність keep_activity_private=Приховати діяльність на сторінці профілю keep_activity_private_popup=Показувати вашу активність лише Вам та адміністраторам @@ -611,6 +617,7 @@ gpg_token_help=Ви можете створити підпис за допомо gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig gpg_token_signature=Текстовий (armored) підпис GPG key_signature_gpg_placeholder=Починається з "-----BEGIN PGP SIGNATURE-----" +ssh_token=Токен subkeys=Підключі key_id=ID ключа key_name=Ім'я ключа @@ -743,7 +750,7 @@ visibility.private=Приватний visibility.private_tooltip=Видимий лише членам організації [repo] -new_repo_helper=Репозиторій містить усі файли проекту, включаючи історію ревізій. Ще десь є? Мігрувати репозиторій. +new_repo_helper=Репозиторій містить усі файли проєкту, включаючи історію ревізій. Ще десь є? Мігрувати репозиторій. owner=Власник owner_helper=Деякі організації можуть не відображатися у випадаючому списку через максимальну кількість репозиторііїв. repo_name=Назва репозиторію @@ -778,10 +785,10 @@ issue_labels=Мітки задачі issue_labels_helper=Вибрати мітку для задачі. license=Ліцензія license_helper=Виберіть ліцензійний файл. -license_helper_desc=Ліцензія регулює те, що інші можуть і не можуть робити з вашим кодом. Не впевнені, що саме підходить для вашого проекту? Дивіться Виберіть ліцензію. +license_helper_desc=Ліцензія регулює те, що інші можуть і не можуть робити з вашим кодом. Не впевнені, що саме підходить для вашого проєкту? Дивіться Виберіть ліцензію. readme=README readme_helper=Виберіть шаблон README. -readme_helper_desc=Це місце, де ви можете написати повний опис вашого проекту. +readme_helper_desc=Це місце, де ви можете написати повний опис вашого проєкту. auto_init=Ініціалізувати репозиторій (Додає .gitignore, LICENSE та README) trust_model_helper=Виберіть модель довіри для підтвердження підпису. Можливі варіанти: trust_model_helper_collaborator=Співавтор: підписи довіри від співавторів @@ -1476,7 +1483,7 @@ pulls.closed_at=`закрив цей запит на злиття %[2]s` pulls.merge_instruction_hint=`Також можна переглянути інструкції для командного рядка.` -pulls.merge_instruction_step1_desc=У репозиторії вашого проекту перевірте нову гілку і протестуйте зміни. +pulls.merge_instruction_step1_desc=У репозиторії вашого проєкту перевірте нову гілку і протестуйте зміни. pulls.merge_instruction_step2_desc=Об'єднати зміни і оновити на Gitea. milestones.new=Новий етап @@ -1636,7 +1643,7 @@ settings.hooks=Веб-хуки settings.githooks=Git хуки settings.basic_settings=Базові налаштування settings.mirror_settings=Налаштування дзеркала -settings.mirror_settings.docs=Налаштуйте свій проект, щоб автоматично відправляти/отримувати зміни з іншого репозиторію. Гілки, теги і коміти будуть синхронізуватися автоматично. Як я можу відзеркалити репозиторії? +settings.mirror_settings.docs=Налаштуйте свій проєкт, щоб автоматично відправляти/отримувати зміни з іншого репозиторію. Гілки, теги та коміти будуть синхронізуватися автоматично. Як я можу відзеркалити репозиторії? settings.mirror_settings.mirrored_repository=Віддзеркалений репозиторій settings.mirror_settings.direction=Напрямок settings.mirror_settings.direction.pull=Pull @@ -1663,7 +1670,7 @@ settings.external_wiki_url_error=Зовнішня URL-адреса wiki не є settings.external_wiki_url_desc=Відвідувачі будуть перенаправлені на URL-адресу, коли вони клацають по вкладці. settings.issues_desc=Увімкнути відстеження задач в репозиторію settings.use_internal_issue_tracker=Використовувати вбудовану систему відстеження задач -settings.use_external_issue_tracker=Використовувати зовнішню систему обліку завдань +settings.use_external_issue_tracker=Використовувати зовнішню систему обліку задач settings.external_tracker_url=URL зовнішньої системи відстеження задач settings.external_tracker_url_error=URL зовнішнього баг-трекера не є допустимою URL-адресою. settings.external_tracker_url_desc=Відвідувачі перенаправляються на зовнішню URL-адресу, коли натискають вкладку 'Задачі'. @@ -2038,7 +2045,7 @@ diff.image.side_by_side=Пліч-о-пліч diff.image.swipe=Свайп diff.image.overlay=Оверлей -releases.desc=Відслідковувати версії проекту (релізи) та завантаження. +releases.desc=Відслідковувати версії проєкту і завантаження. release.releases=Релізи release.detail=Деталі релізу release.tags=Теги @@ -2051,8 +2058,8 @@ release.edit=редагувати release.ahead.commits=%d коміт(ів) release.ahead.target=до %s з моменту цього випуску release.source_code=Код -release.new_subheader=Публікація релізів допоможе зберігати чітку історію розвитку вашого проекту. -release.edit_subheader=Публікація релізів допоможе зберігати чітку історію розвитку вашого проекту. +release.new_subheader=Публікація релізів допоможе вам організувати версію проєкту. +release.edit_subheader=Публікація релізів допоможе вам організувати версію проєкту. release.tag_name=Назва тегу release.target=Ціль release.tag_helper=Виберіть існуючий тег або створіть новий. diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index e78abd05d579..9fc12f2293b6 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -549,6 +549,22 @@ continue=继续操作 cancel=取消操作 language=界面语言 ui=主题 +hidden_comment_types=隐藏的评论类型 +comment_type_group_reference=引用 +comment_type_group_label=标签 +comment_type_group_milestone=里程碑 +comment_type_group_assignee=被指派人 +comment_type_group_title=标题 +comment_type_group_branch=分支 +comment_type_group_time_tracking=时间跟踪 +comment_type_group_deadline=截止日期 +comment_type_group_dependency=依赖项 +comment_type_group_lock=锁定状态 +comment_type_group_review_request=审核请求 +comment_type_group_pull_request_push=添加的提交 +comment_type_group_project=项目 +comment_type_group_issue_ref=工单引用 +saved_successfully=您的设置已成功保存。 privacy=隐私设置 keep_activity_private=隐藏个人资料页面中的活动 keep_activity_private_popup=使活动仅对您和管理员可见 @@ -2787,6 +2803,12 @@ monitor.queue.pool.flush.title=刷新队列 monitor.queue.pool.flush.desc=刷新将添加一个工作者,一旦队列为空或超时将结束。 monitor.queue.pool.flush.submit=添加刷新者 monitor.queue.pool.flush.added=为 %[1]s 添加刷新工作者 +monitor.queue.pool.pause.title=暂停队列 +monitor.queue.pool.pause.desc=暂停队列将阻止它处理数据 +monitor.queue.pool.pause.submit=暂停队列 +monitor.queue.pool.resume.title=恢复队列 +monitor.queue.pool.resume.desc=使此队列恢复工作 +monitor.queue.pool.resume.submit=恢复队列 monitor.queue.settings.title=池设置 monitor.queue.settings.desc=池动态增长以应对队列阻塞。这些变更将不会影响当前的工作者组。 diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index d1a703021a4f..1500f2149590 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -34,6 +34,20 @@ twofa=兩步驟驗證 twofa_scratch=兩步驟驗證備用驗證碼 passcode=驗證碼 +webauthn_insert_key=插入您的安全金鑰 +webauthn_sign_in=按下您安全金鑰上的按鈕。如果您的安全金鑰沒有按鈕,請重新插入。 +webauthn_press_button=請按下您安全金鑰上的按鈕… +webauthn_use_twofa=使用來自手機的兩步驟驗證碼 +webauthn_error=無法讀取您的安全金鑰。 +webauthn_unsupported_browser=您的瀏覽器還不支援 WebAuthn。 +webauthn_error_unknown=發生未知的錯誤,請再試一次。 +webauthn_error_insecure=WebAuthn 只支援安全連線。想在 HTTP 上測試,您可以使用「localhost」或「127.0.0.1」 +webauthn_error_unable_to_process=伺服器無法執行您的請求。 +webauthn_error_duplicated=此請求不允許使用這個安全金鑰。請確保該金鑰尚未註冊。 +webauthn_error_empty=您必須命名此金鑰。 +webauthn_error_timeout=在成功讀取金鑰之前已逾時,請重新載入此頁面並重試。 +webauthn_u2f_deprecated=「%s」金鑰使用已廢棄的 U2F 流程進行驗證。您應該重新註冊此金鑰並將先前註冊的移除。 +webauthn_reload=重新載入 repository=儲存庫 organization=組織 @@ -513,6 +527,7 @@ twofa=兩步驟驗證 account_link=已連結帳號 organization=組織 uid=用戶 ID +webauthn=安全金鑰 public_profile=公開的個人資料 biography_placeholder=告訴我們一些關於你的事 @@ -733,6 +748,11 @@ passcode_invalid=無效的驗證碼,請重試。 twofa_enrolled=您的帳戶已經啟用了兩步驟驗證。請將備用驗證碼 (%s) 保存到一個安全的地方,它只會顯示這麼一次! twofa_failed_get_secret=取得密鑰(Secret)失敗。 +webauthn_desc=安全金鑰是包含加密密鑰的硬體設備,它們可以用於兩步驟驗證。安全金鑰必須支援 WebAuthn Authenticator 標準。 +webauthn_register_key=新增安全金鑰 +webauthn_nickname=暱稱 +webauthn_delete_key=移除安全金鑰 +webauthn_delete_key_desc=如果您移除安全金鑰,將不能再使用它登入。是否繼續? manage_account_links=管理已連結的帳戶 manage_account_links_desc=這些外部帳戶已連結到您的 Gitea 帳戶。 @@ -2767,6 +2787,12 @@ monitor.queue.pool.flush.title=清除佇列 monitor.queue.pool.flush.desc=清除將會加入一個工作者,它會在佇列為空或逾時後中止佇列。 monitor.queue.pool.flush.submit=加入清除者 monitor.queue.pool.flush.added=加入了清除者到 %[1]s +monitor.queue.pool.pause.title=暫停佇列 +monitor.queue.pool.pause.desc=暫停佇列將阻止它處理資料 +monitor.queue.pool.pause.submit=暫停佇列 +monitor.queue.pool.resume.title=繼續佇列 +monitor.queue.pool.resume.desc=令此佇列繼續作業 +monitor.queue.pool.resume.submit=繼續佇列 monitor.queue.settings.title=集區設定 monitor.queue.settings.desc=集區會動態成長以對應它的工作者佇列阻塞。這些變更不會影響目前的工作者群組。 @@ -2874,7 +2900,7 @@ notifications=通知 unread=未讀 read=已讀 no_unread=沒有未讀通知 -no_read=沒有通知 +no_read=沒有已讀通知 pin=固定通知 mark_as_read=標記為已讀 mark_as_unread=標記為未讀 diff --git a/routers/install/install.go b/routers/install/install.go index 043fae26de9e..eb2cd2346395 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -418,7 +418,7 @@ func SubmitInstall(ctx *context.Context) { if form.LFSRootPath != "" { cfg.Section("server").Key("LFS_START_SERVER").SetValue("true") - cfg.Section("server").Key("LFS_CONTENT_PATH").SetValue(form.LFSRootPath) + cfg.Section("lfs").Key("PATH").SetValue(form.LFSRootPath) var lfsJwtSecret string if lfsJwtSecret, err = generate.NewJwtSecretBase64(); err != nil { ctx.RenderWithErr(ctx.Tr("install.lfs_jwt_secret_failed", err), tplInstall, &form) diff --git a/routers/web/repo/http.go b/routers/web/repo/http.go index 1b5004017fa3..32811734d3d4 100644 --- a/routers/web/repo/http.go +++ b/routers/web/repo/http.go @@ -485,7 +485,7 @@ func serviceRPC(ctx gocontext.Context, h serviceHandler, service string) { } var stderr bytes.Buffer - cmd := git.NewCommandContextNoGlobals(h.r.Context(), service, "--stateless-rpc", h.dir) + cmd := git.NewCommandContext(h.r.Context(), service, "--stateless-rpc", h.dir) cmd.SetDescription(fmt.Sprintf("%s %s %s [repo_path: %s]", git.GitExecutable, service, "--stateless-rpc", h.dir)) if err := cmd.RunWithContext(&git.RunContext{ Timeout: -1, diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 80e706b5ed25..ae2800d18042 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -1376,7 +1376,7 @@ func GetDiff(gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff }() go func(ctx context.Context, diffArgs []string, repoPath string, writer *io.PipeWriter) { - cmd := git.NewCommandContextNoGlobals(ctx, diffArgs...) + cmd := git.NewCommandContext(ctx, diffArgs...) cmd.SetDescription(fmt.Sprintf("GetDiffRange [repo_path: %s]", repoPath)) if err := cmd.RunWithContext(&git.RunContext{ Timeout: time.Duration(setting.Git.Timeout.Default) * time.Second, diff --git a/web_src/less/_base.less b/web_src/less/_base.less index b53eae02c8a6..8e06d16405fd 100644 --- a/web_src/less/_base.less +++ b/web_src/less/_base.less @@ -249,7 +249,8 @@ a.label, .ui.search .results a, .ui .menu a, .ui.cards a.card, -.issue-keyword a { +.issue-keyword a, +a.commit-statuses-trigger { text-decoration: none !important; }