Template
1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo synced 2024-11-21 17:34:24 +01:00

Compare commits

...

35 commits

Author SHA1 Message Date
SomeTr 786fa38be0
i18n: translated using Weblate (Ukrainian)
Currently translated at 74.6% (2727 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-18 23:07:00 +00:00
SomeTr 24037176f4
i18n: translated using Weblate (Ukrainian)
Currently translated at 74.5% (2723 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-18 23:07:00 +00:00
SomeTr 3d9884865e
i18n: translated using Weblate (Ukrainian)
Currently translated at 74.4% (2721 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-18 23:07:00 +00:00
SomeTr 59e0334ecf
i18n: translated using Weblate (Ukrainian)
Currently translated at 74.2% (2715 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-18 23:07:00 +00:00
SomeTr e100f1d40e
i18n: translated using Weblate (Ukrainian)
Currently translated at 73.4% (2684 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-18 23:07:00 +00:00
SomeTr de7d50cd54
i18n: translated using Weblate (Ukrainian)
Currently translated at 73.3% (2680 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-18 23:07:00 +00:00
artnay 015266b2eb
i18n: translated using Weblate (Finnish)
Currently translated at 57.2% (2094 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/fi/
2024-11-18 23:06:59 +00:00
xtex 3b1fb3b0b7
i18n: translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (3655 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/zh_Hans/
2024-11-18 23:06:59 +00:00
SomeTr 72bb32ca7a
i18n: translated using Weblate (Ukrainian)
Currently translated at 73.2% (2676 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-18 23:06:59 +00:00
artnay ebcf17d792
i18n: translated using Weblate (Finnish)
Currently translated at 56.3% (2059 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/fi/
2024-11-18 23:06:59 +00:00
SomeTr 2caa110c1c
i18n: translated using Weblate (Ukrainian)
Currently translated at 73.1% (2675 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-18 23:06:59 +00:00
artnay c8487d63a5
i18n: translated using Weblate (Finnish)
Currently translated at 55.8% (2040 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/fi/
2024-11-18 23:06:59 +00:00
SomeTr b803631c66
i18n: translated using Weblate (Ukrainian)
Currently translated at 72.8% (2661 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-18 23:06:59 +00:00
xtex fc69541e4f
i18n: translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (3655 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/zh_Hans/
2024-11-18 23:06:59 +00:00
xtex 863c8b08f5
i18n: translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (3655 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/zh_Hans/
2024-11-18 23:06:59 +00:00
Edgarsons 5ab246dccc
i18n: translated using Weblate (Latvian)
Currently translated at 72.3% (2644 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/lv/
2024-11-18 23:06:59 +00:00
xtex 03d55f0a7e
i18n: translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (3655 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/zh_Hans/
2024-11-18 23:06:59 +00:00
Edgarsons b8433d9439
i18n: translated using Weblate (Latvian)
Currently translated at 71.9% (2628 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/lv/
2024-11-18 23:06:59 +00:00
yumechi 5105146207
i18n: translated using Weblate (Japanese)
Currently translated at 91.7% (3353 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/ja/
2024-11-18 23:06:59 +00:00
Earl Warren 298863c701 Merge pull request 'Don't display email in profile settings when hidden' (#6018) from 0ko/forgejo:ui-settings-email-vis into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6018
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Reviewed-by: Otto <otto@codeberg.org>
2024-11-18 23:06:52 +00:00
JakobDev f90928507a [FEAT]Allow changing git notes (#4753)
Git has a cool feature called git notes. It allows adding a text to a commit without changing the commit itself. Forgejo already displays git notes. With this PR you can also now change git notes.

<details>
<summary>Screenshots</summary>

![grafik](/attachments/53a9546b-c4db-4b07-92ae-eb15b209b21d)
![grafik](/attachments/1bd96f2c-6178-45d2-93d7-d19c7cbe5898)
![grafik](/attachments/9ea73623-25d1-4628-a43f-f5ecbd431788)
![grafik](/attachments/efea0c9e-43c6-4441-bb7e-948177bf9021)

</details>

## Checklist

The [developer guide](https://forgejo.org/docs/next/developer/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).

### Tests

- I added test coverage for Go changes...
  - [ ] in their respective `*_test.go` for unit tests.
  - [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I added test coverage for JavaScript changes...
  - [ ] in `web_src/js/*.test.js` if it can be unit tested.
  - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)).

### Documentation

- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [x] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [ ] I do not want this change to show in the release notes.
- [x] I want the title to show in the release notes with a link to this pull request.
- [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title.

<!--start release-notes-assistant-->

## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Features
  - [PR](https://codeberg.org/forgejo/forgejo/pulls/4753): <!--number 4753 --><!--line 0 --><!--description QWxsb3cgY2hhbmdpbmcgZ2l0IG5vdGVz-->Allow changing git notes<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/4753
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: JakobDev <jakobdev@gmx.de>
Co-committed-by: JakobDev <jakobdev@gmx.de>
2024-11-18 22:56:17 +00:00
Earl Warren 71ff98d61d Merge pull request 'Update help links on page with no workflows' (#5697) from kwonunn/fix-empty-actions-page into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5697
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
2024-11-18 21:50:31 +00:00
Marco De Araujo 1f4be5baad Escaping specific markdown in commit messages on Discord-type embeds #3664 (#5811)
Co-authored-by: Marco De Araujo <marco.araujo.junior@gmail.com>
Co-committed-by: Marco De Araujo <marco.araujo.junior@gmail.com>
2024-11-18 21:47:11 +00:00
Earl Warren cff7754735 Merge pull request 'ci: disable postgresql fsync' (#5962) from viceice/ci/pg/fsync into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5962
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-11-18 21:43:15 +00:00
Earl Warren 0fb3e45ca5 Merge pull request 'chore(ci): merge jobs issue label jobs in one workflow' (#6021) from earl-warren/forgejo:wip-ci-labels into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6021
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-11-18 20:33:38 +00:00
Earl Warren 1806db31d1
chore(ci): merge jobs in issue-labels.yml in one workflow
Fixes: forgejo/forgejo#5999
2024-11-18 19:43:35 +01:00
Earl Warren 7c1f3a7594
chore(ci): cat all issue labels workflows in issue-labels.yml
cat cascade-setup-end-to-end.yml backport.yml merge-requirements.yml release-notes-assistant.yml > issue-labels.yml
rm cascade-setup-end-to-end.yml backport.yml merge-requirements.yml release-notes-assistant.yml
2024-11-18 19:40:15 +01:00
Earl Warren 3c3c9b22a9 Merge pull request 'chore(ci): make release-notes-assistant job copy/pastable (part two)' (#6020) from earl-warren/forgejo:wip-ci-labels into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6020
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-11-18 18:10:13 +00:00
Earl Warren 73cb6c9204
chore(ci): make release-notes-assistant job copy/pastable (part two)
The event is pull_request_target

Refs: forgejo/forgejo#5999
2024-11-18 18:11:07 +01:00
Earl Warren 25354c03a5 Merge pull request 'chore(ci): make release-notes-assistant job copy/pastable' (#6019) from earl-warren/forgejo:wip-ci-labels into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6019
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-11-18 17:02:59 +00:00
Earl Warren 18cecf124f
chore(ci): make release-notes-assistant job copy/pastable
Refs: forgejo/forgejo#5999
2024-11-18 17:23:33 +01:00
0ko c3653e0eaa ui: don't display email in profile settings when hidden 2024-11-18 17:06:38 +05:00
Michael Kriese 7f707b2a6f
ci: disable postgresql fsync 2024-11-15 15:29:06 +01:00
Kwonunn f9169eac96
re-add the string for read-only viewers 2024-11-14 09:47:49 +01:00
Kwonunn f8cbd6301e
reword the no-workflows page 2024-11-14 09:47:48 +01:00
34 changed files with 1206 additions and 368 deletions

View file

@ -1,44 +0,0 @@
# Copyright 2024 The Forgejo Authors
# SPDX-License-Identifier: MIT
#
name: issue-labels
on:
pull_request_target:
types:
- closed
- labeled
jobs:
backporting:
if: >
vars.ROLE == 'forgejo-coding' &&
secrets.BACKPORT_TOKEN != '' &&
github.event_name == 'pull_request_target' &&
(
github.event.pull_request.merged &&
contains(toJSON(github.event.pull_request.labels), 'backport/v')
)
runs-on: docker
container:
image: 'code.forgejo.org/oci/node:20-bookworm'
steps:
- name: Debug info
run: |
cat <<'EOF'
${{ toJSON(github) }}
EOF
- uses: https://code.forgejo.org/actions/git-backporting@v4.8.4
with:
target-branch-pattern: "^backport/(?<target>(v.*))$"
strategy: ort
strategy-option: find-renames
cherry-pick-options: -x
auth: ${{ secrets.BACKPORT_TOKEN }}
pull-request: ${{ github.event.pull_request.url }}
auto-no-squash: true
enable-err-notification: true
git-user: forgejo-backport-action
git-email: forgejo-backport-action@noreply.codeberg.org

View file

@ -1,53 +0,0 @@
# Copyright 2024 The Forgejo Authors
# SPDX-License-Identifier: MIT
#
name: issue-labels
on:
pull_request_target:
types:
- labeled
jobs:
end-to-end:
if: >
vars.ROLE == 'forgejo-coding' &&
secrets.END_TO_END_CASCADING_PR_DESTINATION != '' &&
secrets.END_TO_END_CASCADING_PR_ORIGIN != '' &&
(
github.event_name == 'push' ||
(
github.event_name == 'pull_request_target' &&
github.event.action == 'label_updated' &&
github.event.label.name == 'run-end-to-end-tests'
)
)
runs-on: docker
container:
image: code.forgejo.org/oci/node:20-bookworm
steps:
- name: Debug info
run: |
cat <<'EOF'
${{ toJSON(github) }}
EOF
- uses: actions/checkout@v4
with:
fetch-depth: '0'
show-progress: 'false'
- uses: actions/cascading-pr@v2
with:
origin-url: ${{ env.GITHUB_SERVER_URL }}
origin-repo: ${{ github.repository }}
origin-token: ${{ secrets.END_TO_END_CASCADING_PR_ORIGIN }}
origin-pr: ${{ github.event.pull_request.number }}
origin-ref: ${{ github.event_name == 'push' && github.event.ref || '' }}
destination-url: https://code.forgejo.org
destination-fork-repo: cascading-pr/end-to-end
destination-repo: forgejo/end-to-end
destination-branch: main
destination-token: ${{ secrets.END_TO_END_CASCADING_PR_DESTINATION }}
close-merge: true
update: .forgejo/cascading-pr-end-to-end

View file

@ -0,0 +1,205 @@
# Copyright 2024 The Forgejo Authors
# SPDX-License-Identifier: MIT
#
# To modify the pull_request_target jobs:
#
# - push it to the wip-ci-issue-labels branch on the forgejo repository
# otherwise it will not have access to the required secrets.
#
# - once it works, open a pull request for the sake of keeping track
# of the change even if the PR won't run it because it will use
# whatever is in the default branch instead
#
# - after it is merged, double check it works by changing the labels
# to trigger the job.
#
name: issue-labels
on:
push:
branches:
- 'wip-ci-issue-labels'
pull_request_target:
types:
- closed
- edited
- labeled
- synchronize
pull_request:
types:
- edited
- labeled
- opened
- synchronize
jobs:
info:
if: vars.ROLE == 'forgejo-coding'
runs-on: docker
container:
image: code.forgejo.org/oci/node:20-bookworm
steps:
- name: Debug info
run: |
cat <<'EOF'
${{ toJSON(github) }}
EOF
end-to-end:
if: >
vars.ROLE == 'forgejo-coding' &&
secrets.END_TO_END_CASCADING_PR_DESTINATION != '' &&
secrets.END_TO_END_CASCADING_PR_ORIGIN != '' &&
(
github.event_name == 'push' ||
(
github.event_name == 'pull_request_target' &&
github.event.action == 'label_updated' &&
github.event.label.name == 'run-end-to-end-tests'
)
)
runs-on: docker
container:
image: code.forgejo.org/oci/node:20-bookworm
steps:
- name: Debug info
run: |
cat <<'EOF'
${{ toJSON(github) }}
EOF
- uses: actions/checkout@v4
with:
fetch-depth: '0'
show-progress: 'false'
- uses: actions/cascading-pr@v2
with:
origin-url: ${{ env.GITHUB_SERVER_URL }}
origin-repo: ${{ github.repository }}
origin-token: ${{ secrets.END_TO_END_CASCADING_PR_ORIGIN }}
origin-pr: ${{ github.event.pull_request.number }}
origin-ref: ${{ github.event_name == 'push' && github.event.ref || '' }}
destination-url: https://code.forgejo.org
destination-fork-repo: cascading-pr/end-to-end
destination-repo: forgejo/end-to-end
destination-branch: main
destination-token: ${{ secrets.END_TO_END_CASCADING_PR_DESTINATION }}
close-merge: true
update: .forgejo/cascading-pr-end-to-end
backporting:
if: >
vars.ROLE == 'forgejo-coding' &&
secrets.BACKPORT_TOKEN != '' &&
github.event_name == 'pull_request_target' &&
(
github.event.pull_request.merged &&
contains(toJSON(github.event.pull_request.labels), 'backport/v')
)
runs-on: docker
container:
image: 'code.forgejo.org/oci/node:20-bookworm'
steps:
- name: Debug info
run: |
cat <<'EOF'
${{ toJSON(github) }}
EOF
- uses: https://code.forgejo.org/actions/git-backporting@v4.8.4
with:
target-branch-pattern: "^backport/(?<target>(v.*))$"
strategy: ort
strategy-option: find-renames
cherry-pick-options: -x
auth: ${{ secrets.BACKPORT_TOKEN }}
pull-request: ${{ github.event.pull_request.url }}
auto-no-squash: true
enable-err-notification: true
git-user: forgejo-backport-action
git-email: forgejo-backport-action@noreply.codeberg.org
merge-conditions:
if: >
vars.ROLE == 'forgejo-coding' &&
github.event_name == 'pull_request' &&
(
github.event.action == 'label_updated' ||
github.event.action == 'edited' ||
github.event.action == 'opened'
)
runs-on: docker
container:
image: 'code.forgejo.org/oci/node:20-bookworm'
steps:
- name: Debug info
run: |
cat <<'EOF'
${{ toJSON(github) }}
EOF
- name: Missing test label
if: >
!(
contains(toJSON(github.event.pull_request.labels), 'test/present')
|| contains(toJSON(github.event.pull_request.labels), 'test/not-needed')
|| contains(toJSON(github.event.pull_request.labels), 'test/manual')
)
run: |
echo "Test label must be set to either 'present', 'not-needed' or 'manual'."
exit 1
- name: Missing manual test instructions
if: >
(
contains(toJSON(github.event.pull_request.labels), 'test/manual')
&& !contains(toJSON(github.event.pull_request.body), '# Test')
)
run: |
echo "Manual test label is set. The PR description needs to contain test steps introduced by a heading like:"
echo "# Testing"
exit 1
release-notes:
if: >
vars.ROLE == 'forgejo-coding' &&
secrets.RELEASE_NOTES_ASSISTANT_TOKEN != '' &&
github.event_name == 'pull_request_target' &&
contains(github.event.pull_request.labels.*.name, 'worth a release-note') &&
(
github.event.action == 'label_updated' ||
github.event.action == 'edited' ||
github.event.action == 'synchronized'
)
runs-on: docker
container:
image: 'code.forgejo.org/oci/node:20-bookworm'
steps:
- name: Debug info
run: |
cat <<'EOF'
${{ toJSON(github) }}
EOF
- uses: https://code.forgejo.org/actions/checkout@v4
- uses: https://code.forgejo.org/actions/setup-go@v5
with:
go-version-file: "go.mod"
cache: false
- name: apt install jq
run: |
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get -q install -y -qq jq
- name: release-notes-assistant preview
run: |
go run code.forgejo.org/forgejo/release-notes-assistant@v1.1.1 --config .release-notes-assistant.yaml --storage pr --storage-location ${{ github.event.pull_request.number }} --forgejo-url $GITHUB_SERVER_URL --repository $GITHUB_REPOSITORY --token ${{ secrets.RELEASE_NOTES_ASSISTANT_TOKEN }} preview ${{ github.event.pull_request.number }}

View file

@ -1,52 +0,0 @@
# Copyright 2024 The Forgejo Authors
# SPDX-License-Identifier: MIT
name: issue-labels
on:
pull_request:
types:
- labeled
- edited
- opened
jobs:
merge-conditions:
if: >
vars.ROLE == 'forgejo-coding' &&
github.event_name == 'pull_request' &&
(
github.event.action == 'label_updated' ||
github.event.action == 'edited' ||
github.event.action == 'opened'
)
runs-on: docker
container:
image: 'code.forgejo.org/oci/node:20-bookworm'
steps:
- name: Debug info
run: |
cat <<'EOF'
${{ toJSON(github) }}
EOF
- name: Missing test label
if: >
!(
contains(toJSON(github.event.pull_request.labels), 'test/present')
|| contains(toJSON(github.event.pull_request.labels), 'test/not-needed')
|| contains(toJSON(github.event.pull_request.labels), 'test/manual')
)
run: |
echo "Test label must be set to either 'present', 'not-needed' or 'manual'."
exit 1
- name: Missing manual test instructions
if: >
(
contains(toJSON(github.event.pull_request.labels), 'test/manual')
&& !contains(toJSON(github.event.pull_request.body), '# Test')
)
run: |
echo "Manual test label is set. The PR description needs to contain test steps introduced by a heading like:"
echo "# Testing"
exit 1

View file

@ -1,39 +0,0 @@
on:
pull_request_target:
types:
- edited
- synchronize
- labeled
jobs:
release-notes:
if: ( vars.ROLE == 'forgejo-coding' ) && contains(github.event.pull_request.labels.*.name, 'worth a release-note')
runs-on: docker
container:
image: 'code.forgejo.org/oci/node:20-bookworm'
steps:
- uses: https://code.forgejo.org/actions/checkout@v4
- name: event
run: |
cat <<'EOF'
${{ toJSON(github.event.pull_request.labels.*.name) }}
EOF
cat <<'EOF'
${{ toJSON(github.event) }}
EOF
- uses: https://code.forgejo.org/actions/setup-go@v5
with:
go-version-file: "go.mod"
cache: false
- name: apt install jq
run: |
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get -q install -y -qq jq
- name: release-notes-assistant preview
run: |
go run code.forgejo.org/forgejo/release-notes-assistant@v1.1.1 --config .release-notes-assistant.yaml --storage pr --storage-location ${{ github.event.pull_request.number }} --forgejo-url $GITHUB_SERVER_URL --repository $GITHUB_REPOSITORY --token ${{ secrets.RELEASE_NOTES_ASSISTANT_TOKEN }} preview ${{ github.event.pull_request.number }}

View file

@ -216,11 +216,13 @@ jobs:
ldap:
image: code.forgejo.org/oci/test-openldap:latest
pgsql:
image: 'code.forgejo.org/oci/postgres:15'
image: code.forgejo.org/oci/bitnami/postgresql:15
env:
POSTGRES_DB: test
POSTGRES_PASSWORD: postgres
options: --tmpfs /var/lib/postgresql/data
POSTGRESQL_DATABASE: test
POSTGRESQL_PASSWORD: postgres
POSTGRESQL_FSYNC: off
POSTGRESQL_EXTRA_FLAGS: -c full_page_writes=off
options: --tmpfs /bitnami/postgresql
steps:
- uses: https://code.forgejo.org/actions/checkout@v4
- uses: ./.forgejo/workflows-composite/setup-env

View file

@ -6,6 +6,7 @@ package git
import (
"context"
"io"
"os"
"strings"
"code.gitea.io/gitea/modules/log"
@ -97,3 +98,41 @@ func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note)
return nil
}
func SetNote(ctx context.Context, repo *Repository, commitID, notes, doerName, doerEmail string) error {
_, err := repo.GetCommit(commitID)
if err != nil {
return err
}
env := append(os.Environ(),
"GIT_AUTHOR_NAME="+doerName,
"GIT_AUTHOR_EMAIL="+doerEmail,
"GIT_COMMITTER_NAME="+doerName,
"GIT_COMMITTER_EMAIL="+doerEmail,
)
cmd := NewCommand(ctx, "notes", "add", "-f", "-m")
cmd.AddDynamicArguments(notes, commitID)
_, stderr, err := cmd.RunStdString(&RunOpts{Dir: repo.Path, Env: env})
if err != nil {
log.Error("Error while running git notes add: %s", stderr)
return err
}
return nil
}
func RemoveNote(ctx context.Context, repo *Repository, commitID string) error {
cmd := NewCommand(ctx, "notes", "remove")
cmd.AddDynamicArguments(commitID)
_, stderr, err := cmd.RunStdString(&RunOpts{Dir: repo.Path})
if err != nil {
log.Error("Error while running git notes remove: %s", stderr)
return err
}
return nil
}

View file

@ -1,25 +1,38 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package git
package git_test
import (
"context"
"os"
"path/filepath"
"testing"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/git"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const (
testReposDir = "tests/repos/"
)
// openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext.
func openRepositoryWithDefaultContext(repoPath string) (*git.Repository, error) {
return git.OpenRepository(git.DefaultContext, repoPath)
}
func TestGetNotes(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
require.NoError(t, err)
defer bareRepo1.Close()
note := Note{}
err = GetNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", &note)
note := git.Note{}
err = git.GetNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", &note)
require.NoError(t, err)
assert.Equal(t, []byte("Note contents\n"), note.Message)
assert.Equal(t, "Vladimir Panteleev", note.Commit.Author.Name)
@ -31,11 +44,11 @@ func TestGetNestedNotes(t *testing.T) {
require.NoError(t, err)
defer repo.Close()
note := Note{}
err = GetNote(context.Background(), repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", &note)
note := git.Note{}
err = git.GetNote(context.Background(), repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", &note)
require.NoError(t, err)
assert.Equal(t, []byte("Note 2"), note.Message)
err = GetNote(context.Background(), repo, "ba0a96fa63532d6c5087ecef070b0250ed72fa47", &note)
err = git.GetNote(context.Background(), repo, "ba0a96fa63532d6c5087ecef070b0250ed72fa47", &note)
require.NoError(t, err)
assert.Equal(t, []byte("Note 1"), note.Message)
}
@ -46,8 +59,48 @@ func TestGetNonExistentNotes(t *testing.T) {
require.NoError(t, err)
defer bareRepo1.Close()
note := Note{}
err = GetNote(context.Background(), bareRepo1, "non_existent_sha", &note)
note := git.Note{}
err = git.GetNote(context.Background(), bareRepo1, "non_existent_sha", &note)
require.Error(t, err)
assert.IsType(t, ErrNotExist{}, err)
assert.IsType(t, git.ErrNotExist{}, err)
}
func TestSetNote(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
tempDir, err := os.MkdirTemp("", "")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
require.NoError(t, unittest.CopyDir(bareRepo1Path, filepath.Join(tempDir, "repo1")))
bareRepo1, err := openRepositoryWithDefaultContext(filepath.Join(tempDir, "repo1"))
require.NoError(t, err)
defer bareRepo1.Close()
require.NoError(t, git.SetNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", "This is a new note", "Test", "test@test.com"))
note := git.Note{}
err = git.GetNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", &note)
require.NoError(t, err)
assert.Equal(t, []byte("This is a new note\n"), note.Message)
assert.Equal(t, "Test", note.Commit.Author.Name)
}
func TestRemoveNote(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
tempDir := t.TempDir()
require.NoError(t, unittest.CopyDir(bareRepo1Path, filepath.Join(tempDir, "repo1")))
bareRepo1, err := openRepositoryWithDefaultContext(filepath.Join(tempDir, "repo1"))
require.NoError(t, err)
defer bareRepo1.Close()
require.NoError(t, git.RemoveNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653"))
note := git.Note{}
err = git.GetNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", &note)
require.Error(t, err)
assert.IsType(t, git.ErrNotExist{}, err)
}

View file

@ -8,3 +8,7 @@ type Note struct {
Message string `json:"message"`
Commit *Commit `json:"commit"`
}
type NoteOptions struct {
Message string `json:"message"`
}

View file

@ -2622,6 +2622,9 @@ diff.browse_source = Browse source
diff.parent = parent
diff.commit = commit
diff.git-notes = Notes
diff.git-notes.add = Add Note
diff.git-notes.remove-header = Remove Note
diff.git-notes.remove-body = This will remove this Note
diff.data_not_available = Diff content is not available
diff.options_button = Diff options
diff.show_diff_stats = Show stats
@ -3837,8 +3840,8 @@ runs.actors_no_select = All actors
runs.status_no_select = All status
runs.no_results = No results matched.
runs.no_workflows = There are no workflows yet.
runs.no_workflows.quick_start = Don't know how to start with Forgejo Actions? See <a target="_blank" rel="noopener noreferrer" href="%s">the quick start guide</a>.
runs.no_workflows.documentation = For more information on Forgejo Actions, see <a target="_blank" rel="noopener noreferrer" href="%s">the documentation</a>.
runs.no_workflows.help_write_access = Don't know how to start with Forgejo Actions? Check out the <a target="_blank" rel="noopener noreferrer" href="%s">quick start in the user documentation</a> to write your first workflow, then <a target="_blank" rel="noopener noreferrer" href="%s">set up a Forgejo runner</a> to execute your jobs.
runs.no_workflows.help_no_write_access = To learn about Forgejo Actions, see <a target="_blank" rel="noopener noreferrer" href="%s">the documentation</a>.
runs.no_runs = The workflow has no runs yet.
runs.empty_commit_message = (empty commit message)
runs.expire_log_message = Logs have been purged because they were too old.

View file

@ -197,6 +197,12 @@ buttons.indent.tooltip = Sisennä yhden tason verran
buttons.quote.tooltip = Lainaa tekstiä
buttons.enable_monospace_font = Käytä tasalevyistä fonttia
buttons.ref.tooltip = Viittaa ongelmaa tai vetopyyntöä
buttons.new_table.tooltip = Lisää taulukko
table_modal.header = Lisää taulukko
table_modal.placeholder.header = Otsikko
table_modal.placeholder.content = Sisältö
table_modal.label.rows = Rivit
table_modal.label.columns = Sarakkeet
[filter]
string.asc = A - Ö
@ -246,7 +252,7 @@ err_empty_db_path=SQLite3-tietokannan polku ei voi olla tyhjä.
no_admin_and_disable_registration=Et voi kytkeä rekisteröintiä pois luomatta sitä ennen ylläpitotiliä.
err_empty_admin_password=Ylläpitäjän salasana ei voi olla tyhjä.
err_empty_admin_email=Ylläpitäjän sähköpostiosoite ei voi olla tyhjä.
err_admin_name_is_reserved=Ylläpitäjän käyttäjätunnus on virheellinen: käyttäjätunnus on varattu
err_admin_name_is_reserved=Ylläpitäjän käyttäjätunnus on virheellinen; käyttäjätunnus on varattu
err_admin_name_is_invalid=Ylläpitäjän käyttäjätunnus on virheellinen
general_title=Yleiset asetukset
@ -336,6 +342,7 @@ allow_dots_in_usernames = Salli pisteiden käyttö käyttäjänimissä. Ei vaiku
enable_update_checker = Ota päivitystentarkistus käyttöön
app_slogan = Instanssin tunnuslause
app_slogan_helper = Syötä instanssin tunnuslause tähän. Jätä tyhjäksi poistaaksesi käytöstä.
domain_helper = Palvelimen verkkotunnus tai isäntänimi.
[home]
uname_holder=Käyttäjätunnus tai sähköpostiosoite
@ -381,6 +388,7 @@ stars_few = %d tähteä
relevant_repositories = Vain relevantit repositoriot näytetään, <a href="%s">näytä suodattamattomat tulokset</a>.
forks_one = %d forkki
forks_few = %d forkkia
go_to = Siirry
[auth]
create_new_account=Rekisteröi tili
@ -418,7 +426,7 @@ twofa_scratch_token_incorrect=Kertakäyttökoodisi on virheellinen.
login_userpass=Kirjaudu sisään
tab_openid=OpenID
oauth_signup_tab=Rekisteröi uusi tili
oauth_signup_title=Viimeistele tili
oauth_signup_title=Viimeistele uusi tili
oauth_signup_submit=Viimeistele tili
oauth_signin_tab=Linkitä olemassa olevaan tiliin
oauth_signin_title=Kirjaudu sisään valtuuttaaksesi linkitetyn tilin
@ -452,8 +460,8 @@ activate_account=Ole hyvä ja aktivoi tilisi
activate_email=Vahvista sähköpostiosoitteesi
register_notify=Tervetuloa %san
register_notify.text_2=Voit nyt kirjautua käyttäjätunnuksella: %s.
register_notify=Tervetuloa %s-palveluun
register_notify.text_2=Voit nyt kirjautua tilillesi käyttäjätunnuksella: %s
reset_password=Palauta käyttäjätili
reset_password.title=%s, olet pyytänyt tilisi palauttamista
@ -478,6 +486,14 @@ password_change.text_1 = Tilisi salasana vaihdettiin juuri hetki sitten.
removed_security_key.subject = Turva-avain on poistettu
removed_security_key.text_1 = Turva-avain "%[1]s" on poistettu tililtäsi.
team_invite.text_2 = Napsauta seuraavaa linkkiä liittyäksesi tiimiin:
activate_account.text_1 = Hei <b>%[1]s</b>, kiitos kun rekisteröidyit palveluun %[2]s!
activate_account.text_2 = Aktivoidaksesi tilin, napsauta alla olevaa linkkiä aikaikkunan <b>%s</b> sisällä:
totp_disabled.subject = TOTP on poistettu käytöstä
primary_mail_change.subject = Ensisijainen sähköpostiosoitteesi on vaihdettu
admin.new_user.user_info = Käyttäjätiedot
activate_email.text = Vahvista sähköpostiosoitteesi napsauttamalla linkkiä aikaikkunan <b>%s</b> sisällä:
admin.new_user.subject = Uusi käyttäjä %s rekisteröityi juuri
register_notify.text_3 = Jos joku muu teki tämän tilin puolestasi, <a href="%s">aseta salasana</a> ensin.
@ -486,13 +502,14 @@ yes=Kyllä
no=Ei
cancel=Peruuta
modify=Päivitys
confirm = Vahvista
[form]
UserName=Käyttäjätunnus
RepoName=Repon nimi
Email=Sähköposti osoite
Password=Salasana
Retype=Varmista salasana
Retype=Vahvista salasana
SSHTitle=SSH avain nimi
HttpsUrl=HTTPS-osoite
TeamName=Tiimin nimi
@ -762,7 +779,7 @@ orgs_none=Et ole minkään organisaation jäsen.
delete_account=Poista tilisi
delete_prompt=Tämä toiminto poistaa käyttäjätilisi pysyvästi. Toimintoa <strong>EI VOI</strong> kumota.
confirm_delete_account=Varmista poisto
confirm_delete_account=Vahvista poisto
delete_account_title=Poista käyttäjätili
email_notifications.enable=Ota käyttöön sähköposti-ilmoitukset
@ -806,6 +823,8 @@ keep_activity_private.description = <a href="%s">Julkinen toimintasi</a> näkyy
email_desc = Ensisijaista sähköpostiosoitettasi käytetään ilmoituksiin, salasanan palautukseen ja jos sähköpostiosoite ei ole piilotettu, web-pohjaisiin Git-toimenpiteisiin.
tokens_desc = Nämä poletit mahdollistavat pääsyn tilillesi Forgejon rajapintaa vasten.
keep_email_private_popup = Tämä piilottaa sähköpostiosoitteesi profiilistasi. Se ei ole enää oletus verkkosivukäyttöliittymän kautta tehdyissä kommiteissa, kuten tiedostojen lähetyksissä ja muokkauksissa, eikä sitä käytetä yhdistämiskommiteissa. Sen sijaan erikoisosoitetta %s voidaan käyttää kommittien liittämisessä tiliisi. Ota huomioon, ettei tämän asetuksen muuttaminen vaikuta olemassa oleviin kommitteihin.
added_on = Lisätty %s
additional_repo_units_hint = Ehdota repositorion lisäyksiköiden käyttöönottoa
[repo]
owner=Omistaja
@ -827,7 +846,7 @@ download_zip=Lataa ZIP
download_tar=Lataa TAR.GZ
repo_desc=Kuvaus
repo_lang=Kieli
repo_gitignore_helper=Valitse .gitignore mallit.
repo_gitignore_helper=Valitse .gitignore-mallit
issue_labels=Ongelmien tunnisteet
issue_labels_helper=Valitse pohja ongelmien nimilapuille.
license=Lisenssi
@ -1120,7 +1139,7 @@ issues.push_commits_n=lisäsi %d committia %s
issues.due_date_form=vvvv-kk-pp
issues.due_date_form_edit=Muokkaa
issues.due_date_form_remove=Poista
issues.due_date_not_set=Määräpäivää ei asetettu.
issues.due_date_not_set=Määräpäivää ei ole asetettu.
issues.due_date_overdue=Myöhässä
issues.dependency.title=Riippuvuudet
issues.dependency.issue_no_dependencies=Riippuvuuksia ei asetettu.
@ -1795,6 +1814,18 @@ migrate.codebase.description = Tee migraatio codebasehq.comista.
migrate.git.description = Tee repomigraatio mistä tahansa Git-palvelusta.
migrate.gitlab.description = Tee migraatio gitlab.comista tai muista GitLab-instansseista.
migrate.gitea.description = Tee migraatio gitea.comista tai muista Gitea-instansseista.
repo_gitignore_helper_desc = Valitse mitä tiedostoja ei seurata yleisimpien kielten mallipohjista. Tyypilliset artefaktit, joita eri kielten koostamistyökalut tuottavat, lisätään .gitignore-tiedostoon oletusarvoisesti.
milestones.filter_sort.latest_due_date = Kaukaisin määräpäivä
license_helper_desc = Lisenssi määrää, mitä muut voivat ja eivät voi tehdä koodillasi. Etkö ole varma, mikä lisenssi soveltuu projektillesi? Lue <a target="_blank" rel="noopener noreferrer" href="%s">ohje lisenssin valinnasta.</a>
milestones.filter_sort.earliest_due_data = Lähin määräpäivä
issues.filter_type.reviewed_by_you = Katselmoitu toimestasi
settings.units.overview = Yleisnäkymä
settings.remove_team_success = Tiimin pääsy repositorioon on poistettu.
migrate.cancel_migrating_confirm = Haluatko perua tämän migraation?
settings.units.units = Yksiköt
settings.update_settings_no_unit = Repositorion tulisi sallia edes jonkinlainen vuorovaikutus.
settings.units.add_more = Ota lisää käyttöön
settings.add_team_success = Tiimillä on nyt pääsy repositorioon.
@ -1897,6 +1928,9 @@ code = Koodi
teams.remove_all_repos_title = Poista kaikki tiimin repot
form.name_reserved = Organisaation nimi "%s" on varattu.
settings.delete_org_desc = Organisaatio poistetaan pysyvästi. Jatketaanko?
team_access_desc = Repositorion käyttö
teams.specific_repositories = Määritetyt repositoriot
open_dashboard = Avaa kojelauta
[admin]
dashboard=Kojelauta
@ -2248,6 +2282,7 @@ create_branch=loi haaran <a href="%[2]s">%[3]s</a> repossa <a href="%[1]s">%[4]s
compare_commits = Vertaa %d kommittia
compare_branch = Vertaa
review_dismissed_reason = Syy:
commit_repo = työnsi haaraan <a href="%[2]s">%[3]s</a> repossa <a href="%[1]s">%[4]s</a>
[tool]
now=nyt
@ -2294,6 +2329,7 @@ error.extract_sign = Allekirjoituksen purkaminen epäonnistui
default_key = Allekirjoitettu oletusavaimella
[units]
unit = Yksikkö
[packages]
title=Paketit
@ -2390,6 +2426,10 @@ conda.install = Asenna paketti Condalla suorittamalla seuraava komento:
helm.registry = Määritä tämä rekisteri komentoriviltä:
pub.install = Asenna paketti Dartilla suorittamalla seuraava komento:
owner.settings.cargo.title = Cargon rekisteri-indeksi
settings.delete.description = Paketin poistaminen on peruuttamaton toimenpide, sitä ei voi perua.
settings.link.success = Repositorion linkki päivitettiin onnistuneesti.
settings.link.button = Päivitä repositorion linkki
owner.settings.cleanuprules.preview.overview = %d pakettia on ajastettu poistettavaksi.
[secrets]
creation.failed = Salaisuuden lisääminen epäonnistui.
@ -2402,6 +2442,7 @@ deletion.failed = Salaisuuden poistaminen epäonnistui.
secrets = Salaisuudet
deletion.description = Salaisuuden poistaminen on pysyvä toimenpide, eikä sitä voi perua. Jatketaanko?
deletion.success = Salaisuus on poistettu.
description = Salaisuudet välitetään tietyille toimenpiteille, eikä niitä voi muuten lukea.
[actions]
@ -2489,6 +2530,8 @@ workflow.disable = Poista työnkulku käytöstä
workflow.disable_success = Työnkulku "%s" on poistettu käytöstä.
runs.no_job = Työnkulun tulee sisältää vähintään yksi työ
runs.invalid_workflow_helper = Työnkulun asetustiedosto on virheellinen. Tarkista asetustiedosto: %s
runners = Ajajat
actions = Toimenpiteet
@ -2532,4 +2575,5 @@ issue_kind = Etsi ongelmia...
milestone_kind = Etsi merkkipaaluja...
pull_kind = Etsi pull-vetoja...
commit_kind = Etsi kommitteja...
fuzzy = Sumea
fuzzy = Sumea
runner_kind = Etsi ajajia...

View file

@ -2778,7 +2778,7 @@ issues.archived_label_description = (アーカイブ済) %s
settings.web_hook_name_sourcehut_builds = SourceHut Builds
settings.matrix.room_id_helper = ルームIDは、Element web clientのRoom Settings > Advanced > Internal room IDから取得できます。例%s。
pulls.merged_title_desc_one = %[4]s の <code>%[2]s</code> から %[1]d 件のコミットを <code>%[3]s</code> へマージした
pulls.title_desc_one = <code id="%[4]s">%[3]s</code> から %[1]d 件のコミットを <code>%[2]s</code> へマージしたい
pulls.title_desc_one = <code>%[2]s</code>から %[1]d 件のコミットを <code id="%[4]s">%[3]s</code> へマージしたい
pulls.ready_for_review = レビューの準備ができていますか?
settings.transfer.button = 所有権を移送する
settings.transfer.modal.title = 所有権を移送

View file

@ -1942,9 +1942,9 @@ activity.title.unresolved_conv_n=%d neatrisinātas diskusijas
activity.unresolved_conv_desc=Saraksts ar visām problēmām un izmaiņu pieprasījumiem, kas nesen mainīti un vēl nav atrisināti.
activity.unresolved_conv_label=Atvērts
activity.title.releases_1=%d versiju
activity.title.releases_n=%d versijas
activity.title.releases_n=%d laidieni
activity.title.releases_published_by=%s publicēja %s
activity.published_release_label=Publicēts
activity.published_release_label=Laidiens
activity.no_git_activity=Šajā laika periodā nav notikušas nekādas izmaiņas.
activity.git_stats_exclude_merges=Neskaitot sapludināšanas revīzijas,
activity.git_stats_author_1=%d autors
@ -1990,9 +1990,9 @@ settings.collaboration.read=Skatīšanās
settings.collaboration.owner=Īpašnieks
settings.collaboration.undefined=Nedefinētas
settings.hooks=Tīmekļa āķi
settings.githooks=Git āķi
settings.githooks=Git aizķeres
settings.basic_settings=Pamatiestatījumi
settings.mirror_settings=Spoguļa iestatījumi
settings.mirror_settings=Spoguļservera iestatījumi
settings.mirror_settings.docs=Iestatiet, ka tiks viekta automātiska revīziju, tagu un atzaru sinhronizācija ar citu repozitoriju.
settings.mirror_settings.docs.disabled_pull_mirror.instructions=Iestatiet, ka visas revīzijas, tagi un atzari tiks automātiski nosūtītu uz citu repozitoriju. Izgūšanas spoguļus administrators ir aizliedzis izmantot.
settings.mirror_settings.docs.disabled_push_mirror.instructions=Iestatiet, ka visas revīzijas, tagi un atzari tiks automātiski pārņemti no cita repozitorija.
@ -2011,35 +2011,35 @@ settings.mirror_settings.direction.pull=Izmaiņu saņemšana
settings.mirror_settings.direction.push=Izmaiņu nosūtīšana
settings.mirror_settings.last_update=Pēdējās izmaiņas
settings.mirror_settings.push_mirror.none=Nav konfigurēts iesūtīšanas spogulis
settings.mirror_settings.push_mirror.remote_url=Git attālinātā repozitorija URL
settings.mirror_settings.push_mirror.add=Pievienot iesūtīšanas spoguli
settings.mirror_settings.push_mirror.remote_url=Git attālās glabātavas URL
settings.mirror_settings.push_mirror.add=Pievienot aizgādāšanas spoguļserveri
settings.mirror_settings.push_mirror.edit_sync_time=Labot spoguļa sinhronizācijas intervālu
settings.sync_mirror=Sinhronizēt tagad
settings.pull_mirror_sync_in_progress=Pašlaik tiek saņemtas izmaiņas no attālā %s.
settings.push_mirror_sync_in_progress=Pašlaik tiek piegādātas izmaiņas uz attālo %s.
settings.site=Mājas lapa
settings.update_settings=Mainīt iestatījumus
settings.update_mirror_settings=Atjaunot spoguļa iestatījumus
settings.branches.switch_default_branch=Mainīt noklusēto atzaru
settings.branches.update_default_branch=Atjaunot noklusēto atzaru
settings.branches.add_new_rule=Pievienot jaunu noteikumu
settings.update_settings=Saglabāt iestatījumus
settings.update_mirror_settings=Atjaunināt spoguļservera iestatījumus
settings.branches.switch_default_branch=Mainīt noklusējuma zaru
settings.branches.update_default_branch=Atjaunināt noklusējuma zaru
settings.branches.add_new_rule=Pievienot jaunu kārtulu
settings.advanced_settings=Papildu iestatījumi
settings.wiki_desc=Iespējot vikivietnes
settings.wiki_desc=Iespējot glabātavas vikivietni
settings.use_internal_wiki=Izmantot iebūvēto vikivietni
settings.use_external_wiki=Izmantot ārējo vikivietni
settings.external_wiki_url=Ārējās Vikivietnes adrese
settings.use_external_wiki=Izmantot ārēju vikivietni
settings.external_wiki_url=Ārējās vikivietnes URL
settings.external_wiki_url_error=Ārējās vikivietnes URL nav korekts URL.
settings.external_wiki_url_desc=Apmeklētāji tiks novirzīti uz ārējās vikivietnes adresi, kad uzklikšķinās uz cilnes.
settings.issues_desc=Iespējot iebūvēto problēmu sekotāju
settings.use_internal_issue_tracker=Izmantot iebūvēto problēmu sekotāju
settings.use_external_issue_tracker=Izmantot ārējo problēmu sekotāju
settings.external_tracker_url=Ārējā problēmu reģistra URL
settings.issues_desc=Iespējot glabātavas pieteikumu izsekotāju
settings.use_internal_issue_tracker=Izmantot iebūvēto pieteikumu izsekotāju
settings.use_external_issue_tracker=Izmantot ārēju pieteikumu izsekotāju
settings.external_tracker_url=Ārējā pieteikumu izsekotāja URL
settings.external_tracker_url_error=Nekorekts ārējā problēmu sekotāja URL.
settings.external_tracker_url_desc=Apmeklētāji tiks novirzīti uz ārējā problēmu sekotāja adresi, kad uzklikšķinās uz cilnes.
settings.tracker_url_format=Ārējā problēmu sekotāja adreses formāts
settings.tracker_url_format=Ārējā pieteikumu izsekotāja URL veidols
settings.tracker_url_format_error=Ārējā problēmu sekotāja URL formāts nav korekts URL.
settings.tracker_issue_style=Ārējā problēmu sekotāja numura formāts
settings.tracker_issue_style=Ārējā pieteikumu izsekotājas numuru veidols
settings.tracker_issue_style.numeric=Cipari
settings.tracker_issue_style.alphanumeric=Burti un cipari
settings.tracker_issue_style.regexp=Regulārā izteiksme
@ -2047,37 +2047,37 @@ settings.tracker_issue_style.regexp_pattern=Regulārās izteiksmes šablons
settings.tracker_issue_style.regexp_pattern_desc=Pirmā iegultā grupa tiks izmantota <code>{index}</code> vietā.
settings.tracker_url_format_desc=Jūs varat izmantot <code>{user}</code>, <code>{repo}</code> un <code>{index}</code> lietotājvārdam, repozitorija nosaukumam un problēmas identifikatoram.
settings.enable_timetracker=Iespējot laika uzskaiti
settings.allow_only_contributors_to_track_time=Atļaut tikai dalībniekiem uzskaitīt laiku
settings.pulls_desc=Iespējot repozitorija izmaiņu pieprasījumus
settings.pulls.ignore_whitespace=Pārbaudot konfliktus, ignorēt izmaiņas atstarpēs
settings.allow_only_contributors_to_track_time=Atļaut uzskaitīt laiku tikai līdzdalībniekiem
settings.pulls_desc=Iespējot glabātavas izmaiņu pieprasījumus
settings.pulls.ignore_whitespace=Nesaderību noteikšanā neņemt vērā atstarpes
settings.pulls.enable_autodetect_manual_merge=Iespējot manuālas sapludināšanas noteikšanu (Piezīme: dažos speciālos gadījumos, tas var nostrādāt nekorekti)
settings.pulls.allow_rebase_update=Iespējot izmaiņu pieprasījuma atjaunošanu ar pārbāzēšanu
settings.pulls.default_delete_branch_after_merge=Pēc noklusējuma dzēst izmaiņu pieprasījuma atzaru pēc sapludināšanas
settings.pulls.default_allow_edits_from_maintainers=Atļaut uzturētājiem labot pēc noklusējuma
settings.releases_desc=Iespējot repozitorija laidienus
settings.packages_desc=Iespējot repozitorija pakotņu reģistru
settings.projects_desc=Iespējot repozitorija projektus
settings.actions_desc=Iespējot repozitorija darbības
settings.admin_settings=Administratora iestatījumi
settings.admin_enable_health_check=Iespējot veselības pārbaudi (git fsck) šim repozitorijam
settings.admin_code_indexer=Izejas koda indeksētājs
settings.admin_stats_indexer=Izejas koda statistikas indeksētājs
settings.admin_indexer_commit_sha=Pēdējā indeksētā revīzija
settings.releases_desc=Iespējot glabātavas laidienus
settings.packages_desc=Iespējot glabātavas pakotņu reģistru
settings.projects_desc=Iespējot glabātavas projektus
settings.actions_desc=Iespējot iekļautos CI/CD cauruļvadus ar Forgejo darbībām
settings.admin_settings=Pārvaldītāja iestatījumi
settings.admin_enable_health_check=Iespējot glabātavas darbspējas pārbaudes (git fsck)
settings.admin_code_indexer=Koda indeksētājs
settings.admin_stats_indexer=Koda statistikas indeksētājs
settings.admin_indexer_commit_sha=Pēdējais indeksētais iesūtījums
settings.admin_indexer_unindexed=Neindeksēts
settings.reindex_button=Pievienot pārindeksēšanas rindai
settings.reindex_requested=Pieprasīta pārindeksēšana
settings.admin_enable_close_issues_via_commit_in_any_branch=Aizvērt problēmu ar izmaiņu komentāru iesūtītu jebkurā atzarā
settings.danger_zone=Bīstamā zona
settings.danger_zone=Bīstamais apgabals
settings.new_owner_has_same_repo=Jaunajam īpašniekam jau ir repozitorijs ar šādu nosaukumu.
settings.convert=Konvertēt uz parastu repozitoriju
settings.convert=Pārveidot par parastu glabātavu
settings.convert_desc=Jūs varat nomainīt šo spoguli uz parastu repozitoriju. Šī darbība ir neatgriezeniska.
settings.convert_notices_1=Šī darbība mainīs spoguli uz parastu repozitoriju un ir neatgriezeniska.
settings.convert_confirm=Konvertēt repozitoriju
settings.convert_confirm=Pārveidot glabātavu
settings.convert_succeed=Spogulis tika izmainīts par parastu repozitoriju.
settings.convert_fork=Konvertēt uz parastu repozitoriju
settings.convert_fork=Pārveidot par parastu glabātavu
settings.convert_fork_desc=Jūs varat nomainīt šo atdalīto repozitoriju kā neatkarīgu repozitoriju. Šī darbība ir neatgriezeniska.
settings.convert_fork_notices_1=Šī darbība mainīs atdalīto repozitoriju uz neatkarīgu repozitoriju un ir neatgriezeniska.
settings.convert_fork_confirm=Konvertēt repozitoriju
settings.convert_fork_confirm=Pārveidot glabātavu
settings.convert_fork_succeed=Atdalītais repozitorijs tika izmainīts par neatkarīgu repozitoriju.
settings.transfer.title=Mainīt īpašnieku
settings.transfer.rejected=Repozitorija īpašnieka maiņas pieprasījums tika noraidīts.
@ -2092,11 +2092,11 @@ settings.transfer_notices_1=- Tiks zaudēta piekļuve repozitorijam, ja jaunais
settings.transfer_notices_2=- Tiks saglabāta piekļuve, ja jaunais īpašnieks ir organizācija un esat viens no tās īpašniekiem.
settings.transfer_notices_3=- Ja repozitorijs ir privāts un tas tiks pārsūtīts lietotājam, tad pārliecināties, ka lietotājam ir vismaz skatīšanās tiesības (veiciet nepieciešamās izmaiņas, ja nepieciešams).
settings.transfer_owner=Jaunais īpašnieks
settings.transfer_perform=Veikt īpašnieka maiņu
settings.transfer_perform=Veikt nodošanu
settings.transfer_started=`Šim repozitorijam tiek veikta īpašnieka maiņa un nepieciešams apstiprinājums no "%s"`
settings.transfer_succeed=Repozitorijs tika pārcelts.
settings.signing_settings=Parakstu pārbaudes iestatījumi
settings.trust_model=Uzticēšanās modelis parakstiem
settings.signing_settings=Parakstu apliecināšanas iestatījumi
settings.trust_model=Parakstu uzticēšanās modelis
settings.trust_model.default=Noklusējuma uzticēšanās modelis
settings.trust_model.default.desc=Izmantot noklusēto repozitoriju uzticības modeli.
settings.trust_model.collaborator=Līdzstrādnieka
@ -2108,12 +2108,12 @@ settings.trust_model.committer.desc=Derīgi paraksti tiks atzīmēti kā "uztica
settings.trust_model.collaboratorcommitter=Līdzstrādnieka un revīzijas iesūtītāja
settings.trust_model.collaboratorcommitter.long=Līdzstrādnieka un revīzijas iesūtītāja: Uzticēties līdzstrādnieku parakstiem, kas atbilst revīzijas iesūtītājam
settings.trust_model.collaboratorcommitter.desc=Derīgi līdzstrādnieku paraksti tiks atzīmēti kā "uzticami", ja tie atbilst revīzijas iesūtītājam, citos gadījumos tie tiks atzīmēti kā "neuzticami", ja paraksts atbilst revīzijas iesūtītajam, vai "nesakrītoši", ja neatbilst. Šis nozīmē, ka Forgejo būs kā revīzijas iesūtītājs parakstītām revīzijām, kur īstais revīzijas iesūtītājs tiks atīzmēts revīzijas komentāra beigās ar tekstu Co-Authored-By: un Co-Committed-By:. Noklusētajai Forgejo atslēgai ir jāatbilst lietotājam datubāzē.
settings.wiki_delete=Dzēst vikivietnes datus
settings.wiki_delete=Izdzēst vikivietnes datus
settings.wiki_delete_desc=Vikivietnes repozitorija dzēšana ir neatgriezeniska un nav atsaucama.
settings.wiki_delete_notices_1=- Šī darbība dzēsīs un atspējos repozitorija %s vikivietni.
settings.confirm_wiki_delete=Dzēst vikivietnes datus
settings.confirm_wiki_delete=Izdzēst vikivietnes datus
settings.wiki_deletion_success=Repozitorija vikivietnes dati tika izdzēsti.
settings.delete=Dzēst šo repozitoriju
settings.delete=Izdzēst šo glabātavu
settings.delete_desc=Repozitorija dzēšana ir neatgriezeniska un nav atsaucama.
settings.delete_notices_1=- Šī darbība ir <strong>NEATGRIEZENISKA</strong>.
settings.delete_notices_2=- Šī darbība neatgriezeniski izdzēsīs visu repozitorijā <strong>%s</strong>, tai skaitā problēmas, komentārus, vikivietni un līdzstrādnieku piesaisti.
@ -2121,8 +2121,8 @@ settings.delete_notices_fork_1=- Visi atdalītie repozitoriju pēc dzēšanas k
settings.deletion_success=Repozitorijs tika izdzēsts.
settings.update_settings_success=Repozitorija iestatījumi tika saglabāti.
settings.update_settings_no_unit=Repozitorijam ir jābūt piešķirtām vismaz kādām tiesībām.
settings.confirm_delete=Dzēst repozitoriju
settings.add_collaborator=Pievienot līdzstrādnieku
settings.confirm_delete=Izdzēst glabātavu
settings.add_collaborator=Pievienot līdzdalībnieku
settings.add_collaborator_success=Jauns līdzstrādnieks tika pievienots.
settings.add_collaborator_inactive_user=Nevar pievienot neaktīvu lietotāju kā līdzstrādnieku.
settings.add_collaborator_owner=Nevar pievienot īpašnieku kā līdzstrādnieku.
@ -2143,13 +2143,13 @@ settings.search_team=Meklēt komandu…
settings.change_team_permission_tip=Komandas tiesības tiek uzstādītas komandas iestatījumu lapā un nevar tikt individuāli mainītas katram repozitorijam atsevišķi
settings.delete_team_tip=Komandai ir piekļuve visiem repozitorijiem un tā nevar tikt noņemta individuāli
settings.remove_team_success=Komandas piekļuve šim repozitorijam ir noņemta.
settings.add_webhook=Pievienot tīmekļa āķi
settings.add_webhook=Pievienot tīmekļa aizķeri
settings.add_webhook.invalid_channel_name=Tīmekļa āķa kanāla nosaukums nevar būt tukšs vai saturēt tikai # simbolu.
settings.hooks_desc=Tīmekļa āķi ļauj paziņot ārējiem servisiem par noteiktiem notikumiem, kas notiek Forgejo. Kad iestāsies kāds notikums, katram ārējā servisa URL tiks nosūtīts POST pieprasījums. Lai uzzinātu sīkāk skatieties <a target="_blank" rel="noopener noreferrer" href="%s">tīmekļa āķu rokasgrāmatā</a>.
settings.webhook_deletion=Noņemt tīmekļa āķi
settings.webhook_deletion=Noņemt tīmekļa aizķeri
settings.webhook_deletion_desc=Noņemot tīmekļa āķi, tiks dzēsti visi tā iestatījumi un piegādes vēsture. Vai turpināt?
settings.webhook_deletion_success=Tīmekļa āķis tika noņemts.
settings.webhook.test_delivery=Testa piegāde
settings.webhook.test_delivery=Izmēģināt piegādi
settings.webhook.test_delivery_desc=Veikt viltus push-notikuma piegādi, lai notestētu Jūsu tīmekļa āķa iestatījumus.
settings.webhook.test_delivery_desc_disabled=Lai pārbaudītu šo tīmekļa āķi ar neīstu notikumu, tas ir jāiespējo.
settings.webhook.request=Pieprasījums
@ -2160,11 +2160,11 @@ settings.webhook.body=Saturs
settings.webhook.replay.description=Izpildīt atkārtoti šo tīmekļa āķi.
settings.webhook.replay.description_disabled=Lai atkārtoti izpildītu šo tīmekļa āķi, tas ir jāiespējo.
settings.webhook.delivery.success=Notikums tika veiksmīgi pievienots piegādes rindai. Var paiet vairākas sekundes līdz tas parādās piegādes vēsturē.
settings.githooks_desc=Git āķus apstrādā pats Git. Jūs varat labot atbalstīto āku failus sarakstā zemāk, lai veiktu pielāgotas darbības.
settings.githooks_desc=Git aizķeres apstrādā pats Git. Zemāk var labot aizķeru datnes, lai uzstādītu pielāgotas darbības.
settings.githook_edit_desc=Ja āķis nav aktīvs, tiks attēlots piemērs kā to izmantot. Atstājot āķa saturu tukšu, tas tiks atspējots.
settings.githook_name=Āķa nosaukums
settings.githook_content=Āķa saturs
settings.update_githook=Labot āķi
settings.githook_name=Aizķeres nosaukums
settings.githook_content=Aizķeres saturs
settings.update_githook=Atjaunināt aizķeri
settings.add_webhook_desc=Uz norādīto URL tiks nosūtīts <code>POST</code> pieprasījums ar notikuma datiem. Detalizētāku informāciju ir iespējams uzzināt <a target="_blank" rel="noopener noreferrer" href="%s">tīmekļa āķu rokasgrāmatā</a>.
settings.payload_url=Saņēmēja URL
settings.http_method=HTTP metode
@ -2330,7 +2330,7 @@ settings.delete_protected_branch=Atspējot aizsargāšanu
settings.update_protect_branch_success=Atzara aizsardzības nosacījums "%s" tika saglabāta.
settings.remove_protected_branch_success=Atzara aizsardzības nosacījums "%s" tika noņemts.
settings.remove_protected_branch_failed=Neizdevās izdzēst atzara aizsardzības nosacījumu "%s".
settings.protected_branch_deletion=Atspējot atzara aizsardzību
settings.protected_branch_deletion=Izdzēst zara aizsardzību
settings.protected_branch_deletion_desc=Atspējojot atzara aizsardzību, ļaus lietotājiem ar rakstīšanas tiesībām nosūtīt izmaiņas uz atzaru. Vai turpināt?
settings.block_rejected_reviews=Neļaut sapludināt izmaiņu pieprasījumus, kam ir pieprasītas izmaiņas
settings.block_rejected_reviews_desc=Sapludināšana nebūs iespējama, kad ir pieprasītas izmaiņas, pat ja ir nepieciešamais apstiprinājumu skaits.
@ -2339,32 +2339,32 @@ settings.block_on_official_review_requests_desc=Sapludināšana nebūs iespējam
settings.block_outdated_branch=Bloķēt sapludināšanau, ja izmaiņu pieprasījums ir novecojis
settings.block_outdated_branch_desc=Sapludināšana nebūs pieejama, ja atzars būs atpalicis no bāzes atzara.
settings.default_branch_desc=Norādiet noklusēto repozitorija atzaru izmaiņu pieprasījumiem un koda revīzijām:
settings.merge_style_desc=Sapludināšanas veidi
settings.default_merge_style_desc=Noklusētais sapludināšanas veids izmaiņu pieprasījumiem:
settings.merge_style_desc=Apvienošanas veidi
settings.default_merge_style_desc=Noklusējuma apvienošanas veids
settings.choose_branch=Izvēlieties atzaru…
settings.no_protected_branch=Nav neviena aizsargātā atzara.
settings.edit_protected_branch=Labot
settings.protected_branch_required_rule_name=Nav norādīts noteikuma nosaukums
settings.protected_branch_duplicate_rule_name=Dublējošs noteikuma nosaukumu
settings.protected_branch_duplicate_rule_name=Šai zaru kopai jau pastāv kārtula
settings.protected_branch_required_approvals_min=Pieprasīto recenziju skaits nevar būt negatīvs.
settings.tags=Tagi
settings.tags.protection=Tagu aizsargāšana
settings.tags.protection.pattern=Tagu šablons
settings.tags.protection=Birku aizsargāšana
settings.tags.protection.pattern=Birku paraugs
settings.tags.protection.allowed=Atļauts
settings.tags.protection.allowed.users=Atļauts lietotājiem
settings.tags.protection.allowed.teams=Atļauts komandām
settings.tags.protection.allowed.noone=Nevienam
settings.tags.protection.create=Aizsargāt tagus
settings.tags.protection.create=Pievienot kārtulu
settings.tags.protection.none=Nav uzstādīta tagu aizsargāšana.
settings.tags.protection.pattern.description=Var izmantot vienkāršu nosaukumu vai glob šablonu, vai regulāro izteiksmi, lai atbilstu vairākiem tagiem. Vairāk ir lasāms <a target="_blank" rel="noopener" href="%s">aizsargāto tagu šablonu dokumentācijā</a>.
settings.bot_token=Bota pilnvara
settings.bot_token=Robotprogrammatūras pilnvara
settings.chat_id=Tērzēšanas ID
settings.thread_id=Pavediena ID
settings.matrix.homeserver_url=Mājas servera URL
settings.matrix.room_id=Istabas ID
settings.matrix.message_type=Ziņas veids
settings.archive.button=Arhivēt
settings.archive.header=Arhivēt repozitoriju
settings.matrix.message_type=Ziņojuma veids
settings.archive.button=Arhivēt glabātavu
settings.archive.header=Arhivēt šo glabātavu
settings.archive.text=Repozitorija arhivēšana padarīs to tikai lasāmu. Tas nebūs redzams infopanelī. Neviens nevarēs izveidot jaunas revīzijas vai atvērt jaunus problēmu pieteikumus vai izmaiņu pieprasījumus.
settings.archive.success=Repozitorijs veiksmīgi arhivēts.
settings.archive.error=Arhivējot repozitoriju radās neparedzēta kļūda. Pārbaudiet kļūdu žurnālu, lai uzzinātu sīkāk.
@ -2381,10 +2381,10 @@ settings.lfs=LFS
settings.lfs_filelist=LFS faili, kas saglabāti šajā repozitorijā
settings.lfs_no_lfs_files=Šajā repozitorijā nav saglabāts neviens LFS fails
settings.lfs_findcommits=Atrast revīzijas
settings.lfs_lfs_file_no_commits=Šim LFS failam netika atrasta neviena revīzija
settings.lfs_lfs_file_no_commits=Šai LFS datnei netika atrasts neviens iesūtījums
settings.lfs_noattribute=Norādītājam ceļam nav bloķēšanas atribūta noklusētajā atzarā
settings.lfs_delete=Dzēst LFS failu ar OID %s
settings.lfs_delete_warning=Dzēšot LFS failu, tas var izraisīt kļūdu 'object does not exist' veicot git izmaiņu saņemšanu. Vai vēlaties turpināt?
settings.lfs_delete_warning=LFS datnes izdzēšana var izraisīt kļūdu "object does not exist" veicot paņemšanu. Tiešām izdzēst?
settings.lfs_findpointerfiles=Atrast norāžu failus
settings.lfs_locks=Bloķēšanas
settings.lfs_invalid_locking_path=Nekorekts ceļš: %s
@ -2392,13 +2392,13 @@ settings.lfs_invalid_lock_directory=Nevar bloķēt direktoriju: %s
settings.lfs_lock_already_exists=Fails vai direktorija jau ir bloķēta: %s
settings.lfs_lock=Bloķēt
settings.lfs_lock_path=Faila ceļš, ko bloķēt...
settings.lfs_locks_no_locks=Nav bloķēts neviens fails
settings.lfs_locks_no_locks=Nav slēdzeņu
settings.lfs_lock_file_no_exist=Bloķējamais fails neeksistē noklusētajā atzarā
settings.lfs_force_unlock=Piespiedu atbloķēšana
settings.lfs_force_unlock=Piespiedu atslēgšana
settings.lfs_pointers.found=Atrasta(s) %d binārā objekta norāde(s) - %d saistītas, %d nesaistītas (%d trūkstošas glabātuvē)
settings.lfs_pointers.sha=Binārā objekta SHA
settings.lfs_pointers.sha=Binārā objekta jaucējkods
settings.lfs_pointers.oid=OID
settings.lfs_pointers.inRepo=Repozitorijā
settings.lfs_pointers.inRepo=Glabātavā
settings.lfs_pointers.exists=Eksistē glabātuvē
settings.lfs_pointers.accessible=Pieejams lietotājam
settings.lfs_pointers.associateAccessible=Saistīt pieejamos %d OID'us
@ -2409,16 +2409,16 @@ settings.rename_branch_from=no vecā atzara nosaukuma
settings.rename_branch_to=jaunais atzara nosaukums
settings.rename_branch=Pārsaukt atzaru
diff.browse_source=Pārlūkot izejas kodu
diff.browse_source=Pārlūkot avotu
diff.parent=vecāks
diff.commit=revīzija
diff.git-notes=Piezīmes
diff.data_not_available=Satura salīdzināšana nav pieejama
diff.options_button=Salīdzināšanas iespējas
diff.show_diff_stats=Rādīt statistiku
diff.download_patch=Lejupielādēt ielāpa failu
diff.download_diff=Lejupielādēt izmaiņu failu
diff.show_split_view=Dalītais skats
diff.download_patch=Lejupielādēt ielāpa datni
diff.download_diff=Lejupielādēt atšķirību datni
diff.show_split_view=Sadalītais skats
diff.show_unified_view=Apvienotais skats
diff.whitespace_button=Atstarpes
diff.whitespace_show_everything=Rādīt visas izmaiņas
@ -2429,7 +2429,7 @@ diff.stats_desc=<strong>%d mainīti faili</strong> ar <strong>%d papildinājumie
diff.stats_desc_file=%d izmaiņas: %d pievienotas un %d dzēstas
diff.bin=Binārs
diff.bin_not_shown=Bināro failu nav iespējams attēlot.
diff.view_file=Parādīt failu
diff.view_file=Apskatīt datni
diff.file_before=Pirms
diff.file_after=Pēc
diff.file_image_width=Platums
@ -2438,18 +2438,18 @@ diff.file_byte_size=Izmērs
diff.file_suppressed=Failā izmaiņas netiks attēlotas, jo tās ir par lielu
diff.file_suppressed_line_too_long=Faila izmaiņas netiek rādītas, jo viena vai vairākas līnijas ir pārāk garas
diff.too_many_files=Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels
diff.show_more=Rādīt vairāk
diff.load=Ielādēt izmaiņas
diff.show_more=Parādīt vairāk
diff.load=Ielādēt atšķirības
diff.generated=ģenerēts
diff.vendored=ārējs
diff.comment.add_line_comment=Pievienot rindas komentāru
diff.comment.placeholder=Ievadiet komentāru
diff.comment.markdown_info=Tiek atbalstīta formatēšana ar Markdown.
diff.comment.markdown_info=Tiek nodrošināta formatēšana ar Markdown.
diff.comment.add_single_comment=Pievienot vienu komentāru
diff.comment.add_review_comment=Pievienot komentāru
diff.comment.start_review=Sākt recenziju
diff.comment.reply=Atbildēt
diff.review=Recenzija
diff.review=Pabeigt izskatīšanu
diff.review.header=Iesūtīt recenziju
diff.review.placeholder=Recenzijas komentārs
diff.review.comment=Komentēt
@ -2472,14 +2472,14 @@ release.detail=Laidiena papildus informācija
release.tags=Tagi
release.new_release=Jauns laidiens
release.draft=Melnraksts
release.prerelease=Pirmsizlaides versija
release.prerelease=Pirmslaidiens
release.stable=Stabila
release.compare=Salīdzināt
release.edit=labot
release.edit=Labot
release.ahead.commits=<strong>%d</strong> revīzijas
release.ahead.target=no %s kopš laidiena publicēšanas
tag.ahead.target=revīzijas atzarā %s no šī taga izveidošanas
release.source_code=Izejas kods
release.source_code=Pirmkods
release.new_subheader=Laidieni palīdz organizēt projekta versijas.
release.edit_subheader=Laidieni palīdz organizēt projekta versijas.
release.tag_name=Taga nosaukums
@ -2490,15 +2490,15 @@ release.tag_helper_existing=Esošs tags.
release.title=Laidiena nosaukums
release.title_empty=Nosaukums nevar būt tukšs.
release.message=Aprakstiet šo laidienu
release.prerelease_desc=Atzīmēt kā pirmslaidiena versiju
release.prerelease_desc=Atzīmēt kā pirmslaidienu
release.prerelease_helper=Atzīmēt, ka šo laidienu nav ieteicams lietot produkcijā.
release.cancel=Atcelt
release.publish=Publicēt laidienu
release.publish=Laist klajā laidienu
release.save_draft=Saglabāt melnrakstu
release.edit_release=Labot laidienu
release.delete_release=Dzēst laidienu
release.delete_tag=Dzēst tagu
release.deletion=Dzēst laidienu
release.edit_release=Atjaunināt laidienu
release.delete_release=Izdzēst laidienu
release.delete_tag=Izdzēst birku
release.deletion=Izdzēst laidienu
release.deletion_desc=Laidiena izdzēšana tikai noņem to no Gitea. Tā neietekmēs Git tagu, repozitorija saturu vai vēsturi. Vai turpināt?
release.deletion_success=Laidiens tika izdzēsts.
release.deletion_tag_desc=Tiks izdzēsts tags no repozitorija. Repozitorija saturs un vēsture netiks mainīta. Vai turpināt?
@ -2510,15 +2510,15 @@ release.tag_already_exist=Tags ar šādu nosaukumu jau eksistē.
release.downloads=Lejupielādes
release.download_count=Lejupielādes: %s
release.add_tag_msg=Izmantot laidiena nosaukumu un saturu kā taga aprakstu.
release.add_tag=Izveidot tikai tagu
release.add_tag=Izveidot birku
release.releases_for=Repozitorja %s laidieni
release.tags_for=Repozitorija %s tagi
branch.name=Atzara nosaukums
branch.name=Zara nosaukums
branch.already_exists=Atzars ar nosaukumu "%s" jau eksistē.
branch.delete_head=Dzēst
branch.delete=`Dzēst atzaru "%s"`
branch.delete_html=Dzēst atzaru
branch.delete=Izdzēst zaru "%s"
branch.delete_html=Izdzēst zaru
branch.delete_desc=Atzara dzēšana ir neatgriezeniska. Kaut arī izdzēstais zars neilgu laiku var turpināt pastāvēt, pirms tas tiešām tiek noņemts, to vairumā gadījumu NEVAR atsaukt. Vai turpināt?
branch.deletion_success=Atzars "%s" tika izdzēsts.
branch.deletion_failed=Neizdevās izdzēst atzaru "%s".
@ -2534,9 +2534,9 @@ branch.restore_success=Tika atjaunots atzars "%s".
branch.restore_failed=Neizdevās atjaunot atzaru "%s".
branch.protected_deletion_failed=Atzars "%s" ir aizsargāts. To nevar dzēst.
branch.default_deletion_failed=Atzars "%s" ir noklusētais atzars un to nevar dzēst.
branch.restore=`Atjaunot atzaru "%s"`
branch.download=`Lejupielādēt atzaru "%s"`
branch.rename=`Pārsaukt atzaru "%s"`
branch.restore=Atjaunot zaru "%s"
branch.download=Lejupielādēt zaru "%s"
branch.rename=Pārsaukt zaru "%s"
branch.search=Meklēt atzarā
branch.included_desc=Šis atzars ir daļa no noklusēta atzara
branch.included=Iekļauts
@ -2617,7 +2617,7 @@ settings.visibility.limited_shortname=Ierobežota
settings.visibility.private=Privāta (redzama tikai organizācijas dalībniekiem)
settings.visibility.private_shortname=Privāta
settings.update_settings=Mainīt iestatījumus
settings.update_settings=Atjaunināt iestatījumus
settings.update_setting_success=Organizācijas iestatījumi tika saglabāti.
settings.change_orgname_prompt=Piezīme: organizācijas nosaukuma maiņa izmainīs arī organizācijas URL un atbrīvos veco nosaukumu.
settings.change_orgname_redirect_prompt=Vecais vārds pārsūtīs uz jauno, kamēr vien tas nebūs izmantots.
@ -2666,7 +2666,7 @@ teams.no_desc=Komandai nav apraksta
teams.settings=Iestatījumi
teams.owners_permission_desc=Īpašniekiem ir pilna piekļuve <strong>visiem repozitorijiem</strong> un ir organizācijas <strong>administratora tiesības</strong>.
teams.members=Komandas biedri
teams.update_settings=Saglabāt iestatījumus
teams.update_settings=Atjaunināt iestatījumus
teams.delete_team=Dzēst komandu
teams.add_team_member=Pievienot komandas biedru
teams.invite_team_member=`Uzaicināt komandā "%s"`
@ -2754,9 +2754,9 @@ dashboard.archive_cleanup=Dzēst repozitoriju vecos arhīvus
dashboard.deleted_branches_cleanup=Notīrīt dzēstos atzarus
dashboard.update_migration_poster_id=Atjaunot migrācijām autoru ID
dashboard.git_gc_repos=Veikt atkritumu uzkopšanas darbus visiem repozitorijiem
dashboard.resync_all_sshkeys=Atjaunot '.ssh/authorized_keys' failu ar Forgejo SSH atslēgām.
dashboard.resync_all_sshprincipals=Atjaunot '.ssh/authorized_principals' failu ar Forgejo SSH sertifikātu identitātēm.
dashboard.resync_all_hooks=Pārsinhronizēt pirms-saņemšanas, atjaunošanas un pēc-saņemšanas āķus visiem repozitorijiem.
dashboard.resync_all_sshkeys=Atjaunināt datni '.ssh/authorized_keys' ar Forgejo SSH atslēgām.
dashboard.resync_all_sshprincipals=Atjaunināt datni ".ssh/authorized_principals" ar Forgejo SSH identitātēm.
dashboard.resync_all_hooks=Atkārtoti sinhroznēt pirmssaņemšanas, atjaunināšanas un pēcsaņemšans aizķeres visās glabātavās
dashboard.reinit_missing_repos=Atkārtoti inicializēt visus pazaudētos Git repozitorijus par kuriem eksistē ieraksti
dashboard.sync_external_users=Sinhronizēt ārējo lietotāju datus
dashboard.cleanup_hook_task_table=Iztīrīt tīmekļa āķu vēsturi
@ -2764,18 +2764,18 @@ dashboard.cleanup_packages=Notīrīt novecojušās pakotnes
dashboard.cleanup_actions=Notīrīt darbību izbeigušos žurnālus un artefaktus
dashboard.server_uptime=Servera darbības laiks
dashboard.current_goroutine=Izmantotās Gorutīnas
dashboard.current_memory_usage=Pašreiz izmantotā atmiņa
dashboard.total_memory_allocated=Kopējā piešķirtā atmiņa
dashboard.current_memory_usage=Pašreizējais atmiņas lietojums
dashboard.total_memory_allocated=Kopējā iedalītā atmiņa
dashboard.memory_obtained=Iegūtā atmiņa
dashboard.pointer_lookup_times=Rādītāju meklēšanas reizes
dashboard.memory_allocate_times=Atmiņas piešķiršanas reizes
dashboard.memory_free_times=Atmiņas atbrīvošanas reizes
dashboard.current_heap_usage=Pašreizējā kaudzes izmantošana
dashboard.heap_memory_obtained=Iegūtā kaudzes atmiņa
dashboard.heap_memory_idle=Neizmantotā kaudzes atmiņa
dashboard.heap_memory_in_use=Izmantotā kaudzes atmiņa
dashboard.heap_memory_released=Atbrīvotā kaudzes atmiņa
dashboard.heap_objects=Kaudzes atmiņas objekti
dashboard.pointer_lookup_times=Rādītāju pārlūkošanas reizes
dashboard.memory_allocate_times=Atmiņas piešķīrumi
dashboard.memory_free_times=Atmiņas atbrīvošanas
dashboard.current_heap_usage=Pašreizējais grēdas lietojums
dashboard.heap_memory_obtained=Iegūtā grēdas atmiņa
dashboard.heap_memory_idle=Neizmantotā grēdas atmiņa
dashboard.heap_memory_in_use=Izmantotā grēdas atmiņa
dashboard.heap_memory_released=Atbrīvotā grēdas atmiņa
dashboard.heap_objects=Grēdas objekti
dashboard.bootstrap_stack_usage=Izmantotais sāknēšanas steka lielums
dashboard.stack_memory_obtained=Iegūtā steka atmiņa
dashboard.mspan_structures_usage=Izmantotās MSpan struktūras
@ -3207,7 +3207,7 @@ monitor.queue.settings.desc=Pūls dinamiski tiek palielināts atkarībā no blo
monitor.queue.settings.maxnumberworkers=Maksimālais strādņu skaits
monitor.queue.settings.maxnumberworkers.placeholder=Pašalaik %[1]d
monitor.queue.settings.maxnumberworkers.error=Maksimālajam strādņu skaitam ir jābūt skaitlim
monitor.queue.settings.submit=Saglabāt iestatījumus
monitor.queue.settings.submit=Atjaunināt iestatījumus
monitor.queue.settings.changed=Iestatījumi saglabāti
monitor.queue.settings.remove_all_items=Noņemt visus
monitor.queue.settings.remove_all_items_done=Visi ieraksti rindā tika noņemti.

View file

@ -41,7 +41,7 @@ mirror=Дзеркало
new_repo=Новий репозиторій
new_migrate=Нова міграція
new_mirror=Нове дзеркало
new_fork=Нова розвилка репозиторію
new_fork=Новий форк репозиторію
new_org=Нова організація
new_project=Новий проєкт
manage_org=Керування організаціями
@ -159,8 +159,8 @@ new_org.link = Нова організація
copy_generic = Скопіювати до буфера обміну
show_log_seconds = Показувати секунди
show_full_screen = Показувати у повноекранному режимі
filter.is_fork = Розвилки
filter.not_fork = Не розвилки
filter.is_fork = Форки
filter.not_fork = Не форки
filter.is_mirror = Дзеркала
filter.not_mirror = Не дзеркала
filter.not_template = Не шаблони
@ -234,7 +234,7 @@ install=Встановлення
title=Початкова конфігурація
docker_helper=Якщо ви запускаєте Forgejo всередині Docker, будь ласка уважно прочитайте <a target="_blank" rel="noopener" href="%s">документацію</a> перед тим, як щось змінити на цій сторінці.
db_title=Налаштування бази даних
db_type=Вид бази даних
db_type=Тип бази даних
host=Хост
user=Ім'я кристувача
password=Пароль
@ -258,8 +258,8 @@ err_admin_name_pattern_not_allowed=Ім'я адміністратора неді
err_admin_name_is_invalid=Неправильне ім'я користувача-адміністратора
general_title=Загальні налаштування
app_name=Назва екземпляру
app_name_helper=Тут ви можете ввести назву свого екземпляру.
app_name=Назва екземпляра
app_name_helper=Уведіть тут назву свого екземпляра. Вона відображатиметься на кожній сторінці.
repo_path=Коренева тека репозиторію
repo_path_helper=Всі вилучені Git репозиторії будуть збережені в цей каталог.
lfs_path=Кореневий шлях Git LFS
@ -339,8 +339,8 @@ require_db_desc = Forgejo вимагає MySQL, PostgreSQL, SQLite3 чи TiDB (
allow_only_external_registration = Дозволити реєстрацію тільки через зовнішні сервіси
require_sign_in_view.description = Обмежити доступ до контенту лише користувачам, що увійшли. Гості зможуть лише відвідувати сторінки автентифікації.
password_algorithm_helper = Встановити алгоритм хешування паролів. Алгоритми мають різні вимоги та силу. Алгоритм argon2 є досить безпечним, проте споживає багато памʼяті та є недоречним для малих систем.
app_slogan = Гасло екземпляру
app_slogan_helper = Уведіть гасло вашого екземпляру тут. Залиште порожнім, аби вимкнути.
app_slogan = Гасло екземпляра
app_slogan_helper = Уведіть гасло вашого екземпляра тут. Залиште порожнім, аби вимкнути.
run_user_helper = Імʼя користувача операційної системи, від якого запущено Forgejo. Зауважте, що цей користувач повинен мати доступ до кореневої теки репозиторію.
smtp_from_invalid = Адреса з «Відправляти email від імені» недійсна
allow_dots_in_usernames = Дозволити користувачам використовувати крапки у своїх іменах. Не впливає на облікові записи, що вже існують.
@ -388,12 +388,12 @@ org_no_results=Відповідних організацій не знайден
code_no_results=Відповідний пошуковому запитанню код не знайдено.
code_last_indexed_at=Останні індексовані %s
relevant_repositories = Відображаються лише релевантні репозиторії, <a href="%s">переглянути результати без фільтру</a>.
relevant_repositories_tooltip = Приховано розвилки, а також сховища без теми, значка й опису.
relevant_repositories_tooltip = Приховано форки, а також репозиторії без теми, значка й опису.
go_to = Перейти до
stars_one = %d зірка
stars_few = %d зірок
forks_one = розвилка %d
forks_few = %d розвилок
forks_one = %d форк
forks_few = %d форків
[auth]
create_new_account=Реєстрація облікового запису
@ -540,6 +540,10 @@ admin.new_user.text = Будь ласка, <a href="%s">натисніть ту
admin.new_user.subject = Новий користувач %s щойно ввійшов
removed_security_key.text_1 = Ключ безпеки «%[1]s» було щойно видалено з вашого облікового запису.
removed_security_key.subject = Ключ безпеки видалено
team_invite.text_2 = Щоб приєднатися до команди, будь ласка, перейдіть за посиланням:
team_invite.subject = %[1]s запрошує Вас приєднатися до організації %[2]s
team_invite.text_3 = Примітка: Це запрошення призначене для %[1]s. Якщо Ви не очікували цього запрошення, можете проігнорувати цей лист.
team_invite.text_1 = %[1]s запрошує Вас приєднатися до команди %[2]s в організації %[3]s.
[modal]
@ -626,18 +630,23 @@ still_own_packages = Ваш обліковий запис володіє одн
org_still_own_packages = Організація все ще володіє одним чи більше пакунками, спочатку видаліть їх.
username_error_no_dots = ` може містити тільки літерно-цифрові символи («0-9», «a-z», «A-Z»), дефіс («-») та підкреслення («_»). Не може починатися або закінчуватися нелітерними символами; нелітерні символи підряд також заборонені.`
username_error = ` може містити тільки літерно-цифрові символи («0-9», «a-z», «A-Z»), дефіс («-»), підкреслення («_») та крапки («.»). Не може починатися або закінчуватися нелітерними символами; нелітерні символи підряд також заборонені.`
Description = Опис
Pronouns = Займенники
Biography = Про себе
FullName = Повне ім'я
Website = Вебсайт
[user]
change_avatar=Змінити свій аватар…
repositories=Репозиторії
activity=Публічна активність
followers_few=%d читачі
followers_few=%d ежать
starred=Обрані репозиторії
watched=Відстежувані репозиторії
projects=Проєкт
overview=Огляд
following_few=%d читає
following_few=%d відстежуваних
follow=Підписатися
unfollow=Відписатися
user_bio=Біографія
@ -655,7 +664,13 @@ unblock = Розблокувати
code = Код
block_user = Заблокувати користувача
block_user.detail = Зверніть увагу, що блокування користувача має такі наслідки:
follow_blocked_user = Ви не можете підписатися на цього користувача, тому що ви його заблокували або він заблокував вас.
follow_blocked_user = Ви не можете стежити за цим користувачем, тому що ви його заблокували або він заблокував вас.
following_one = %d відстежуваний
followers_one = %d cтежить
followers.title.one = ежить
followers.title.few = ежать
following.title.one = Відстежуваний
following.title.few = Відстежувані
[settings]
@ -947,9 +962,9 @@ template_description=Шаблонні репозиторії дозволяют
visibility=Видимість
visibility_description=Тільки власник або члени організації які мають віповідні права, зможуть побачити.
visibility_helper_forced=Адміністратор вашого сайту налаштував параметри: всі нові репозиторії будуть приватними.
visibility_fork_helper=(Ці зміни вплинуть на всі розвилки.)
visibility_fork_helper=(Ці зміни вплинуть на всі форки.)
clone_helper=Потрібна допомога у клонуванні? Відвідайте сторінку <a target="_blank" rel="noopener" href="%s">Допомога</a>.
fork_repo=Форкнути репозиторій
fork_repo=Створити форк репозиторію
fork_from=Форк з
fork_visibility_helper=Неможливо змінити видимість форкнутого репозиторію.
use_template=Застосувати цей шаблон
@ -1166,7 +1181,7 @@ editor.fork_before_edit=Необхідно зробити форк цього р
editor.delete_this_file=Видалити файл
editor.must_have_write_access=Ви повинні мати доступ на запис щоб запропонувати зміни до цього файлу.
editor.name_your_file=Дайте назву файлу…
editor.filename_help=Щоб додати каталог, наберіть його назву, а потім - косу риску ('/'). Щоб видалити каталог, перейдіть до початку поля і натисніть backspace.
editor.filename_help=Щоб додати каталог, наберіть його назву, а потім — косу риску «/». Щоб видалити каталог, перейдіть до початку поля і натисніть Backspace.
editor.or=або
editor.cancel_lower=Скасувати
editor.commit_signed_changes=Внести підписані зміни
@ -1564,7 +1579,7 @@ pulls.reject_count_1=%d запит на зміну
pulls.reject_count_n=%d запити на зміну
pulls.waiting_count_1=очікується %d рецензія
pulls.waiting_count_n=очікується %d рецензії(й)
pulls.wrong_commit_id=id коміту повинен бути id коміту в цільовій гілці
pulls.wrong_commit_id=ID коміта повинен бути ID коміта в цільовій гілці
pulls.no_merge_desc=Цей запити на злиття неможливо злити, оскільки всі параметри об'єднання репозиторія вимкнено.
pulls.no_merge_helper=Увімкніть параметри злиття в налаштуваннях репозиторія або злийте запити на злиття вручну.
@ -2192,7 +2207,7 @@ find_file.go_to_file = Знайти файл
visibility_helper = Зробити репозиторій приватним
projects.card_type.desc = Попередній вигляд карток
projects.card_type.text_only = Лише текст
projects.card_type.images_and_text = Світлини та текст
projects.card_type.images_and_text = Зображення і текст
issues.filter_poster = Автор
issues.author = Автор
issues.author_helper = Цей користувач - автор.
@ -2361,6 +2376,23 @@ wiki.no_search_results = Нічого не знайдено
pulls.closed = Запит на злиття закрито
signing.wont_sign.not_signed_in = Ви не ввійшли в систему.
settings.wiki_globally_editable = Дозволити всім користувачам редагувати вікі
settings.reindex_button = Додати в чергу на переіндексацію
settings.reindex_requested = Потрібна переіндексація
editor.file_delete_success = Файл «%s» видалено.
file_follow = Слідувати за символьним посиланням
projects.column.set_default = Установити за замовчуванням
settings.federation_following_repos = URL-адреси відстежуваних репозиторіїв. Через «;», без пробілів.
settings.federation_not_enabled = Федерацію вимкнено у вашому екземплярі.
settings.federation_settings = Налаштування федерації
signing.wont_sign.nokey = Цей екземпляр не має ключа для підписання цього коміта.
settings.federation_apapiurl = URL федерації цього репозиторію. Скопіюйте її та вставте в налаштування федерації іншого репозиторію як URL-адресу відстежуваного репозиторію.
fork_branch = Гілка, яку буде клоновано у форк
already_forked = Ви вже створили форк %s
fork_to_different_account = Створити форк до іншого облікового запису
fork_no_valid_owners = Неможливо створити форк цього репозиторію, оскільки тут немає дійсних власників.
pulls.agit_explanation = Створено через робочий потік AGit. AGit дозволяє дописувачам пропонувати зміни за допомогою «git push» без створення форку або нової гілки.
diff.review.self_approve = Автори запитів на злиття не можуть схвалювати власні запити на злиття
settings.event_pull_request_approvals = Схвалення запитів на злиття
[graphs]
contributors.what = внески
@ -2478,6 +2510,9 @@ teams.all_repositories_write_permission_desc=Ця команда надає до
teams.all_repositories_admin_permission_desc=Ця команда надає дозвіл <strong>Адміністрування</strong> для <strong>всіх репозиторіїв</strong>: учасники можуть переглядати, виконувати push та додавати співробітників.
code = Код
open_dashboard = Відкрити панель управління
follow_blocked_user = Ви не можете стежити за цією організацією, тому що вас у ній заблокували.
teams.invite.description = Щоб приєднатися до команди, натисніть кнопку нижче.
teams.invite.title = Вас запрошено приєднатися до команди <strong>%s</strong> в організації <strong>%s</strong>.
[admin]
dashboard=Панель управління
@ -2898,8 +2933,8 @@ monitor.queue=Черга: %s
monitor.queue.name=Назва
monitor.queue.type=Тип
monitor.queue.exemplar=Приклад типу
monitor.queue.numberworkers=Кількість робочих потоків
monitor.queue.maxnumberworkers=Максимальна кількість робочих потоків
monitor.queue.numberworkers=Кількість обробників
monitor.queue.maxnumberworkers=Максимальна кількість обробників
monitor.queue.settings.title=Налаштування пулу
monitor.queue.settings.maxnumberworkers=Максимальна кількість робочих потоків
monitor.queue.settings.maxnumberworkers.placeholder=Поточний %[1]d
@ -2949,6 +2984,13 @@ users.new_success = Обліковий запис «%s» створено.
config_settings = Налаштування
self_check.no_problem_found = Проблем поки що не виявлено.
config_summary = Підсумок
monitor.queue.review_add = Переглянути / додати обробники
monitor.queue.activeworkers = Активні обробники
monitor.queue.numberinqueue = Номер у черзі
monitor.queue.settings.desc = Пули динамічно зростають у відповідь на блокування їхніх черг обробників.
monitor.queue.settings.remove_all_items_done = Усі елементи в черзі видалено.
monitor.queue.settings.remove_all_items = Видалити всі
config.app_slogan = Гасло екземпляра
[action]
@ -3067,7 +3109,7 @@ installation = Установлення
details.license = Ліцензія
filter.type.all = Усі
conan.install = Аби встановити пакунок, використовуючи Conan, запустіть команду:
container.layers = Шари світлини
container.layers = Шари образу
details.project_site = Вебсторінка проєкту
details.documentation_site = Вебсторінка документації
desc = Керувати пакунками репозиторію.
@ -3092,8 +3134,8 @@ arch.version.properties = Властивості версії
arch.version.description = Опис
chef.install = Аби встановити пакунок, запустіть команду:
container.details.platform = Платформа
container.details.type = Вид світлини
container.pull = Завантажити світлину з командного рядка:
container.details.type = Тип образу
container.pull = Завантажити образ із командного рядка:
details.repository_site = Вебсторінка репозиторію
composer.dependencies = Залежності
debian.install = Аби встановити пакунок, запустіть команду:
@ -3130,6 +3172,7 @@ creation = Додати секрет
none = Секретів ще немає.
creation.name_placeholder = без урахування регістру, тільки літерно-цифрові символи або підкреслення, не може починатися з GITEA_ або GITHUB_
secrets = Секрети
creation.value_placeholder = Уведіть довільний вміст. Пробіли на початку та в кінці будуть пропущені.
[actions]
@ -3179,6 +3222,20 @@ runners.task_list.status = Стан
runners.status = Стан
runs.no_workflows.documentation = Докладніше про Дії Forgejo читайте в <a target="_blank" rel="noopener noreferrer" href="%s">документації</a>.
runners.reset_registration_token = Скинути токен реєстрації
workflow.enable_success = Робочий потік «%s» успішно ввімкнено.
runs.workflow = Робочий потік
workflow.disable = Вимкнути робочий потік
workflow.disable_success = Робочий потік «%s» успішно вимкнено.
workflow.disabled = Робочий потік вимкнено.
workflow.enable = Увімкнути робочий потік
runs.no_workflows = Робочих потоків ще немає.
runs.all_workflows = Усі робочі потоки
runs.no_results = Не знайдено відповідних результатів.
status.failure = Помилка
status.running = Працює
status.success = Успіх
status.skipped = Пропущено
need_approval_desc = Потрібне схвалення для запуску робочих потоків для запиту на злиття.

View file

@ -669,7 +669,7 @@ target_branch_not_exist=目标分支不存在。
username_error_no_dots = ` 只能包含英文字母与数字“0-9”、“a-z”、“A-Z”、横杠“-”) 与下划线“_”。 开头与结尾的字符只能使用英文字母或数字,且不能包含连续的非字母非数字字符。`
admin_cannot_delete_self = 您无法以管理员的身份删除自己。请先移除您的管理员权限。
admin_cannot_delete_self=当您是管理员时,您不能删除自己。请先移除您的管理员权限
admin_cannot_delete_self=当您是管理员时,您不能删除自己。请先移除您的管理员权限
unsupported_login_type = 该账号使用的登录方式不支持删除此账户。
unset_password = 当前登录用户尚未设置密码。
required_prefix = 输入必须以“%s”开头
@ -714,7 +714,7 @@ follow_blocked_user = 您不能关注该用户,因为您已屏蔽该用户或
block = 屏蔽
unblock = 解除屏蔽
block_user.detail_3 = 您将无法将彼此添加为仓库协作者。
followers_one = %d 关注者
followers_one = %d 关注者
following_one = %d 关注
public_activity.visibility_hint.self_public = 您的活动对所有人都是可见的,但在私人空间中的交互除外。<a href="%s">配置</a>。
public_activity.visibility_hint.admin_public = 此活动对所有人可见,但作为管理员,您还可以看到私人空间中的交互。
@ -766,8 +766,8 @@ continue=继续操作
cancel=取消操作
language=界面语言
ui=主题
hidden_comment_types=隐藏的评论类型
hidden_comment_types_description=此处选中的注释类型不会显示在问题页面中。比如,勾选”标签“删除所有 "<user> 添加/删除的 <label>" 注释。
hidden_comment_types=隐藏的注释类型
hidden_comment_types_description=此处选中的注释类型不会显示在工单页面中。例如,勾选“标签”将移除所有“<用户>添加/删除了<标签>”注释。
hidden_comment_types.ref_tooltip=注释此问题在何处被提及过,如另一个问题、代码提交等…
hidden_comment_types.issue_ref_tooltip=注释用户在何处更改了与此问题相关联的分支/标签
comment_type_group_reference=引用
@ -1043,7 +1043,7 @@ blocked_since = 自 %s 起被屏蔽
user_unblock_success = 已成功取消对该用户的屏蔽。
user_block_success = 已成功屏蔽该用户。
change_password = 更改密码
additional_repo_units_hint = 建议仓库启用更多功能
additional_repo_units_hint = 建议启用更多仓库功能
hints = 提示
update_hints = 更新提示
additional_repo_units_hint_description = 在所有存在未启用的功能的仓库内显示“启用更多”提示。
@ -1103,7 +1103,7 @@ object_format_helper=仓库的对象格式。之后无法更改。SHA1 是最兼
readme=自述
readme_helper=选择自述文件模板
readme_helper_desc=这是您可以为您的项目撰写完整描述的地方。
auto_init=初始化仓库(添加. gitignore、许可证和自述文件)
auto_init=初始化仓库(添加 .gitignore、许可证和自述文件)
trust_model_helper=选择签名验证的“信任模型”。可能的选项是:
trust_model_helper_collaborator=协作者:信任协作者的签名
trust_model_helper_committer=提交者:信任与提交者相符的签名
@ -1617,7 +1617,7 @@ issues.no_content=没有提供说明。
issues.close=关闭工单
issues.comment_pull_merged_at=已合并提交 %[1]s 到 %[2]s %[3]s
issues.comment_manually_pull_merged_at=手动合并提交 %[1]s 到 %[2]s %[3]s
issues.close_comment_issue=关闭评论
issues.close_comment_issue=评论并关闭
issues.reopen_issue=重新开放
issues.reopen_comment_issue=重新打开评论
issues.create_comment=评论
@ -1934,7 +1934,7 @@ pulls.update_branch_rebase=通过变基更新分支
pulls.update_branch_success=分支更新成功
pulls.update_not_allowed=您无权更新分支
pulls.outdated_with_base_branch=此分支相比基础分支已过期
pulls.close=关闭合并请求
pulls.close=关闭
pulls.closed_at=`于 <a id="%[1]s" href="#%[1]s">%[2]s</a> 关闭此合并请求 `
pulls.reopened_at=`重新打开此合并请求 <a id="%[1]s" href="#%[1]s">%[2]s</a>`
pulls.cmd_instruction_hint=查看命令行说明
@ -2433,7 +2433,7 @@ settings.protect_enable_merge=启用合并
settings.protect_enable_merge_desc=任何具有写入权限的人都可以将合并请求合并到此分支中。
settings.protect_whitelist_committers=受白名单限制的推送
settings.protect_whitelist_committers_desc=只有列入白名单的用户或团队才能被允许推送到此分支(但不能强行推送)。
settings.protect_whitelist_deploy_keys=具有推送权限的部署密钥白名单。
settings.protect_whitelist_deploy_keys=具有推送权限的部署密钥加入白名单。
settings.protect_whitelist_users=推送白名单用户
settings.protect_whitelist_search_users=搜索用户...
settings.protect_whitelist_teams=推送白名单团队
@ -2854,6 +2854,7 @@ issues.review.add_remove_review_requests = 于 %[3]s 请求 %[1]s 评审,并
pulls.delete_after_merge.head_branch.is_protected = 您要删除的头部分支是受保护的分支,无法删除。
pulls.delete_after_merge.head_branch.insufficient_branch = 您没有权限删除头部分支。
pulls.delete_after_merge.head_branch.is_default = 您要删除的头部分支是默认分支,无法删除。
issues.filter_sort.relevance = 相关性
[graphs]
component_loading=正在加载 %s...

View file

@ -1316,7 +1316,11 @@ func Routes() *web.Route {
m.Get("/trees/{sha}", repo.GetTree)
m.Get("/blobs/{sha}", repo.GetBlob)
m.Get("/tags/{sha}", repo.GetAnnotatedTag)
m.Get("/notes/{sha}", repo.GetNote)
m.Group("/notes/{sha}", func() {
m.Get("", repo.GetNote)
m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), bind(api.NoteOptions{}), repo.SetNote)
m.Delete("", reqToken(), reqRepoWriter(unit.TypeCode), repo.RemoveNote)
})
}, context.ReferencesGitRepo(true), reqRepoReader(unit.TypeCode))
m.Post("/diffpatch", reqRepoWriter(unit.TypeCode), reqToken(), bind(api.ApplyDiffPatchFileOptions{}), mustNotBeArchived, context.EnforceQuotaAPI(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetRepo), repo.ApplyDiffPatch)
m.Group("/contents", func() {

View file

@ -9,6 +9,7 @@ import (
"code.gitea.io/gitea/modules/git"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/convert"
)
@ -102,3 +103,107 @@ func getNote(ctx *context.APIContext, identifier string) {
apiNote := api.Note{Message: string(note.Message), Commit: cmt}
ctx.JSON(http.StatusOK, apiNote)
}
// SetNote Sets a note corresponding to a single commit from a repository
func SetNote(ctx *context.APIContext) {
// swagger:operation POST /repos/{owner}/{repo}/git/notes/{sha} repository repoSetNote
// ---
// summary: Set a note corresponding to a single commit from a repository
// produces:
// - application/json
// parameters:
// - name: owner
// in: path
// description: owner of the repo
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repo
// type: string
// required: true
// - name: sha
// in: path
// description: a git ref or commit sha
// type: string
// required: true
// - name: body
// in: body
// schema:
// "$ref": "#/definitions/NoteOptions"
// responses:
// "200":
// "$ref": "#/responses/Note"
// "404":
// "$ref": "#/responses/notFound"
// "422":
// "$ref": "#/responses/validationError"
sha := ctx.Params(":sha")
if !git.IsValidRefPattern(sha) {
ctx.Error(http.StatusUnprocessableEntity, "no valid ref or sha", fmt.Sprintf("no valid ref or sha: %s", sha))
return
}
form := web.GetForm(ctx).(*api.NoteOptions)
err := git.SetNote(ctx, ctx.Repo.GitRepo, sha, form.Message, ctx.Doer.Name, ctx.Doer.GetEmail())
if err != nil {
if git.IsErrNotExist(err) {
ctx.NotFound(sha)
} else {
ctx.Error(http.StatusInternalServerError, "SetNote", err)
}
return
}
getNote(ctx, sha)
}
// RemoveNote Removes a note corresponding to a single commit from a repository
func RemoveNote(ctx *context.APIContext) {
// swagger:operation DELETE /repos/{owner}/{repo}/git/notes/{sha} repository repoRemoveNote
// ---
// summary: Removes a note corresponding to a single commit from a repository
// produces:
// - application/json
// parameters:
// - name: owner
// in: path
// description: owner of the repo
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repo
// type: string
// required: true
// - name: sha
// in: path
// description: a git ref or commit sha
// type: string
// required: true
// responses:
// "204":
// "$ref": "#/responses/empty"
// "404":
// "$ref": "#/responses/notFound"
// "422":
// "$ref": "#/responses/validationError"
sha := ctx.Params(":sha")
if !git.IsValidRefPattern(sha) {
ctx.Error(http.StatusUnprocessableEntity, "no valid ref or sha", fmt.Sprintf("no valid ref or sha: %s", sha))
return
}
err := git.RemoveNote(ctx, ctx.Repo.GitRepo, sha)
if err != nil {
if git.IsErrNotExist(err) {
ctx.NotFound(sha)
} else {
ctx.Error(http.StatusInternalServerError, "RemoveNote", err)
}
return
}
ctx.Status(http.StatusNoContent)
}

View file

@ -231,4 +231,7 @@ type swaggerParameterBodies struct {
// in:body
SetUserQuotaGroupsOptions api.SetUserQuotaGroupsOptions
// in:body
NoteOptions api.NoteOptions
}

View file

@ -27,7 +27,9 @@ import (
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/forms"
"code.gitea.io/gitea/services/gitdiff"
git_service "code.gitea.io/gitea/services/repository"
)
@ -467,3 +469,29 @@ func processGitCommits(ctx *context.Context, gitCommits []*git.Commit) []*git_mo
}
return commits
}
func SetCommitNotes(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.CommitNotesForm)
commitID := ctx.Params(":sha")
err := git.SetNote(ctx, ctx.Repo.GitRepo, commitID, form.Notes, ctx.Doer.Name, ctx.Doer.GetEmail())
if err != nil {
ctx.ServerError("SetNote", err)
return
}
ctx.Redirect(fmt.Sprintf("%s/commit/%s", ctx.Repo.Repository.HTMLURL(), commitID))
}
func RemoveCommitNotes(ctx *context.Context) {
commitID := ctx.Params(":sha")
err := git.RemoveNote(ctx, ctx.Repo.GitRepo, commitID)
if err != nil {
ctx.ServerError("RemoveNotes", err)
return
}
ctx.Redirect(fmt.Sprintf("%s/commit/%s", ctx.Repo.Repository.HTMLURL(), commitID))
}

View file

@ -1559,6 +1559,10 @@ func registerRoutes(m *web.Route) {
m.Get("/graph", repo.Graph)
m.Get("/commit/{sha:([a-f0-9]{4,64})$}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.Diff)
m.Get("/commit/{sha:([a-f0-9]{4,64})$}/load-branches-and-tags", repo.LoadBranchesAndTags)
m.Group("/commit/{sha:([a-f0-9]{4,64})$}/notes", func() {
m.Post("", web.Bind(forms.CommitNotesForm{}), repo.SetCommitNotes)
m.Post("/remove", repo.RemoveCommitNotes)
}, reqSignIn, reqRepoCodeWriter)
m.Get("/cherry-pick/{sha:([a-f0-9]{4,64})$}", repo.SetEditorconfigIfExists, repo.CherryPick)
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)

View file

@ -749,3 +749,7 @@ func (f *DeadlineForm) Validate(req *http.Request, errs binding.Errors) binding.
ctx := context.GetValidateContext(req)
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
}
type CommitNotesForm struct {
Notes string
}

View file

@ -10,6 +10,7 @@ import (
"html/template"
"net/http"
"net/url"
"regexp"
"strconv"
"strings"
"unicode/utf8"
@ -202,6 +203,9 @@ func (d discordConvertor) Push(p *api.PushPayload) (DiscordPayload, error) {
// limit the commit message display to just the summary, otherwise it would be hard to read
message := strings.TrimRight(strings.SplitN(commit.Message, "\n", 1)[0], "\r")
// Escaping markdown character
message = escapeMarkdown(message)
// a limit of 50 is set because GitHub does the same
if utf8.RuneCountInString(message) > 50 {
message = fmt.Sprintf("%.47s...", message)
@ -365,3 +369,40 @@ func (d discordConvertor) createPayload(s *api.User, title, text, url string, co
},
}
}
var orderedListPattern = regexp.MustCompile(`(\d+)\.`)
var markdownPatterns = map[string]*regexp.Regexp{
"~": regexp.MustCompile(`\~(.*?)\~`),
"*": regexp.MustCompile(`\*(.*?)\*`),
"_": regexp.MustCompile(`\_(.*?)\_`),
}
var markdownToEscape = strings.NewReplacer(
"* ", "\\* ",
"`", "\\`",
"[", "\\[",
"]", "\\]",
"(", "\\(",
")", "\\)",
"#", "\\#",
"+ ", "\\+ ",
"- ", "\\- ",
"---", "\\---",
"!", "\\!",
"|", "\\|",
"<", "\\<",
">", "\\>",
)
// Escape Markdown characters
func escapeMarkdown(input string) string {
// Escaping ordered list
output := orderedListPattern.ReplaceAllString(input, "$1\\.")
for char, pattern := range markdownPatterns {
output = pattern.ReplaceAllString(output, fmt.Sprintf(`\%s$1\%s`, char, char))
}
return markdownToEscape.Replace(output)
}

View file

@ -94,6 +94,20 @@ func TestDiscordPayload(t *testing.T) {
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
t.Run("PushWithMarkdownCharactersInCommitMessage", func(t *testing.T) {
p := pushTestEscapeCommitMessagePayload()
pl, err := dc.Push(p)
require.NoError(t, err)
assert.Len(t, pl.Embeds, 1)
assert.Equal(t, "[test/repo:test] 2 new commits", pl.Embeds[0].Title)
assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) \\# conflicts\n\\# \\- some/conflicting/file.txt - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) \\# conflicts\n\\# \\- some/conflicting/file.txt - user1", pl.Embeds[0].Description)
assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
@ -346,3 +360,89 @@ func TestDiscordJSONPayload(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", body.Embeds[0].Description)
}
var escapedMarkdownTests = map[string]struct {
input string
expected string
}{
"Escape heading level 1": {
input: "# Heading level 1",
expected: "\\# Heading level 1",
},
"Escape heading level 2": {
input: "## Heading level 2",
expected: "\\#\\# Heading level 2",
},
"Escape heading level 3": {
input: "### Heading level 3",
expected: "\\#\\#\\# Heading level 3",
},
"Escape bold text": {
input: "**bold text**",
expected: "\\*\\*bold text\\*\\*",
},
"Escape italic text": {
input: "*italic text*",
expected: "\\*italic text\\*",
},
"Escape italic text underline": {
input: "_italic text_",
expected: "\\_italic text\\_",
},
"Escape strikethrough": {
input: "~~strikethrough~~",
expected: "\\~\\~strikethrough\\~\\~",
},
"Escape Ordered list item": {
input: "1. Ordered list item\n2. Second ordered list item\n999999999999. 999999999999 ordered list item",
expected: "1\\. Ordered list item\n2\\. Second ordered list item\n999999999999\\. 999999999999 ordered list item",
},
"Escape Unordered list item": {
input: "- Unordered list\n + using plus",
expected: "\\- Unordered list\n \\+ using plus",
},
"Escape bullet list item": {
input: "* Bullet list item",
expected: "\\* Bullet list item",
},
"Escape table": {
input: "| Table | Example |\n|-|-|\n| Lorem | Ipsum |",
expected: "\\| Table \\| Example \\|\n\\|-\\|-\\|\n\\| Lorem \\| Ipsum \\|",
},
"Escape link": {
input: "[Link to Forgejo](https://forgejo.org/)",
expected: "\\[Link to Forgejo\\]\\(https://forgejo.org/\\)",
},
"Escape Alt text for an image": {
input: "![Alt text for an image](https://forgejo.org/_astro/mascot-dark.1omhhgvT_Zm0N2n.webp)",
expected: "\\!\\[Alt text for an image\\]\\(https://forgejo.org/\\_astro/mascot-dark.1omhhgvT\\_Zm0N2n.webp\\)",
},
"Escape URL if it has markdown character": {
input: "https://forgejo.org/_astro/mascot-dark.1omhhgvT_Zm0N2n.webp",
expected: "https://forgejo.org/\\_astro/mascot-dark.1omhhgvT\\_Zm0N2n.webp",
},
"Escape blockquote text": {
input: "> Blockquote text.",
expected: "\\> Blockquote text.",
},
"Escape inline code": {
input: "`Inline code`",
expected: "\\`Inline code\\`",
},
"Escape multiple code": {
input: "```\nCode block\nwith multiple lines\n```\n",
expected: "\\`\\`\\`\nCode block\nwith multiple lines\n\\`\\`\\`\n",
},
"Escape horizontal rule": {
input: "---",
expected: "\\---",
},
}
func TestEscapeMarkdownChar(t *testing.T) {
for name, test := range escapedMarkdownTests {
t.Run(name, func(t *testing.T) {
assert.Equal(t, test.expected, escapeMarkdown(test.input))
})
}
}

View file

@ -72,6 +72,10 @@ func pushTestMultilineCommitMessagePayload() *api.PushPayload {
return pushTestPayloadWithCommitMessage("This is a commit summary ⚠️⚠️⚠️⚠️ containing 你好 ⚠️⚠️️\n\nThis is the message body.")
}
func pushTestEscapeCommitMessagePayload() *api.PushPayload {
return pushTestPayloadWithCommitMessage("# conflicts\n# - some/conflicting/file.txt")
}
func pushTestPayloadWithCommitMessage(message string) *api.PushPayload {
commit := &api.PayloadCommit{
ID: "2020558fe2e34debb818a514715839cabd25e778",

View file

@ -2,7 +2,8 @@
{{svg "octicon-no-entry" 48}}
<h2>{{ctx.Locale.Tr "actions.runs.no_workflows"}}</h2>
{{if and .CanWriteCode .CanWriteActions}}
<p>{{ctx.Locale.Tr "actions.runs.no_workflows.quick_start" "https://forgejo.org/docs/latest/admin/actions/"}}</p>
<p>{{ctx.Locale.Tr "actions.runs.no_workflows.help_write_access" "https://forgejo.org/docs/latest/user/actions/#quick-start" "https://forgejo.org/docs/latest/admin/runner-installation/"}}</p>
{{else}}
<p>{{ctx.Locale.Tr "actions.runs.no_workflows.help_no_write_access" "https://forgejo.org/docs/latest/user/actions/"}}</p>
{{end}}
<p>{{ctx.Locale.Tr "actions.runs.no_workflows.documentation" "https://forgejo.org/docs/latest/admin/actions/"}}</p>
</div>

View file

@ -275,10 +275,61 @@
<strong>{{.NoteCommit.Author.Name}}</strong>
{{end}}
<span class="text grey" id="note-authored-time">{{DateUtils.TimeSince .NoteCommit.Author.When}}</span>
{{if or ($.Permission.CanWrite $.UnitTypeCode) (not $.Repository.IsArchived) (not .IsDeleted)}}
<div class="ui right">
<button id="commit-notes-edit-button" class="ui tiny button yellow" data-modal="#delete-note-modal">{{ctx.Locale.Tr "edit"}}</button>
<button class="ui tiny button red show-modal" data-modal="#delete-note-modal">{{ctx.Locale.Tr "remove"}}</button>
</div>
<div class="ui small modal" id="delete-note-modal">
<div class="header">
{{ctx.Locale.Tr "repo.diff.git-notes.remove-header"}}
</div>
<p>{{ctx.Locale.Tr "repo.diff.git-notes.remove-body"}}</p>
<div class="content">
<div class="text right actions">
<form action="{{.Link}}/notes/remove" method="post">
{{.CsrfTokenHtml}}
<button type="button" class="ui cancel button">{{ctx.Locale.Tr "settings.cancel"}}</button>
<button type="submit" class="ui primary button red" href="{{.Link}}/notes/remove">{{ctx.Locale.Tr "remove"}}</button>
</form>
</div>
</div>
</div>
{{end}}
</div>
<div class="ui bottom attached info segment git-notes">
<div id="commit-notes-display-area" class="ui bottom attached info segment git-notes">
<pre class="commit-body">{{.NoteRendered | SanitizeHTML}}</pre>
</div>
{{if and ($.Permission.CanWrite $.UnitTypeCode) (not $.Repository.IsArchived) (not .IsDeleted)}}
<div id="commit-notes-edit-area" class="ui bottom attached info segment git-notes tw-hidden">
<form class="ui form" action="{{.Link}}/notes" method="post">
{{.CsrfTokenHtml}}
<div class="field">
<textarea name="notes">{{.NoteRendered | SanitizeHTML}}</textarea>
</div>
<div class="field">
<button id="notes-save-button" class="ui primary button">{{ctx.Locale.Tr "save"}}</button>
</div>
</form>
</div>
{{end}}
{{else if and ($.Permission.CanWrite $.UnitTypeCode) (not $.Repository.IsArchived) (not .IsDeleted)}}
<button id="commit-notes-add-button" class="ui primary button green tw-mt-3">{{ctx.Locale.Tr "repo.diff.git-notes.add"}}</button>
<div id="commit-notes-add-area" class="ui tw-mt-3 segment tw-hidden">
<form class="ui form" action="{{.Link}}/notes" method="post">
{{.CsrfTokenHtml}}
<div class="field">
<textarea name="notes"></textarea>
</div>
<div class="field">
<button class="ui primary button">{{ctx.Locale.Tr "add"}}</button>
</div>
</form>
</div>
{{end}}
{{template "repo/diff/box" .}}
</div>

View file

@ -7375,6 +7375,101 @@
"$ref": "#/responses/validationError"
}
}
},
"post": {
"produces": [
"application/json"
],
"tags": [
"repository"
],
"summary": "Set a note corresponding to a single commit from a repository",
"operationId": "repoSetNote",
"parameters": [
{
"type": "string",
"description": "owner of the repo",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the repo",
"name": "repo",
"in": "path",
"required": true
},
{
"type": "string",
"description": "a git ref or commit sha",
"name": "sha",
"in": "path",
"required": true
},
{
"name": "body",
"in": "body",
"schema": {
"$ref": "#/definitions/NoteOptions"
}
}
],
"responses": {
"200": {
"$ref": "#/responses/Note"
},
"404": {
"$ref": "#/responses/notFound"
},
"422": {
"$ref": "#/responses/validationError"
}
}
},
"delete": {
"produces": [
"application/json"
],
"tags": [
"repository"
],
"summary": "Removes a note corresponding to a single commit from a repository",
"operationId": "repoRemoveNote",
"parameters": [
{
"type": "string",
"description": "owner of the repo",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the repo",
"name": "repo",
"in": "path",
"required": true
},
{
"type": "string",
"description": "a git ref or commit sha",
"name": "sha",
"in": "path",
"required": true
}
],
"responses": {
"204": {
"$ref": "#/responses/empty"
},
"404": {
"$ref": "#/responses/notFound"
},
"422": {
"$ref": "#/responses/validationError"
}
}
}
},
"/repos/{owner}/{repo}/git/refs": {
@ -24601,6 +24696,16 @@
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
"NoteOptions": {
"type": "object",
"properties": {
"message": {
"type": "string",
"x-go-name": "Message"
}
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
"NotificationCount": {
"description": "NotificationCount number of unread notifications",
"type": "object",
@ -28350,7 +28455,7 @@
"parameterBodies": {
"description": "parameterBodies",
"schema": {
"$ref": "#/definitions/SetUserQuotaGroupsOptions"
"$ref": "#/definitions/NoteOptions"
}
},
"quotaExceeded": {

View file

@ -51,10 +51,12 @@
</div>
<input id="pronouns-custom" name="pronouns" value="{{.SignedUser.Pronouns}}" maxlength="50">
</div>
<div class="field {{if .Err_Email}}error{{end}}">
<label>{{ctx.Locale.Tr "email"}}</label>
<p id="signed-user-email">{{.SignedUser.Email}}</p>
</div>
{{if not .SignedUser.KeepEmailPrivate}}
<div class="field">
<label>{{ctx.Locale.Tr "email"}}</label>
<p id="signed-user-email">{{.SignedUser.Email}}</p>
</div>
{{end}}
<div class="field {{if .Err_Biography}}error{{end}}">
<label for="biography">{{ctx.Locale.Tr "user.user_bio"}}</label>
<textarea id="biography" name="biography" rows="2" placeholder="{{ctx.Locale.Tr "settings.biography_placeholder"}}" maxlength="255">{{.SignedUser.Description}}</textarea>

View file

@ -0,0 +1,30 @@
// @ts-check
import {test, expect} from '@playwright/test';
import {login_user, load_logged_in_context} from './utils_e2e.ts';
test.beforeAll(async ({browser}, workerInfo) => {
await login_user(browser, workerInfo, 'user2');
});
test('Change git note', async ({browser}, workerInfo) => {
const context = await load_logged_in_context(browser, workerInfo, 'user2');
const page = await context.newPage();
let response = await page.goto('/user2/repo1/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d');
expect(response?.status()).toBe(200);
await page.locator('#commit-notes-edit-button').click();
let textarea = page.locator('textarea[name="notes"]');
await expect(textarea).toBeVisible();
await textarea.fill('This is a new note');
await page.locator('#notes-save-button').click();
expect(response?.status()).toBe(200);
response = await page.goto('/user2/repo1/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d');
expect(response?.status()).toBe(200);
textarea = page.locator('textarea[name="notes"]');
await expect(textarea).toHaveText('This is a new note');
});

View file

@ -4,11 +4,13 @@
package integration
import (
"fmt"
"net/http"
"net/url"
"testing"
auth_model "code.gitea.io/gitea/models/auth"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
api "code.gitea.io/gitea/modules/structs"
@ -16,7 +18,7 @@ import (
"github.com/stretchr/testify/assert"
)
func TestAPIReposGitNotes(t *testing.T) {
func TestAPIReposGetGitNotes(t *testing.T) {
onGiteaRun(t, func(*testing.T, *url.URL) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
@ -44,3 +46,53 @@ func TestAPIReposGitNotes(t *testing.T) {
assert.NotNil(t, apiData.Commit.RepoCommit.Verification)
})
}
func TestAPIReposSetGitNotes(t *testing.T) {
onGiteaRun(t, func(*testing.T, *url.URL) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/git/notes/65f1bf27bc3bf70f64657658635e66094edbcb4d", repo.FullName())
resp := MakeRequest(t, req, http.StatusOK)
var apiData api.Note
DecodeJSON(t, resp, &apiData)
assert.Equal(t, "This is a test note\n", apiData.Message)
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/git/notes/65f1bf27bc3bf70f64657658635e66094edbcb4d", repo.FullName()), &api.NoteOptions{
Message: "This is a new note",
}).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiData)
assert.Equal(t, "This is a new note\n", apiData.Message)
req = NewRequestf(t, "GET", "/api/v1/repos/%s/git/notes/65f1bf27bc3bf70f64657658635e66094edbcb4d", repo.FullName())
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiData)
assert.Equal(t, "This is a new note\n", apiData.Message)
})
}
func TestAPIReposDeleteGitNotes(t *testing.T) {
onGiteaRun(t, func(*testing.T, *url.URL) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/git/notes/65f1bf27bc3bf70f64657658635e66094edbcb4d", repo.FullName())
resp := MakeRequest(t, req, http.StatusOK)
var apiData api.Note
DecodeJSON(t, resp, &apiData)
assert.Equal(t, "This is a test note\n", apiData.Message)
req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/git/notes/65f1bf27bc3bf70f64657658635e66094edbcb4d", repo.FullName()).AddTokenAuth(token)
MakeRequest(t, req, http.StatusNoContent)
req = NewRequestf(t, "GET", "/api/v1/repos/%s/git/notes/65f1bf27bc3bf70f64657658635e66094edbcb4d", repo.FullName())
MakeRequest(t, req, http.StatusNotFound)
})
}

View file

@ -0,0 +1,44 @@
package integration
import (
"net/http"
"net/url"
"testing"
"github.com/stretchr/testify/assert"
)
func TestRepoModifyGitNotes(t *testing.T) {
onGiteaRun(t, func(*testing.T, *url.URL) {
session := loginUser(t, "user2")
req := NewRequest(t, "GET", "/user2/repo1/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d")
resp := MakeRequest(t, req, http.StatusOK)
assert.Contains(t, resp.Body.String(), "<pre class=\"commit-body\">This is a test note\n</pre>")
assert.Contains(t, resp.Body.String(), "commit-notes-display-area")
t.Run("Set", func(t *testing.T) {
req = NewRequestWithValues(t, "POST", "/user2/repo1/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d/notes", map[string]string{
"_csrf": GetCSRF(t, session, "/user2/repo1"),
"notes": "This is a new note",
})
session.MakeRequest(t, req, http.StatusSeeOther)
req = NewRequest(t, "GET", "/user2/repo1/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d")
resp = MakeRequest(t, req, http.StatusOK)
assert.Contains(t, resp.Body.String(), "<pre class=\"commit-body\">This is a new note\n</pre>")
assert.Contains(t, resp.Body.String(), "commit-notes-display-area")
})
t.Run("Delete", func(t *testing.T) {
req = NewRequestWithValues(t, "POST", "/user2/repo1/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d/notes/remove", map[string]string{
"_csrf": GetCSRF(t, session, "/user2/repo1"),
})
session.MakeRequest(t, req, http.StatusSeeOther)
req = NewRequest(t, "GET", "/user2/repo1/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d")
resp = MakeRequest(t, req, http.StatusOK)
assert.NotContains(t, resp.Body.String(), "commit-notes-display-area")
})
})
}

View file

@ -1,4 +1,5 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package integration
@ -156,3 +157,23 @@ func TestSettingSecurityAuthSource(t *testing.T) {
assert.Contains(t, resp.Body.String(), `gitlab-active`)
assert.Contains(t, resp.Body.String(), `gitlab-inactive`)
}
func TestSettingShowUserEmailSettings(t *testing.T) {
defer tests.PrepareTestEnv(t)()
// user1: keep_email_private = false, user2: keep_email_private = true
// user1 can see own visible email
session := loginUser(t, "user1")
req := NewRequest(t, "GET", "/user/settings")
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
assert.Contains(t, htmlDoc.doc.Find("#signed-user-email").Text(), "user1@example.com")
// user2 cannot see own hidden email
session = loginUser(t, "user2")
req = NewRequest(t, "GET", "/user/settings")
resp = session.MakeRequest(t, req, http.StatusOK)
htmlDoc = NewHTMLParser(t, resp.Body)
assert.NotContains(t, htmlDoc.doc.Find("#signed-user-email").Text(), "user2@example.com")
}

View file

@ -25,3 +25,21 @@ export function initCommitStatuses() {
});
}
}
export function initCommitNotes() {
const notesEditButton = document.getElementById('commit-notes-edit-button');
if (notesEditButton !== null) {
notesEditButton.addEventListener('click', () => {
document.getElementById('commit-notes-display-area').classList.add('tw-hidden');
document.getElementById('commit-notes-edit-area').classList.remove('tw-hidden');
});
}
const notesAddButton = document.getElementById('commit-notes-add-button');
if (notesAddButton !== null) {
notesAddButton.addEventListener('click', () => {
notesAddButton.classList.add('tw-hidden');
document.getElementById('commit-notes-add-area').classList.remove('tw-hidden');
});
}
}

View file

@ -33,7 +33,7 @@ import {
initRepoPullRequestAllowMaintainerEdit,
initRepoPullRequestReview, initRepoIssueSidebarList, initArchivedLabelHandler,
} from './features/repo-issue.js';
import {initRepoEllipsisButton, initCommitStatuses} from './features/repo-commit.js';
import {initRepoEllipsisButton, initCommitStatuses, initCommitNotes} from './features/repo-commit.js';
import {
initFootLanguageMenu,
initGlobalButtonClickOnEnter,
@ -179,6 +179,7 @@ onDomReady(() => {
initRepoMilestoneEditor();
initCommitStatuses();
initCommitNotes();
initCaptcha();
initUserAuthOauth2();