mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-17 00:01:00 -04:00
Compare commits
11 Commits
8cadd51bf2
...
d647e74502
Author | SHA1 | Date | |
---|---|---|---|
|
d647e74502 | ||
|
0141d1667d | ||
|
92d3e2a6f8 | ||
|
17c8a0523a | ||
|
c775053476 | ||
|
79af6e367c | ||
|
e6df743eca | ||
|
8bdc0acf97 | ||
|
689770c928 | ||
|
542cec98f8 | ||
|
e52ac62d8e |
@ -1,12 +1,18 @@
|
||||
plugins:
|
||||
- stylelint-declaration-strict-value
|
||||
|
||||
ignoreFiles:
|
||||
- "**/*.go"
|
||||
|
||||
overrides:
|
||||
- files: ["**/*.less"]
|
||||
customSyntax: postcss-less
|
||||
- files: ["**/chroma/*", "**/codemirror/*", "**/standalone/*", "**/console/*"]
|
||||
rules:
|
||||
scale-unlimited/declaration-strict-value: null
|
||||
- files: ["**/chroma/*", "**/codemirror/*"]
|
||||
rules:
|
||||
block-no-empty: null
|
||||
|
||||
rules:
|
||||
alpha-value-notation: null
|
||||
|
84
contrib/init/ubuntu/gitea
Normal file
84
contrib/init/ubuntu/gitea
Normal file
@ -0,0 +1,84 @@
|
||||
#!/bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: gitea
|
||||
# Required-Start: $syslog $network
|
||||
# Required-Stop: $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: A self-hosted Git service written in Go.
|
||||
# Description: A self-hosted Git service written in Go.
|
||||
### END INIT INFO
|
||||
|
||||
# Do NOT "set -e"
|
||||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
|
||||
DESC="Gitea - Git with a cup of tea"
|
||||
NAME=gitea
|
||||
SERVICEVERBOSE=yes
|
||||
PIDFILE=/run/$NAME.pid
|
||||
SCRIPTNAME=/etc/init.d/$NAME
|
||||
WORKINGDIR=/var/lib/$NAME
|
||||
DAEMON=/usr/local/bin/$NAME
|
||||
DAEMON_ARGS="web -c /etc/$NAME/app.ini"
|
||||
USER=git
|
||||
STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/1/KILL/5}"
|
||||
|
||||
# Read configuration variable file if it is present
|
||||
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
do_start()
|
||||
{
|
||||
GITEA_ENVS="USER=$USER GITEA_WORK_DIR=$WORKINGDIR HOME=/home/$USER"
|
||||
GITEA_EXEC="$DAEMON -- $DAEMON_ARGS"
|
||||
sh -c "start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \\
|
||||
--background --chdir $WORKINGDIR --chuid $USER \\
|
||||
--exec /bin/bash -- -c '/usr/bin/env $GITEA_ENVS $GITEA_EXEC'"
|
||||
}
|
||||
|
||||
do_stop()
|
||||
{
|
||||
start-stop-daemon --stop --quiet --retry=$STOP_SCHEDULE --pidfile $PIDFILE --name $NAME --oknodo
|
||||
rm -f $PIDFILE
|
||||
}
|
||||
|
||||
do_status()
|
||||
{
|
||||
if [ -f $PIDFILE ]; then
|
||||
if kill -0 $(cat "$PIDFILE"); then
|
||||
echo "$NAME is running, PID is $(cat $PIDFILE)"
|
||||
else
|
||||
echo "$NAME process is dead, but pidfile exists"
|
||||
fi
|
||||
else
|
||||
echo "$NAME is not running"
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo "Starting $DESC" "$NAME"
|
||||
do_start
|
||||
;;
|
||||
stop)
|
||||
echo "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
;;
|
||||
status)
|
||||
do_status
|
||||
;;
|
||||
restart)
|
||||
echo "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
do_start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
@ -23,7 +23,7 @@ Publish [Maven](https://maven.apache.org) packages for your user or organization
|
||||
## Requirements
|
||||
|
||||
To work with the Maven package registry, you can use [Maven](https://maven.apache.org/install.html) or [Gradle](https://gradle.org/install/).
|
||||
The following examples use `Maven`.
|
||||
The following examples use `Maven` and `Gradle Groovy`.
|
||||
|
||||
## Configuring the package registry
|
||||
|
||||
@ -73,6 +73,40 @@ Afterwards add the following sections to your project `pom.xml` file:
|
||||
| `access_token` | Your [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}). |
|
||||
| `owner` | The owner of the package. |
|
||||
|
||||
### Gradle variant
|
||||
|
||||
When you plan to add some packages from Gitea instance in your project, you should add it in repositories section:
|
||||
|
||||
```groovy
|
||||
repositories {
|
||||
// other repositories
|
||||
maven { url "https://gitea.example.com/api/packages/{owner}/maven" }
|
||||
}
|
||||
```
|
||||
|
||||
In Groovy gradle you may include next script in your publishing part:
|
||||
|
||||
```groovy
|
||||
publishing {
|
||||
// other settings of publication
|
||||
repositories {
|
||||
maven {
|
||||
name = "Gitea"
|
||||
url = uri("https://gitea.example.com/api/packages/{owner}/maven")
|
||||
|
||||
credentials(HttpHeaderCredentials) {
|
||||
name = "Authorization"
|
||||
value = "token {access_token}"
|
||||
}
|
||||
|
||||
authentication {
|
||||
header(HttpHeaderAuthentication)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Publish a package
|
||||
|
||||
To publish a package simply run:
|
||||
@ -81,6 +115,12 @@ To publish a package simply run:
|
||||
mvn deploy
|
||||
```
|
||||
|
||||
Or call `gradle` with task `publishAllPublicationsToGiteaRepository` in case you are using gradle:
|
||||
|
||||
```groovy
|
||||
./gradlew publishAllPublicationsToGiteaRepository
|
||||
```
|
||||
|
||||
If you want to publish a prebuild package to the registry, you can use [`mvn deploy:deploy-file`](https://maven.apache.org/plugins/maven-deploy-plugin/deploy-file-mojo.html):
|
||||
|
||||
```shell
|
||||
@ -105,6 +145,12 @@ To install a Maven package from the package registry, add a new dependency to yo
|
||||
</dependency>
|
||||
```
|
||||
|
||||
And analog in gradle groovy:
|
||||
|
||||
```groovy
|
||||
implementation "com.test.package:test_project:1.0.0"
|
||||
```
|
||||
|
||||
Afterwards run:
|
||||
|
||||
```shell
|
||||
|
@ -179,7 +179,7 @@ func (c *Command) AddDashesAndList(list ...string) *Command {
|
||||
}
|
||||
|
||||
// ToTrustedCmdArgs converts a list of strings (trusted as argument) to TrustedCmdArgs
|
||||
// In most cases, it shouldn't be used. Use AddXxx function instead
|
||||
// In most cases, it shouldn't be used. Use NewCommand().AddXxx() function instead
|
||||
func ToTrustedCmdArgs(args []string) TrustedCmdArgs {
|
||||
ret := make(TrustedCmdArgs, len(args))
|
||||
for i, arg := range args {
|
||||
|
@ -218,6 +218,19 @@ func (c *Commit) HasPreviousCommit(commitHash SHA1) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// IsForcePush returns true if a push from oldCommitHash to this is a force push
|
||||
func (c *Commit) IsForcePush(oldCommitID string) (bool, error) {
|
||||
if oldCommitID == EmptySHA {
|
||||
return false, nil
|
||||
}
|
||||
oldCommit, err := c.repo.GetCommit(oldCommitID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
hasPreviousCommit, err := c.HasPreviousCommit(oldCommit.ID)
|
||||
return !hasPreviousCommit, err
|
||||
}
|
||||
|
||||
// CommitsBeforeLimit returns num commits before current revision
|
||||
func (c *Commit) CommitsBeforeLimit(num int) ([]*Commit, error) {
|
||||
return c.repo.getCommitsBeforeLimit(c.ID, num)
|
||||
|
@ -323,6 +323,27 @@ func (repo *Repository) CommitsBetweenLimit(last, before *Commit, limit, skip in
|
||||
return repo.parsePrettyFormatLogToList(bytes.TrimSpace(stdout))
|
||||
}
|
||||
|
||||
// CommitsBetweenNotBase returns a list that contains commits between [before, last), excluding commits in baseBranch.
|
||||
// If before is detached (removed by reset + push) it is not included.
|
||||
func (repo *Repository) CommitsBetweenNotBase(last, before *Commit, baseBranch string) ([]*Commit, error) {
|
||||
var stdout []byte
|
||||
var err error
|
||||
if before == nil {
|
||||
stdout, _, err = NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(last.ID.String()).AddOptionValues("--not", baseBranch).RunStdBytes(&RunOpts{Dir: repo.Path})
|
||||
} else {
|
||||
stdout, _, err = NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(before.ID.String()+".."+last.ID.String()).AddOptionValues("--not", baseBranch).RunStdBytes(&RunOpts{Dir: repo.Path})
|
||||
if err != nil && strings.Contains(err.Error(), "no merge base") {
|
||||
// future versions of git >= 2.28 are likely to return an error if before and last have become unrelated.
|
||||
// previously it would return the results of git rev-list before last so let's try that...
|
||||
stdout, _, err = NewCommand(repo.Ctx, "rev-list").AddDynamicArguments(before.ID.String(), last.ID.String()).AddOptionValues("--not", baseBranch).RunStdBytes(&RunOpts{Dir: repo.Path})
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return repo.parsePrettyFormatLogToList(bytes.TrimSpace(stdout))
|
||||
}
|
||||
|
||||
// CommitsBetweenIDs return commits between twoe commits
|
||||
func (repo *Repository) CommitsBetweenIDs(last, before string) ([]*Commit, error) {
|
||||
lastCommit, err := repo.GetCommit(last)
|
||||
|
@ -4,10 +4,8 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
)
|
||||
|
||||
@ -96,19 +94,3 @@ func (opts *PushUpdateOptions) RefName() string {
|
||||
func (opts *PushUpdateOptions) RepoFullName() string {
|
||||
return opts.RepoUserName + "/" + opts.RepoName
|
||||
}
|
||||
|
||||
// IsForcePush detect if a push is a force push
|
||||
func IsForcePush(ctx context.Context, opts *PushUpdateOptions) (bool, error) {
|
||||
if !opts.IsUpdateBranch() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
output, _, err := git.NewCommand(ctx, "rev-list", "--max-count=1").AddDynamicArguments(opts.OldCommitID, "^"+opts.NewCommitID).
|
||||
RunStdString(&git.RunOpts{Dir: repo_model.RepoPath(opts.RepoUserName, opts.RepoName)})
|
||||
if err != nil {
|
||||
return false, err
|
||||
} else if len(output) > 0 {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ new_mirror=Nové zrcadlo
|
||||
new_fork=Nové rozštěpení repozitáře
|
||||
new_org=Nová organizace
|
||||
new_project=Nový projekt
|
||||
new_project_column=Nový sloupec
|
||||
manage_org=Spravovat organizace
|
||||
admin_panel=Administrace
|
||||
account_settings=Nastavení účtu
|
||||
@ -90,9 +91,11 @@ disabled=Zakázané
|
||||
|
||||
copy=Kopírovat
|
||||
copy_url=Kopírovat URL
|
||||
copy_content=Kopírovat obsah
|
||||
copy_branch=Kopírovat jméno větve
|
||||
copy_success=Zkopírováno!
|
||||
copy_error=Kopírování se nezdařilo
|
||||
copy_type_unsupported=Tento typ souboru nelze zkopírovat
|
||||
|
||||
write=Zapsat
|
||||
preview=Náhled
|
||||
@ -109,6 +112,10 @@ never=Nikdy
|
||||
rss_feed=RSS kanál
|
||||
|
||||
[aria]
|
||||
navbar=Navigační lišta
|
||||
footer=Patička
|
||||
footer.software=O softwaru
|
||||
footer.links=Odkazy
|
||||
|
||||
[filter]
|
||||
string.asc=A – Z
|
||||
@ -292,23 +299,71 @@ code_search_results=Výsledky hledání pro „%s“
|
||||
code_last_indexed_at=Naposledy indexováno %s
|
||||
relevant_repositories_tooltip=Repozitáře, které jsou rozštěpení nebo nemají žádné téma, ikonu a žádný popis jsou skryty.
|
||||
relevant_repositories=`Zobrazují se pouze relevantní repositáře, <a href="`
|
||||
internal_token_failed=Nepodařilo se vytvořit interní token: %v
|
||||
secret_key_failed=Nepodařilo se vytvořit tajný klíč: %v
|
||||
save_config_failed=Uložení konfigurace se nezdařilo: %v
|
||||
invalid_admin_setting=Nastavení účtu správce není správné: %v
|
||||
invalid_log_root_path=Kořenový adresář logů není správný: %v
|
||||
default_keep_email_private=Jako počáteční nastavení skrýt e-mailové adresy
|
||||
default_keep_email_private_popup=Nastaví e-mailové adresy novým uživatelským účtům jako skryté.
|
||||
default_allow_create_organization=Dovolí novým uživatelům zakládat organizace
|
||||
default_allow_create_organization_popup=Povolit novým uživatelským účtům vytvářet organizace.
|
||||
default_enable_timetracking=Povolit sledování času ve výchozím nastavení
|
||||
default_enable_timetracking_popup=Povolí sledování času pro nové repozitáře.
|
||||
no_reply_address=Skrytá e-mailová doména
|
||||
no_reply_address_helper=Název domény pro uživatele se skrytou e-mailovou adresou. Příklad: Pokud je název skryté e-mailové domény nastaven na „noreply.example.org“, uživatelské jméno „joe“ bude zaznamenáno v Gitu jako „joe@noreply.example.org“.
|
||||
password_algorithm=Hash algoritmus hesla
|
||||
password_algorithm_helper=Nastavte algoritmus hashování hesla. Algoritmy mají odlišné požadavky a sílu. `argon2` používá mnoho paměti a může být nevhodný pro malé systémy.
|
||||
enable_update_checker=Povolit kontrolu aktualizací
|
||||
enable_update_checker_helper=Kontroluje vydání nových verzí pravidelně připojením ke gitea.io.
|
||||
|
||||
[home]
|
||||
uname_holder=Uživatelské jméno nebo e-mailová adresa
|
||||
password_holder=Heslo
|
||||
switch_dashboard_context=Přepnout kontext přehledu
|
||||
my_repos=Repozitáře
|
||||
show_more_repos=Zobrazit více repozitářů…
|
||||
collaborative_repos=Společné repozitáře
|
||||
my_orgs=Mé organizace
|
||||
my_mirrors=Má zrcadla
|
||||
view_home=Zobrazit %s
|
||||
search_repos=Nalézt repozitář…
|
||||
filter=Ostatní filtry
|
||||
filter_by_team_repositories=Filtrovat podle repozitářů týmu
|
||||
feed_of=Kanál z „%s“
|
||||
|
||||
show_archived=Archivováno
|
||||
show_both_archived_unarchived=Zobrazeny jak archivované tak nearchivované
|
||||
show_only_archived=Zobrazeny pouze archivované
|
||||
show_only_unarchived=Zobrazeny pouze nearchivované
|
||||
|
||||
show_private=Soukromý
|
||||
show_both_private_public=Zobrazeny jak veřejné tak soukromé
|
||||
show_only_private=Zobrazeny pouze soukromé
|
||||
show_only_public=Zobrazeny pouze veřejné
|
||||
|
||||
issues.in_your_repos=Ve vašich repozitářích
|
||||
|
||||
[explore]
|
||||
repos=Repozitáře
|
||||
users=Uživatelé
|
||||
organizations=Organizace
|
||||
search=Vyhledat
|
||||
code=Kód
|
||||
search.type.tooltip=Druh vyhledávání
|
||||
search.fuzzy=Fuzzy
|
||||
search.fuzzy.tooltip=Zahrnout výsledky, které také úzce odpovídají hledanému výrazu
|
||||
search.match=Shoda
|
||||
search.match.tooltip=Zahrnout pouze výsledky, které odpovídají přesnému hledanému výrazu
|
||||
code_search_unavailable=V současné době není vyhledávání kódu dostupné. Obraťte se na správce webu.
|
||||
repo_no_results=Nebyly nalezeny žádné odpovídající repozitáře.
|
||||
user_no_results=Nebyly nalezeni žádní odpovídající uživatelé.
|
||||
org_no_results=Nebyly nalezeny žádné odpovídající organizace.
|
||||
code_no_results=Nebyl nalezen žádný zdrojový kód odpovídající hledanému výrazu.
|
||||
code_search_results=Výsledky hledání pro „%s“
|
||||
code_last_indexed_at=Naposledy indexováno %s
|
||||
relevant_repositories_tooltip=Repozitáře, které jsou rozštěpení nebo nemají žádné téma, ikonu a žádný popis jsou skryty.
|
||||
relevant_repositories=Zobrazují se pouze relevantní repositáře, <a href="%s">zobrazit nefiltrované výsledky</a>.
|
||||
|
||||
|
||||
[auth]
|
||||
@ -338,6 +393,7 @@ email_not_associate=Tato e-mailová adresa není spojena s žádným účtem.
|
||||
send_reset_mail=Zaslat e-mail pro obnovení účtu
|
||||
reset_password=Obnovení účtu
|
||||
invalid_code=Tento potvrzující kód je neplatný nebo mu vypršela platnost.
|
||||
invalid_password=Vaše heslo se neshoduje s heslem, které bylo použito k vytvoření účtu.
|
||||
reset_password_helper=Obnovit účet
|
||||
reset_password_wrong_user=Jste přihlášen/a jako %s, ale odkaz pro obnovení účtu je pro %s
|
||||
password_too_short=Délka hesla musí být minimálně %d znaků.
|
||||
@ -381,6 +437,7 @@ password_pwned_err=Nelze dokončit požadavek na HaveIBeenPwned
|
||||
|
||||
[mail]
|
||||
view_it_on=Zobrazit na %s
|
||||
reply=nebo přímo odpovědět na tento e-mail
|
||||
link_not_working_do_paste=Nefunguje? Zkuste jej zkopírovat a vložit do svého prohlížeče.
|
||||
hi_user_x=Ahoj <b>%s</b>,
|
||||
|
||||
@ -484,6 +541,7 @@ url_error=`„%s“ není platná adresa URL.`
|
||||
include_error=` musí obsahovat řetězec „%s“.`
|
||||
glob_pattern_error=`zástupný vzor je neplatný: %s.`
|
||||
regex_pattern_error=` regex vzor je neplatný: %s.`
|
||||
invalid_group_team_map_error=` mapování je neplatné: %s`
|
||||
unknown_error=Neznámá chyba:
|
||||
captcha_incorrect=CAPTCHA kód není správný.
|
||||
password_not_match=Zadaná hesla nesouhlasí.
|
||||
@ -520,10 +578,12 @@ team_not_exist=Tento tým neexistuje.
|
||||
last_org_owner=Nemůžete odstranit posledního uživatele z týmu „vlastníci“. Musí existovat alespoň jeden vlastník pro organizaci.
|
||||
cannot_add_org_to_team=Organizace nemůže být přidána jako člen týmu.
|
||||
duplicate_invite_to_team=Uživatel byl již pozván jako člen týmu.
|
||||
organization_leave_success=Úspěšně jste opustili organizaci %s.
|
||||
|
||||
invalid_ssh_key=Nelze ověřit váš SSH klíč: %s
|
||||
invalid_gpg_key=Nelze ověřit váš GPG klíč: %s
|
||||
invalid_ssh_principal=Neplatný SSH Principal certifikát: %s
|
||||
must_use_public_key=Zadaný klíč je soukromý klíč. Nenahrávejte svůj soukromý klíč nikde. Místo toho použijte váš veřejný klíč.
|
||||
unable_verify_ssh_key=Nelze ověřit váš SSH klíč
|
||||
auth_failed=Ověření selhalo: %v
|
||||
|
||||
@ -1185,6 +1245,7 @@ commits.signed_by_untrusted_user_unmatched=Podepsáno nedůvěryhodným uživate
|
||||
commits.gpg_key_id=ID GPG klíče
|
||||
commits.ssh_key_fingerprint=Otisk klíče SSH
|
||||
|
||||
commit.operations=Operace
|
||||
commit.revert=Vrátit
|
||||
commit.revert-header=Vrátit: %s
|
||||
commit.revert-content=Vyberte větev pro návrat na:
|
||||
@ -1217,11 +1278,21 @@ projects.type.bug_triage=Třídění chyb
|
||||
projects.template.desc=Šablona projektu
|
||||
projects.template.desc_helper=Vyberte šablonu projektu pro začátek
|
||||
projects.type.uncategorized=Nezařazené
|
||||
projects.column.edit=Upravit sloupec
|
||||
projects.column.edit_title=Název
|
||||
projects.column.new_title=Název
|
||||
projects.column.new_submit=Vytvořit sloupec
|
||||
projects.column.new=Nový sloupec
|
||||
projects.column.set_default=Nastavit jako výchozí
|
||||
projects.column.set_default_desc=Nastavit tento sloupec jako výchozí pro nekategorizované úkoly a požadavky na natažení
|
||||
projects.column.delete=Smazat sloupec
|
||||
projects.column.deletion_desc=Smazání projektového sloupce přesune všechny související problémy do kategorie „Nezařazené“. Pokračovat?
|
||||
projects.column.color=Barva
|
||||
projects.open=Otevřít
|
||||
projects.close=Zavřít
|
||||
projects.column.assigned_to=Přiřazeno k
|
||||
projects.card_type.images_and_text=Obrázky a text
|
||||
projects.card_type.text_only=Pouze text
|
||||
|
||||
issues.desc=Organizování hlášení chyb, úkolů a milníků.
|
||||
issues.filter_assignees=Filtrovat zpracovatele
|
||||
@ -1298,6 +1369,7 @@ issues.filter_label_no_select=Všechny štítky
|
||||
issues.filter_milestone=Milník
|
||||
issues.filter_milestone_no_select=Všechny milníky
|
||||
issues.filter_project=Projekt
|
||||
issues.filter_project_all=Všechny projekty
|
||||
issues.filter_project_none=Žádný projekt
|
||||
issues.filter_assignee=Zpracovatel
|
||||
issues.filter_assginee_no_select=Všichni zpracovatelé
|
||||
@ -1383,6 +1455,7 @@ issues.save=Uložit
|
||||
issues.label_title=Název štítku
|
||||
issues.label_description=Popis štítku
|
||||
issues.label_color=Barva štítku
|
||||
issues.label_exclusive=Exkluzivní
|
||||
issues.label_count=%d štítků
|
||||
issues.label_open_issues=%d otevřených úkolů
|
||||
issues.label_edit=Upravit
|
||||
@ -1828,6 +1901,7 @@ settings.mirror_sync_in_progress=Právě probíhá synchronizace zrcadla. Zkuste
|
||||
settings.site=Webová stránka
|
||||
settings.update_settings=Aktualizovat nastavení
|
||||
settings.branches.update_default_branch=Aktualizovat výchozí větev
|
||||
settings.branches.add_new_rule=Přidat nové pravidlo
|
||||
settings.advanced_settings=Pokročilá nastavení
|
||||
settings.wiki_desc=Povolit Wiki repozitáře
|
||||
settings.use_internal_wiki=Používat vestavěnou Wiki
|
||||
@ -2022,6 +2096,8 @@ settings.event_package=Balíček
|
||||
settings.event_package_desc=Balíček vytvořen nebo odstraněn v repozitáři.
|
||||
settings.branch_filter=Filtr větví
|
||||
settings.branch_filter_desc=Povolené větve pro události nahrání, vytvoření větve a smazání větve jsou určeny pomocí zástupného vzoru. Pokud je prázdný nebo <code>*</code>, všechny události jsou ohlášeny. Podívejte se na dokumentaci syntaxe na <a href="https://pkg.go.dev/github.com/gobwas/glob#Compile">github.com/gobwas/glob</a>. Příklady: <code>master</code>, <code>{master,release*}</code>.
|
||||
settings.authorization_header=Autorizační hlavička
|
||||
settings.authorization_header_desc=Pokud vyplněno, bude připojeno k požadavkům jako autorizační hlavička. Příklady: %s.
|
||||
settings.active=Aktivní
|
||||
settings.active_helper=Informace o spuštěných událostech budou odeslány na URL webového háčku.
|
||||
settings.add_hook_success=Webový háček byl přidán.
|
||||
@ -2066,6 +2142,8 @@ settings.deploy_key_deletion_desc=Odstranění klíče pro nasazení zruší jeh
|
||||
settings.deploy_key_deletion_success=Klíč pro nasazení byl odstraněn.
|
||||
settings.branches=Větve
|
||||
settings.protected_branch=Ochrana větví
|
||||
settings.protected_branch.save_rule=Uložit pravidlo
|
||||
settings.protected_branch.delete_rule=Odstranit pravidlo
|
||||
settings.protected_branch_can_push=Povolit nahrání?
|
||||
settings.protected_branch_can_push_yes=Můžete nahrávat
|
||||
settings.protected_branch_can_push_no=Nemůžete nahrávat
|
||||
@ -2543,6 +2621,9 @@ dashboard.delete_old_actions=Odstranit všechny staré akce z databáze
|
||||
dashboard.delete_old_actions.started=Začalo odstraňování všech starých akcí z databáze.
|
||||
dashboard.update_checker=Kontrola aktualizací
|
||||
dashboard.delete_old_system_notices=Odstranit všechna stará systémová upozornění z databáze
|
||||
dashboard.stop_zombie_tasks=Zastavit zombie úkoly
|
||||
dashboard.stop_endless_tasks=Zastavit nekonečné úkoly
|
||||
dashboard.cancel_abandoned_jobs=Zrušit opuštěné úlohy
|
||||
|
||||
users.user_manage_panel=Správa uživatelských účtů
|
||||
users.new_account=Vytvořit uživatelský účet
|
||||
@ -2724,6 +2805,7 @@ auths.oauth2_required_claim_value_helper=Nastavte tuto hodnotu pro omezení při
|
||||
auths.oauth2_group_claim_name=Název tvrzení poskytující názvy skupin pro tento zdroj. (nepovinné)
|
||||
auths.oauth2_admin_group=Hodnota tvrzení pro skupinu uživatelů administrátorů. (Volitelné - vyžaduje název tvrzení výše)
|
||||
auths.oauth2_restricted_group=Hodnota tvrzení pro skupinu omezených uživatelů. (Volitelné - vyžaduje název tvrzení výše)
|
||||
auths.oauth2_map_group_to_team_removal=Odebrat uživatele z synchronizovaných týmů, pokud uživatel nepatří do odpovídající skupiny.
|
||||
auths.enable_auto_register=Povolit zaregistrování se
|
||||
auths.sspi_auto_create_users=Automaticky vytvářet uživatele
|
||||
auths.sspi_auto_create_users_helper=Povolit SSPI autentizační metodě automaticky vytvářet nové účty pro uživatele, kteří se poprvé přihlásili
|
||||
@ -2986,6 +3068,7 @@ monitor.queue.pool.cancel_desc=Opustit frontu bez skupin workerů může způsob
|
||||
|
||||
notices.system_notice_list=Systémová oznámení
|
||||
notices.view_detail_header=Zobrazit detaily oznámení
|
||||
notices.operations=Operace
|
||||
notices.select_all=Vybrat vše
|
||||
notices.deselect_all=Zrušit výběr všech
|
||||
notices.inverse_selection=Inverzní výběr
|
||||
@ -3011,6 +3094,7 @@ reopen_pull_request=`znovuotevřel/a požadavek na natažení <a href="%[1]s">%[
|
||||
comment_issue=`okomentoval/a problém <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
comment_pull=`okomentoval/a požadavek na natažení <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
merge_pull_request=`sloučil/a požadavek na natažení <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
auto_merge_pull_request=`automaticky sloučen požadavek na natažení <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
transfer_repo=předal/a repozitář <code>%s</code> uživateli/organizaci <a href="%s">%s</a>
|
||||
push_tag=nahrál/a značku <a href="%[2]s">%[3]s</a> do <a href="%[1]s">%[4]s</a>
|
||||
delete_tag=smazal/a značku %[2]s z <a href="%[1]s">%[3]s</a>
|
||||
@ -3109,6 +3193,8 @@ keywords=Klíčová slova
|
||||
details=Podrobnosti
|
||||
details.author=Autor
|
||||
details.project_site=Stránka projektu
|
||||
details.repository_site=Stránka repositáře
|
||||
details.documentation_site=Stránka dokumentace
|
||||
details.license=Licence
|
||||
assets=Prostředky
|
||||
versions=Verze
|
||||
@ -3116,7 +3202,13 @@ versions.on=
|
||||
versions.view_all=Zobrazit všechny
|
||||
dependency.id=ID
|
||||
dependency.version=Verze
|
||||
cargo.install=Chcete-li nainstalovat balíček pomocí Cargo, spusťte následující příkaz:
|
||||
cargo.documentation=Další informace o registru Cargo naleznete v <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/cargo/">dokumentaci</a>.
|
||||
cargo.details.repository_site=Stránka repositáře
|
||||
cargo.details.documentation_site=Stránka dokumentace
|
||||
chef.registry=Nastavit tento registr v souboru <code>~/.chef/config.rb</code>:
|
||||
chef.install=Pro instalaci balíčku spusťte následující příkaz:
|
||||
chef.documentation=Další informace o registru Chef naleznete v <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/chef/">dokumentaci</a>.
|
||||
composer.registry=Nastavit tento registr v souboru <code>~/.composer/config.json</code>:
|
||||
composer.install=Pro instalaci balíčku pomocí Compposer spusťte následující příkaz:
|
||||
composer.documentation=Další informace o registru Composer naleznete v <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/composer/">dokumentaci</a>.
|
||||
@ -3126,6 +3218,11 @@ conan.details.repository=Repozitář
|
||||
conan.registry=Nastavte tento registr z příkazového řádku:
|
||||
conan.install=Pro instalaci balíčku pomocí Conan spusťte následující příkaz:
|
||||
conan.documentation=Další informace o registru Conan naleznete v <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/conan/">dokumentaci</a>.
|
||||
conda.registry=Nastavte tento registr jako Conda repozitář ve vašem <code>.condarc</code>:
|
||||
conda.install=Pro instalaci balíčku pomocí Conda spusťte následující příkaz:
|
||||
conda.documentation=Další informace o registru Conda naleznete v <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/conda/">dokumentaci</a>.
|
||||
conda.details.repository_site=Stránka repositáře
|
||||
conda.details.documentation_site=Stránka dokumentace
|
||||
container.details.type=Typ obrazu
|
||||
container.details.platform=Platforma
|
||||
container.pull=Stáhněte obraz z příkazové řádky:
|
||||
@ -3184,26 +3281,79 @@ settings.delete.description=Smazání balíčku je trvalé a nelze ho vrátit zp
|
||||
settings.delete.notice=Chystáte se odstranit %s (%s). Tato operace je nevratná, jste si jisti?
|
||||
settings.delete.success=Balíček byl odstraněn.
|
||||
settings.delete.error=Nepodařilo se odstranit balíček.
|
||||
owner.settings.cargo.initialize=Inicializovat index
|
||||
owner.settings.cargo.initialize.description=K použití registru Cargo je zapotřebí speciální indexový repozitář git. Zde jej můžete (znovu) vytvořit s požadovanou konfigurací.
|
||||
owner.settings.cargo.initialize.error=Nepodařilo se inicializovat Cargo index: %v
|
||||
owner.settings.cargo.initialize.success=Index Cargo byl úspěšně vytvořen.
|
||||
owner.settings.cargo.rebuild=Znovu vytvořit Index
|
||||
owner.settings.cargo.rebuild.description=Pokud index není synchronizován s uloženými balíčky Cargo, můžete jej zde obnovit.
|
||||
owner.settings.cargo.rebuild.error=Obnovení Cargo indexu se nezdařilo: %v
|
||||
owner.settings.cargo.rebuild.success=Cargo Index byl úspěšně obnoven.
|
||||
owner.settings.cleanuprules.title=Spravovat pravidla pro čištění
|
||||
owner.settings.cleanuprules.add=Přidat pravidlo pro čištění
|
||||
owner.settings.cleanuprules.edit=Upravit pravidlo pro čištění
|
||||
owner.settings.cleanuprules.none=Nejsou k dispozici žádná pravidla čištění. Přečtěte si dokumentaci a dozvíte se více.
|
||||
owner.settings.cleanuprules.preview=Náhled pravidla pro čištění
|
||||
owner.settings.cleanuprules.preview.overview=%d balíčků má být odstraněno.
|
||||
owner.settings.cleanuprules.preview.none=Pravidlo čištění neodpovídá žádným balíčkům.
|
||||
owner.settings.cleanuprules.enabled=Povolený
|
||||
owner.settings.cleanuprules.pattern_full_match=Použít vzor na úplný název balíčku
|
||||
owner.settings.cleanuprules.keep.title=Verze, které odpovídají těmto pravidlům, jsou zachovány, i když odpovídají níže uvedenému pravidlu pro odstranění.
|
||||
owner.settings.cleanuprules.keep.count=Zachovat nejnovější
|
||||
owner.settings.cleanuprules.keep.count.1=1 verze na balíček
|
||||
owner.settings.cleanuprules.keep.count.n=%d verzí na balíček
|
||||
owner.settings.cleanuprules.keep.pattern=Ponechat odpovídající verze
|
||||
owner.settings.cleanuprules.keep.pattern.container=U balíčků Container je vždy zachována <code>nejnovější</code> verze.
|
||||
owner.settings.cleanuprules.remove.title=Verze, které odpovídají těmto pravidlům, jsou odstraněny, pokud výše uvedené pravidlo neukládá jejich zachování.
|
||||
owner.settings.cleanuprules.remove.days=Odstranit verze starší než
|
||||
owner.settings.cleanuprules.remove.pattern=Odstranit odpovídající verze
|
||||
owner.settings.cleanuprules.success.update=Pravidlo pro čištění bylo aktualizováno.
|
||||
owner.settings.cleanuprules.success.delete=Pravidlo pro čištění bylo odstraněno.
|
||||
owner.settings.chef.keypair=Generovat pár klíčů
|
||||
|
||||
[secrets]
|
||||
secrets=Tajné klíče
|
||||
value=Hodnota
|
||||
name=Název
|
||||
|
||||
[actions]
|
||||
actions=Akce
|
||||
|
||||
unit.desc=Spravovat akce
|
||||
|
||||
status.unknown=Neznámý
|
||||
status.waiting=Čekání
|
||||
status.running=Probíhá
|
||||
status.success=Úspěch
|
||||
status.failure=Chyba
|
||||
status.cancelled=Zrušeno
|
||||
status.skipped=Přeskočeno
|
||||
status.blocked=Blokováno
|
||||
|
||||
runners.status=Status
|
||||
runners.id=ID
|
||||
runners.name=Název
|
||||
runners.owner_type=Typ
|
||||
runners.description=Popis
|
||||
runners.labels=Štítky
|
||||
runners.last_online=Poslední čas online
|
||||
runners.agent_labels=Štítky agenta
|
||||
runners.custom_labels=Vlastní štítky
|
||||
runners.custom_labels_helper=Vlastní štítky jsou štítky, které správce přidává ručně. Štítky se oddělují čárkou, bílé znaky na začátku a na konci každého štítku se ignorují.
|
||||
runners.task_list.run=Spustit
|
||||
runners.task_list.status=Status
|
||||
runners.task_list.repository=Repozitář
|
||||
runners.task_list.commit=Commit
|
||||
runners.task_list.done_at=Dokončeno v
|
||||
runners.update_runner=Aktualizovat změny
|
||||
runners.status.unspecified=Neznámý
|
||||
runners.status.idle=Nečinný
|
||||
runners.status.active=Aktivní
|
||||
runners.status.offline=Offline
|
||||
|
||||
runs.all_workflows=Všechny pracovní postupy
|
||||
runs.open_tab=%d otevřeno
|
||||
runs.closed_tab=%d uzavřeno
|
||||
runs.commit=Commit
|
||||
|
||||
|
||||
|
@ -328,6 +328,7 @@ email_not_associate=此電子信箱未與任何帳戶連結
|
||||
send_reset_mail=發送帳戶救援信
|
||||
reset_password=帳戶救援
|
||||
invalid_code=您的確認代碼無效或已過期。
|
||||
invalid_password=您的密碼和用來建立帳戶的不符。
|
||||
reset_password_helper=帳戶救援
|
||||
reset_password_wrong_user=您已經使用 %s 的帳戶登入,但帳戶救援連結是給 %s 的
|
||||
password_too_short=密碼長度不能少於 %d 個字!
|
||||
@ -430,6 +431,10 @@ repo.transfer.body=請造訪 %s 以接受或拒絕轉移,您也可以忽略它
|
||||
repo.collaborator.added.subject=%s 把您加入到 %s
|
||||
repo.collaborator.added.text=您已被新增為儲存庫的協作者:
|
||||
|
||||
team_invite.subject=%[1]s 邀請您加入組織 %[2]s
|
||||
team_invite.text_1=%[1]s 邀請您加入組織 %[3]s 中的 %[2]s 團隊
|
||||
team_invite.text_2=請點擊下方連結加入團隊:
|
||||
team_invite.text_3=備註: 這是寄給 %[1]s 的邀請。若您未預期收到此邀請,請忽略此郵件。
|
||||
|
||||
[modal]
|
||||
yes=是
|
||||
@ -446,7 +451,7 @@ SSHTitle=SSH 金鑰名稱
|
||||
HttpsUrl=HTTPS URL 地址
|
||||
PayloadUrl=推送地址
|
||||
TeamName=團隊名稱
|
||||
AuthName=認證名稱
|
||||
AuthName=授權名稱
|
||||
AdminEmail=管理員電子信箱
|
||||
|
||||
NewBranchName=新的分支名稱
|
||||
@ -506,11 +511,13 @@ user_not_exist=該用戶名不存在
|
||||
team_not_exist=團隊不存在
|
||||
last_org_owner=你不能從「Owners」團隊中刪除最後一個使用者。每個組織中至少要有一個擁有者。
|
||||
cannot_add_org_to_team=組織不能被新增為團隊成員。
|
||||
duplicate_invite_to_team=該使用者已經被邀請為團隊成員。
|
||||
organization_leave_success=您已成功離開組織 %s。
|
||||
|
||||
invalid_ssh_key=無法驗證您的 SSH 密鑰:%s
|
||||
invalid_gpg_key=無法驗證您的 GPG 密鑰:%s
|
||||
invalid_ssh_principal=無效的主體: %s
|
||||
must_use_public_key=您提供的金鑰是私有金鑰,請勿上傳您的私有金鑰到任何地方,請使用您的公鑰。
|
||||
unable_verify_ssh_key=無法驗證 SSH 密鑰
|
||||
auth_failed=授權認證失敗:%v
|
||||
|
||||
@ -747,6 +754,8 @@ access_token_deletion_cancel_action=取消
|
||||
access_token_deletion_confirm_action=刪除
|
||||
access_token_deletion_desc=刪除 Token 後,使用此 Token 的應用程式將無法再存取您的帳戶,此動作不可還原。是否繼續?
|
||||
delete_token_success=已刪除 Token。使用此 Token 的應用程式無法再存取您的帳戶。
|
||||
select_scopes=選擇範圍 (Scope)
|
||||
scopes_list=範圍 (Scope):
|
||||
|
||||
manage_oauth2_applications=管理 OAuth2 應用程式
|
||||
edit_oauth2_application=編輯 OAuth2 應用程式
|
||||
@ -759,6 +768,7 @@ create_oauth2_application_button=建立應用程式
|
||||
create_oauth2_application_success=您已成功新增一個 OAuth2 應用程式。
|
||||
update_oauth2_application_success=您已成功更新了 OAuth2 應用程式。
|
||||
oauth2_application_name=應用程式名稱
|
||||
oauth2_confidential_client=機密客戶端 (Confidential Client)。請為能保持機密性的程式勾選,例如網頁應用程式。使用原生程式時不要勾選,包含桌面、行動應用程式。
|
||||
oauth2_redirect_uri=重新導向 URI
|
||||
save_application=儲存
|
||||
oauth2_client_id=客戶端 ID
|
||||
@ -1203,7 +1213,7 @@ projects.edit_success=已更新專案「%s」。
|
||||
projects.type.none=無
|
||||
projects.type.basic_kanban=基本看板
|
||||
projects.type.bug_triage=Bug 檢傷分類
|
||||
projects.template.desc=專案範本
|
||||
projects.template.desc=範本
|
||||
projects.template.desc_helper=選擇專案範本以開始
|
||||
projects.type.uncategorized=未分類
|
||||
projects.column.edit=編輯欄位
|
||||
@ -1215,7 +1225,7 @@ projects.column.set_default=設為預設
|
||||
projects.column.set_default_desc=將此欄位設定為未分類問題及合併請求的預設預設值
|
||||
projects.column.delete=刪除欄位
|
||||
projects.column.deletion_desc=刪除專案欄位會將所有相關的問題移動到「未分類」,是否繼續?
|
||||
projects.column.color=彩色
|
||||
projects.column.color=顏色
|
||||
projects.open=開啟
|
||||
projects.close=關閉
|
||||
projects.column.assigned_to=已指派給
|
||||
@ -1310,6 +1320,7 @@ issues.filter_type.assigned_to_you=指派給您的
|
||||
issues.filter_type.created_by_you=由您建立的
|
||||
issues.filter_type.mentioning_you=提及您的
|
||||
issues.filter_type.review_requested=已提出審核請求
|
||||
issues.filter_type.reviewed_by_you=由您審核
|
||||
issues.filter_sort=排序
|
||||
issues.filter_sort.latest=最新建立
|
||||
issues.filter_sort.oldest=最早建立
|
||||
@ -1383,11 +1394,14 @@ issues.sign_in_require_desc=<a href="%s"> 登入</a> 才能加入這對話。
|
||||
issues.edit=編輯
|
||||
issues.cancel=取消
|
||||
issues.save=儲存
|
||||
issues.label_title=標籤名稱
|
||||
issues.label_description=標籤描述
|
||||
issues.label_color=標籤顏色
|
||||
issues.label_title=名稱
|
||||
issues.label_description=描述
|
||||
issues.label_color=顏色
|
||||
issues.label_exclusive=互斥
|
||||
issues.label_exclusive_desc=請以此格式命名標籤: <code>scope/item</code>,使它和其他 <code>scope/</code> (相同範圍) 標籤互斥。
|
||||
issues.label_exclusive_warning=在編輯問題及合併請求的標籤時,將會刪除任何有相同範圍的標籤。
|
||||
issues.label_count=%d 個標籤
|
||||
issues.label_open_issues=%d 個開放中的問題
|
||||
issues.label_open_issues=%d 個開放中的問題/合併請求
|
||||
issues.label_edit=編輯
|
||||
issues.label_delete=刪除
|
||||
issues.label_modify=編輯標籤
|
||||
@ -1640,6 +1654,7 @@ pulls.reopened_at=`重新開放了這個合併請求 <a id="%[1]s" href="#%[1]s"
|
||||
pulls.merge_instruction_hint=`您也可以查看<a class="show-instruction">命令列指南</a>。`
|
||||
pulls.merge_instruction_step1_desc=在您的儲存庫中切換到新分支並測試變更。
|
||||
pulls.merge_instruction_step2_desc=合併變更並更新到 Gitea。
|
||||
pulls.clear_merge_message=清除合併訊息
|
||||
|
||||
pulls.auto_merge_button_when_succeed=(當通過檢查後)
|
||||
pulls.auto_merge_when_succeed=通過所有檢查後自動合併
|
||||
@ -2423,7 +2438,7 @@ teams.leave.detail=確定要離開 %s 嗎?
|
||||
teams.can_create_org_repo=建立儲存庫
|
||||
teams.can_create_org_repo_helper=成員可以在組織中新增儲存庫。建立者將自動取得新儲存庫的管理員權限。
|
||||
teams.none_access=沒有權限
|
||||
teams.none_access_helper=成員無法檢視此單元或對其執行其他動作。
|
||||
teams.none_access_helper=成員無法檢視此單元或對其執行其他動作,這對公開儲存庫沒有影響。
|
||||
teams.general_access=一般權限
|
||||
teams.general_access_helper=成員權限將由下列權限表決定。
|
||||
teams.read_access=讀取
|
||||
@ -2561,6 +2576,10 @@ dashboard.delete_old_actions=從資料庫刪除所有舊行為
|
||||
dashboard.delete_old_actions.started=從資料庫刪除所有舊行為的任務已啟動。
|
||||
dashboard.update_checker=更新檢查器
|
||||
dashboard.delete_old_system_notices=從資料庫刪除所有舊系統提示
|
||||
dashboard.gc_lfs=對 LFS meta objects 進行垃圾回收
|
||||
dashboard.stop_zombie_tasks=停止殭屍任務
|
||||
dashboard.stop_endless_tasks=停止永不停止的任務
|
||||
dashboard.cancel_abandoned_jobs=取消已放棄的工作
|
||||
|
||||
users.user_manage_panel=使用者帳戶管理
|
||||
users.new_account=建立使用者帳戶
|
||||
@ -2649,6 +2668,7 @@ repos.size=大小
|
||||
|
||||
packages.package_manage_panel=套件管理
|
||||
packages.total_size=總大小: %s
|
||||
packages.unreferenced_size=未參考大小: %s
|
||||
packages.owner=擁有者
|
||||
packages.creator=建立者
|
||||
packages.name=名稱
|
||||
@ -2742,6 +2762,7 @@ auths.oauth2_required_claim_value_helper=填寫此名稱以限制 Claim 中有
|
||||
auths.oauth2_group_claim_name=Claim 名稱提供群組名稱給此來源。(選用)
|
||||
auths.oauth2_admin_group=管理員使用者的群組 Claim 值。(選用 - 需要上面的 Claim 名稱)
|
||||
auths.oauth2_restricted_group=受限制使用者的群組 Claim 值。(選用 - 需要上面的 Claim 名稱)
|
||||
auths.oauth2_map_group_to_team_removal=如果使用者不屬於相對應的群組,將使用者從已同步的團隊移除。
|
||||
auths.enable_auto_register=允許授權用戶自動註冊
|
||||
auths.sspi_auto_create_users=自動建立使用者
|
||||
auths.sspi_auto_create_users_helper=允許 SSPI 認證方法於使用者首次登入時自動建立新帳戶
|
||||
@ -3218,8 +3239,14 @@ settings.delete.description=刪除套件是永久且不可還原的。
|
||||
settings.delete.notice=您正要刪除 %s (%s),此動作是無法還原的,您確定嗎?
|
||||
settings.delete.success=已刪除該套件。
|
||||
settings.delete.error=刪除套件失敗。
|
||||
owner.settings.cargo.title=Cargo Registry 索引
|
||||
owner.settings.cargo.initialize=初始化索引
|
||||
owner.settings.cargo.initialize.error=初始化 Cargo 索引失敗: %v
|
||||
owner.settings.cargo.initialize.success=成功建立了 Cargo 索引。
|
||||
owner.settings.cargo.rebuild=重建索引
|
||||
owner.settings.cargo.rebuild.description=如果索引和 Cargo 套件不同步,您可在此重建它。
|
||||
owner.settings.cargo.rebuild.error=重建 Cargo 索引失敗: %v
|
||||
owner.settings.cargo.rebuild.success=成功重建了 Cargo 索引。
|
||||
owner.settings.cleanuprules.title=管理清理規則
|
||||
owner.settings.cleanuprules.add=加入清理規則
|
||||
owner.settings.cleanuprules.edit=編輯清理規則
|
||||
@ -3239,32 +3266,80 @@ owner.settings.cleanuprules.remove.days=移除早於天數的版本
|
||||
owner.settings.cleanuprules.remove.pattern=移除版本的比對規則
|
||||
owner.settings.cleanuprules.success.update=已更新清理規則。
|
||||
owner.settings.cleanuprules.success.delete=已刪除清理規則。
|
||||
owner.settings.chef.title=Chef Registry
|
||||
owner.settings.chef.keypair=產生密鑰組
|
||||
owner.settings.chef.keypair.description=產生用來認證 Chef Registry 的密鑰組,之前的密鑰未來將無法使用。
|
||||
|
||||
[secrets]
|
||||
secrets=Secret
|
||||
description=Secret 會被傳給特定的 Action,其他情況無法讀取。
|
||||
none=還沒有 Secret。
|
||||
value=值
|
||||
name=組織名稱
|
||||
creation=加入 Secret
|
||||
creation.value_placeholder=輸入任何內容,頭尾的空白都會被忽略。
|
||||
creation.success=已加入 Secret「%s」。
|
||||
creation.failed=加入 Secret 失敗。
|
||||
deletion=移除 Secret
|
||||
deletion.description=移除 Secret 是永久的且不可還原,是否繼續?
|
||||
deletion.success=已移除此 Secret。
|
||||
deletion.failed=移除 Secret 失敗。
|
||||
|
||||
[actions]
|
||||
actions=Actions
|
||||
|
||||
unit.desc=管理 Actions
|
||||
|
||||
status.unknown=未知
|
||||
status.waiting=正在等候
|
||||
status.running=正在執行
|
||||
status.success=成功
|
||||
status.failure=失敗
|
||||
status.cancelled=已取消
|
||||
status.skipped=已略過
|
||||
status.blocked=已阻塞
|
||||
|
||||
runners=Runner
|
||||
runners.runner_manage_panel=Runner 管理
|
||||
runners.new=建立 Runner
|
||||
runners.new_notice=如何啟動 Runner
|
||||
runners.status=狀態
|
||||
runners.id=ID
|
||||
runners.name=組織名稱
|
||||
runners.owner_type=認證類型
|
||||
runners.description=組織描述
|
||||
runners.labels=標籤
|
||||
runners.last_online=最後上線時間
|
||||
runners.agent_labels=代理程式標籤
|
||||
runners.custom_labels=自訂標籤
|
||||
runners.custom_labels_helper=自訂標籤是由管理員手動加上的標籤。標籤之間以半形逗號「,」分隔,標籤頭尾的空白將被忽略。
|
||||
runners.runner_title=Runner
|
||||
runners.task_list=最近在此 Runner 上的任務
|
||||
runners.task_list.run=執行
|
||||
runners.task_list.status=狀態
|
||||
runners.task_list.repository=儲存庫
|
||||
runners.task_list.commit=提交
|
||||
runners.task_list.done_at=完成於
|
||||
runners.edit_runner=編輯 Runner
|
||||
runners.update_runner=更新變更
|
||||
runners.update_runner_success=更新 Runner 成功
|
||||
runners.update_runner_failed=更新 Runner 失敗
|
||||
runners.delete_runner=刪除此 Runner
|
||||
runners.delete_runner_success=刪除 Runner 成功
|
||||
runners.delete_runner_failed=刪除 Runner 失敗
|
||||
runners.delete_runner_header=確認刪除此 Runner
|
||||
runners.delete_runner_notice=如果有任務正在此 Runner 上執行,它可能會被中止並標記為失敗,這可能會打斷建置工作流程。
|
||||
runners.none=沒有可用的 Runner
|
||||
runners.status.unspecified=未知
|
||||
runners.status.idle=閒置
|
||||
runners.status.active=啟用
|
||||
runners.status.offline=離線
|
||||
|
||||
runs.all_workflows=所有工作流程
|
||||
runs.open_tab=%d 開放中
|
||||
runs.closed_tab=%d 已關閉
|
||||
runs.commit=提交
|
||||
runs.pushed_by=推送者
|
||||
|
||||
need_approval_desc=來自 Frok 儲存庫的合併請求需要核可才能執行工作流程。
|
||||
|
||||
|
@ -103,7 +103,7 @@ func Projects(ctx *context.Context) {
|
||||
pager.AddParam(ctx, "state", "State")
|
||||
ctx.Data["Page"] = pager
|
||||
|
||||
ctx.Data["CanWriteProjects"] = canWriteUnit(ctx)
|
||||
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
|
||||
ctx.Data["IsShowClosed"] = isShowClosed
|
||||
ctx.Data["PageIsViewProjects"] = true
|
||||
ctx.Data["SortType"] = sortType
|
||||
@ -111,7 +111,7 @@ func Projects(ctx *context.Context) {
|
||||
ctx.HTML(http.StatusOK, tplProjects)
|
||||
}
|
||||
|
||||
func canWriteUnit(ctx *context.Context) bool {
|
||||
func canWriteProjects(ctx *context.Context) bool {
|
||||
if ctx.ContextUser.IsOrganization() {
|
||||
return ctx.Org.CanWriteUnit(ctx, unit.TypeProjects)
|
||||
}
|
||||
@ -122,7 +122,7 @@ func canWriteUnit(ctx *context.Context) bool {
|
||||
func NewProject(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.projects.new")
|
||||
ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
|
||||
ctx.Data["CanWriteProjects"] = canWriteUnit(ctx)
|
||||
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
|
||||
ctx.Data["HomeLink"] = ctx.ContextUser.HomeLink()
|
||||
shared_user.RenderUserHeader(ctx)
|
||||
ctx.HTML(http.StatusOK, tplProjectsNew)
|
||||
@ -135,7 +135,7 @@ func NewProjectPost(ctx *context.Context) {
|
||||
shared_user.RenderUserHeader(ctx)
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.Data["CanWriteProjects"] = canWriteUnit(ctx)
|
||||
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
|
||||
ctx.Data["PageIsViewProjects"] = true
|
||||
ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
|
||||
ctx.HTML(http.StatusOK, tplProjectsNew)
|
||||
@ -193,7 +193,7 @@ func DeleteProject(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
if p.RepoID != ctx.Repo.Repository.ID {
|
||||
if p.OwnerID != ctx.ContextUser.ID {
|
||||
ctx.NotFound("", nil)
|
||||
return
|
||||
}
|
||||
@ -214,7 +214,7 @@ func EditProject(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
|
||||
ctx.Data["PageIsEditProjects"] = true
|
||||
ctx.Data["PageIsViewProjects"] = true
|
||||
ctx.Data["CanWriteProjects"] = canWriteUnit(ctx)
|
||||
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
|
||||
shared_user.RenderUserHeader(ctx)
|
||||
|
||||
p, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
|
||||
@ -226,13 +226,14 @@ func EditProject(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
if p.RepoID != ctx.Repo.Repository.ID {
|
||||
if p.OwnerID != ctx.ContextUser.ID {
|
||||
ctx.NotFound("", nil)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["title"] = p.Title
|
||||
ctx.Data["content"] = p.Description
|
||||
ctx.Data["redirect"] = ctx.FormString("redirect")
|
||||
|
||||
ctx.HTML(http.StatusOK, tplProjectsNew)
|
||||
}
|
||||
@ -243,7 +244,7 @@ func EditProjectPost(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
|
||||
ctx.Data["PageIsEditProjects"] = true
|
||||
ctx.Data["PageIsViewProjects"] = true
|
||||
ctx.Data["CanWriteProjects"] = canWriteUnit(ctx)
|
||||
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
|
||||
shared_user.RenderUserHeader(ctx)
|
||||
|
||||
if ctx.HasError() {
|
||||
@ -260,7 +261,7 @@ func EditProjectPost(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
if p.RepoID != ctx.Repo.Repository.ID {
|
||||
if p.OwnerID != ctx.ContextUser.ID {
|
||||
ctx.NotFound("", nil)
|
||||
return
|
||||
}
|
||||
@ -273,7 +274,11 @@ func EditProjectPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.projects.edit_success", p.Title))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/projects")
|
||||
if ctx.FormString("redirect") == "project" {
|
||||
ctx.Redirect(p.Link())
|
||||
} else {
|
||||
ctx.Redirect(ctx.ContextUser.HomeLink() + "/-/projects")
|
||||
}
|
||||
}
|
||||
|
||||
// ViewProject renders the project board for a project
|
||||
@ -332,7 +337,7 @@ func ViewProject(ctx *context.Context) {
|
||||
project.RenderedContent = project.Description
|
||||
ctx.Data["LinkedPRs"] = linkedPrsMap
|
||||
ctx.Data["PageIsViewProjects"] = true
|
||||
ctx.Data["CanWriteProjects"] = canWriteUnit(ctx)
|
||||
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
|
||||
ctx.Data["Project"] = project
|
||||
ctx.Data["IssuesMap"] = issuesMap
|
||||
ctx.Data["Boards"] = boards
|
||||
|
@ -235,6 +235,7 @@ func EditProject(ctx *context.Context) {
|
||||
ctx.Data["title"] = p.Title
|
||||
ctx.Data["content"] = p.Description
|
||||
ctx.Data["card_type"] = p.CardType
|
||||
ctx.Data["redirect"] = ctx.FormString("redirect")
|
||||
|
||||
ctx.HTML(http.StatusOK, tplProjectsNew)
|
||||
}
|
||||
@ -275,7 +276,11 @@ func EditProjectPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.projects.edit_success", p.Title))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/projects")
|
||||
if ctx.FormString("redirect") == "project" {
|
||||
ctx.Redirect(p.Link())
|
||||
} else {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/projects")
|
||||
}
|
||||
}
|
||||
|
||||
// ViewProject renders the project board for a project
|
||||
|
@ -14,58 +14,6 @@ import (
|
||||
issue_service "code.gitea.io/gitea/services/issue"
|
||||
)
|
||||
|
||||
type commitBranchCheckItem struct {
|
||||
Commit *git.Commit
|
||||
Checked bool
|
||||
}
|
||||
|
||||
func commitBranchCheck(gitRepo *git.Repository, startCommit *git.Commit, endCommitID, baseBranch string, commitList map[string]*commitBranchCheckItem) error {
|
||||
if startCommit.ID.String() == endCommitID {
|
||||
return nil
|
||||
}
|
||||
|
||||
checkStack := make([]string, 0, 10)
|
||||
checkStack = append(checkStack, startCommit.ID.String())
|
||||
|
||||
for len(checkStack) > 0 {
|
||||
commitID := checkStack[0]
|
||||
checkStack = checkStack[1:]
|
||||
|
||||
item, ok := commitList[commitID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if item.Commit.ID.String() == endCommitID {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := item.Commit.LoadBranchName(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if item.Commit.Branch == baseBranch {
|
||||
continue
|
||||
}
|
||||
|
||||
if item.Checked {
|
||||
continue
|
||||
}
|
||||
|
||||
item.Checked = true
|
||||
|
||||
parentNum := item.Commit.ParentCount()
|
||||
for i := 0; i < parentNum; i++ {
|
||||
parentCommit, err := item.Commit.Parent(i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
checkStack = append(checkStack, parentCommit.ID.String())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getCommitIDsFromRepo get commit IDs from repo in between oldCommitID and newCommitID
|
||||
// isForcePush will be true if oldCommit isn't on the branch
|
||||
// Commit on baseBranch will skip
|
||||
@ -82,47 +30,33 @@ func getCommitIDsFromRepo(ctx context.Context, repo *repo_model.Repository, oldC
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if err = oldCommit.LoadBranchName(); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if len(oldCommit.Branch) == 0 {
|
||||
commitIDs = make([]string, 2)
|
||||
commitIDs[0] = oldCommitID
|
||||
commitIDs[1] = newCommitID
|
||||
|
||||
return commitIDs, true, err
|
||||
}
|
||||
|
||||
newCommit, err := gitRepo.GetCommit(newCommitID)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
commits, err := newCommit.CommitsBeforeUntil(oldCommitID)
|
||||
isForcePush, err = newCommit.IsForcePush(oldCommitID)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if isForcePush {
|
||||
commitIDs = make([]string, 2)
|
||||
commitIDs[0] = oldCommitID
|
||||
commitIDs[1] = newCommitID
|
||||
|
||||
return commitIDs, isForcePush, err
|
||||
}
|
||||
|
||||
// Find commits between new and old commit exclusing base branch commits
|
||||
commits, err := gitRepo.CommitsBetweenNotBase(newCommit, oldCommit, baseBranch)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
commitIDs = make([]string, 0, len(commits))
|
||||
commitChecks := make(map[string]*commitBranchCheckItem)
|
||||
|
||||
for _, commit := range commits {
|
||||
commitChecks[commit.ID.String()] = &commitBranchCheckItem{
|
||||
Commit: commit,
|
||||
Checked: false,
|
||||
}
|
||||
}
|
||||
|
||||
if err = commitBranchCheck(gitRepo, newCommit, oldCommitID, baseBranch, commitChecks); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for i := len(commits) - 1; i >= 0; i-- {
|
||||
commitID := commits[i].ID.String()
|
||||
if item, ok := commitChecks[commitID]; ok && item.Checked {
|
||||
commitIDs = append(commitIDs, commitID)
|
||||
}
|
||||
commitIDs = append(commitIDs, commits[i].ID.String())
|
||||
}
|
||||
|
||||
return commitIDs, isForcePush, err
|
||||
|
@ -332,8 +332,13 @@ func doMergeAndPush(ctx context.Context, pr *issues_model.PullRequest, doer *use
|
||||
}
|
||||
|
||||
func commitAndSignNoAuthor(ctx *mergeContext, message string) error {
|
||||
if err := git.NewCommand(ctx, "commit").AddArguments(ctx.signArg...).AddOptionFormat("--message=%s", message).
|
||||
Run(ctx.RunOpts()); err != nil {
|
||||
cmdCommit := git.NewCommand(ctx, "commit").AddOptionFormat("--message=%s", message)
|
||||
if ctx.signKeyID == "" {
|
||||
cmdCommit.AddArguments("--no-gpg-sign")
|
||||
} else {
|
||||
cmdCommit.AddOptionFormat("-S%s", ctx.signKeyID)
|
||||
}
|
||||
if err := cmdCommit.Run(ctx.RunOpts()); err != nil {
|
||||
log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||
return fmt.Errorf("git commit %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ type mergeContext struct {
|
||||
doer *user_model.User
|
||||
sig *git.Signature
|
||||
committer *git.Signature
|
||||
signArg git.TrustedCmdArgs
|
||||
signKeyID string // empty for no-sign, non-empty to sign
|
||||
env []string
|
||||
}
|
||||
|
||||
@ -85,12 +85,10 @@ func createTemporaryRepoForMerge(ctx context.Context, pr *issues_model.PullReque
|
||||
// Determine if we should sign
|
||||
sign, keyID, signer, _ := asymkey_service.SignMerge(ctx, mergeCtx.pr, mergeCtx.doer, mergeCtx.tmpBasePath, "HEAD", trackingBranch)
|
||||
if sign {
|
||||
mergeCtx.signArg = git.ToTrustedCmdArgs([]string{"-S" + keyID})
|
||||
mergeCtx.signKeyID = keyID
|
||||
if pr.BaseRepo.GetTrustModel() == repo_model.CommitterTrustModel || pr.BaseRepo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {
|
||||
mergeCtx.committer = signer
|
||||
}
|
||||
} else {
|
||||
mergeCtx.signArg = git.ToTrustedCmdArgs([]string{"--no-gpg-sign"})
|
||||
}
|
||||
|
||||
commitTimeStr := time.Now().Format(time.RFC3339)
|
||||
@ -136,18 +134,11 @@ func prepareTemporaryRepoForMerge(ctx *mergeContext) error {
|
||||
return fmt.Errorf("Unable to close .git/info/sparse-checkout file in tmpBasePath: %w", err)
|
||||
}
|
||||
|
||||
gitConfigCommand := func() *git.Command {
|
||||
return git.NewCommand(ctx, "config", "--local")
|
||||
}
|
||||
|
||||
setConfig := func(key, value string) error {
|
||||
if err := gitConfigCommand().AddArguments(git.ToTrustedCmdArgs([]string{key, value})...).
|
||||
if err := git.NewCommand(ctx, "config", "--local").AddDynamicArguments(key, value).
|
||||
Run(ctx.RunOpts()); err != nil {
|
||||
if value == "" {
|
||||
value = "<>"
|
||||
}
|
||||
log.Error("git config [%s -> %s ]: %v\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||
return fmt.Errorf("git config [%s -> %s ]: %w\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||
log.Error("git config [%s -> %q]: %v\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||
return fmt.Errorf("git config [%s -> %q]: %w\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||
}
|
||||
ctx.outbuf.Reset()
|
||||
ctx.errbuf.Reset()
|
||||
|
@ -7,45 +7,77 @@ import (
|
||||
"fmt"
|
||||
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
// doMergeStyleSquash gets a commit author signature for squash commits
|
||||
func getAuthorSignatureSquash(ctx *mergeContext) (*git.Signature, error) {
|
||||
if err := ctx.pr.Issue.LoadPoster(ctx); err != nil {
|
||||
log.Error("%-v Issue[%d].LoadPoster: %v", ctx.pr, ctx.pr.Issue.ID, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Try to get an signature from the same user in one of the commits, as the
|
||||
// poster email might be private or commits might have a different signature
|
||||
// than the primary email address of the poster.
|
||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, ctx.tmpBasePath)
|
||||
if err != nil {
|
||||
log.Error("%-v Unable to open base repository: %v", ctx.pr, err)
|
||||
return nil, err
|
||||
}
|
||||
defer closer.Close()
|
||||
|
||||
commits, err := gitRepo.CommitsBetweenIDs(trackingBranch, "HEAD")
|
||||
if err != nil {
|
||||
log.Error("%-v Unable to get commits between: %s %s: %v", ctx.pr, "HEAD", trackingBranch, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
uniqueEmails := make(container.Set[string])
|
||||
for _, commit := range commits {
|
||||
if commit.Author != nil && uniqueEmails.Add(commit.Author.Email) {
|
||||
commitUser, _ := user_model.GetUserByEmail(ctx, commit.Author.Email)
|
||||
if commitUser != nil && commitUser.ID == ctx.pr.Issue.Poster.ID {
|
||||
return commit.Author, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ctx.pr.Issue.Poster.NewGitSig(), nil
|
||||
}
|
||||
|
||||
// doMergeStyleSquash squashes the tracking branch on the current HEAD (=base)
|
||||
func doMergeStyleSquash(ctx *mergeContext, message string) error {
|
||||
cmd := git.NewCommand(ctx, "merge", "--squash").AddDynamicArguments(trackingBranch)
|
||||
if err := runMergeCommand(ctx, repo_model.MergeStyleSquash, cmd); err != nil {
|
||||
sig, err := getAuthorSignatureSquash(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getAuthorSignatureSquash: %w", err)
|
||||
}
|
||||
|
||||
cmdMerge := git.NewCommand(ctx, "merge", "--squash").AddDynamicArguments(trackingBranch)
|
||||
if err := runMergeCommand(ctx, repo_model.MergeStyleSquash, cmdMerge); err != nil {
|
||||
log.Error("%-v Unable to merge --squash tracking into base: %v", ctx.pr, err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ctx.pr.Issue.LoadPoster(ctx); err != nil {
|
||||
log.Error("%-v Issue[%d].LoadPoster: %v", ctx.pr, ctx.pr.Issue.ID, err)
|
||||
return fmt.Errorf("LoadPoster: %w", err)
|
||||
if setting.Repository.PullRequest.AddCoCommitterTrailers && ctx.committer.String() != sig.String() {
|
||||
// add trailer
|
||||
message += fmt.Sprintf("\nCo-authored-by: %s\nCo-committed-by: %s\n", sig.String(), sig.String())
|
||||
}
|
||||
sig := ctx.pr.Issue.Poster.NewGitSig()
|
||||
if len(ctx.signArg) == 0 {
|
||||
if err := git.NewCommand(ctx, "commit").
|
||||
AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email).
|
||||
AddOptionFormat("--message=%s", message).
|
||||
Run(ctx.RunOpts()); err != nil {
|
||||
log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||
return fmt.Errorf("git commit [%s:%s -> %s:%s]: %w\n%s\n%s", ctx.pr.HeadRepo.FullName(), ctx.pr.HeadBranch, ctx.pr.BaseRepo.FullName(), ctx.pr.BaseBranch, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||
}
|
||||
cmdCommit := git.NewCommand(ctx, "commit").
|
||||
AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email).
|
||||
AddOptionFormat("--message=%s", message)
|
||||
if ctx.signKeyID == "" {
|
||||
cmdCommit.AddArguments("--no-gpg-sign")
|
||||
} else {
|
||||
if setting.Repository.PullRequest.AddCoCommitterTrailers && ctx.committer.String() != sig.String() {
|
||||
// add trailer
|
||||
message += fmt.Sprintf("\nCo-authored-by: %s\nCo-committed-by: %s\n", sig.String(), sig.String())
|
||||
}
|
||||
if err := git.NewCommand(ctx, "commit").
|
||||
AddArguments(ctx.signArg...).
|
||||
AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email).
|
||||
AddOptionFormat("--message=%s", message).
|
||||
Run(ctx.RunOpts()); err != nil {
|
||||
log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||
return fmt.Errorf("git commit [%s:%s -> %s:%s]: %w\n%s\n%s", ctx.pr.HeadRepo.FullName(), ctx.pr.HeadBranch, ctx.pr.BaseRepo.FullName(), ctx.pr.BaseBranch, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||
}
|
||||
cmdCommit.AddOptionFormat("-S%s", ctx.signKeyID)
|
||||
}
|
||||
if err := cmdCommit.Run(ctx.RunOpts()); err != nil {
|
||||
log.Error("git commit %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||
return fmt.Errorf("git commit [%s:%s -> %s:%s]: %w\n%s\n%s", ctx.pr.HeadRepo.FullName(), ctx.pr.HeadBranch, ctx.pr.BaseRepo.FullName(), ctx.pr.BaseBranch, err, ctx.outbuf.String(), ctx.errbuf.String())
|
||||
}
|
||||
ctx.outbuf.Reset()
|
||||
ctx.errbuf.Reset()
|
||||
|
@ -669,7 +669,12 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequ
|
||||
|
||||
authorString := commit.Author.String()
|
||||
if uniqueAuthors.Add(authorString) && authorString != posterSig {
|
||||
authors = append(authors, authorString)
|
||||
// Compare use account as well to avoid adding the same author multiple times
|
||||
// times when email addresses are private or multiple emails are used.
|
||||
commitUser, _ := user_model.GetUserByEmail(ctx, commit.Author.Email)
|
||||
if commitUser == nil || commitUser.ID != pr.Issue.Poster.ID {
|
||||
authors = append(authors, authorString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -690,7 +695,10 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequ
|
||||
for _, commit := range commits {
|
||||
authorString := commit.Author.String()
|
||||
if uniqueAuthors.Add(authorString) && authorString != posterSig {
|
||||
authors = append(authors, authorString)
|
||||
commitUser, _ := user_model.GetUserByEmail(ctx, commit.Author.Email)
|
||||
if commitUser == nil || commitUser.ID != pr.Issue.Poster.ID {
|
||||
authors = append(authors, authorString)
|
||||
}
|
||||
}
|
||||
}
|
||||
skip += limit
|
||||
|
@ -206,12 +206,12 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
|
||||
return fmt.Errorf("newCommit.CommitsBeforeUntil: %w", err)
|
||||
}
|
||||
|
||||
isForce, err := repo_module.IsForcePush(ctx, opts)
|
||||
isForcePush, err := newCommit.IsForcePush(opts.OldCommitID)
|
||||
if err != nil {
|
||||
log.Error("isForcePush %s:%s failed: %v", repo.FullName(), branch, err)
|
||||
log.Error("IsForcePush %s:%s failed: %v", repo.FullName(), branch, err)
|
||||
}
|
||||
|
||||
if isForce {
|
||||
if isForcePush {
|
||||
log.Trace("Push %s is a force push", opts.NewCommitID)
|
||||
|
||||
cache.Remove(repo.GetCommitsCountCacheKey(opts.RefName(), true))
|
||||
|
@ -21,6 +21,7 @@
|
||||
<form class="ui form grid" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="eleven wide column">
|
||||
<input type="hidden" id="redirect" name="redirect" value="{{.redirect}}">
|
||||
<div class="field {{if .Err_Title}}error{{end}}">
|
||||
<label>{{.locale.Tr "repo.projects.title"}}</label>
|
||||
<input name="title" placeholder="{{.locale.Tr "repo.projects.title"}}" value="{{.title}}" autofocus required>
|
||||
|
@ -46,7 +46,7 @@
|
||||
{{if or $.CanWriteIssues $.CanWritePulls}}
|
||||
<div class="column right aligned">
|
||||
<div class="ui compact right small menu">
|
||||
<a class="item" href="{{$.Link}}/edit" data-id={{$.Project.ID}} data-title={{$.Project.Title}}>
|
||||
<a class="item" href="{{$.Link}}/edit?redirect=project" data-id={{$.Project.ID}} data-title={{$.Project.Title}}>
|
||||
{{svg "octicon-pencil"}}
|
||||
<span class="gt-mx-3">{{$.locale.Tr "repo.issues.label_edit"}}</span>
|
||||
</a>
|
||||
|
@ -63,7 +63,7 @@
|
||||
{{end}}
|
||||
{{template "repo/sub_menu" .}}
|
||||
<div class="repo-button-row gt-df gt-ac gt-sb gt-fw">
|
||||
<div class="gt-df gt-ac">
|
||||
<div class="gt-df gt-ac gt-fw gt-gap-y-3">
|
||||
{{template "repo/branch_dropdown" dict "root" .}}
|
||||
{{$n := len .TreeNames}}
|
||||
{{$l := Subtract $n 1}}
|
||||
@ -99,20 +99,16 @@
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
</button>
|
||||
{{end}}
|
||||
{{if and (eq $n 0) (.Repository.IsTemplate)}}
|
||||
<a role="button" class="ui primary compact button" href="{{AppSubUrl}}/repo/create?template_id={{.Repository.ID}}">
|
||||
{{.locale.Tr "repo.use_template"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if ne $n 0}}
|
||||
<span class="ui breadcrumb repo-path gt-ml-2"><a class="section" href="{{.RepoLink}}/src/{{.BranchNameSubURL}}" title="{{.Repository.Name}}">{{EllipsisString .Repository.Name 30}}</a>{{range $i, $v := .TreeNames}}<span class="divider">/</span>{{if eq $i $l}}<span class="active section" title="{{$v}}">{{EllipsisString $v 30}}</span>{{else}}{{$p := index $.Paths $i}}<span class="section"><a href="{{$.BranchLink}}/{{PathEscapeSegments $p}}" title="{{$v}}">{{EllipsisString $v 30}}</a></span>{{end}}{{end}}</span>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="gt-df gt-ac">
|
||||
{{if eq $n 0}}
|
||||
{{if .Repository.IsTemplate}}
|
||||
<div class="ui tiny primary buttons">
|
||||
<a href="{{AppSubUrl}}/repo/create?template_id={{.Repository.ID}}" class="ui button">
|
||||
{{.locale.Tr "repo.use_template"}}
|
||||
</a>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<!-- Only show clone panel in repository home page -->
|
||||
{{if eq $n 0}}
|
||||
<div class="ui action tiny input" id="clone-panel">
|
||||
|
@ -24,6 +24,7 @@
|
||||
<form class="ui form grid" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="eleven wide column">
|
||||
<input type="hidden" id="redirect" name="redirect" value="{{.redirect}}">
|
||||
<div class="field {{if .Err_Title}}error{{end}}">
|
||||
<label>{{.locale.Tr "repo.projects.title"}}</label>
|
||||
<input name="title" placeholder="{{.locale.Tr "repo.projects.title"}}" value="{{.title}}" autofocus required>
|
||||
|
@ -50,7 +50,7 @@
|
||||
{{if and (or $.CanWriteIssues $.CanWritePulls) (not $.Repository.IsArchived)}}
|
||||
<div class="column right aligned">
|
||||
<div class="ui compact right small menu">
|
||||
<a class="item" href="{{$.RepoLink}}/projects/{{.Project.ID}}/edit" data-id={{$.Project.ID}} data-title={{$.Project.Title}}>
|
||||
<a class="item" href="{{$.RepoLink}}/projects/{{.Project.ID}}/edit?redirect=project" data-id={{$.Project.ID}} data-title={{$.Project.Title}}>
|
||||
{{svg "octicon-pencil"}}
|
||||
<span class="gt-mx-3">{{$.locale.Tr "repo.issues.label_edit"}}</span>
|
||||
</a>
|
||||
|
@ -2876,7 +2876,7 @@
|
||||
}
|
||||
|
||||
.repo-button-row > * {
|
||||
margin-top: 10px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.wiki .repo-button-row {
|
||||
|
79
web_src/less/chroma/chroma-style-diff.go
Normal file
79
web_src/less/chroma/chroma-style-diff.go
Normal file
@ -0,0 +1,79 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build ignore
|
||||
|
||||
/*
|
||||
This tool is used to compare the CSS names in a chroma builtin styles with the Gitea theme CSS names.
|
||||
|
||||
It outputs the difference between the two sets of CSS names, eg:
|
||||
|
||||
```
|
||||
CSS names not in builtin:
|
||||
.chroma .ln
|
||||
----
|
||||
Builtin CSS names not in file:
|
||||
.chroma .vm
|
||||
```
|
||||
|
||||
Developers could use this tool to re-sync the CSS names in the Gitea theme.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/chroma/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
println("Usage: chroma-style-diff css-or-less-file")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(os.Args[1])
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
content := string(data)
|
||||
|
||||
// a simple CSS parser to collect CSS names
|
||||
content = regexp.MustCompile("//.*\r?\n").ReplaceAllString(content, "\n")
|
||||
content = regexp.MustCompile("/\\*.*?\\*/").ReplaceAllString(content, "")
|
||||
matches := regexp.MustCompile("\\s*([-.#:\\w\\s]+)\\s*\\{[^}]*}").FindAllStringSubmatch(content, -1)
|
||||
|
||||
cssNames := map[string]bool{}
|
||||
for _, matchGroup := range matches {
|
||||
cssName := strings.TrimSpace(matchGroup[1])
|
||||
cssNames[cssName] = true
|
||||
}
|
||||
|
||||
// collect Chroma builtin CSS names
|
||||
builtin := map[string]bool{}
|
||||
for tokenType, cssName := range chroma.StandardTypes {
|
||||
if tokenType > 0 && cssName != "" {
|
||||
builtin[".chroma ."+cssName] = true
|
||||
}
|
||||
}
|
||||
|
||||
// show the diff
|
||||
println("CSS names not in builtin:")
|
||||
for cssName := range cssNames {
|
||||
if !builtin[cssName] {
|
||||
println(cssName)
|
||||
}
|
||||
}
|
||||
println("----")
|
||||
println("Builtin CSS names not in file:")
|
||||
for cssName := range builtin {
|
||||
if !cssNames[cssName] {
|
||||
println(cssName)
|
||||
}
|
||||
}
|
||||
}
|
@ -7,17 +7,19 @@
|
||||
.chroma .cpf { color: #649bc4; } /* CommentPreprocFile */
|
||||
.chroma .cs { color: #9075cd; } /* CommentSpecial */
|
||||
.chroma .dl { color: #649bc4; } /* LiteralStringDelimiter */
|
||||
.chroma .fm {} /* NameFunctionMagic */
|
||||
.chroma .g {} /* Generic */
|
||||
.chroma .gd { color: #ffffff; background-color: #5f3737; } /* GenericDeleted */
|
||||
.chroma .ge { color: #ddee30; } /* GenericEmph */
|
||||
.chroma .gh { color: #ffaa10; } /* GenericHeading */
|
||||
.chroma .gi { color: #ffffff; background-color: #3a523a; } /* GenericInserted */
|
||||
.chroma .gl {} /* GenericUnderline */
|
||||
.chroma .go { color: #777e94; } /* GenericOutput */
|
||||
.chroma .gp { color: #ebdbb2; } /* GenericPrompt */
|
||||
.chroma .gr { color: #ff4433; } /* GenericError */
|
||||
.chroma .gs { color: #ebdbb2; } /* GenericStrong */
|
||||
.chroma .gt { color: #ff7540; } /* GenericTraceback */
|
||||
.chroma .gu { color: #b8bb26; } /* GenericSubheading */
|
||||
.chroma .hl { background-color: #3f424d; } /* LineHighlight */
|
||||
.chroma .il { color: #649bc4; } /* LiteralNumberIntegerLong */
|
||||
.chroma .k { color: #ff7540; } /* Keyword */
|
||||
.chroma .kc { color: #649bc4; } /* KeywordConstant */
|
||||
@ -25,16 +27,16 @@
|
||||
.chroma .kn { color: #ffaa10; } /* KeywordNamespace */
|
||||
.chroma .kp { color: #5f8700; } /* KeywordPseudo */
|
||||
.chroma .kr { color: #ff7540; } /* KeywordReserved */
|
||||
.chroma .kt { color: #fabd2f; } /* KeywordType */
|
||||
.chroma .ln { color: #7f8699; } /* LineNumbers */
|
||||
.chroma .lnt { color: #7f8699; } /* LineNumbersTable */
|
||||
.chroma .kt { color: #ff7b72; } /* KeywordType */
|
||||
.chroma .l {} /* Literal */
|
||||
.chroma .ld {} /* LiteralDate */
|
||||
.chroma .m { color: #649bc4; } /* LiteralNumber */
|
||||
.chroma .mb { color: #649bc4; } /* LiteralNumberBin */
|
||||
.chroma .mf { color: #649bc4; } /* LiteralNumberFloat */
|
||||
.chroma .mh { color: #649bc4; } /* LiteralNumberHex */
|
||||
.chroma .mi { color: #649bc4; } /* LiteralNumberInteger */
|
||||
.chroma .mo { color: #649bc4; } /* LiteralNumberOct */
|
||||
.chroma .n { color: #fabd2f; } /* Name */
|
||||
.chroma .n { color: #c9d1d9; } /* Name */
|
||||
.chroma .na { color: #b8bb26; } /* NameAttribute */
|
||||
.chroma .nb { color: #fabd2f; } /* NameBuiltin */
|
||||
.chroma .nc { color: #ffaa10; } /* NameClass */
|
||||
@ -51,6 +53,7 @@
|
||||
.chroma .o { color: #ff7540; } /* Operator */
|
||||
.chroma .ow { color: #5f8700; } /* OperatorWord */
|
||||
.chroma .p { color: #d2d4db; } /* Punctuation */
|
||||
.chroma .py {} /* NameProperty */
|
||||
.chroma .s { color: #b8bb26; } /* LiteralString */
|
||||
.chroma .s1 { color: #b8bb26; } /* LiteralStringSingle */
|
||||
.chroma .s2 { color: #b8bb26; } /* LiteralStringDouble */
|
||||
@ -67,4 +70,5 @@
|
||||
.chroma .vc { color: #ff7540; } /* NameVariableClass */
|
||||
.chroma .vg { color: #ffaa10; } /* NameVariableGlobal */
|
||||
.chroma .vi { color: #ffaa10; } /* NameVariableInstance */
|
||||
.chroma .vm {} /* NameVariableMagic */
|
||||
.chroma .w { color: #7f8699; } /* TextWhitespace */
|
||||
|
@ -7,16 +7,19 @@
|
||||
.chroma .cpf { color: #4c4dbc; } /* CommentPreprocFile */
|
||||
.chroma .cs { color: #999999; } /* CommentSpecial */
|
||||
.chroma .dl { color: #106303; } /* LiteralStringDelimiter */
|
||||
.chroma .fm {} /* NameFunctionMagic */
|
||||
.chroma .g {} /* Generic */
|
||||
.chroma .gd { color: #000000; background-color: #ffdddd; } /* GenericDeleted */
|
||||
.chroma .ge { color: #000000; } /* GenericEmph */
|
||||
.chroma .gh { color: #999999; } /* GenericHeading */
|
||||
.chroma .gi { color: #000000; background-color: #ddffdd; } /* GenericInserted */
|
||||
.chroma .gl {} /* GenericUnderline */
|
||||
.chroma .go { color: #888888; } /* GenericOutput */
|
||||
.chroma .gp { color: #555555; } /* GenericPrompt */
|
||||
.chroma .gr { color: #aa0000; } /* GenericError */
|
||||
.chroma .gs {} /* GenericStrong */
|
||||
.chroma .gt { color: #aa0000; } /* GenericTraceback */
|
||||
.chroma .gu { color: #aaaaaa; } /* GenericSubheading */
|
||||
.chroma .hl { background-color: #e5e5e5; } /* LineHighlight */
|
||||
.chroma .il { color: #009999; } /* LiteralNumberIntegerLong */
|
||||
.chroma .k { color: #d73a49; } /* Keyword */
|
||||
.chroma .kc { color: #d73a49; } /* KeywordConstant */
|
||||
@ -25,14 +28,15 @@
|
||||
.chroma .kp { color: #d73a49; } /* KeywordPseudo */
|
||||
.chroma .kr { color: #d73a49; } /* KeywordReserved */
|
||||
.chroma .kt { color: #445588; } /* KeywordType */
|
||||
.chroma .ln { color: #7f7f7f; } /* LineNumbers */
|
||||
.chroma .lnt { color: #7f7f7f; } /* LineNumbersTable */
|
||||
.chroma .l {} /* Literal */
|
||||
.chroma .ld {} /* LiteralDate */
|
||||
.chroma .m { color: #009999; } /* LiteralNumber */
|
||||
.chroma .mb { color: #009999; } /* LiteralNumberBin */
|
||||
.chroma .mf { color: #009999; } /* LiteralNumberFloat */
|
||||
.chroma .mh { color: #009999; } /* LiteralNumberHex */
|
||||
.chroma .mi { color: #009999; } /* LiteralNumberInteger */
|
||||
.chroma .mo { color: #009999; } /* LiteralNumberOct */
|
||||
.chroma .n {} /* Name */
|
||||
.chroma .na { color: #d73a49; } /* NameAttribute */
|
||||
.chroma .nb { color: #005cc5; } /* NameBuiltin */
|
||||
.chroma .nc { color: #445588; } /* NameClass */
|
||||
@ -48,6 +52,8 @@
|
||||
.chroma .nx { color: #24292e; } /* NameOther */
|
||||
.chroma .o { color: #d73a49; } /* Operator */
|
||||
.chroma .ow { color: #d73a49; } /* OperatorWord */
|
||||
.chroma .p {} /* Punctuation */
|
||||
.chroma .py {} /* NameProperty */
|
||||
.chroma .s { color: #106303; } /* LiteralString */
|
||||
.chroma .s1 { color: #cc7a00; } /* LiteralStringSingle */
|
||||
.chroma .s2 { color: #106303; } /* LiteralStringDouble */
|
||||
@ -64,4 +70,5 @@
|
||||
.chroma .vc { color: #008080; } /* NameVariableClass */
|
||||
.chroma .vg { color: #008080; } /* NameVariableGlobal */
|
||||
.chroma .vi { color: #008080; } /* NameVariableInstance */
|
||||
.chroma .vm {} /* NameVariableMagic */
|
||||
.chroma .w { color: #bbbbbb; } /* TextWhitespace */
|
||||
|
@ -172,6 +172,27 @@
|
||||
.gt-py-4 { padding-top: 1rem !important; padding-bottom: 1rem !important; }
|
||||
.gt-py-5 { padding-top: 2rem !important; padding-bottom: 2rem !important; }
|
||||
|
||||
.gt-gap-0 { gap: 0 !important; }
|
||||
.gt-gap-1 { gap: .125rem !important; }
|
||||
.gt-gap-2 { gap: .25rem !important; }
|
||||
.gt-gap-3 { gap: .5rem !important; }
|
||||
.gt-gap-4 { gap: 1rem !important; }
|
||||
.gt-gap-5 { gap: 2rem !important; }
|
||||
|
||||
.gt-gap-x-0 { column-gap: 0 !important; }
|
||||
.gt-gap-x-1 { column-gap: .125rem !important; }
|
||||
.gt-gap-x-2 { column-gap: .25rem !important; }
|
||||
.gt-gap-x-3 { column-gap: .5rem !important; }
|
||||
.gt-gap-x-4 { column-gap: 1rem !important; }
|
||||
.gt-gap-x-5 { column-gap: 2rem !important; }
|
||||
|
||||
.gt-gap-y-0 { row-gap: 0 !important; }
|
||||
.gt-gap-y-1 { row-gap: .125rem !important; }
|
||||
.gt-gap-y-2 { row-gap: .25rem !important; }
|
||||
.gt-gap-y-3 { row-gap: .5rem !important; }
|
||||
.gt-gap-y-4 { row-gap: 1rem !important; }
|
||||
.gt-gap-y-5 { row-gap: 2rem !important; }
|
||||
|
||||
.gt-content-center { align-content: center !important; }
|
||||
|
||||
@media @mediaSm {
|
||||
|
@ -1,3 +1,4 @@
|
||||
@import "../chroma/base.less";
|
||||
@import "../chroma/dark.less";
|
||||
@import "../codemirror/dark.less";
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user