同步旧版接口 #42

Merged
wonderful merged 84 commits from develop into master 2021-12-29 10:01:09 +08:00
88 changed files with 58084 additions and 105 deletions

79
conf/locale/TRANSLATORS Normal file
View File

@ -0,0 +1,79 @@
# This file lists all PUBLIC individuals having contributed content to the translation.
# Entries are in alphabetical order.
Adam Jurkiewicz <a DOT jurkiewicz5 AT gmail DOT com>
Adam Strzelecki <ono AT java DOT pl>
Adrian Verde <me AT adrianverde DOT com>
Akihiro YAGASAKI <yaggytter AT momiage DOT com>
Aleksejs Grocevs <aleksejs AT grocevs DOT pro>
Aleksey Tarakin <hukendo AT yandex DOT ru>
Alexander Steinhöfer <kontakt AT lx-s DOT de>
Alexandre Magno <alexandre DOT mbm AT gmail DOT com>
Anderi Azuki <k1nzy AT outlook DOT com>
Andrey Nering <andrey AT nering DOT com DOT br>
Andrey Solomatin <toadron AT yandex DOT ru>
Antoine GIRARD <sapk AT sapk DOT fr>
Antonio Briola <briolantonio AT gmail DOT com>
Arthur Aslanyan <arthur DOT e DOT aslanyan AT gmail DOT com>
Aurelien Darragon <aurelien DOT darragon AT gmail DOT com>
Barış Arda Yılmaz <ardayilmazgamer AT gmail DOT com>
bugreport0
Camille Baronnet <gogs AT camillebaronnet DOT fr>
Christoph Kisfeld <christoph DOT kisfeld AT gmail DOT com>
Cysioland
Damaris Padieu <damizx AT hotmail DOT fr>
Daniel Speichert <daniel AT speichert DOT pl>
David Yzaguirre <dvdyzag AT gmail DOT com>
Dmitriy Nogay <me AT catwhocode DOT ga>
Emanuel Angelo <emanuel DOT angelo AT gmail DOT com>
Enrico Testori hypertesto AT gmail DOT com
Ezequiel Gonzalez Rial <gonrial AT gmail DOT com>
Gabriel Dugny <gabriel DOT dugny AT gmail DOT com>
Gregor Santner <gdev AT live DOT de>
Guilhem Marion <gmarion AT netc DOT fr>
Halil Kaya <halil AT halilkaya DOT net>
Hamid Feizabadi <hamidfzm AT gmail DOT com>
Hilton Wichwski Silva <hilton AT hiltonws DOT com DOT br>
Huimin Wang <wanghm2009 AT hotmail DOT co DOT jp>
ilko <kontact-mr DOT k AT outlook DOT com>
Ilya Makarov
Jamie Mansfield <dev AT jamierocks DOT uk>
Jean THOMAS <contact AT tibounise DOT com>
Joan Sánchez <dev AT discusal DOT com>
Joel da Rosa <webjoel AT hotmail DOT com>
Joubert RedRat <me+github AT redrat DOT com DOT br>
Jonathan Lozada De La Matta <jlozada2426 AT protonmail DOT com>
Juraj Bubniak <contact AT jbub DOT eu>
Kazuki Sawada <kazuki AT 6715 DOT jp>
Lafriks <lafriks AT gmail DOT com>
Lauri Ojansivu <x AT xet7 DOT org>
Luc Stepniewski <luc AT stepniewski DOT fr>
Luca Bozzo <luca AT bozzo DOT it>
Luca Kröger <l DOT kroeger01 AT gmail DOT com>
Marc Schiller <marc AT schiller DOT im>
Marvin Menzerath <github AT marvin-menzerath DOT de>
Michael Härtl <haertl DOT mike AT gmail DOT com>
Miguel de la Cruz <miguel AT mcrx DOT me>
Mikhail Burdin <xdshot9000 AT gmail DOT com>
Morten Sørensen <klim8d AT gmail DOT com>
Muhammad Fawwaz Orabi <mfawwaz93 AT gmail DOT com>
Nakao Takamasa <at.mattenn AT gmail DOT com>
Natan Albuquerque <natanalbuquerque5 AT gmail DOT com>
Niclas Kroon <niclas DOT kroon AT gmail DOT com>
Odilon Junior <odilon DOT junior93 AT gmail DOT com>
Pablo Saavedra <psaavedra AT igalia DOT com>
Piotr Orzechowski <piotr AT orzechowski DOT tech>
Richard Bukovansky <richard DOT bukovansky AT gmail DOT com>
Robert Nuske <robert DOT nuske AT web DOT de>
Robin Hübner <profan AT prfn DOT se>
SeongJae Park <sj38 DOT park AT gmail DOT com>
Thiago Avelino <thiago AT avelino DOT xxx>
Thomas Fanninger <gogs DOT thomas AT fanninger DOT at>
Tilmann Bach <tilmann AT outlook DOT com>
Toni Villena Jiménez <tonivj5 AT gmail DOT com>
Viktor Sperl <viktike32 AT gmail DOT com>
Vladimir Jigulin mogaika AT yandex DOT ru
Vladimir Vissoultchev <wqweto AT gmail DOT com>
Yaşar Çiv <yasarciv67 AT gmail DOT com>
YJSoft <yjsoft AT yjsoft DOT pe DOT kr>
Łukasz Jan Niemier <lukasz AT niemier DOT pl>

1290
conf/locale/locale_bg-BG.ini Normal file

File diff suppressed because it is too large Load Diff

2376
conf/locale/locale_cs-CZ.ini Normal file

File diff suppressed because it is too large Load Diff

2388
conf/locale/locale_de-DE.ini Normal file

File diff suppressed because it is too large Load Diff

2388
conf/locale/locale_en-US.ini Normal file

File diff suppressed because it is too large Load Diff

2385
conf/locale/locale_es-ES.ini Normal file

File diff suppressed because it is too large Load Diff

2121
conf/locale/locale_fa-IR.ini Normal file

File diff suppressed because it is too large Load Diff

1351
conf/locale/locale_fi-FI.ini Normal file

File diff suppressed because it is too large Load Diff

2329
conf/locale/locale_fr-FR.ini Normal file

File diff suppressed because it is too large Load Diff

1776
conf/locale/locale_hu-HU.ini Normal file

File diff suppressed because it is too large Load Diff

1440
conf/locale/locale_id-ID.ini Normal file

File diff suppressed because it is too large Load Diff

2263
conf/locale/locale_it-IT.ini Normal file

File diff suppressed because it is too large Load Diff

2388
conf/locale/locale_ja-JP.ini Normal file

File diff suppressed because it is too large Load Diff

1631
conf/locale/locale_ko-KR.ini Normal file

File diff suppressed because it is too large Load Diff

2383
conf/locale/locale_lv-LV.ini Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,816 @@
home=പൂമുഖം
dashboard=ഡാഷ്ബോർഡ്
explore=കണ്ടെത്തൂ
help=സഹായം
sign_in=പ്രവേശിക്കുക
sign_in_with=ഉപയോഗിച്ചു് പ്രവേശിയ്ക്കുക
sign_out=പുറത്തുകടക്കുക
sign_up=രജിസ്റ്റർ
link_account=അക്കൌണ്ട് ബന്ധിപ്പിയ്ക്കുക
register=രജിസ്റ്റർ
website=വെബ് സൈറ്റ്
version=പതിപ്പ്
page=പേജ്
template=ടെംപ്ലേറ്റ്
language=ഭാഷ
notifications=അറിയിപ്പുകൾ
create_new=സൃഷ്ടിക്കുക…
user_profile_and_more=പ്രൊഫൈലും ക്രമീകരണങ്ങളും…
signed_in_as=ഇയാളായി പ്രവേശിയ്ക്കുക
enable_javascript=ഈ വെബ്‌സൈറ്റ് ജാവാസ്ക്രിപ്റ്റിനൊപ്പം മികച്ച രീതിയിൽ പ്രവർത്തിക്കുന്നു.
username=ഉപയോക്ത്രു നാമം
email=ഈമെയില്‍ വിലാസം
password=രഹസ്യവാക്കു്
re_type=രഹസ്യവാക്കു് വീണ്ടും നല്‍കുക
captcha=ക്യാപ്ച
twofa=ഇരട്ട ഘടക പ്രാമാണീകരണം
twofa_scratch=ഇരട്ട ഫാക്ടർ സ്ക്രാച്ച് കോഡ്
passcode=രഹസ്യ കോഡ്
u2f_insert_key=സെക്യൂരിറ്റി കീ ഇന്‍സേര്‍ട്ടു് ചെയ്യുക
u2f_sign_in=സെക്യൂരിറ്റി കീയിലെ ബട്ടണ്‍ അമര്‍ത്തുക. സെക്യൂരിറ്റി കീയില്‍ ബട്ടണൊന്നും ഇല്ലെങ്കില്‍ വീണ്ടും ഇന്‍സേര്‍ട്ടു് ചെയ്യുക.
u2f_press_button=ദയവായി സെക്യൂരിറ്റി കീയിലെ ബട്ടണ്‍ അമര്‍ത്തൂ…
u2f_use_twofa=നിങ്ങളുടെ ഫോണിൽ നിന്നുള്ള ഇരട്ട-ഘടക കോഡ് ഉപയോഗിക്കുക
u2f_error=സെക്യൂരിറ്റി കീ വായിയ്ക്കാനാകുന്നില്ല.
u2f_unsupported_browser=നീങ്ങളുടെ ബ്രൗസര്‍ ഇരട്ട ഘടക സെക്യൂരിറ്റി പിന്തുണയ്ക്കുന്നില്ല.
u2f_error_1=ഒരു അവിചാരിതമായ പിശക് സംഭവിച്ചു. ദയവായി വീണ്ടും ശ്രമിക്കുക.
u2f_error_2=നിങ്ങള്‍ ഉപയോഗിക്കുന്നത് ശരിയായ, എൻ‌ക്രിപ്റ്റ് ചെയ്ത (https://) യുആർഎൽ ആണെന്നു ദയവായി ഉറപ്പാക്കുക.
u2f_error_3=നിങ്ങളുടെ അഭ്യർത്ഥന പ്രോസസ്സ് ചെയ്യാൻ സെർവറിന് കഴിഞ്ഞില്ല.
u2f_error_4=ഈ അഭ്യർത്ഥന പൂര്‍ത്തിയാക്കാന്‍ സുരക്ഷാ കീ അനുവദനിയ്ക്കുന്നില്ല. ഈ കീ ഇതിനോടകം രജിസ്റ്റർ ചെയ്തിട്ടില്ലെന്ന് ഉറപ്പു വരുത്തുക.
u2f_error_5=നിങ്ങളുടെ കീ വായിക്കുന്നതിന് പൂര്‍ത്തിയാക്കാനായില്ല. ദയവായി ഈ പേജ് പുതുക്കി വീണ്ടും ശ്രമിക്കുക.
u2f_reload=പുതുക്കുക
repository=കലവറ
organization=സംഘടന
mirror=മിറര്‍
new_repo=പുതിയ കലവറ
new_migrate=പുതിയ കുടിയേറ്റിപ്പാര്‍പ്പിക്കല്‍
new_mirror=പുതിയ മിറര്‍
new_fork=കലവറയുടെ പുതിയ ശിഖരം
new_org=പുതിയ സംഘടന
manage_org=സംഘടനകളെ നിയന്ത്രിക്കുക
admin_panel=സൈറ്റിന്റെ കാര്യനിര്‍വ്വാഹണം
account_settings=അക്കൌണ്ട് ക്രമീകരണങള്‍
settings=ക്രമീകരണങ്ങള്‍
your_profile=പ്രൊഫൈൽ
your_starred=നക്ഷത്ര ചിഹ്നമിട്ടവ
your_settings=ക്രമീകരണങ്ങള്‍
all=എല്ലാം
sources=ഉറവിടങ്ങൾ
mirrors=മിററുകള്‍
collaborative=സഹകരിക്കുന്ന
forks=ശാഖകള്‍
activities=പ്രവര്‍ത്തനങ്ങള്‍
pull_requests=ലയന അഭ്യർത്ഥനകൾ
issues=പ്രശ്നങ്ങൾ
cancel=റദ്ദാക്കുക
write=എഴുതുക
preview=തിരനോട്ടം
loading=ലഭ്യമാക്കുന്നു…
[error]
[startpage]
[install]
install=സന്നിവേശിപ്പിയ്ക്കുക
title=പ്രാരംഭ ക്രമീകരണങ്ങള്‍
docker_helper=ഡോക്കറിനുള്ളിലാണ് ഗിറ്റീ പ്രവര്‍ത്തിപ്പിയ്ക്കുന്നതെങ്കില്‍, മാറ്റങ്ങള്‍ വരുത്തുന്നതിനു മുമ്പു് ദയവായി <a target="_blank" rel="noopener noreferrer" href="%s">ഡോക്യുമെന്റേഷൻ</a> വായിയ്ക്കുക.
requite_db_desc=ഗിറ്റീയ്ക്കു് MySQL, PostgreSQL, MSSQL അല്ലെങ്കിൽ SQLite3 ആവശ്യമാണ്.
db_title=ഡാറ്റാബേസ് ക്രമീകരണങ്ങൾ
db_type=ഡാറ്റാബേസിന്റെ തരം
host=ഹോസ്റ്റ്
user=ഉപയോക്ത്രു നാമം
password=രഹസ്യവാക്കു്
db_name=ഡാറ്റാബേസിന്റെ പേര്
db_helper=MySQL ഉപയോക്താക്കൾക്കുള്ള കുറിപ്പ്: ദയവായി InnoDB സ്റ്റോറേജ് എഞ്ചിൻ ഉപയോഗിക്കുക. നിങ്ങൾ "utf8mb4" ഉപയോഗിക്കുകയാണെങ്കിൽ, InnoDB പതിപ്പ് 5.6 നേക്കാൾ വലുതായിരിക്കണം.
ssl_mode=SSL
charset=ക്യാര്‍സെറ്റ്
path=പാത
sqlite_helper=SQLite3 ഡാറ്റാബേസിന്റെ ഫയല്‍ പാത്ത്.<br>നിങ്ങൾ ഗിറ്റീയെ ഒരു സേവനമായി പ്രവർത്തിപ്പിക്കുകയാണെങ്കിൽ സമ്പൂര്‍ണ്ണ ഫയല്‍ പാത നൽകുക.
err_empty_db_path=SQLite3 ഡാറ്റാബേസ് പാത്ത് ശൂന്യമായിരിക്കരുത്.
no_admin_and_disable_registration=ഒരു അഡ്മിനിസ്ട്രേറ്റർ അക്കൌണ്ട് സൃഷ്ടിക്കാതെ നിങ്ങൾക്ക് ഉപയോക്തൃ സ്വയം രജിസ്ട്രേഷൻ അപ്രാപ്തമാക്കാൻ കഴിയില്ല.
err_empty_admin_password=അഡ്മിനിസ്ട്രേറ്ററുടെ രഹസ്യവാക്കു് ശൂന്യമായിരിക്കരുത്.
err_empty_admin_email=അഡ്മിനിസ്ട്രേറ്ററുടെ ഇമെയില്‍ വിലാസം ശൂന്യമായിരിക്കരുത്.
err_admin_name_is_reserved=അഡ്മിനിസ്ട്രേറ്റര്‍ ഉപയോക്തൃനാമം അസാധുവാണ്, ഉപയോക്തൃനാമം റിസര്‍വ്വ് ചെയ്തതാണ്
err_admin_name_is_invalid=അഡ്മിനിസ്ട്രേറ്റർ ഉപയോക്തൃനാമം അസാധുവാണ്
general_title=പൊതുവായ ക്രമീകരണങ്ങൾ
app_name=സൈറ്റ് ശീർഷകം
app_name_helper=നിങ്ങളുടെ കമ്പനിയുടെ പേര് ഇവിടെ നൽകാം.
repo_path=സംഭരണിയുടെ റൂട്ട് പാത്ത്
repo_path_helper=വിദൂര ഗിറ്റു് സംഭരണികള്‍ ഈ ഡയറക്ടറിയിലേക്ക് സംരക്ഷിക്കും.
lfs_path=Git LFS റൂട്ട് പാത്ത്
lfs_path_helper=Git LFS ട്രാക്കുചെയ്ത ഫയലുകൾ ഈ ഡയറക്ടറിയിൽ സൂക്ഷിക്കും. പ്രവർത്തനരഹിതമാക്കാൻ ഈ കളം ശൂന്യമായി വിടുക.
run_user=ഉപയോക്താവായി പ്രവര്‍ത്തിപ്പിക്കുക
run_user_helper=ഗിറ്റീ പ്രവർത്തിക്കുന്ന ഓപ്പറേറ്റിംഗ് സിസ്റ്റത്തിന്റെ ഉപയോക്തൃനാമം നല്കുക. ഈ ഉപയോക്താവിന് സംഭരണിയുടെ റൂട്ട് പാത്തിലേക്ക് പ്രവേശനം ഉണ്ടായിരിക്കണം.
domain=SSH സെർവർ ഡൊമെയ്ൻ
domain_helper=SSH ക്ലോൺ URL- കൾക്കായുള്ള ഡൊമെയ്ൻ അല്ലെങ്കിൽ ഹോസ്റ്റ് വിലാസം.
ssh_port=SSH സെർവർ പോര്‍ട്ട്
ssh_port_helper=നിങ്ങളുടെ SSH സെർവർ ശ്രവിക്കുന്ന പോർട്ട് നമ്പർ നല്‍കുക. പ്രവർത്തനരഹിതമാക്കാൻ കളം ശൂന്യമായി വിടുക.
http_port=ഗിറ്റീ എച്ച്ടിടിപി ശ്രവിയ്ക്കുന്ന പോർട്ട്
http_port_helper=ഗിറ്റീ വെബ് സെർവർ ശ്രവിയ്ക്കുന്ന പോർട്ട് നമ്പർ.
app_url=ഗിറ്റീയുടെ അടിസ്ഥാന വിലാസം
app_url_helper=എച്ച്ടിടിപി(എസ്) ക്ലോണുകള്‍ക്കും ഇമെയിൽ അറിയിപ്പുകൾക്കുമായുള്ള അടിസ്ഥാന വിലാസം.
log_root_path=ലോഗ് പാത്ത്
log_root_path_helper=ലോഗ് ഫയലുകൾ ഈ ഡയറക്ടറിയിലേക്ക് എഴുതപ്പെടും.
optional_title=ഐച്ഛികമായ ക്രമീകരണങ്ങൾ
email_title=ഇമെയിൽ ക്രമീകരണങ്ങൾ
smtp_host=SMTP ഹോസ്റ്റ്
smtp_from=ഈ വിലാസത്തില്‍ ഇമെയിൽ അയയ്‌ക്കുക
smtp_from_helper=ഗിറ്റീ ഉപയോഗിയ്ക്കുന്ന ഇമെയില്‍ വിലാസം. ഒരു സാധാ ഇമെയിൽ വിലാസം നൽകുക അല്ലെങ്കിൽ "പേര്"<email@example.com> എന്ന ഘടന ഉപയോഗിക്കുക.
mailer_user=SMTP ഉപയോക്തൃനാമം
mailer_password=SMTP രഹസ്യവാക്കു്
register_confirm=രജിസ്റ്റർ ചെയ്യുന്നതിന് ഇമെയിൽ സ്ഥിരീകരണം ആവശ്യമാക്കുക
mail_notify=ഇമെയിൽ അറിയിപ്പുകൾ പ്രാപ്തമാക്കുക
server_service_title=സെർവറിന്റെയും മൂന്നാം കക്ഷി സേവനങ്ങളുടെയും ക്രമീകരണങ്ങള്‍
offline_mode=പ്രാദേശിക മോഡ് പ്രവർത്തനക്ഷമമാക്കുക
offline_mode_popup=മൂന്നാം കക്ഷി ഉള്ളടക്ക ഡെലിവറി നെറ്റ്‌വർക്കുകൾ അപ്രാപ്‌തമാക്കി എല്ലാ വിഭവങ്ങളും പ്രാദേശികമായി നല്‍കുക.
disable_gravatar=ഗ്രവതാര്‍ പ്രവർത്തനരഹിതമാക്കുക
disable_gravatar_popup=ഗ്രവതാര്‍ അല്ലെങ്കില്‍ മൂന്നാം കക്ഷി അവതാർ ഉറവിടങ്ങൾ പ്രവർത്തനരഹിതമാക്കുക. ഒരു ഉപയോക്താവ് പ്രാദേശികമായി ഒരു അവതാർ അപ്‌ലോഡുചെയ്യുന്നില്ലെങ്കിൽ സ്ഥിരസ്ഥിതി അവതാർ ഉപയോഗിക്കും.
federated_avatar_lookup=കേന്ദ്രീകൃത അവതാര്‍ പ്രാപ്തമാക്കുക
federated_avatar_lookup_popup=ലിബ്രാവതാർ ഉപയോഗിച്ച് കേന്ദ്രീക്രത അവതാർ തിരയൽ പ്രാപ്തമാക്കുക.
disable_registration=സ്വയം രജിസ്ട്രേഷൻ അപ്രാപ്തമാക്കുക
disable_registration_popup=ഉപയോക്താക്കള്‍ സ്വയം രജിസ്റ്റര്‍ ചെയ്യുന്നതു അപ്രാപ്യമാക്കുക. അഡ്മിനിസ്ട്രേറ്റർമാർക്ക് മാത്രമേ പുതിയ ഉപയോക്തൃ അക്കൌണ്ടുകൾ സൃഷ്ടിക്കാന്‍ കഴിയൂ.
allow_only_external_registration_popup=ബാഹ്യ സേവനങ്ങളിലൂടെ മാത്രം രജിസ്ട്രേഷന്‍ അനുവദിക്കുക
openid_signin=OpenID പ്രവേശനം പ്രവർത്തനക്ഷമമാക്കുക
openid_signin_popup=OpenID വഴി ഉപയോക്തൃ പ്രവേശനം പ്രാപ്തമാക്കുക.
openid_signup=OpenID സ്വയം രജിസ്ട്രേഷൻ പ്രാപ്തമാക്കുക
openid_signup_popup=OpenID അടിസ്ഥാനമാക്കിയുള്ള ഉപയോക്തൃ സ്വയം രജിസ്ട്രേഷൻ പ്രാപ്തമാക്കുക.
enable_captcha_popup=ഉപയോക്താക്കള്‍ സ്വയം രജിസ്ട്രേഷന്‍ ചെയ്യുന്നതിനു് ഒരു ക്യാപ്ച ആവശ്യമാണ്.
require_sign_in_view=പേജുകൾ കാണുന്നതിന് സൈറ്റില്‍ പ്രവേശിക്കണം
require_sign_in_view_popup=പേജ് ആക്‌സസ്സ്, പ്രവേശിച്ച ഉപയോക്താക്കൾക്കുമാത്രമായി പരിമിതപ്പെടുത്തുക. സന്ദർശകർ 'പ്രവേശനം', രജിസ്ട്രേഷൻ പേജുകൾ എന്നിവ മാത്രമേ കാണൂ.
admin_setting_desc=ഒരു അഡ്മിനിസ്ട്രേറ്റര്‍ അക്കൗണ്ട് സൃഷ്ടിക്കുന്നത് ഐച്ഛികമാണ്. ആദ്യം രജിസ്റ്റര്‍ ചെയ്ത ഉപയോക്താവ് യാന്ത്രികമായി ഒരു അഡ്മിനിസ്ട്രേറ്ററായി മാറും.
admin_title=അഡ്മിനിസ്ട്രേറ്റര്‍ അക്കൗണ്ട് ക്രമീകരണങ്ങൾ
admin_name=അഡ്മിനിസ്ട്രേറ്ററുടെ ഉപയോക്തൃനാമം
admin_password=രഹസ്യവാക്കു്
confirm_password=രഹസ്യവാക്കു് സ്ഥിരീകരിക്കുക
admin_email=ഇ-മെയില്‍ വിലാസം
install_btn_confirm=ഗിറ്റീ സന്നിവേശിപ്പിയ്ക്കുക
test_git_failed='git' കമാന്‍ഡ് പരീക്ഷിക്കാന്‍ കഴിഞ്ഞില്ല: %v
sqlite3_not_available=ഗിറ്റീയുടെ ഈ വേര്‍ഷന്‍ SQLite3യെ പിന്തുണക്കുന്നില്ല. %s ൽ നിന്നും ഔദ്യോഗിക ബൈനറി പതിപ്പ് ഡൌണ്‍‌ലോഡ് ചെയ്യുക ('gobuild' പതിപ്പല്ല).
invalid_db_setting=ഡാറ്റാബേസ് ക്രമീകരണങ്ങൾ അസാധുവാണ്: %v
invalid_repo_path=കലവറയുടെ റൂട്ട് പാത്ത് അസാധുവാണ്: %v
run_user_not_match='റൺ ആസ്' ഉപയോക്തൃനാമം നിലവിലെ ഉപയോക്തൃനാമമല്ല: %s -> %s
save_config_failed=കോൺഫിഗറേഷൻ സംരക്ഷിക്കുന്നതിൽ പരാജയപ്പെട്ടു: %v
invalid_admin_setting=അഡ്മിനിസ്ട്രേറ്റര്‍ അക്കൌണ്ട് ക്രമീകരണം അസാധുവാണ്: %v
install_success=സ്വാഗതം! ഗിറ്റീ തിരഞ്ഞെടുത്തതിന് നന്ദി. സൂക്ഷിക്കുക, ആസ്വദിക്കൂ,!
invalid_log_root_path=ലോഗ് പാത്ത് അസാധുവാണ്: %v
default_keep_email_private=സ്ഥിരസ്ഥിതിയായി ഇമെയില്‍ വിലാസങ്ങള്‍ മറയ്‌ക്കുക
default_keep_email_private_popup=സ്ഥിരസ്ഥിതിയായി പുതിയ ഉപയോക്തൃ അക്കൗണ്ടുകളുടെ ഇമെയില്‍ വിലാസങ്ങള്‍ മറയ്ക്കുക.
default_allow_create_organization=സ്ഥിരസ്ഥിതിയായി സംഘടനകള്‍ സൃഷ്ടിക്കാന്‍ അനുവദിക്കുക
default_allow_create_organization_popup=സ്ഥിരസ്ഥിതിയായി സംഘടനകള്‍ സൃഷ്ടിക്കാന്‍ പുതിയ ഉപയോക്തൃ അക്കൗണ്ടുകളെ അനുവദിക്കുക.
default_enable_timetracking=സ്ഥിരസ്ഥിതിയായി സമയം ട്രാക്കു് ചെയ്യുന്നതു പ്രാപ്തമാക്കുക
default_enable_timetracking_popup=സ്ഥിരസ്ഥിതിയായി പുതിയ കലവറകള്‍ക്കു് സമയം ട്രാക്കു് ചെയ്യുന്നതു് പ്രാപ്തമാക്കുക.
no_reply_address=മറച്ച ഇമെയിൽ ഡൊമെയ്ൻ
no_reply_address_helper=മറഞ്ഞിരിക്കുന്ന ഇമെയിൽ വിലാസമുള്ള ഉപയോക്താക്കൾക്കുള്ള ഡൊമെയ്ൻ നാമം. ഉദാഹരണത്തിന്, മറഞ്ഞിരിക്കുന്ന ഇമെയിൽ ഡൊമെയ്ൻ 'noreply.example.org' ആയി സജ്ജീകരിച്ചിട്ടുണ്ടെങ്കിൽ 'joe' എന്ന ഉപയോക്താവു് 'joe@noreply.example.org' ആയി ലോഗിൻ ചെയ്യും.
[home]
uname_holder=ഉപയോക്തൃനാമമോ ഇമെയിൽ വിലാസമോ
password_holder=രഹസ്യവാക്കു്
switch_dashboard_context=ഡാഷ്‌ബോർഡ് സന്ദർഭം മാറ്റുക
my_repos=കലവറകള്‍
show_more_repos=കൂടുതൽ കലവറകള്‍ കാണിക്കുക…
collaborative_repos=സഹകരിക്കാവുന്ന കലവറകള്‍
my_orgs=എന്റെ സംഘടനകള്‍
my_mirrors=എന്റെ മിററുകള്‍
view_home=%s കാണുക
search_repos=ഒരു കലവറ കണ്ടെത്തുക…
issues.in_your_repos=നിങ്ങളുടെ കലവറകളില്‍
[explore]
repos=കലവറകള്‍
users=ഉപയോക്താക്കള്‍
organizations=സംഘടനകള്‍
search=തിരയുക
code=കോഡ്
repo_no_results=പൊരുത്തപ്പെടുന്ന കലവറകളൊന്നും കണ്ടെത്താനായില്ല.
user_no_results=പൊരുത്തപ്പെടുന്ന ഉപയോക്താക്കളെയൊന്നും കണ്ടെത്താനായില്ല.
org_no_results=പൊരുത്തപ്പെടുന്ന സംഘടനകളൊന്നും കണ്ടെത്താനായില്ല.
code_no_results=നിങ്ങളുടെ തിരയൽ പദവുമായി പൊരുത്തപ്പെടുന്ന സോഴ്സ് കോഡുകളൊന്നും കണ്ടെത്താനായില്ല.
code_search_results=%s എന്നതിനായുള്ള തിരയൽ ഫലങ്ങൾ
[auth]
create_new_account=അക്കൗണ്ട് രജിസ്റ്റർ ചെയ്യുക
register_helper_msg=ഇതിനകം ഒരു അക്കൗണ്ട് ഉണ്ടോ? ഇപ്പോൾ പ്രവേശിക്കുക!
social_register_helper_msg=ഇതിനകം ഒരു അക്കൗണ്ട് ഉണ്ടോ? ഇത് ഇപ്പോൾ ബന്ധിപ്പിയ്ക്കുക!
disable_register_prompt=രജിസ്ട്രേഷൻ അപ്രാപ്തമാക്കി. നിങ്ങളുടെ സൈറ്റ് അഡ്മിനിസ്ട്രേറ്ററുമായി ബന്ധപ്പെടുക.
disable_register_mail=രജിസ്ട്രേഷനായുള്ള ഇമെയിൽ സ്ഥിരീകരണം അപ്രാപ്തമാക്കി.
remember_me=ഓര്‍മ്മിയ്ക്കുക
forgot_password_title=അടയാളവാക്യം മറന്നുപോയോ
forgot_password=അടയാള വാക്ക് ഓർക്കുന്നില്ലേ?
sign_up_now=ഒരു അക്കൗണ്ട് ആവശ്യമുണ്ടോ? ഇപ്പോള്‍ രജിസ്റ്റര്‍ ചെയ്യുക.
sign_up_successful=അക്കൗണ്ട് വിജയകരമായി സൃഷ്ടിച്ചു.
confirmation_mail_sent_prompt=<b>%s</b> ലേക്ക് ഒരു പുതിയ സ്ഥിരീകരണ ഇമെയിൽ അയച്ചു. രജിസ്ട്രേഷൻ പ്രക്രിയ പൂർത്തിയാക്കുന്നതിന് അടുത്ത %s നുള്ളിൽ നിങ്ങളുടെ ഇൻ‌ബോക്സ് പരിശോധിക്കുക.
must_change_password=നിങ്ങളുടെ രഹസ്യവാക്കു് പുതുക്കുക
allow_password_change=രഹസ്യവാക്കു് മാറ്റാൻ ഉപയോക്താവിനോട് ആവശ്യപ്പെടുക (ശുപാർശിതം)
reset_password_mail_sent_prompt=<b>%s</b> ലേക്ക് ഒരു പുതിയ സ്ഥിരീകരണ ഇമെയിൽ അയച്ചു. അക്കൗണ്ട് വീണ്ടെടുക്കൽ പ്രക്രിയ പൂർത്തിയാക്കുന്നതിന് അടുത്ത %s നുള്ളിൽ നിങ്ങളുടെ ഇൻ‌ബോക്സ് പരിശോധിക്കുക.
active_your_account=നിങ്ങളുടെ അക്കൗണ്ട് സജീവമാക്കുക
account_activated=നിങ്ങളുടെ അക്കൗണ്ട് സജീവമാക്കി
prohibit_login=പ്രവേശനം നിരോധിച്ചിരിക്കുന്നു
prohibit_login_desc=നിങ്ങളുടെ അക്കൗണ്ടിലേയ്ക്കുള്ള പ്രവേശനം നിരോധിച്ചിരിക്കുന്നു, ദയവായി നിങ്ങളുടെ സൈറ്റ് അഡ്മിനിസ്ട്രേറ്ററുമായി ബന്ധപ്പെടുക.
resent_limit_prompt=നിങ്ങൾ അടുത്തിടെ ഒരു സജീവമാക്കൽ ഇമെയിൽ അഭ്യർത്ഥിച്ചു. 3 മിനിറ്റ് കാത്തിരുന്ന് വീണ്ടും ശ്രമിക്കുക.
has_unconfirmed_mail=ഹായ് %s, നിങ്ങൾക്ക് സ്ഥിരീകരിക്കാത്ത ഇമെയിൽ വിലാസം (<b>%s</b>) ഉണ്ട്. നിങ്ങൾക്ക് ഒരു സ്ഥിരീകരണ ഇമെയിൽ ലഭിച്ചില്ലെങ്കിലോ പുതിയതൊന്ന് വീണ്ടും അയയ്‌ക്കേണ്ടതുണ്ടെങ്കിലോ, ചുവടെയുള്ള ബട്ടണിൽ ക്ലിക്കുചെയ്യുക.
resend_mail=നിങ്ങളുടെ സജീവമാക്കൽ ഇമെയിൽ വീണ്ടും അയയ്‌ക്കാൻ ഇവിടെ ക്ലിക്കുചെയ്യുക
email_not_associate=ഇമെയിൽ വിലാസം ഏതെങ്കിലും അക്കൗണ്ടുമായി ബന്ധപ്പെടുത്തിയിട്ടില്ല.
send_reset_mail=അക്കൗണ്ട് വീണ്ടെടുക്കൽ ഇമെയിൽ അയയ്‌ക്കുക
reset_password=അക്കൗണ്ട് വീണ്ടെടുക്കൽ
invalid_code=നിങ്ങളുടെ സ്ഥിരീകരണ കോഡ് അസാധുവാണ് അല്ലെങ്കിൽ കാലഹരണപ്പെട്ടു.
reset_password_helper=അക്കൗണ്ട് വീണ്ടെടുക്കുക
reset_password_wrong_user=നിങ്ങൾ %s ആയി സൈൻ ഇൻ ചെയ്‌തു, പക്ഷേ അക്കൗണ്ട് വീണ്ടെടുക്കൽ ലിങ്ക് %s എന്നതിനാണ്
password_too_short=പാസ്‌വേഡ് ദൈർഘ്യം %d അക്ഷരങ്ങളിലും കുറവായിരിക്കരുത്.
non_local_account=പ്രാദേശിക ഇതര ഉപയോക്താക്കൾക്ക് ഗിറ്റീ വെബ് വഴി പാസ്‌വേഡ് പുതുക്കാന്‍ ചെയ്യാൻ കഴിയില്ല.
verify=പ്രമാണീകരിയ്ക്കുക
scratch_code=സ്ക്രാച്ച് കോഡ്
use_scratch_code=ഒരു സ്ക്രാച്ച് കോഡ് ഉപയോഗിക്കുക
twofa_scratch_used=നിങ്ങളുടെ സ്ക്രാച്ച് കോഡ് ഉപയോഗിച്ചു. നിങ്ങളെ രണ്ട്-ഘടക ക്രമീകരണ പേജിലേക്ക് റീഡയറക്‌ട് ചെയ്‌തിരിക്കുന്നതിനാൽ നിങ്ങളുടെ ഉപകരണ എൻറോൾമെന്റ് നീക്കംചെയ്യാനോ പുതിയ സ്‌ക്രാച്ച് കോഡ് സൃഷ്‌ടിക്കാനോ കഴിയും.
twofa_passcode_incorrect=നിങ്ങളുടെ പാസ്‌കോഡ് തെറ്റാണ്. നിങ്ങളുടെ ഉപകരണം തെറ്റായി സ്ഥാപിച്ചിട്ടുണ്ടെങ്കിൽ, പ്രവേശിക്കാൻ നിങ്ങളുടെ സ്ക്രാച്ച് കോഡ് ഉപയോഗിക്കുക.
twofa_scratch_token_incorrect=നിങ്ങളുടെ സ്ക്രാച്ച് കോഡ് തെറ്റാണ്.
login_userpass=പ്രവേശിക്കുക
login_openid=OpenID
oauth_signup_tab=പുതിയ അക്കൗണ്ട് രജിസ്റ്റർ ചെയ്യുക
oauth_signup_title=ഇമെയിലും പാസ്‌വേഡും ചേർക്കുക (അക്കൗണ്ട് വീണ്ടെടുക്കലിനായി)
oauth_signup_submit=അക്കൗണ്ട് പൂർത്തിയാക്കുക
oauth_signin_tab=നിലവിലുള്ള അക്കൌണ്ടുമായി ബന്ധിപ്പിയ്ക്കുക
oauth_signin_title=അക്കൗണ്ട് ബന്ധിപ്പിയ്ക്കുന്നതു് അംഗീകരിക്കുന്നതിനായി സൈറ്റിലേയ്ക്കു് പ്രവേശിക്കുക
oauth_signin_submit=അക്കൌണ്ട് ബന്ധിപ്പിയ്ക്കുക
openid_connect_submit=ബന്ധിപ്പിക്കുക
openid_connect_title=നിലവിലുള്ള അക്കൗണ്ടുമായി ബന്ധിപ്പിയ്ക്കുക
openid_connect_desc=തിരഞ്ഞെടുത്ത ഓപ്പൺഐഡി യുആർഐ അജ്ഞാതമാണ്. ഇവിടെ നിന്നും ഒരു പുതിയ അക്കൗണ്ടുമായി ബന്ധപ്പെടുത്തുക.
openid_register_title=അംഗത്വമെടുക്കുക
openid_register_desc=തിരഞ്ഞെടുത്ത ഓപ്പൺഐഡി യുആർഐ അജ്ഞാതമാണ്. ഇവിടെ നിന്നും ഒരു പുതിയ അക്കൗണ്ടുമായി ബന്ധപ്പെടുത്തുക.
openid_signin_desc=നിങ്ങളുടെ OpenID URI നൽകുക. ഉദാഹരണത്തിന്: https://anne.me, bob.openid.org.cn അല്ലെങ്കിൽ gnusocial.net/carry.
disable_forgot_password_mail=അക്കൗണ്ട് വീണ്ടെടുക്കൽ പ്രവർത്തനരഹിതമാണ്. നിങ്ങളുടെ സൈറ്റ് അഡ്മിനിസ്ട്രേറ്ററുമായി ബന്ധപ്പെടുക.
email_domain_blacklisted=നിങ്ങളുടെ ഇമെയിൽ വിലാസത്തിൽ രജിസ്റ്റർ ചെയ്യാൻ കഴിയില്ല.
authorize_application=അപ്ലിക്കേഷനു് അംഗീകാരം നല്കുക
authorize_application_created_by=%s സൃഷ്‌ടിച്ച അപ്ലിക്കേഷൻ ആണ്.
authorize_application_description=നിങ്ങൾ പ്രവേശനം അനുവദിക്കുകയാണെങ്കിൽ, സ്വകാര്യ റിപ്പോകളും ഓർഗനൈസേഷനുകളും ഉൾപ്പെടെ നിങ്ങളുടെ എല്ലാ അക്കൌണ്ട് വിവരങ്ങള്‍ നേടാനും വേണമെങ്കില്‍‍ മാറ്റങ്ങള്‍ വരുത്താനും അതിന് കഴിയും.
authorize_title=നിങ്ങളുടെ അക്കൌണ്ടില്‍ പ്രവേശിയ്ക്കുന്നതിനു് "%s"നു് അംഗീകാരം നൽകണോ?
authorization_failed=അംഗീകാരം നല്‍കുന്നതില്‍ പരാജയപ്പെട്ടു
authorization_failed_desc=അസാധുവായ ഒരു അഭ്യർത്ഥന കണ്ടെത്തിയതിനാൽ ഞങ്ങൾ അംഗീകാരം പരാജയപ്പെടുത്തി. ദയവായി നിങ്ങൾ അംഗീകരിക്കാൻ ശ്രമിച്ച അപ്ലിക്കേഷന്റെ പരിപാലകനുമായി ബന്ധപ്പെടുക.
[mail]
activate_account=നിങ്ങളുടെ അക്കൗണ്ട് സജീവമാക്കുക
activate_email=ഇമെയില്‍ വിലാസം സ്ഥിരീകരിയ്ക്കുക
reset_password=നിങ്ങളുടെ അക്കൗണ്ട് വീണ്ടെടുക്കുക
register_success=രജിസ്ട്രേഷൻ വിജയകരം
register_notify=ഗിറ്റീയിലേയ്ക്കു് സ്വാഗതം
[modal]
yes=അതെ
no=ഇല്ല
modify=പുതുക്കുക
[form]
UserName=ഉപയോക്ത്രു നാമം
RepoName=കലവറയുടെ പേരു്
Email=ഇ-മെയില്‍ വിലാസം
Password=രഹസ്യവാക്കു്
Retype=രഹസ്യവാക്കു് വീണ്ടും നല്‍കുക
SSHTitle=SSH കീയുടെ പേരു്
HttpsUrl=HTTPS URL
PayloadUrl=പേലോഡ് URL
TeamName=ടീമിന്റെ പേരു്
AuthName=അംഗീകാരത്തിന്റെ പേരു്
AdminEmail=അഡ്‌മിൻ ഇമെയിൽ
NewBranchName=പുതിയ ശാഖയുടെ പേരു്
CommitSummary=നിയോഗത്തിന്റെ സംഗ്രഹം
CommitMessage=നിയോഗത്തിന്റെ സന്ദേശം
CommitChoice=നിയോഗത്തിന്റെ തിരഞ്ഞെടുക്കല്‍
TreeName=ഫയല്‍ പാത്ത്
Content=ഉള്ളടക്കം
require_error=`ശൂന്യമായിരിക്കരുത്.`
alpha_dash_error=`ആൽ‌ഫാന്യൂമെറിക്, ഡാഷ് ('-'), അടിവരയിട്ട ('_') എന്നീ ചിഹ്നങ്ങള്‍ മാത്രം അടങ്ങിയിരിക്കണം.`
alpha_dash_dot_error=`ആൽ‌ഫാന്യൂമെറിക്, ഡാഷ് ('-'), അടിവരയിടുക ('_'), ഡോട്ട് ('.') എന്നീ ച്ഹ്നങ്ങള്‍ മാത്രം അടങ്ങിയിരിക്കണം.`
git_ref_name_error=`നന്നായി രൂപപ്പെടുത്തിയ Git റഫറൻസ് നാമമായിരിക്കണം.`
size_error=`വലുപ്പം %s ആയിരിക്കണം.`
min_size_error=`കുറഞ്ഞത് %s അക്ഷരങ്ങള്‍ അടങ്ങിയിരിക്കണം.`
max_size_error=`പരമാവധി %s അക്ഷരങ്ങള്‍ അടങ്ങിയിരിക്കണം.`
email_error=സാധുവായ ഒരു ഈ-മെയിൽ വിലാസം അല്ല
url_error=`സാധുവായ ഒരു URL അല്ല.`
include_error=`%s'എന്ന ഉപവാക്യം അടങ്ങിയിരിക്കണം.`
glob_pattern_error=ഗ്ലോബു് ശൃേണി തെറ്റാണു്: %s
unknown_error=അജ്ഞാതമായ പിശക്:
captcha_incorrect=ക്യാപ്ച കോഡ് തെറ്റാണ്.
password_not_match=രഹസ്യവാക്കുകള്‍ യോജിക്കുന്നില്ല.
username_been_taken=ഉപയോക്തൃനാമം ലഭ്യമല്ല.
repo_name_been_taken=കലവറയുടെ പേരു് ഇതിനോടകം ഉപയോഗിച്ചിട്ടുണ്ടു്.
visit_rate_limit=വിദൂര വിലാസം വിവരകൈമാറ്റത്തിനു് പരിധി നിശ്ചയിച്ചിട്ടുണ്ടു്.
2fa_auth_required=വിദൂര വിലാസം ഇരട്ട ഘടക പ്രാമാണീകരണം ആവശ്യപ്പെടുന്നുണ്ടു്.
org_name_been_taken=സംഘടനയുടെ പേര് ഇതിനകം എടുത്തിട്ടുണ്ട്.
team_name_been_taken=ടീമിന്റെ പേര് ഇതിനകം എടുത്തിട്ടുണ്ട്.
team_no_units_error=കുറഞ്ഞത് ഒരു കലവറ വിഭാഗത്തിലേക്ക് പ്രവേശനം അനുവദിക്കുക.
email_been_used=ഈ ഇമെയിൽ വിലാസം ഇതിനു മുന്നേ എടുത്തിട്ടുണ്ട്.
openid_been_used=%s എന്ന ഓപ്പണ്‍ഐഡി വിലാസം ഇതിനു മുന്നേ എടുത്തിട്ടുണ്ട്.
username_password_incorrect=ഉപഭോക്തൃനാമമോ രഹസ്യവാക്കോ തെറ്റാണ്.
enterred_invalid_repo_name=ഈ കവവറയുടെ പേരു് തെറ്റാണു്.
enterred_invalid_owner_name=പുതിയ ഉടമസ്ഥന്റെ പേരു് സാധുവല്ല.
enterred_invalid_password=താങ്കള്‍ നല്‍കിയ രഹസ്യവാക്കു് തെറ്റാണ്.
user_not_exist=ഉപയോക്താവ് നിലവിലില്ല.
last_org_owner='ഉടമകളുടെ' ടീമിൽ നിന്നും അവസാനത്തെ ഉപയോക്താവിനെ നീക്കംചെയ്യാൻ നിങ്ങൾക്ക് കഴിയില്ല. ടീമിൽ കുറഞ്ഞത് ഒരു ഉടമയെങ്കിലും ഉണ്ടായിരിക്കണം.
cannot_add_org_to_team=ഒരു സംഘടനയെ ടീം അംഗമായി ചേർക്കാൻ കഴിയില്ല.
invalid_ssh_key=നിങ്ങളുടെ SSH കീ സ്ഥിരീകരിക്കാൻ കഴിയില്ല: %s
invalid_gpg_key=നിങ്ങളുടെ GPG കീ സ്ഥിരീകരിക്കാൻ കഴിയില്ല: %s
unable_verify_ssh_key=SSH കീ സ്ഥിരീകരിക്കാൻ കഴിയില്ല; തെറ്റുകളുണ്ടോയെന്നു് ഒന്നുകൂടി പരിശോധിക്കുക.
auth_failed=പ്രാമാണീകരണം പരാജയപ്പെട്ടു: %v
still_own_repo=നിങ്ങളുടെ അക്കൗണ്ടിന് ഒന്നോ അതിലധികമോ കലവറകള്‍ ഉണ്ട്; ആദ്യം അവ ഇല്ലാതാക്കുക അല്ലെങ്കിൽ കൈമാറുക.
still_has_org=നിങ്ങളുടെ അക്കൗണ്ട് ഒന്നോ അതിലധികമോ സംഘടനകളില്‍ അംഗമാണ്; ആദ്യം അവ വിടുക.
org_still_own_repo=നിങ്ങളുടെ സംഘടന ഇനിയും ഒന്നോ അതിലധികമോ കലവറകളുടെ ഉടമസ്ഥനാണു്; ആദ്യം അവ ഇല്ലാതാക്കുക അല്ലെങ്കിൽ കൈമാറുക.
target_branch_not_exist=ലക്ഷ്യമാക്കിയ ശാഖ നിലവിലില്ല.
[user]
change_avatar=നിങ്ങളുടെ അവതാർ മാറ്റുക…
join_on=ചേർന്നതു്
repositories=കലവറകള്‍
activity=പൊതുവായ പ്രവർത്തനങ്ങള്‍
followers=പിന്തുടരുന്നവര്‍‌
starred=നക്ഷത്രമിട്ട കലവറകള്‍
following=പിന്തുടരുന്നവര്‍
follow=പിന്തുടരൂ
unfollow=പിന്തുടരുന്നത് നിര്‍ത്തുക
heatmap.loading=ഹീറ്റ്മാപ്പ് ലോഡുചെയ്യുന്നു…
user_bio=ജീവചരിത്രം
form.name_reserved='%s' എന്ന ഉപയോക്തൃനാമം മറ്റാവശ്യങ്ങള്‍ക്കായി നീക്കിവച്ചിരിക്കുന്നു.
form.name_pattern_not_allowed=ഉപയോക്തൃനാമത്തിൽ '%s' എന്ന ശ്രേണി അനുവദനീയമല്ല.
[settings]
profile=പ്രൊഫൈൽ
account=അക്കൗണ്ട്
password=രഹസ്യവാക്കു്
security=സുരക്ഷ
avatar=അവതാര്‍
ssh_gpg_keys=SSH / GPG കീകള്‍
social=സോഷ്യൽ അക്കൗണ്ടുകൾ
applications=അപ്ലിക്കേഷനുകൾ
orgs=സംഘടനകളെ നിയന്ത്രിക്കുക
repos=കലവറകള്‍
delete=അക്കൗണ്ട് ഇല്ലാതാക്കുക
twofa=ഇരട്ട ഘടക പ്രാമാണീകരണം
account_link=ബന്ധിപ്പിച്ച അക്കൌണ്ടുകള്‍
organization=സംഘടനകള്‍
uid=Uid
u2f=സുരക്ഷാ കീകൾ
public_profile=പരസ്യമായ പ്രൊഫൈൽ
profile_desc=അറിയിപ്പുകൾക്കും മറ്റ് പ്രവർത്തനങ്ങൾക്കുമായി നിങ്ങളുടെ ഇമെയിൽ വിലാസം ഉപയോഗിക്കും.
password_username_disabled=പ്രാദേശികമല്ലാത്ത ഉപയോക്താക്കൾക്ക് അവരുടെ ഉപയോക്തൃനാമം മാറ്റാൻ അനുവാദമില്ല. കൂടുതൽ വിവരങ്ങൾക്ക് നിങ്ങളുടെ സൈറ്റ് അഡ്മിനിസ്ട്രേറ്ററുമായി ബന്ധപ്പെടുക.
full_name=പൂർണ്ണമായ പേര്
website=വെബ് സൈറ്റ്
location=സ്ഥലം
update_theme=പ്രമേയം പുതുക്കുക
update_profile=പ്രോഫൈല്‍ പരിഷ്കരിക്കുക
update_profile_success=നിങ്ങളുടെ പ്രൊഫൈൽ പരിഷ്കരിച്ചിരിക്കുന്നു.
change_username=നിങ്ങളുടെ ഉപയോക്തൃനാമം മാറ്റി.
change_username_prompt=കുറിപ്പ്: ഉപയോക്തൃനാമത്തിലെ മാറ്റം നിങ്ങളുടെ അക്കൗണ്ട് URLഉ മാറ്റുന്നു.
continue=തുടരുക
cancel=റദ്ദാക്കുക
language=ഭാഷ
ui=പ്രമേയങ്ങള്‍
lookup_avatar_by_mail=ഇമെയിൽ വിലാസം അനുസരിച്ച് അവതാർ കണ്ടെത്തുക
federated_avatar_lookup=കേന്ദ്രീക്രത അവതാര്‍ കണ്ടെത്തല്‍
enable_custom_avatar=ഇഷ്‌ടാനുസൃത അവതാർ ഉപയോഗിക്കുക
choose_new_avatar=പുതിയ അവതാർ തിരഞ്ഞെടുക്കുക
update_avatar=അവതാർ പുതുക്കുക
delete_current_avatar=നിലവിലെ അവതാർ ഇല്ലാതാക്കുക
uploaded_avatar_not_a_image=അപ്‌ലോഡുചെയ്‌ത ഫയൽ ഒരു ചിത്രമല്ല.
uploaded_avatar_is_too_big=അപ്‌ലോഡുചെയ്‌ത ഫയൽ പരമാവധി വലുപ്പം കവിഞ്ഞു.
update_avatar_success=നിങ്ങളുടെ അവതാര്‍ പരിഷ്കരിച്ചിരിക്കുന്നു.
change_password=പാസ്‌വേഡ് പുതുക്കുക
old_password=നിലവിലുള്ള രഹസ്യവാക്കു്
new_password=പുതിയ രഹസ്യവാക്കു്
retype_new_password=പുതിയ രഹസ്യവാക്കു് വീണ്ടും നല്‍കുക
password_incorrect=നിലവിലെ പാസ്‌വേഡ് തെറ്റാണ്.
change_password_success=നിങ്ങളുടെ പാസ്‌വേഡ് അപ്‌ഡേറ്റുചെയ്‌തു. ഇനി മുതൽ നിങ്ങളുടെ പുതിയ പാസ്‌വേഡ് ഉപയോഗിച്ച് പ്രവേശിക്കുക.
password_change_disabled=പ്രാദേശിക ഇതര ഉപയോക്താക്കൾക്ക് ഗിറ്റീ വെബ് വഴി പാസ്‌വേഡ് പുതുക്കാന്‍ ചെയ്യാൻ കഴിയില്ല.
emails=ഇ-മെയില്‍ വിലാസങ്ങള്‍
manage_emails=ഇമെയിൽ വിലാസങ്ങൾ നിയന്ത്രിക്കുക
manage_themes=സ്ഥിരസ്ഥിതി പ്രമേയം തിരഞ്ഞെടുക്കുക
manage_openid=ഓപ്പൺഐഡി വിലാസങ്ങൾ നിയന്ത്രിക്കുക
email_desc=അറിയിപ്പുകൾക്കും മറ്റ് പ്രവർത്തനങ്ങൾക്കുമായി നിങ്ങളുടെ പ്രാഥമിക ഇമെയിൽ വിലാസം ഉപയോഗിക്കും.
theme_desc=സൈറ്റിലുടനീളം ഇത് നിങ്ങളുടെ സ്ഥിരസ്ഥിതി പ്രമേയം ആയിരിക്കും.
primary=പ്രാഥമികം
primary_email=പ്രാഥമികമാക്കുക
delete_email=നീക്കം ചെയ്യുക
email_deletion=ഈ-മെയില്‍ വിലാസം നീക്കം ചെയ്യുക
email_deletion_desc=ഇമെയിൽ വിലാസവും അനുബന്ധ വിവരങ്ങളും നിങ്ങളുടെ അക്കൗണ്ടിൽ നിന്ന് നീക്കംചെയ്യും. ഈ ഇമെയിൽ വിലാസം വഴിയുള്ള ഗിറ്റു് നിയോഗങ്ങളും മാറ്റമില്ലാതെ ഉണ്ടാകും. തുടരട്ടെ?
email_deletion_success=ഇമെയിൽ വിലാസം നീക്കംചെയ്‌തു.
theme_update_success=നിങ്ങളുടെ പ്രമേയം പുതുക്കി.
theme_update_error=തിരഞ്ഞെടുത്ത പ്രമേയം നിലവിലില്ല.
openid_deletion=OpenID വിലാസം നീക്കം ചെയ്യുക
openid_deletion_desc=നിങ്ങളുടെ അക്കൗണ്ടിൽ നിന്ന് ഓപ്പൺഐഡി വിലാസം നീക്കംചെയ്യുന്നത് ഇതുപയോഗിച്ചു് ഇനി പ്രവേശിക്കുന്നതിൽ നിന്ന് നിങ്ങളെ തടയും. തുടരട്ടെ?
openid_deletion_success=ഓപ്പൺഐഡി വിലാസം നീക്കംചെയ്‌തു.
add_new_email=ഈ-മെയില്‍ വിലാസം ചേര്‍ക്കുക
add_new_openid=പുതിയ ഓപ്പണ്‍ ഐഡി വിലാസം ചേര്‍ക്കുക
add_email=ഈ-മെയില്‍ വിലാസം ചേര്‍ക്കുക
add_openid=ഓപ്പണ്‍ ഐഡി വിലാസം ചേര്‍ക്കുക
add_email_confirmation_sent=ഒരു സ്ഥിരീകരണ ഇമെയിൽ '%s' ലേക്ക് അയച്ചു. നിങ്ങളുടെ ഇമെയിൽ വിലാസം സ്ഥിരീകരിക്കുന്നതിന് അടുത്ത %s നുള്ളിൽ നിങ്ങളുടെ ഇൻ‌ബോക്സ് പരിശോധിക്കുക.
add_email_success=പുതിയ ഇമെയിൽ വിലാസം ചേര്‍ത്തു.
add_openid_success=പുതിയ ഓപ്പണ്‍ഐഡി വിലാസം ചേര്‍ത്തു.
keep_email_private=ഈ-മെയില്‍ വിലാസം മറയ്ക്കുക
keep_email_private_popup=നിങ്ങളുടെ ഇമെയിൽ വിലാസം മറ്റ് ഉപയോക്താക്കു് കാണാനാകില്ല.
openid_desc=ഒരു ബാഹ്യ ദാതാവിന് പ്രാമാണീകരണം നിയുക്തമാക്കാൻ ഓപ്പൺഐഡി നിങ്ങളെ അനുവദിക്കുന്നു.
manage_ssh_keys=​എസ്. എസ്. എച്ച് കീകള്‍ നിയന്ത്രിക്കുക
manage_gpg_keys=ജീ പീ. ജി കീകള്‍ നിയന്ത്രിക്കുക
add_key=കീ ചേര്‍ക്കുക
ssh_desc=ഇവയാണു് നിങ്ങളുടെ അക്കൗണ്ടുമായി ബന്ധപ്പെടുത്തിയിരിക്കുന്ന പൊതുവായ എസ്. എസ്. എച്ച് കീകൾ. ഇതിനോടനു ബന്ധിപ്പിച്ചിട്ടുള്ള സ്വകാര്യ കീകൾ നിങ്ങളുടെ കലവറകളിലേയ്ക്കു് പൂർണ്ണ ആക്സസ് അനുവദിക്കുന്നു.
gpg_desc=ഈ പൊതു GPG കീകൾ നിങ്ങളുടെ അക്കൗണ്ടുമായി ബന്ധപ്പെട്ടിരിക്കുന്നു. കമ്മിറ്റുകളെ പരിശോധിച്ചുറപ്പിക്കാൻ നിങ്ങളുടെ സ്വകാര്യ കീകൾ അനുവദിക്കുന്നതിനാൽ അവ സുരക്ഷിതമായി സൂക്ഷിക്കുക.
ssh_helper=<strong>സഹായം ആവശ്യമുണ്ടോ?</strong> <a href="%s"> നിങ്ങളുടെ സ്വന്തം SSH കീകൾ സൃഷ്ടിക്കുക,</a> അല്ലെങ്കിൽ <a href="%s"> പൊതുവായ പ്രശ്നങ്ങൾ </a> എന്നിവയ്ക്കായുള്ള ഗിറ്റ്ഹബ്ബിന്റെ മാര്‍ഗദര്‍ശനങ്ങള്‍ ഉപയോഗിച്ചു് നിങ്ങൾക്ക് എസ്. എസ്. എച്ചുമായി ബന്ധപ്പെട്ട പ്രശ്നങ്ങള്‍ പരിഹരിക്കാം.
gpg_helper=<strong> സഹായം ആവശ്യമുണ്ടോ? </strong> ജിപിജിയെക്കുറിച്ച് ഗിറ്റ്ഹബിന്റെ മാര്‍ഗ്ഗനിര്‍ദ്ദേശങ്ങള്‍ <a href="%s"> പരിശോധിയ്ക്കുക</a>.
add_new_key=SSH കീ ചേർക്കുക
add_new_gpg_key=GPG കീ ചേർക്കുക
ssh_key_been_used=ഈ SSH കീ ഇതിനകം ചേർത്തു.
ssh_key_name_used=ഇതേ പേരിലുള്ള ഒരു SSH കീ ഇതിനകം നിങ്ങളുടെ അക്കൗണ്ടിലേക്ക് ചേർത്തിട്ടുണ്ടു്.
gpg_key_id_used=സമാന ഐഡിയുള്ള ഒരു പൊതു ജിപിജി കീ ഇതിനകം നിലവിലുണ്ട്.
gpg_no_key_email_found=നിങ്ങളുടെ അക്കൗണ്ടുമായി ബന്ധപ്പെട്ട ഏതെങ്കിലും ഇമെയിൽ വിലാസത്തിൽ ഈ GPG കീ ഉപയോഗിക്കാൻ കഴിയില്ല.
subkeys=സബ് കീകള്‍
key_id=കീ ഐഡി
key_name=കീയുടെ പേരു്
key_content=ഉള്ളടക്കം
add_key_success='%s' എന്ന SSH കീ ചേർത്തു.
add_gpg_key_success='%s' എന്ന GPG കീ ചേർത്തു.
delete_key=നീക്കം ചെയ്യുക
ssh_key_deletion=SSH കീ നീക്കം ചെയ്യുക
gpg_key_deletion=GPG കീ നീക്കം ചെയ്യുക
ssh_key_deletion_desc=ഒരു SSH കീ നീക്കംചെയ്യുന്നത് നിങ്ങളുടെ അക്കൌണ്ടിലേക്കുള്ള പ്രവേശനം അസാധുവാക്കുന്നു. തുടരട്ടെ?
gpg_key_deletion_desc=ഒരു ജി‌പി‌ജി കീ നീക്കംചെയ്യുന്നത് അതിൽ ഒപ്പിട്ട കമ്മിറ്റുകളെ സ്ഥിരീകരിക്കില്ല. തുടരട്ടെ?
ssh_key_deletion_success=SSH കീ നീക്കംചെയ്‌തു.
gpg_key_deletion_success=GPG കീ നീക്കംചെയ്‌തു.
add_on=ചേര്‍ത്തതു്
valid_until=വരെ സാധുവാണ്
valid_forever=എന്നും സാധുവാണു്
last_used=അവസാനം ഉപയോഗിച്ചത്
no_activity=സമീപകാലത്തു് പ്രവർത്തനങ്ങളൊന്നുമില്ല
can_read_info=വായിയ്ക്കുക
can_write_info=എഴുതുക
key_state_desc=കഴിഞ്ഞ 7 ദിവസങ്ങളിൽ ഈ കീ ഉപയോഗിച്ചു
token_state_desc=ഈ ടോക്കൺ കഴിഞ്ഞ 7 ദിവസങ്ങളിൽ ഉപയോഗിച്ചു
show_openid=പ്രൊഫൈലിൽ കാണുക
hide_openid=പ്രൊഫൈലിൽ നിന്ന് മറയ്‌ക്കുക
ssh_disabled=SSH അപ്രാപ്‌തമാക്കി
manage_social=സഹവസിക്കുന്ന സോഷ്യൽ അക്കൗണ്ടുകളെ നിയന്ത്രിക്കുക
social_desc=ഈ സോഷ്യൽ അക്കൗണ്ടുകൾ നിങ്ങളുടെ ഗിറ്റീ അക്കൗണ്ടുമായി ലിങ്കുചെയ്‌തു. ഇവ നിങ്ങളുടെ ഗീറ്റീ അക്കൗണ്ടിലേക്ക് പ്രവേശിക്കാൻ ഉപയോഗിക്കാവുന്നതിനാൽ അവയെല്ലാം നിങ്ങൾ തിരിച്ചറിഞ്ഞുവെന്ന് ഉറപ്പാക്കുക.
unbind=അൺലിങ്ക് ചെയ്യുക
unbind_success=നിങ്ങളുടെ ഗീറ്റീ അക്കൗണ്ടിൽ നിന്ന് സോഷ്യൽ അക്കൗണ്ട് അൺലിങ്ക് ചെയ്തു.
manage_access_token=ആക്‌സസ്സ് ടോക്കണുകൾ നിയന്ത്രിക്കുക
generate_new_token=പുതിയ ടോക്കൺ സൃഷ്‌ടിക്കുക
tokens_desc=ഈ ടോക്കണുകൾ ഗിറ്റീ API ഉപയോഗിച്ച് നിങ്ങളുടെ അക്കൌണ്ടിലേക്ക് പ്രവേശനം നൽകുന്നു.
new_token_desc=ഒരു ടോക്കൺ ഉപയോഗിക്കുന്ന അപ്ലിക്കേഷനുകൾക്ക് നിങ്ങളുടെ അക്കൌണ്ടിലേക്ക് പൂർണ്ണ പ്രവേശനം ഉണ്ട്.
token_name=ടോക്കണിന്റെ പേരു്
generate_token=ടോക്കൺ സൃഷ്‌ടിക്കുക
generate_token_success=നിങ്ങളുടെ പുതിയ ടോക്കൺ ജനറേറ്റുചെയ്‌തു. ഇത് വീണ്ടും കാണിക്കാത്തതിനാൽ ഇപ്പോൾ തന്നെ പകർത്തുക.
delete_token=നീക്കം ചെയ്യുക
access_token_deletion=ആക്‌സസ്സ് ടോക്കണ്‍ നീക്കം ചെയ്യുക
access_token_deletion_desc=ഒരു ടോക്കൺ ഇല്ലാതാക്കുന്നത് നിങ്ങളുടെ അക്കൗണ്ട് ഉപയോഗിക്കുന്ന അപ്ലിക്കേഷനുകൾക്കുള്ള പ്രവേശനം അസാധുവാക്കും. തുടരട്ടേ?
delete_token_success=ടോക്കൺ ഇല്ലാതാക്കി. ഇനി ഇത് ഉപയോഗിക്കുന്ന അപ്ലിക്കേഷനുകൾക്ക് നിങ്ങളുടെ അക്കൌണ്ടിലേക്ക് പ്രവേശനം ഉണ്ടാകില്ല.
manage_oauth2_applications=OAuth2 അപ്ലിക്കേഷനുകൾ നിയന്ത്രിക്കുക
edit_oauth2_application=OAuth2 അപ്ലിക്കേഷൻ എഡിറ്റുചെയ്യുക
oauth2_applications_desc=നിങ്ങളുടെ മൂന്നാം കക്ഷി അപ്ലിക്കേഷനെ, ഈ ഗിറ്റീ ഇന്‍സ്റ്റാളേഷനുമായി സുരക്ഷിതമായി ഉപയോക്താക്കളെ പ്രാമാണീകരിക്കാൻ OAuth2 അപ്ലിക്കേഷനുകൾ പ്രാപ്തമാക്കുന്നു.
remove_oauth2_application=OAuth2 അപ്ലിക്കേഷനുകൾ നീക്കംചെയ്യുക
remove_oauth2_application_desc=ഒരു OAuth2 അപ്ലിക്കേഷൻ നീക്കംചെയ്യുന്നത് ഒപ്പിട്ട എല്ലാ ആക്സസ് ടോക്കണുകളിലേക്കും പ്രവേശനം റദ്ദാക്കും. തുടരട്ടെ?
remove_oauth2_application_success=അപ്ലിക്കേഷൻ ഇല്ലാതാക്കി.
create_oauth2_application=ഒരു പുതിയ OAuth2 അപ്ലിക്കേഷൻ സൃഷ്ടിക്കുക
create_oauth2_application_button=അപ്ലിക്കേഷൻ സൃഷ്ടിക്കുക
create_oauth2_application_success=നിങ്ങൾ വിജയകരമായി ഒരു പുതിയ OAuth2 അപ്ലിക്കേഷൻ സൃഷ്ടിച്ചു.
update_oauth2_application_success=നിങ്ങൾ വിജയകരമായി ഒരു പുതിയ OAuth2 അപ്ലിക്കേഷൻ പുതുക്കി.
oauth2_application_name=അപ്ലിക്കേഷന്റെ പേര്
oauth2_select_type=ഏത് തരം അപ്ലിക്കേഷനാണ് ഇതു്?
oauth2_type_web=വെബ് (e.g. Node.JS, Tomcat, Go)
oauth2_type_native=നേറ്റീവ് (ഉദാ. മൊബൈൽ, ഡെസ്ക്ടോപ്പ്, ബ്രൌസർ)
oauth2_redirect_uri=URI റീഡയറക്‌ട് ചെയ്യുക
save_application=സംരക്ഷിയ്ക്കുക
oauth2_client_id=ക്ലൈന്റ് ഐഡി
oauth2_client_secret=ക്ലൈന്റു് രഹസ്യം
oauth2_regenerate_secret=രഹസ്യം പുനഃസൃഷ്ടിയ്ക്കുക
oauth2_regenerate_secret_hint=നിങ്ങളുടെ രഹസ്യം നഷ്ടപ്പെട്ടോ?
oauth2_client_secret_hint=നിങ്ങൾ ഈ പേജ് വീണ്ടും സന്ദർശിക്കുകയാണെങ്കിൽ രഹസ്യം ദൃശ്യമാകില്ല. നിങ്ങളുടെ രഹസ്യം സംരക്ഷിക്കുക.
oauth2_application_edit=ക്രമീകരിക്കുക
oauth2_application_create_description=OAuth2 ആപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ മൂന്നാം കക്ഷി ആപ്ലിക്കേഷൻ ഉപയോക്തൃ അക്കൌണ്ടുകളിലേക്ക് ആക്സസ് നൽകുന്നു.
oauth2_application_remove_description=ഒരു OAuth2 ആപ്ലിക്കേഷൻ നീക്കംചെയ്യുന്നത് ഈ സന്ദർഭത്തിൽ അംഗീകൃത ഉപയോക്തൃ അക്കൌണ്ടുകളിലേക്ക് പ്രവേശിക്കുന്നത് തടയും. തുടരട്ടെ?
authorized_oauth2_applications=അംഗീകൃത OAuth2 അപ്ലിക്കേഷനുകൾ
authorized_oauth2_applications_description=ഈ മൂന്നാം കക്ഷി അപ്ലിക്കേഷനുകളിലേക്ക് നിങ്ങളുടെ സ്വകാര്യ ഗീറ്റീ അക്കൗണ്ടിലേക്ക് പ്രവേശനം അനുവദിച്ചു. അപ്ലിക്കേഷനുകൾക്കായുള്ള നിയന്ത്രണം ഇനി ആവശ്യമില്ല.
revoke_key=അസാധുവാക്കുക
revoke_oauth2_grant=നിയന്ത്രണം തിരിച്ചെടുക്കുക
revoke_oauth2_grant_description=ഈ മൂന്നാം കക്ഷി ആപ്ലിക്കേഷനായി ആക്സസ് അസാധുവാക്കുന്നത് നിങ്ങളുടെ ഡാറ്റ ആക്സസ് ചെയ്യുന്നതിൽ നിന്ന് ഈ ആപ്ലിക്കേഷനെ തടയും. നിങ്ങള്‍ക്ക് ഉറപ്പാണോ?
revoke_oauth2_grant_success=നിങ്ങൾ വിജയകരമായി പ്രവേശനം റദ്ദാക്കി.
twofa_desc=ഇരട്ട ഘടക പ്രാമാണീകരണം നിങ്ങളുടെ അക്കൗണ്ടിന്റെ സുരക്ഷ വർദ്ധിപ്പിക്കുന്നു.
twofa_is_enrolled=നിങ്ങളുടെ അക്കൗണ്ട് നിലവിൽ ഇരട്ട ഘടക പ്രമാണീകരണത്തിനു് <strong> എൻറോൾ ചെയ്തിട്ടുണ്ട്. </strong>.
twofa_not_enrolled=നിങ്ങളുടെ അക്കൗണ്ട് നിലവിൽ ഇരട്ട ഘടക പ്രമാണീകരണത്തിനു് <strong> എൻറോൾ ചെയ്തിട്ടില്ല.</strong>.
twofa_disable=ഇരട്ട ഘടക പ്രാമാണീകരണം റദ്ദാക്കി
twofa_scratch_token_regenerate=സ്ക്രാച്ച് ടോക്കൺ പുനഃനിര്‍മ്മിയ്ക്കുക
twofa_scratch_token_regenerated=%s ആണ് ഇപ്പോൾ നിങ്ങളുടെ സ്ക്രാച്ച് ടോക്കൺ. സുരക്ഷിതമായ സ്ഥലത്ത് സൂക്ഷിക്കുക.
twofa_enroll=ഇരട്ട ഘടക പ്രാമാണീകരണത്തില്‍ അംഗമാകുക
twofa_disable_note=ആവശ്യമെങ്കിൽ നിങ്ങൾക്ക് രണ്ട്-ഘടക പ്രാമാണീകരണം അപ്രാപ്തമാക്കാൻ കഴിയും.
twofa_disable_desc=രണ്ട്-ഘടക പ്രാമാണീകരണം അപ്രാപ്‌തമാക്കുന്നത് നിങ്ങളുടെ അക്കൗണ്ട് സുരക്ഷിതമല്ലാത്തതാക്കും. തുടരട്ടെ?
regenerate_scratch_token_desc=നിങ്ങളുടെ സ്ക്രാച്ച് ടോക്കൺ തെറ്റായി സ്ഥാപിക്കുകയോ അല്ലെങ്കിൽ സൈൻ ഇൻ ചെയ്യാൻ ഇതിനകം ഉപയോഗിക്കുകയോ ചെയ്തിട്ടുണ്ടെങ്കിൽ അത് ഇവിടെനിന്നു് പുനഃസജ്ജമാക്കാൻ കഴിയും.
twofa_disabled=രണ്ട്-ഘട്ട പ്രാമാണീകരണം അപ്രാപ്‌തമാക്കി.
scan_this_image=നിങ്ങളുടെ പ്രാമാണീകരണ ആപ്ലിക്കേഷൻ ഉപയോഗിച്ച് ഈ ചിത്രം സൂക്ഷ്‌മപരിശോധന നടത്തുക:
or_enter_secret=അല്ലെങ്കിൽ രഹസ്യ കോഡ് നൽകുക: %s
then_enter_passcode=അപ്ലിക്കേഷനിൽ കാണിച്ചിരിക്കുന്ന പാസ്‌കോഡ് നൽകുക:
passcode_invalid=പാസ്‌കോഡ് തെറ്റാണ്. വീണ്ടും ശ്രമിക്കുക.
twofa_enrolled=നിങ്ങളുടെ അക്കൌണ്ട് രണ്ട്-ഘട്ട പ്രാമാണീകരണത്തിലേക്ക് ചേർത്തിട്ടുണ്ട്. നിങ്ങളുടെ സ്ക്രാച്ച് ടോക്കൺ (%s) ഒരു തവണ മാത്രം കാണിക്കുന്നതിനാൽ അതു് സുരക്ഷിതമായ സ്ഥലത്ത് സൂക്ഷിക്കുക!
u2f_desc=ക്രിപ്‌റ്റോഗ്രാഫിക് കീകൾ അടങ്ങിയ ഹാർഡ്‌വെയർ ഉപകരണങ്ങളാണ് സുരക്ഷാ കീകൾ. രണ്ട്-ഘട്ട പ്രാമാണീകരണത്തിനായി അവ ഉപയോഗിക്കാം. പക്ഷേ സുരക്ഷാ കീകൾ <a rel="noreferrer" href="https://fidoalliance.org/"> FIDO U2F </a> സ്റ്റാൻഡേർഡിനെ പിന്തുണയ്‌ക്കുന്നവയാകണം.
u2f_require_twofa=സുരക്ഷാ കീകൾ‌ ഉപയോഗിക്കുന്നതിന് നിങ്ങളുടെ അക്കൌണ്ട് രണ്ട്-ഘട്ട പ്രാമാണീകരണത്തിൽ‌ ചേർ‌ത്തിരിക്കണം.
u2f_register_key=സുരക്ഷാ കീ ചേർക്കുക
u2f_nickname=വിളിപ്പേരു്
u2f_press_button=രജിസ്റ്റർ ചെയ്യുന്നതിന് നിങ്ങളുടെ സുരക്ഷാ കീയിലെ ബട്ടൺ അമർത്തുക.
u2f_delete_key=സുരക്ഷാ കീ നീക്കംചെയ്യുക
u2f_delete_key_desc=നിങ്ങൾ ഒരു സുരക്ഷാ കീ നീക്കംചെയ്യുകയാണെങ്കിൽ, നിങ്ങൾക്ക് ഇത് ഉപയോഗിച്ച് പ്രവേശിയ്ക്കാന്‍ കഴിയില്ല. തുടരട്ടെ?
manage_account_links=ബന്ധിപ്പിച്ചിട്ടുള്ള അക്കൗണ്ടുകൾ നിയന്ത്രിക്കുക
manage_account_links_desc=ഈ ബാഹ്യ അക്കൗണ്ടുകൾ നിങ്ങളുടെ ഗിറ്റീ അക്കൗണ്ടുമായി ലിങ്കുചെയ്‌തു.
account_links_not_available=നിങ്ങളുടെ ഗിറ്റീ അക്കൌണ്ടുമായി നിലവിൽ മറ്റു് ബാഹ്യ അക്കൌണ്ടുകളൊന്നും ബന്ധിപ്പിച്ചിട്ടില്ല.
remove_account_link=ബന്ധിപ്പിച്ച അക്കൗണ്ട് നീക്കംചെയ്യുക
remove_account_link_desc=ഒരു ബന്ധിപ്പിച്ച അക്കൗണ്ട് നീക്കംചെയ്യുന്നത് നിങ്ങളുടെ ഗിറ്റീ അക്കൗണ്ടിലേക്കുള്ള പ്രവേശനം അസാധുവാക്കും. തുടരട്ടെ?
remove_account_link_success=ബന്ധിപ്പിച്ച അക്കൗണ്ട് നീക്കംചെയ്‌തു.
orgs_none=നിങ്ങൾ ഏതെങ്കിലും സംഘടനയില്‍ അംഗമല്ല.
repos_none=നിങ്ങൾക്ക് ഒരു കലവറയും സ്വന്തമായി ഇല്ല
delete_account=അക്കൗണ്ട് ഇല്ലാതാക്കുക
delete_prompt=ഈ പ്രവർത്തനം നിങ്ങളുടെ ഉപയോക്തൃ അക്കൗണ്ട് ശാശ്വതമായി ഇല്ലാതാക്കും. ഇത് <strong> പൂർ‌വ്വാവസ്ഥയിലാക്കാൻ‌ കഴിയില്ല.</strong>.
confirm_delete_account=ഇല്ലാതാക്കൽ സ്ഥിരീകരിക്കുക
delete_account_title=ഉപയോക്തൃ അക്കൗണ്ട് ഇല്ലാതാക്കുക
delete_account_desc=ഈ ഉപയോക്തൃ അക്കൗണ്ട് ശാശ്വതമായി ഇല്ലാതാക്കാൻ നിങ്ങൾ ആഗ്രഹിക്കുന്നുണ്ടോ?
email_notifications.enable=ഇമെയിൽ അറിയിപ്പുകൾ പ്രാപ്തമാക്കുക
email_notifications.onmention=ഇ-മെയിൽ പരാമര്‍ശിച്ചാൽ മാത്രം അയയ്ക്കുക
email_notifications.disable=ഇമെയിൽ അറിയിപ്പുകൾ അപ്രാപ്തമാക്കുക
email_notifications.submit=ഇ-മെയില്‍ മുൻഗണനകള്‍
[repo]
owner=ഉടമസ്ഥന്‍
repo_name=കലവറയുടെ പേരു്
repo_name_helper=നല്ല കലവറയുടെ പേരു് ഹ്രസ്വവും അവിസ്മരണീയവും അതുല്യവുമായ കീവേഡുകൾ ഉപയോഗിക്കുന്നു.
visibility=കാണാനാവുന്നതു്
visibility_description=ഉടമയ്‌ക്കോ ഓർഗനൈസേഷൻ അംഗങ്ങൾക്കോ അവകാശങ്ങളുണ്ടെങ്കിൽ മാത്രമേ കാണാൻ കഴിയൂ.
visibility_helper=കലവറ സ്വകാര്യമാക്കുക
visibility_helper_forced=നിങ്ങളുടെ സൈറ്റ് അഡ്മിനിസ്ട്രേറ്റർ പുതിയ കലവറകളെ സ്വകാര്യമാക്കാൻ നിർബന്ധിക്കുന്നു.
visibility_fork_helper=(മാറ്റം എല്ലാ ഫോർക്കുകളെയും ബാധിക്കും.)
clone_helper=ക്ലോണ്‍ ചെയ്യാന്‍ സഹായം വേണോ? <a target="_blank" rel="noopener noreferrer" href="%s">സഹായം</a> സന്ദര്‍ശിക്കുക.
fork_repo=കലവറ ഫോര്‍ക്കു് ചെയ്യുക
fork_from=ല്‍ നിന്നും ഫോര്‍ക്കു് ചെയ്യൂ
fork_visibility_helper=ഒരു കലവറയുടെ ഫോര്‍ക്കിന്റെ ദൃശ്യപരത മാറ്റാൻ കഴിയില്ല.
repo_desc=വിരരണം
repo_lang=ഭാഷ
repo_gitignore_helper=.gitignore ടെംപ്ലേറ്റുകൾ തിരഞ്ഞെടുക്കുക.
license=ലൈസൻസ്
license_helper=ഒരു ലൈസൻസ് ഫയൽ തിരഞ്ഞെടുക്കുക.
readme=റീഡ്‍മീ
readme_helper=ഒരു റീഡ്‍മീ ഫയൽ ടെംപ്ലേറ്റ് തിരഞ്ഞെടുക്കുക.
auto_init=കലവറ സമാരംഭിക്കുക (.gitignore, ലൈസൻസ്, റീഡ്‍മീ എന്നിവ ചേർക്കുന്നു)
create_repo=കലവറ സൃഷ്ടിക്കുക
default_branch=സ്ഥിരസ്ഥിതി ശാഖ
mirror_prune=വെട്ടിഒതുക്കുക
mirror_prune_desc=കാലഹരണപ്പെട്ട വിദൂര ട്രാക്കിംഗ് റഫറൻസുകൾ നീക്കംചെയ്യുക
mirror_interval=മിറർ ചെയ്യാനുള്ള ഇടവേള (സാധുവായ സമയ യൂണിറ്റുകൾ 'h', 'm', 's' എന്നിവയാണ്). യാന്ത്രിക സമന്വയം പ്രവർത്തനരഹിതമാക്കാൻ 0 നല്‍കുക.
mirror_interval_invalid=മിറർ ചെയ്യാനുള്ള ഇടവേള സാധുവല്ല.
mirror_address=URL- ൽ നിന്നുള്ള ക്ലോൺ
mirror_address_url_invalid=നൽകിയ url അസാധുവാണ്. നിങ്ങൾ url- ന്റെ എല്ലാ ഘടകങ്ങളും ശരിയായി നല്‍കണം.
mirror_address_protocol_invalid=നൽകിയ url അസാധുവാണ്. http(s):// അല്ലെങ്കിൽ git:// ലൊക്കേഷനുകൾ മാത്രമേ മിറർ ചെയ്യാൻ കഴിയൂ.
mirror_last_synced=അവസാനം സമന്വയിപ്പിച്ചതു്
watchers=നിരീക്ഷകർ
stargazers=സ്റ്റാർഗാസറുകൾ
forks=ശാഖകള്‍
pick_reaction=നിങ്ങളുടെ പ്രതികരണം തിരഞ്ഞെടുക്കുക
reactions_more=കൂടാതെ %d അധികം
archive.title=ഈ കലവറ ചരിത്രരേഖാപരമായി നിലനിര്‍ത്തിയിരിക്കുന്നു. നിങ്ങൾക്ക് ഫയലുകൾ കാണാനും ക്ലോൺ ചെയ്യാനും കഴിയും, പക്ഷേ പ്രശ്‌നങ്ങൾ / ലയന അഭ്യർത്ഥനകൾ ഉണ്ടാക്കാനോ തുറക്കാനോ കഴിയില്ല.
archive.issue.nocomment=ഈ കലവറ ചരിത്രപരമായി നിലനിര്‍ത്തിയിരിക്കുന്നതാണു്. നിങ്ങൾക്ക് പ്രശ്നങ്ങളിൽ അഭിപ്രായമിടാൻ കഴിയില്ല.
archive.pull.nocomment=ഈ കലവറ ചരിത്രപരമായി നിലനിര്‍ത്തിയിരിക്കുന്നതാണു്. നിങ്ങൾക്ക് ലയന അഭ്യർത്ഥനകളില്‍ അഭിപ്രായമിടാൻ കഴിയില്ല.
form.reach_limit_of_creation=നിങ്ങളുടെ കലവറകളുടെ പരിധിയായ %d നിങ്ങൾ ഇതിനകം എത്തി.
form.name_reserved='%s' എന്ന കലവറയുടെ പേരു് മറ്റാവശ്യങ്ങള്‍ക്കായി നീക്കിവച്ചിരിക്കുന്നു.
form.name_pattern_not_allowed=കലവറനാമത്തിൽ '%s' എന്ന ശ്രേണി അനുവദനീയമല്ല.
need_auth=ക്ലോൺ അംഗീകാരിയ്ക്കുക
migrate_type=മൈഗ്രേഷൻ തരം
migrate_type_helper=ഈ കലവറ ഒരു <span class="text blue"> മിറർ </span> ആയിരിക്കും
migrate_items=മൈഗ്രേഷൻ ഇനങ്ങൾ
migrate_items_wiki=വിക്കി
migrate_items_milestones=നാഴികക്കല്ലുകള്‍
migrate_items_labels=ലേബലുകള്‍
migrate_items_issues=പ്രശ്നങ്ങൾ
migrate_items_pullrequests=ലയന അഭ്യർത്ഥനകൾ
migrate_items_releases=പ്രസിദ്ധീകരണങ്ങള്‍
migrate_repo=കലവറ മൈഗ്രേറ്റ് ചെയ്യുക
migrate.clone_address=URL- ൽ നിന്ന് മൈഗ്രേറ്റ് / ക്ലോൺ ചെയ്യുക
migrate.clone_address_desc=നിലവിലുള്ള ഒരു കലവറയുടെ HTTP(S) അല്ലെങ്കിൽ ഗിറ്റു് 'ക്ലോൺ' URL
migrate.clone_local_path=അല്ലെങ്കിൽ ഒരു പ്രാദേശിക സെർവർ പാത
migrate.permission_denied=പ്രാദേശിക കലവറകള്‍ ഇറക്കുമതി ചെയ്യാൻ നിങ്ങള്‍ക്കു് അനുവാദമില്ല.
migrate.invalid_local_path=പ്രാദേശിക പാത അസാധുവാണ്. ഇത് നിലവിലില്ല അല്ലെങ്കിൽ ഒരു ഡയറക്ടറിയല്ല.
migrate.failed=മൈഗ്രേഷൻ പരാജയപ്പെട്ടു: %v
migrate.lfs_mirror_unsupported=എൽ‌എഫ്‌എസ് ഒബ്‌ജക്റ്റുകളുടെ മിററിംഗ് പിന്തുണയ്‌ക്കുന്നില്ല - പകരം 'git lfs fetch --all', 'git lfs push --all' എന്നിവ ഉപയോഗിക്കുക.
migrate.migrate_items_options=ഗിറ്റ്ഹബിൽ നിന്ന് മൈഗ്രേറ്റ് ചെയ്യുമ്പോൾ, ഒരു ഉപയോക്തൃനാമവും മൈഗ്രേഷൻ ഓപ്ഷനുകളും നല്‍കാം.
migrated_from=<a href="%[1]s">%[2]s</a> നിന്ന് മൈഗ്രേറ്റുചെയ്‌തു
migrated_from_fake=%[1]s നിന്ന് മൈഗ്രേറ്റുചെയ്തു
mirror_from=ന്റെ കണ്ണാടി
forked_from=ല്‍ നിന്നും വഴിപിരിഞ്ഞതു്
fork_from_self=നിങ്ങളുടെ ഉടമസ്ഥതയിലുള്ള ഒരു ശേഖരം നിങ്ങൾക്ക് ഫോര്‍ക്കു് ചെയ്യാൻ കഴിയില്ല.
fork_guest_user=ഈ ശേഖരം ഫോർക്ക് ചെയ്യുന്നതിന് സൈൻ ഇൻ ചെയ്യുക.
copy_link=പകര്‍ത്തുക
copy_link_success=കണ്ണി പകർത്തി
copy_link_error=പകർത്താൻ ⌘C അല്ലെങ്കിൽ Ctrl-C ഉപയോഗിക്കുക
copied=പകര്‍ത്തല്‍ പൂര്‍ത്തിയായി
unwatch=ശ്രദ്ധിക്കാതിരിയ്ക്കുക
watch=ശ്രദ്ധിയ്ക്കുക
unstar=നക്ഷത്രം നീക്കുക
star=നക്ഷത്രം നല്‍ക്കുക
fork=ഫോര്‍ക്കു്
download_archive=കലവറ ഡൗൺലോഡുചെയ്യുക
no_desc=വിവരണം ലഭ്യമല്ല
quick_guide=ദ്രുത മാര്‍ഗദര്‍ശനം
clone_this_repo=ഈ കലവറ ക്ലോൺ ചെയ്യുക
create_new_repo_command=കമാൻഡ് ലൈന്‍ വഴി ഒരു പുതിയ കലവറ സൃഷ്ടിക്കുക
push_exist_repo=കമാൻഡ് ലൈനിൽ നിന്ന് നിലവിലുള്ള ഒരു കലവറ തള്ളിക്കയറ്റുക
empty_message=ഈ കലവറയില്‍ ഉള്ളടക്കമൊന്നും അടങ്ങിയിട്ടില്ല.
code=കോഡ്
code.desc=ഉറവിട കോഡ്, ഫയലുകൾ, കമ്മിറ്റുകളും ശാഖകളും പ്രവേശിയ്ക്കുക.
branch=ശാഖ
tree=മരം
filter_branch_and_tag=ശാഖ അല്ലെങ്കിൽ ടാഗ് അരിച്ചെടുക്കുക
branches=ശാഖകള്‍
tags=ടാഗുകള്‍
issues=പ്രശ്നങ്ങൾ
pulls=ലയന അഭ്യർത്ഥനകൾ
labels=ലേബലുകള്‍
milestones=നാഴികക്കല്ലുകള്‍
commits=കമ്മിറ്റുകള്‍
commit=കമ്മിറ്റ്
releases=പ്രസിദ്ധപ്പെടുത്തുക
file_raw=കലര്‍പ്പില്ലാത്തതു്
file_history=നാള്‍വഴി
file_view_raw=കലര്‍പ്പില്ലാതെ കാണുക
file_permalink=സ്ഥിരമായ കണ്ണി
file_too_large=ഈ ഫയൽ കാണിക്കാൻ കഴിയാത്തത്ര വലുതാണ്.
video_not_supported_in_browser=നിങ്ങളുടെ ബ്രൌസർ HTML5 'വീഡിയോ' ടാഗിനെ പിന്തുണയ്ക്കുന്നില്ല.
audio_not_supported_in_browser=നിങ്ങളുടെ ബ്ര browser സർ HTML5 'ഓഡിയോ' ടാഗിനെ പിന്തുണയ്ക്കുന്നില്ല.
stored_lfs=ഗിറ്റു് LFS ഉപയോഗിച്ച് സംഭരിച്ചു
commit_graph=കമ്മിറ്റ് ഗ്രാഫ്
blame=ചുമതല
normal_view=സാധാരണ കാഴ്ച
editor.new_file=പുതിയ ഫയൽ
editor.upload_file=ഫയൽ അപ്‌ലോഡ്
editor.edit_file=ഫയൽ തിരുത്തുക
editor.preview_changes=മാറ്റങ്ങൾ കാണുക
editor.cannot_edit_lfs_files=വെബ് ഇന്റർഫേസിൽ LFS ഫയലുകൾ എഡിറ്റുചെയ്യാൻ കഴിയില്ല.
editor.cannot_edit_non_text_files=വെബ് ഇന്റർഫേസിൽ ബൈനറി ഫയലുകൾ എഡിറ്റുചെയ്യാൻ കഴിയില്ല.
editor.edit_this_file=ഫയൽ തിരുത്തുക
editor.must_be_on_a_branch=ഈ ഫയലിൽ മാറ്റങ്ങൾ വരുത്താനോ നിർദ്ദേശിക്കാനോ നിങ്ങൾ ഏതെങ്കിലും ഒരു ശാഖയിൽ ആയിരിക്കണം.
editor.fork_before_edit=ഈ ഫയലിൽ മാറ്റങ്ങൾ വരുത്താനോ നിർദ്ദേശിക്കാനോ നിങ്ങൾ ഈ ശേഖരം ഫോര്‍ക്കു ചെയ്തിരിക്കണം.
editor.delete_this_file=ഫയൽ ഇല്ലാതാക്കുക
editor.must_have_write_access=ഈ ഫയലിൽ മാറ്റങ്ങൾ വരുത്താനോ നിർദ്ദേശിക്കാനോ നിങ്ങൾക്ക് എഴുതാനുള്ള അനുമതി ഉണ്ടായിരിക്കണം.
editor.file_delete_success=%s ഫയൽ ഇല്ലാതാക്കി.
editor.name_your_file=നിങ്ങളുടെ ഫയലിന് പേര് നൽകുക…
editor.filename_help=ഒരു ഡയറക്‌ടറിയുടെ പേര് ടൈപ്പുചെയ്‌ത് സ്ലാഷും ('/') ചേർത്ത് ചേർക്കുക. ഇൻപുട്ട് ഫീൽഡിന്റെ തുടക്കത്തിൽ ബാക്ക്‌സ്‌പെയ്‌സ് ടൈപ്പുചെയ്‌ത് ഒരു ഡയറക്‌ടറി നീക്കംചെയ്യുക.
editor.or=അഥവാ
editor.cancel_lower=റദ്ദാക്കുക
editor.commit_changes=മാറ്റങ്ങൾ വരുത്തുക
editor.add_tmpl='<ഫയല്‍>' ചേർക്കുക
editor.add=%s ചേര്‍ക്കുക
editor.update=%s പുതുക്കുക
editor.delete=%s നീക്കം ചെയ്യുക
editor.propose_file_change=ഫയലിനു് മാറ്റങ്ങള്‍ നിർദ്ദേശിക്കുക
editor.new_branch_name_desc=പുതിയ ശാഖയുടെ പേരു്…
editor.cancel=റദ്ദാക്കുക
editor.filename_cannot_be_empty=ഫയലിന്റെ പേരു് ശൂന്യമായിരിക്കരുത്.
editor.add_subdir=ഒരു ഡയറക്ടറി ചേർക്കുക…
editor.upload_files_to_dir=ഫയലുകൾ %s ലേക്ക് അപ്‌ലോഡുചെയ്യുക
issues.new.clear_labels=ലേബലുകൾ മായ്‌ക്കുക
issues.new.milestone=നാഴികക്കല്ല്
issues.new.no_milestone=നാഴികക്കല്ല് ഇല്ല
issues.new.clear_milestone=നാഴികക്കല്ല് എടുത്തു മാറ്റുക
issues.new.open_milestone=നാഴികക്കല്ലുകൾ തുറക്കുക
issues.new.closed_milestone=അടച്ച നാഴികക്കല്ലുകൾ
issues.new.assignees=നിശ്ചയിക്കുന്നവര്‍
issues.new.clear_assignees=നിശ്ചയിക്കുന്നവരെ നീക്കം ചെയ്യുക
issues.new.no_assignees=നിശ്ചയിക്കുന്നവര്‍ ഇല്ല
issues.no_ref=ശാഖാ അഥവാ ടാഗ് വ്യക്തമാക്കിയിട്ടില്ല
issues.create=പ്രശ്നം സൃഷ്ടിക്കുക
issues.new_label=പുതിയ അടയാളം
issues.new_label_placeholder=അടയാള നാമം
issues.new_label_desc_placeholder=വിരരണം
issues.create_label=അടയാളം സൃഷ്ടിക്കുക
issues.label_templates.title=മുൻ‌നിശ്ചയിച്ച ഒരു കൂട്ടം ലേബലുകൾ‌ നിറയ്‌ക്കുക
issues.label_templates.info=ലേബലുകളൊന്നും ഇതുവരെ നിലവിലില്ല. 'പുതിയ ലേബൽ' ഉപയോഗിച്ച് ഒരു ലേബൽ സൃഷ്ടിക്കുക അല്ലെങ്കിൽ മുൻ‌നിശ്ചയിച്ച ലേബൽ സെറ്റ് ഉപയോഗിക്കുക:
issues.label_templates.helper=ഒരു ലേബൽ സെറ്റ് തിരഞ്ഞെടുക്കുക
issues.label_templates.use=ലേബൽ സെറ്റ് ഉപയോഗിക്കുക
issues.deleted_milestone=`(ഇല്ലാതാക്കി)`
issues.filter_type.all_issues=എല്ലാ ഇഷ്യൂകളും
issues.label_open_issues=%d തുറന്നനിലയിലുള്ള ഇഷ്യൂകള്‍
issues.label_deletion_desc=ഒരു ലേബൽ ഇല്ലാതാക്കിയാല്‍, അതു് നിയുകതമാക്കിയ എല്ലാ ഇഷ്യൂകളില്‍ നിന്നും നീക്കംചെയ്യും. തുടരട്ടെ?
issues.dependency.issue_closing_blockedby=ഈ ലയന അഭ്യര്‍ത്ഥന അടയ്‌ക്കുന്നത് ഇനിപ്പറയുന്ന ഇഷ്യൂകള്‍ തടയുന്നു്
issues.dependency.pr_closing_blockedby=ഈ ഇഷ്യു അടയ്‌ക്കുന്നത് ഇനിപ്പറയുന്ന ലയന അഭ്യര്‍ത്ഥന തടയുന്നു്
issues.dependency.issue_close_blocks=ഈ ഇഷ്യു അടയ്‌ക്കുന്നത് ഇനിപ്പറയുന്ന ഇഷ്യൂകള്‍ തടയുന്നു്
issues.dependency.pr_close_blocks=ഈ ഇഷ്യൂകള്‍ അടയ്‌ക്കുന്നത് ഈ ലയന അഭ്യര്‍ത്ഥന തടയുന്നു്
issues.dependency.issue_close_blocked=ഈ ഇഷ്യൂ അടയ്‌ക്കുന്നതിന് മുമ്പ് ഇതിനെ തടയുന്ന എല്ലാ ഇഷ്യൂകളും നിങ്ങൾ അടയ്‌ക്കേണ്ടതുണ്ട്.
issues.dependency.pr_close_blocked=ഈ ലയന അഭ്യര്‍ത്ഥന സ്ഥിരീകരിയ്ക്കുന്നതിനു മുമ്പ് ഇതിനെ തടയുന്ന എല്ലാ ഇഷ്യൂകളും നിങ്ങൾ അടയ്‌ക്കേണ്ടതുണ്ട്.
issues.dependency.setting=ലയന അഭ്യര്‍ത്ഥനകള്‍ക്കും ഇഷ്യൂകള്‍ക്കുമായി ആശ്രിതത്വം സജ്ജമാക്കുക
issues.dependency.add_error_cannot_create_circular=രണ്ട് ഇഷ്യൂകളും പരസ്പരം തടയുന്നതാകുന്നതിലൂടെ നിങ്ങൾക്ക് ഒരു ആശ്രയത്വം സൃഷ്ടിക്കാൻ കഴിയില്ല.
issues.dependency.add_error_dep_not_same_repo=രണ്ട് പ്രശ്നങ്ങളും ഒരേ കലവറയിലേതു് ആയിരിക്കണം.
milestones.filter_sort.most_issues=മിക്ക ഇഷ്യൂകളും
milestones.filter_sort.least_issues=കുറഞ്ഞ ഇഷ്യൂകളെങ്കിലും
activity.active_issues_count_n=<strong>%d</strong> സജ്ജീവ ഇഷ്യൂകള്‍
activity.closed_issues_count_n=അടച്ച ഇഷ്യൂകള്‍
activity.title.issues_n=%d ഇഷ്യൂകള്‍
activity.new_issues_count_n=പുതിയ ഇഷ്യൂകള്‍
settings.event_issues=ഇഷ്യൂകള്‍
[org]
[admin]
repos.issues=ഇഷ്യൂകള്‍
[action]
[tool]
[dropzone]
[notification]
[gpg]
[units]

2107
conf/locale/locale_nl-NL.ini Normal file

File diff suppressed because it is too large Load Diff

2332
conf/locale/locale_pl-PL.ini Normal file

File diff suppressed because it is too large Load Diff

2235
conf/locale/locale_pt-BR.ini Normal file

File diff suppressed because it is too large Load Diff

2351
conf/locale/locale_pt-PT.ini Normal file

File diff suppressed because it is too large Load Diff

2306
conf/locale/locale_ru-RU.ini Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,732 @@
home=Почетна
dashboard=Контролни панел
explore=Преглед
help=Помоћ
sign_in=Пријавите Се
sign_out=Одјава
register=Регистрација
website=Веб-страница
version=Верзија
page=Страница
template=Шаблон
language=Језик
signed_in_as=Пријављени сте као
username=Корисничко име
password=Лозинка
repository=Спремиште
organization=Организација
mirror=Огледало
new_repo=Ново спремиште
new_migrate=Нова миграција
new_mirror=Ново огледало
new_org=Нова организација
manage_org=Управљање организацијама
account_settings=Подешавања налога
settings=Подешавања
activities=Активности
pull_requests=Захтеви за спајање
issues=Дискусије
cancel=Откажи
[error]
[startpage]
[install]
install=Инсталација
db_title=Подешавања базе
db_type=Тип базе података
host=Хост
password=Лозинка
db_name=Име базе података
path=Пут
repo_path=Пут до корена спремишта
log_root_path=Пут до журнала
optional_title=Напредна подешавања
smtp_host=SMTP сервер
federated_avatar_lookup_popup=Омогућите federated avatars lookup да би сте користили федеративни сервис помоћу libravatar.
enable_captcha_popup=Тражи Captcha приликом регистрације корисника.
admin_password=Лозинка
confirm_password=Потврдите лозинку
install_btn_confirm=Успостави Gitea
test_git_failed=Команда 'git' није успела: %v
[home]
password_holder=Лозинка
switch_dashboard_context=Пребаците контекст контролној панели
collaborative_repos=Заједничка спремишта
my_orgs=Моје организације
my_mirrors=Моја огледала
view_home=Прикажи %s
issues.in_your_repos=У вашим спремиштима
[explore]
repos=Спремишта
users=Корисници
search=Претрага
[auth]
register_helper_msg=Већ имате налог? Пријавите се!
remember_me=Запамти ме
active_your_account=Активирајте ваш налог
has_unconfirmed_mail=Здраво, %s! Имате непотврђену адресу е-поште (<b>%s</b>). Ако вам није стигло писмо са потврдом или морате да пошаљете нову поруку, притисните на пратеће дугме.
resend_mail=Кликните овде да поново пошаљете писмо
[mail]
activate_account=Молимо вас активирајте ваш налог
activate_email=Потврдите вашу адресу е-поште
[modal]
yes=Да
no=Не
[form]
UserName=Корисничко име
RepoName=Име спремишта
Email=Адреса ел. поште
Password=Лозинка
SSHTitle=Име SSH кључа
HttpsUrl=HTTPS URL адреса
PayloadUrl=URL адреса за слање
TeamName=Име тима
AuthName=Ауторизацијско име
AdminEmail=Адреса е-поште администратора
NewBranchName=Име нове гране
CommitSummary=Опис за ревизију
CommitMessage=Ревизни текст
CommitChoice=Избор ревизије
TreeName=Пут до датотеке
Content=Садржај
require_error=` не може бити празно.`
size_error=` мора бити величине %s.`
min_size_error=` мора да садржи најмање %s карактера.`
max_size_error=` мора да садржи највише %s карактера.`
email_error=` није важећа адреса е-поште.`
url_error=` није исправна URL адреса.`
include_error=` мора да садржи текст '%s'.`
unknown_error=Непозната грешка:
auth_failed=Грешка идентитета: %v
target_branch_not_exist=Ова грана не постоји.
[user]
join_on=Регистриран
repositories=Спремишта
activity=Активности
followers=Пратиоци
following=Пратим
follow=Прати
unfollow=Престани да пратиш
[settings]
profile=Профил
password=Лозинка
avatar=Аватар
social=Налози на друштвеним мрежама
delete=Уклоните налог
public_profile=Јавни профил
full_name=Име и презиме
website=Веб страница
location=Локација
update_profile=Ажурирај профил
continue=Настави
cancel=Откажи
federated_avatar_lookup=Federated Avatar претрага
enable_custom_avatar=Укључи ваш аватар
choose_new_avatar=Изаберите нови аватар
delete_current_avatar=Обришите тренутни аватар
old_password=Тренутна лозинка
new_password=Нова лозинка
emails=Адреса ел. поште
email_desc=Ваша главна адреса ће се користити за обавештења и других операција.
primary=Главно
manage_ssh_keys=Управљање SSH кључева
add_key=Додај кључ
add_new_key=Додај SSH кључ
key_name=Име кључа
key_content=Садржај
add_on=Додато
last_used=Задње корршћено
no_activity=Нема недавних активности
manage_social=Управљање прикључених друштвеним мрежама
generate_new_token=Генериши нови токен
token_name=Име токена
generate_token=Генериши токен
delete_token=Уклони
delete_account=Уклоните ваш налог
confirm_delete_account=Потврдите брисање
[repo]
owner=Власник
repo_name=Име спремишта
visibility=Видљивост
fork_repo=Креирај огранак спремишта
fork_from=Огранак од
repo_desc=Опис
repo_lang=Језик
license=Лиценца
create_repo=Ново спремиште
default_branch=Главна грана
mirror_prune=Очисти
watchers=Посматрачи
stargazers=Пратиоци
forks=Огранци
migrate_type=Тип миграције
migrate_type_helper=Ово спремиште ће бити <span class="text blue">огледало</span>
migrate_repo=Мигрирајте спремиште
migrate.permission_denied=Немате права на увезете локално спремиште.
migrate.failed=Миграција није успела: %v
mirror_from=огледало од
forked_from=изданак од
copy_link=Копирај
copied=Успешно ископирано
unwatch=Престани пратити
watch=Прати
unstar=Улкони звезду
star=Волим
fork=Креирај огранак
no_desc=Нема описа
quick_guide=Кратак водич
clone_this_repo=Клонирај спремиште
code=Код
branch=Грана
tree=Дрво
filter_branch_and_tag=Профилтрирај по грани или ознаци
branches=Гране
tags=Ознаке
issues=Дискусије
pulls=Захтеви за спајање
labels=Лабеле
milestones=Фазе
commits=Комити
releases=Издања
file_raw=Датотека
file_history=Историја
file_view_raw=Прегледај саму датотеку
file_permalink=Пермалинк
editor.preview_changes=Преглед промена
editor.or=или
editor.commit_changes=Изврши комит промена
editor.add=Додај '%s'
editor.update=Ажурирај '%s'
editor.delete=Уклони '%s'
editor.commit_directly_to_this_branch=Изврши комит директно на <strong class="branch-name">%s</strong> грану.
editor.create_new_branch=Креирај <strong>нову грану</strong> за овај комит и поднеси захтев за спајање.
editor.cancel=Откажи
editor.branch_already_exists=Грана '%s' већ постоји за ово спремиште.
editor.no_changes_to_show=Нема никаквих промена.
editor.fail_to_update_file=Промена над '%s' није успело са грешком: %v
editor.unable_to_upload_files=Учитање датотеке '%s' није успело са грешкном: %v
editor.upload_files_to_dir=Пошаљи датотеке на '%s'
commits.commits=Комити
commits.author=Аутор
commits.message=Порука
commits.date=Датум
commits.older=Старије
commits.newer=Новије
issues.new=Нови задатак
issues.new.labels=Лавеле
issues.new.no_label=Нема лабеле
issues.new.clear_labels=Уклони лабеле
issues.new.milestone=Фаза
issues.new.no_milestone=Нема фазе
issues.new.clear_milestone=Уклони фазу
issues.new.open_milestone=Отворене фазе
issues.new.closed_milestone=Затворене фазе
issues.create=Додај задатак
issues.new_label=Нова лабела
issues.create_label=Креирај лабелу
issues.label_templates.title=Преузмите унапред дефинисани скуп лабела
issues.label_templates.helper=Изаберите скуп лабела
issues.label_templates.fail_to_load_file=Није могуће преузети датотеку '%s': %v
issues.open_tab=%d отворено
issues.close_tab=%d затворено
issues.filter_label=Лабела
issues.filter_milestone=Фаза
issues.filter_assignee=Одговорни
issues.filter_type=Тип
issues.filter_type.all_issues=Сви задаци
issues.filter_type.assigned_to_you=Заказано вама
issues.filter_type.created_by_you=креирано од вас
issues.filter_type.mentioning_you=Помењује вас
issues.filter_sort=Сортирај
issues.filter_sort.latest=Најновије
issues.filter_sort.oldest=Најстарије
issues.filter_sort.recentupdate=Недавно ажурирано
issues.filter_sort.leastupdate=Давно ажуриано
issues.filter_sort.mostcomment=Највише коментара
issues.filter_sort.leastcomment=Најмање коментара
issues.opened_by=отворено %[1]s од <a href="%[2]s">%[3]s</a>
issues.opened_by_fake=отворено %[1]s од %[2]s
issues.previous=Претходна
issues.next=Следеће
issues.open_title=Отворено
issues.closed_title=Затворено
issues.num_comments=%d коментара
issues.commented_at=`коментирира <a href="#%s">%s</a>`
issues.delete_comment_confirm=Да ли желите да избришете овај коментар?
issues.no_content=Још нема садржаја.
issues.close_issue=Затвори
issues.reopen_issue=Поново отвори
issues.create_comment=Коментирај
issues.commit_ref_at=`поменуо овај задатак у комит <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.poster=Аутор
issues.collaborator=Коаутор
issues.owner=Власник
issues.sign_in_require_desc=<a href="%s">Пријавите се</a> да се прикључе у овом разговору.
issues.edit=Уреди
issues.cancel=Откажи
issues.save=Сачувај
issues.label_title=Име лабеле
issues.label_color=Боја лабеле
issues.label_count=%d лабела
issues.label_open_issues=%d отворених задатака
issues.label_edit=Уреди
issues.label_delete=Уклони
issues.num_participants=%d учесника
issues.attachment.open_tab=`Кликните "%s" да видите у новом прозору`
issues.attachment.download=`Кликните да преузмете "%s"`
pulls.new=Нови захтев за спајање
pulls.filter_branch=Филтер по грани
pulls.no_results=Нема резултата.
pulls.create=Поднеси захтев за спајање
pulls.merged_title_desc=споји(ла) %[1]d комит(е) из <code>%[2]s</code> у <code>%[3]s</code> %[4]s
pulls.tab_conversation=Дискусија
pulls.tab_commits=Комити
pulls.merged=Спојено
pulls.can_auto_merge_desc=Овај захтев за спајање може бити обављен аутоматски.
pulls.merge_pull_request=Обави спајање
milestones.new=Нова фаза
milestones.open_tab=%d отворено
milestones.close_tab=%d затворено
milestones.closed=Затворено %s
milestones.no_due_date=Рок није наведен
milestones.open=Отвори
milestones.close=Затвори
milestones.create=Креирај фазу
milestones.title=Наслов
milestones.desc=Опис
milestones.due_date=Датум завршетка (опционо)
milestones.clear=Уклони
milestones.edit=Ажурирај фазу
milestones.cancel=Откажи
wiki=Вики
wiki.page=Страница
wiki.filter_page=Филтер странице
wiki.save_page=Сачувај страницу
wiki.last_commit_info=%s урећивао ову страницу %s
wiki.edit_page_button=Уреди
wiki.new_page_button=Нова страница
wiki.delete_page_button=Уклони страницу
wiki.page_already_exists=Страница са овим именом већ постоји.
wiki.pages=Странице
wiki.last_updated=Последње ажурирано %s
settings=Подешавања
settings.collaboration.write=За писање
settings.collaboration.read=Читање
settings.collaboration.undefined=Није дефинисано
settings.githooks=Git хуки
settings.basic_settings=Основна подешавања
settings.mirror_settings=Подешавања огледала
settings.update_settings=Примени промене
settings.advanced_settings=Напредна подешавања
settings.external_wiki_url=URL адреса спољног Вики
settings.tracker_url_format=Спољни формат везе система за праћење грешака
settings.tracker_issue_style.numeric=Нумерично
settings.tracker_issue_style.alphanumeric=Алфанумерично
settings.danger_zone=Опасна зона
settings.new_owner_has_same_repo=Нови власник већ има спремиште по истим називом. Молимо вас изаберите друго име.
settings.transfer=Пренеси власништво
settings.delete=Уклони ово спремиште
settings.delete_notices_1=- Ова операција <strong>НЕЋЕ МОЧИ</strong> бити укинута.
settings.transfer_owner=Нови власник
settings.add_webhook=Додај Webhook
settings.webhook.test_delivery=Провери испоруку
settings.webhook.request=Захтев
settings.webhook.response=Одговор
settings.webhook.headers=Наслови
settings.webhook.body=Тело
settings.githook_edit_desc=о Webhook није активан, примерни садржај ће бити представљен. Ако оставите празно, Webhook ће бити онемогућен.
settings.githook_name=Име Hook-а
settings.githook_content=Садржај Hook-а
settings.update_githook=Ажурирај Hook
settings.secret=Тајна
settings.slack_username=Корисничко име
settings.slack_icon_url=URL адреса иконице
settings.slack_color=Боја
settings.event_create=Креирај
settings.event_pull_request=Захтев за спајање
settings.update_webhook=Ажурирај Webhook
settings.recent_deliveries=Недавне испоруке
settings.hook_type=Тип Hook-а
settings.slack_token=Токен
settings.slack_domain=Домен
settings.slack_channel=Канал
settings.deploy_keys=Кључеви за распоређивање
settings.add_deploy_key=Додај кључ за распоређивање
settings.title=Наслов
settings.deploy_key_content=Садржај
diff.browse_source=Преглед изворни кода
diff.parent=родитељ
diff.commit=комит
diff.show_split_view=Подељен поглед
diff.show_unified_view=Један поглед
diff.stats_desc=<strong> %d измењених фајлова</strong> са <strong>%d додато</strong> и <strong>%d уклоњено</strong>
diff.view_file=Прегледај датотеку
diff.file_suppressed=Разлика између датотеке није приказан због своје велике величине
diff.too_many_files=Неке датотеке нису приказане због велике количине промена
release.releases=Издања
release.new_release=Ново издање
release.draft=Нацрт
release.prerelease=Пред-верзија
release.stable=Стабилно
release.edit=уреди
release.source_code=Изворни код
release.tag_name=Име ознаке
release.target=Циљ
release.title=Наслов
release.content=Садржај
release.cancel=Откажи
release.publish=Објави издање
release.save_draft=Сачувај нацрт
release.downloads=Преузимања
[org]
org_name_holder=Име организације
org_full_name_holder=Пун назив организације
create_org=Створи Организацију
repo_updated=Ажурирано
people=Особе
teams=Тимови
lower_members=чланови
lower_repositories=спремишта
org_desc=Опис
team_name=Име тима
team_desc=Опис
settings=Подешавања
settings.full_name=Пуно име
settings.website=Саит
settings.location=Локација
settings.update_settings=Ажурирај подешавања
settings.delete=Уклони организацију
settings.delete_account=Уклони ову организацију
settings.confirm_delete_account=Потврди брисање
members.membership_visibility=Видљивост:
members.member_role=Улога учесника:
members.owner=Власник
members.member=Члан
members.remove=Уклони
members.leave=Изађи
members.invite_desc=Додја новог члана %s:
members.invite_now=Позовите сада
teams.join=Придружи се
teams.leave=Изаћи
teams.read_access=Приступ за читање
teams.write_access=Приступ за писање
teams.no_desc=Овај тим нема описа
teams.settings=Подешавања
teams.members=Чланови тима
teams.update_settings=Примени промене
teams.add_team_member=Додај члан тиму
teams.repositories=Тимска спремишта
teams.add_nonexistent_repo=Овакво спремиште не постоји, молим вас прво да га направите.
[admin]
dashboard=Контролни панел
organizations=Организације
repositories=Спремишта
config=Подешавања
notices=Системска обавештења
monitor=Праћење
first_page=Први
last_page=Последњи
total=Укупно: %d
dashboard.operation_name=Име операције
dashboard.operation_switch=Пребаци
dashboard.operation_run=Покрени
dashboard.server_uptime=Време непрекидног рада сервера
dashboard.current_goroutine=Тренутнe Goroutine
dashboard.current_memory_usage=Тренутна употреба меморије
dashboard.total_memory_allocated=Укупно меморије алоцирано
dashboard.memory_obtained=Коришћена меморија
dashboard.pointer_lookup_times=Захтева показивача
dashboard.current_heap_usage=Тренутна употреба динамичке меморије
dashboard.heap_memory_obtained=Слободно динамичке меморије
dashboard.heap_memory_idle=Неактиво динамичке меморије
dashboard.heap_memory_in_use=Динамичка меморија у употреби
dashboard.heap_memory_released=Ослобођено динамичке меморије
dashboard.heap_objects=Објекти динамичке меморије
dashboard.bootstrap_stack_usage=Коришћење стек меморије
dashboard.stack_memory_obtained=Слободно стек меморије
dashboard.mspan_structures_usage=Употреба структуре MSpan
dashboard.mspan_structures_obtained=Добијено структуре MSpan
dashboard.mcache_structures_usage=Употреба структурa MCache
dashboard.mcache_structures_obtained=Добијено структурa MCache
dashboard.profiling_bucket_hash_table_obtained=Хеш-таблеа постигнуто за Profiling Bucket
dashboard.gc_metadata_obtained=Добијених метаподатака cакупљању смећа
dashboard.other_system_allocation_obtained=Добијено друга системска меморија
dashboard.next_gc_recycle=Следећа рециклажа cакупљању смећа
dashboard.last_gc_time=Времена од прошлог cакупљању смећа
dashboard.total_gc_time=Укупно време cакупљању смећа
dashboard.total_gc_pause=Укупно време cакупљању смећа
dashboard.last_gc_pause=Задња пауза у cакупљању смећа
dashboard.gc_times=Времена cакупљању смећа
users.activated=Активиран
users.admin=Администратор
users.repos=Спремишта
users.created=Креирано
users.edit=Уреди
users.auth_source=Извор аутентикације
users.local=Локално
orgs.name=Име
orgs.teams=Тимови
orgs.members=Чланови
repos.owner=Власник
repos.name=Име
repos.private=Приватно
repos.stars=Фаворити
repos.issues=Задаци
auths.name=Име
auths.type=Тип
auths.enabled=Омогућено
auths.updated=Ажурирано
auths.auth_type=Врста провере аутентичности
auths.auth_name=Име провере аутентичности
auths.security_protocol=Протокол безбедности
auths.domain=Домен
auths.host=Хост
auths.port=Порт
auths.bind_password=Bind лозинкa
auths.user_base=База претраживање корисника
auths.user_dn=DN корисника
auths.filter=Филтер корисника
auths.admin_filter=Филтер администратора
auths.smtp_auth=Тип SMTP аутентикације
auths.smtphost=SMTP хост
auths.smtpport=SMTP порт
auths.allowed_domains=Дозвољени домени
auths.enable_tls=Омогући TLS шифровање
auths.skip_tls_verify=Прескочи TLS проверу
auths.pam_service_name=Назив PAM сервиса
auths.enable_auto_register=Омогући аутоматску регистрацију
auths.tips=Савети
config.server_config=Конфигурација сервера
config.disable_router_log=Онемогући журнал рутера
config.run_mode=Режим извршавања
config.repo_root_path=Пут до корена спремишта
config.static_file_root_path=Пут до статичке датотеке
config.script_type=Врста скрипта
config.reverse_auth_user=Корисничко име при обрнуту аутентикацију
config.ssh_config=SSH конфигурација
config.ssh_enabled=Омогућено
config.ssh_port=Порт
config.ssh_listen_port=Порт за слушање
config.ssh_root_path=Основни пут
config.ssh_key_test_path=Пут до кључу
config.ssh_keygen_path=Пут до генератор кључева ('ssh-keygen')
config.ssh_minimum_key_size_check=Минимална величина провера кључа
config.ssh_minimum_key_sizes=Минимална величина кључева
config.db_config=Конфигурација базе података
config.db_type=Тип
config.db_host=Хост
config.db_name=Име
config.db_path=Пут
config.service_config=Подешавања сервиса
config.show_registration_button=Прикажи дугме за регистрацију
config.disable_key_size_check=Онемогући проверу на минималној величини кључа
config.active_code_lives=Дужина живота активних кодова
config.webhook_config=Подешавања Webhook
config.queue_length=Дужина реда
config.deliver_timeout=Време до отказивање слања
config.mailer_enabled=Омогућено
config.mailer_disable_helo=Онемогући HELO
config.mailer_name=Име
config.mailer_host=Хост
config.mailer_user=Корисник
config.oauth_config=Подешавања OAuth
config.oauth_enabled=Укључено
config.cache_config=Подешавања кеша
config.cache_adapter=Кеш адаптер
config.cache_interval=Кеш интервал
config.cache_conn=Кеш на вези
config.session_config=Подешавања сесије
config.session_provider=Добављач сесија
config.provider_config=Конфигурација на добављачу
config.cookie_name=Име датотеке cookie
config.enable_set_cookie=Укључи поставку cookie
config.gc_interval_time=Интервал cакупљања смећа
config.session_life_time=Дужина живота сесјие
config.https_only=Само HTTPS
config.cookie_life_time=Дужина живота датотеке cookie
config.picture_service=Услуга за слике
config.disable_gravatar=Онемогући Gravatar
config.enable_federated_avatar=Омогући Federated Avatars
config.git_config=Git конфигурација
config.git_disable_diff_highlight=Онемогући бојење синтаксе када гледате разлике
config.git_max_diff_lines=Максималан број различитих редова (у датотеци)
config.git_max_diff_line_characters=Максималан број различитих карактера (у реду)
config.git_max_diff_files=Максималан број измењених датотека (приказаних)
config.git_gc_args=Аргументи на cакупљање смећа
config.git_migrate_timeout=Време до отказања миграције
config.git_mirror_timeout=Време до отазање синхронизацији огледала
config.git_clone_timeout=Време до отказивања клонирањем
config.git_pull_timeout=Време до отказивања pull операцији
config.git_gc_timeout=Време до отказивања cакупљање смећа
config.log_config=Kонфигурација журнала
config.log_mode=Режим журналовања
monitor.cron=Cron задаци
monitor.name=Име
monitor.schedule=Распоред
monitor.next=Следећи пут
monitor.previous=Претходни пут
monitor.process=Покренути процеси
monitor.desc=Опис
monitor.start=Почетно време
monitor.execute_time=Време извршивања
notices.system_notice_list=Системска обавештавања
notices.actions=Акције
notices.select_all=Изабери све
notices.deselect_all=Уклоните избор свих
notices.inverse_selection=Обрна селекција
notices.delete_selected=Избриши изабране
notices.delete_all=Уклони сва обавештења
notices.type=Тип
notices.type_1=Спремиште
notices.desc=Опис
notices.op=Oп.
[action]
create_repo=креира спремиште <a href="%s">%s</a>
rename_repo=преимензје спремиште од <code>%[1]s</code> на <a href="%[2]s">%[3]s</a>
create_issue=`отвара задатак <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`затвара задатак <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`поново отвара задатак <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`шаље захтев за спајање <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`затвара захтев за спајање <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`поново отвара захтев за спајање <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`коментарише на задатаку <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=`прихваћује захтев за спајање <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=преноси спремиште <code>%s</code> на <a href="%s">%s</a>
[tool]
ago=пре %s
from_now=од сада %s
now=сада
1s=1 секунд
1m=1 минут
1h=1 час
1d=1 дан
1w=1 недеља
1mon=1 месец
1y=1 година
seconds=%d секунди
minutes=%d минута
hours=%d часа
days=%d дана
weeks=%d недеља
months=%d месеци
years=%d година
raw_seconds=секунди
raw_minutes=минута
[dropzone]
remove_file=Уклони датотеку
[notification]
[gpg]
[units]

2113
conf/locale/locale_sv-SE.ini Normal file

File diff suppressed because it is too large Load Diff

2388
conf/locale/locale_tr-TR.ini Normal file

File diff suppressed because it is too large Load Diff

2262
conf/locale/locale_uk-UA.ini Normal file

File diff suppressed because it is too large Load Diff

2353
conf/locale/locale_zh-CN.ini Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,875 @@
home=首頁
dashboard=控制面版
explore=探索
help=說明
sign_in=登入
sign_out=登出
link_account=連結帳戶
register=註冊
website=網站
version=版本
page=頁面
template=樣板
language=語言
notifications=訊息
password=密碼
passcode=驗證碼
repository=儲存庫
organization=組織
mirror=鏡像
new_repo=新增儲存庫
new_migrate=遷移外部儲存庫
new_mirror=新鏡像
new_fork=Fork 新的儲存庫
new_org=新增組織
manage_org=管理組織
account_settings=帳號設定
settings=設定
all=所有
sources=來源
mirrors=鏡像
collaborative=協同者
forks=複製列表
activities=活動
pull_requests=合併請求
issues=問題
cancel=取消
[error]
[startpage]
[install]
install=安裝頁面
db_title=資料庫設定
db_type=資料庫類型
host=主機
password=密碼
db_name=資料庫名稱
path=資料庫文件路徑
repo_path=儲存庫的根目錄
log_root_path=日誌路徑
optional_title=可選設定
smtp_host=SMTP 主機
federated_avatar_lookup_popup=開啟聯合頭像查詢並使用基於開放源碼的 libravatar 服務
enable_captcha_popup=要求在用戶註冊時輸入驗證碼
admin_password=管理員密碼
confirm_password=確認密碼
install_btn_confirm=立即安裝
test_git_failed=無法識別 'git' 命令:%v
save_config_failed=儲存設定失敗:%v
[home]
password_holder=密碼
switch_dashboard_context=切換控制面版用戶
collaborative_repos=參與協作的儲存庫
my_orgs=我的組織
my_mirrors=我的鏡像
view_home=訪問 %s
issues.in_your_repos=屬於該用戶儲存庫的
[explore]
repos=儲存庫
users=使用者
organizations=組織
search=搜尋
[auth]
register_helper_msg=已經註冊?立即登錄!
remember_me=記住登錄
forgot_password_title=忘記密碼
forgot_password=忘記密碼?
confirmation_mail_sent_prompt=一封新的確認郵件已發送至 <b>%s</b>。請檢查您的收件箱並在 %s 小時內完成確認註冊操作。
active_your_account=啟用您的帳戶
has_unconfirmed_mail=%s 您好,您有一封發送至( <b>%s</b>) 但未被確認的郵件。如果您未收到啟用郵件,或需要重新發送,請單擊下方的按鈕。
resend_mail=單擊此處重新發送確認郵件
email_not_associate=此電子郵件地址未與任何帳戶連結
verify=驗證
scratch_code=備用碼
use_scratch_code=使用備用碼
twofa_scratch_used=你已經使用了你的備用碼。你將會被轉到兩步驟驗證設定頁面以便移除你已註冊設備或重新產生新的備用碼。
twofa_scratch_token_incorrect=您的備用碼不正確
openid_connect_submit=連接
openid_connect_title=連接到現有帳戶
openid_register_title=建立新帳戶
[mail]
activate_account=請啟用您的帳戶
activate_email=請驗證您的郵箱地址
register_success=註冊成功
register_notify=歡迎來到 Gitea
[modal]
yes=確認操作
no=取消操作
[form]
UserName=使用者名稱
RepoName=儲存庫名稱
Email=郵箱地址
Password=密碼
SSHTitle=SSH 金鑰名稱
HttpsUrl=HTTPS URL 地址
PayloadUrl=推送地址
TeamName=團隊名稱
AuthName=認證名稱
AdminEmail=管理員郵箱
NewBranchName=新的分支名稱
CommitSummary=提交摘要
CommitMessage=提交訊息
CommitChoice=提交選擇
TreeName=檔案路徑
Content=內容
require_error=不能為空。
size_error=長度必須為 %s。
min_size_error=長度最小為 %s 個字符。
max_size_error=長度最大為 %s 個字符。
email_error=不是一個有效的郵箱地址。
url_error=不是一個有效的 URL。
include_error=必須包含子字符串 '%s'。
unknown_error=未知錯誤:
user_not_exist=該使用者名稱並不存在
auth_failed=授權驗證失敗:%v
target_branch_not_exist=目標分支不存在
[user]
join_on=加入於
repositories=儲存庫列表
activity=公開活動
followers=關註者
following=關註中
follow=關注
unfollow=取消關注
form.name_reserved=這個使用者名稱已被系統保留,請改用其他名稱。
[settings]
profile=個人訊息
password=修改密碼
avatar=頭像
ssh_gpg_keys=SSH / GPG 金鑰
social=社交帳號綁定
delete=刪除帳戶
twofa=兩步驟驗證
uid=使用者 ID
public_profile=公開訊息
full_name=自定義名稱
website=個人網站
location=所在地區
update_profile=更新訊息
update_profile_success=您的個人資料已被更新
continue=繼續操作
cancel=取消操作
federated_avatar_lookup=Federated Avatar 查詢
enable_custom_avatar=啟動自定義頭像
choose_new_avatar=選擇新的頭像
delete_current_avatar=刪除當前頭像
old_password=當前密碼
new_password=新的密碼
emails=電子郵件地址
email_desc=您的主要邮箱地址将被用于通知提醒和其它操作。
primary=主要
add_openid=新增 OpenID URI
manage_ssh_keys=管理 SSH 金鑰
manage_gpg_keys=管理 GPG 金鑰
add_key=增加金鑰
ssh_helper=<strong>需要協助?</strong> 查詢GitHub的文件以 <a href="%s">您自有SSH金鑰</a> or solve <a href="%s">common problems</a> you may encounter using SSH.
gpg_helper=<strong>需要協助嗎?</strong>建議可看看 GitHub 的 <a href="%s">about GPG</a> 文件。
add_new_key=增加 SSH 金鑰
add_new_gpg_key=新增 GPG 金鑰
subkeys=次金鑰
key_id=金鑰 ID
key_name=金鑰名稱
key_content=金鑰內容
add_on=增加於
valid_until=有效期至
valid_forever=永遠有效
last_used=上次使用在
no_activity=沒有最近活動
key_state_desc=該金鑰在 7 天內被使用過
token_state_desc=此 token 在過去七天內曾經被使用過
show_openid=在設定檔顯示
hide_openid=從設定檔隱藏
manage_social=管理關聯社交帳戶
generate_new_token=生成新的令牌
token_name=令牌名稱
generate_token=生成令牌
delete_token=删除令牌
twofa_is_enrolled=您的帳號已經<strong>啟用</strong>兩步驟驗證。
twofa_not_enrolled=您的帳號目前尚未啟用兩步驟驗證。
twofa_disabled=兩步驟驗證已經被關閉。
scan_this_image=使用您的授權應用程式來掃瞄圖片:
or_enter_secret=或者輸入密碼: %s
orgs_none=您尚未成為任一組織的成員。
repos_none=您不擁有任何存儲庫
delete_account=刪除當前帳戶
confirm_delete_account=確認刪除帳戶
[repo]
owner=擁有者
repo_name=儲存庫名稱
visibility=可見度
fork_repo=複製儲存庫
fork_from=複製自
repo_desc=儲存庫描述
repo_lang=儲存庫語言
license=授權許可
create_repo=建立儲存庫
default_branch=默認分支
mirror_prune=裁減
watchers=關注者
stargazers=稱讚者
forks=複製儲存庫
form.reach_limit_of_creation=您已經達到了儲存庫 %d 的上限。
form.name_reserved=儲存庫名稱 '%s' 是預留的。
migrate_type=遷移類型
migrate_type_helper=該儲存庫將是一個 <span class="text blue">鏡像</span>
migrate_repo=遷移儲存庫
migrate.permission_denied=您並沒有導入本地儲存庫的權限。
migrate.failed=遷移失敗:%v
mirror_from=镜像来自
forked_from=複製自
copy_link=複製連結
copied=複製成功
unwatch=取消關注
watch=關註
unstar=取消收藏
star=收藏
fork=複製
no_desc=暫無描述
quick_guide=快速幫助
clone_this_repo=複製當前儲存庫
create_new_repo_command=從命令列建立新儲存庫。
push_exist_repo=從命令列推送已存在的儲存庫
code=程式碼
branch=分支
tree=目錄樹
filter_branch_and_tag=過濾分支或標籤
branches=分支列表
tags=標籤列表
issues=問題管理
pulls=合併請求
labels=標籤
milestones=里程碑
commits=提交歷史
releases=版本發佈
file_raw=原始文件
file_history=文件歷史
file_view_raw=查看原始文件
file_permalink=永久連結
stored_lfs=儲存到到 Git LFS
editor.preview_changes=預覽更改
editor.or=
editor.commit_changes=提交更改嗎?
editor.add=新增 '%s'
editor.update=更新 '%s'
editor.delete=刪除 '%s'
editor.commit_directly_to_this_branch=直接提交到 <strong class="branch-name">%s</strong> 分支。
editor.create_new_branch=建立 <strong>新的分支</strong> 為此提交和開始合併請求。
editor.cancel=取消
editor.branch_already_exists='%s' 已存在於此存儲庫。
editor.no_changes_to_show=沒有可以顯示的變更。
editor.fail_to_update_file=上傳/建立檔案 '%s' 失敗, 錯誤訊息: %v
editor.unable_to_upload_files=上傳檔案失敗到 '%s', 錯誤訊息: %v
editor.upload_files_to_dir=上傳檔案到 '%s'
commits.commits=次程式碼提交
commits.find=搜尋
commits.author=作者
commits.message=備註
commits.date=提交日期
commits.older=更舊的提交
commits.newer=更新的提交
commits.signed_by=簽署人
issues.new=建立問題
issues.new.labels=標籤
issues.new.no_label=未選擇標籤
issues.new.clear_labels=清除已選取標籤
issues.new.milestone=里程碑
issues.new.no_milestone=未選擇里程碑
issues.new.clear_milestone=清除已選取里程碑
issues.new.open_milestone=開啟中的里程碑
issues.new.closed_milestone=已關閉的里程碑
issues.create=建立問題
issues.new_label=建立標籤
issues.create_label=建立標籤
issues.label_templates.title=載入一組預定義的標籤
issues.label_templates.helper=選擇一個標籤集
issues.label_templates.fail_to_load_file=載入標籤範本檔案 '%s' 失敗: %v
issues.add_milestone_at=`新增至<b>%s</b> 里程碑 %s`
issues.change_milestone_at=`%[3]s 修改了里程碑 <b>%[1]s</b> 到 <b>%[2]s</b>`
issues.remove_milestone_at=`從里程碑 %[2]s 刪除 <b>%[1]s</b>`
issues.deleted_milestone=`(已刪除)`
issues.self_assign_at=將 %s 指派給自己
issues.add_assignee_at=`被<b>%s</b> %s指派`
issues.delete_branch_at=`刪除分支 <b>%s</b> %s`
issues.open_tab=%d 個開啓中
issues.close_tab=%d 個已關閉
issues.filter_label=標籤篩選
issues.filter_milestone=里程碑篩選
issues.filter_assignee=指派人篩選
issues.filter_type=類型篩選
issues.filter_type.all_issues=所有問題
issues.filter_type.assigned_to_you=指派給您的
issues.filter_type.created_by_you=由您建立的
issues.filter_type.mentioning_you=提及您的
issues.filter_sort=排序
issues.filter_sort.latest=最新建立
issues.filter_sort.oldest=最早建立
issues.filter_sort.recentupdate=最近更新
issues.filter_sort.leastupdate=最少更新
issues.filter_sort.mostcomment=最多評論
issues.filter_sort.leastcomment=最少評論
issues.action_open=開啟
issues.action_close=關閉
issues.action_label=標籤
issues.action_milestone=里程碑
issues.action_milestone_no_select=無里程碑
issues.action_assignee=負責人
issues.action_assignee_no_select=無負責人
issues.opened_by=由 <a href="%[2]s">%[3]s</a> 於 %[1]s建立
issues.opened_by_fake=由 %[2]s 於 %[1]s建立
issues.previous=上一頁
issues.next=下一頁
issues.open_title=開啟中
issues.closed_title=已關閉
issues.num_comments=%d 條評論
issues.commented_at=` 評論 <a href="#%s"> %s</a>`
issues.delete_comment_confirm=您確定要刪除該條評論嗎?
issues.no_content=尚未有任何內容
issues.close_issue=關閉
issues.reopen_issue=重新開啟
issues.create_comment=評論
issues.commit_ref_at=`在代碼提交 <a id="%[1]s" href="#%[1]s">%[2]s</a> 中引用了該問題`
issues.poster=發佈者
issues.collaborator=協同者
issues.owner=所有者
issues.sign_in_require_desc=<a href="%s"> 登入</a> 才能加入這對話。
issues.edit=編輯
issues.cancel=取消
issues.save=儲存
issues.label_title=標籤名稱
issues.label_color=標籤顏色
issues.label_count=%d 個標籤
issues.label_open_issues=%d 個開啓的問題
issues.label_edit=編輯
issues.label_delete=刪除
issues.label.filter_sort.alphabetically=按字母顺序排序
issues.label.filter_sort.reverse_alphabetically=按字母反向排序
issues.num_participants=%d 參與者
issues.attachment.open_tab=`在新的標籤頁中查看 '%s'`
issues.attachment.download=`點擊下載 '%s'`
issues.subscribe=訂閱
issues.unsubscribe=取消訂閱
pulls.new=建立合併請求
pulls.filter_branch=過濾分支
pulls.no_results=未找到結果
pulls.create=建立合併請求
pulls.merged_title_desc=於 %[4]s 將 %[1]d 次代碼提交從 <code>%[2]s</code>合併至 <code>%[3]s</code>
pulls.tab_conversation=對話內容
pulls.tab_commits=程式碼提交
pulls.reopen_to_merge=請重新開啟合併請求來完成合併操作。
pulls.merged=已合併
pulls.can_auto_merge_desc=這個拉請求可以自動合併。
pulls.merge_pull_request=合併請求
milestones.new=新的里程碑
milestones.open_tab=%d 開啟中
milestones.close_tab=%d 已關閉
milestones.closed=於 %s關閉
milestones.no_due_date=暫無截止日期
milestones.open=開啟
milestones.close=關閉
milestones.create=建立里程碑
milestones.title=標題
milestones.desc=描述
milestones.due_date=截止日期(可選)
milestones.clear=清除
milestones.edit=編輯里程碑
milestones.cancel=取消
milestones.filter_sort.closest_due_date=到期日由近到遠
milestones.filter_sort.furthest_due_date=到期日由遠到近
milestones.filter_sort.least_complete=完成度由低到高
milestones.filter_sort.most_complete=完成度由高到低
milestones.filter_sort.most_issues=問題由多到少
milestones.filter_sort.least_issues=問題由少到多
wiki.page=頁面
wiki.filter_page=過濾頁面
wiki.default_commit_message=關於此次頁面修改的說明(非必要)。
wiki.save_page=儲存頁面
wiki.last_commit_info=%s 於 %s 修改了此頁面
wiki.edit_page_button=修改
wiki.new_page_button=新的頁面
wiki.delete_page_button=刪除頁面
wiki.page_already_exists=相同名稱的 Wiki 頁面已經存在。
wiki.pages=所有頁面
wiki.last_updated=最後更新於 %s
settings=儲存庫設定
settings.desc=設定是您可以管理儲存庫設定的地方
settings.collaboration.write=可寫權限
settings.collaboration.read=可讀權限
settings.collaboration.undefined=未定義
settings.hooks=管理 Webhooks
settings.githooks=管理 Git Hooks
settings.basic_settings=基本設定
settings.mirror_settings=鏡像設定
settings.update_settings=更新儲存庫設定
settings.advanced_settings=高級設定
settings.external_wiki_url=外部 Wiki 連結
settings.external_tracker_url=外部 Issue 追蹤網址
settings.tracker_url_format=外部問題管理系統的 URL 格式
settings.tracker_issue_style.numeric=數字
settings.tracker_issue_style.alphanumeric=字母及數字
settings.danger_zone=危險操作區
settings.new_owner_has_same_repo=新的儲存庫擁有者已經存在同名儲存庫!
settings.transfer=轉移儲存庫所有權
settings.delete=刪除本儲存庫
settings.delete_notices_1=- 此操作 <strong>不可以</strong> 被回滾。
settings.transfer_owner=新擁有者
settings.add_webhook=建立 Webhook
settings.webhook.test_delivery=測試推送
settings.webhook.request=請求內容
settings.webhook.response=響應內容
settings.webhook.headers=標題
settings.webhook.body=響應內容
settings.githook_edit_desc=如果 Hook 未啟動,則會顯示樣例文件中的內容。如果想要刪除某個 Hook則提交空白文本即可。
settings.githook_name=Hook 名稱
settings.githook_content=Hook 內容
settings.update_githook=更新 Hook 設定
settings.secret=金鑰文本
settings.slack_username=服務名稱
settings.slack_icon_url=圖標 URL
settings.slack_color=顏色代碼
settings.event_create=建立
settings.event_push=推送
settings.event_pull_request=合併請求
settings.update_webhook=更新 Webhook
settings.recent_deliveries=最近推送記錄
settings.hook_type=Hook 類型
settings.slack_token=令牌
settings.slack_domain=域名
settings.slack_channel=頻道
settings.deploy_keys=管理部署金鑰
settings.add_deploy_key=新增部署金鑰
settings.title=標題
settings.deploy_key_content=金鑰文本
settings.branches=分支列表
settings.protected_branch=分支保護
settings.protected_branch_can_push=允許推送?
settings.protected_branch_can_push_yes=你可以推送
settings.protected_branch_can_push_no=你不能推送
settings.add_protected_branch=啟用保護
settings.delete_protected_branch=停用保護
diff.browse_source=瀏覽代碼
diff.parent=父節點
diff.commit=當前提交
diff.data_not_available=沒有內容比較可以使用
diff.show_split_view=分割檢視
diff.show_unified_view=統一視圖
diff.stats_desc=共有 <strong> %d 個文件被更改</strong>,包括 <strong>%d 次插入</strong> 和 <strong>%d 次删除</strong>
diff.bin=二進制
diff.view_file=查看文件
diff.file_suppressed=文件差異過大導致無法顯示
diff.too_many_files=部分文件因文件數量過多而無法顯示
release.releases=版本發佈
release.new_release=發佈新版本
release.draft=草稿
release.prerelease=預發佈版本
release.stable=穩定
release.edit=編輯
release.source_code=程式碼
release.tag_name=標籤名稱
release.target=目標分支
release.title=標題
release.content=內容
release.cancel=取消
release.publish=發佈版本
release.save_draft=儲存草稿
release.deletion_success=已刪除此版本發佈。
release.downloads=下載附件
[org]
org_name_holder=組織名稱
org_full_name_holder=組織全名
create_org=建立組織
repo_updated=最後更新於
people=組織成員
teams=組織團隊
lower_members=名成員
lower_repositories=個儲存庫
org_desc=組織描述
team_name=團隊名稱
team_desc=團隊描述
settings=組織設定
settings.full_name=組織全名
settings.website=官方網站
settings.location=所在地區
settings.update_settings=更新組織設定
settings.update_setting_success=組織設定已更新。
settings.delete=刪除組織
settings.delete_account=刪除當前組織
settings.confirm_delete_account=確認刪除組織
settings.hooks_desc=新增 webhooks 將觸發在這個組織下 <strong>全部的儲存庫</strong> 。
members.membership_visibility=成員可見性:
members.member_role=成員角色:
members.owner=管理員
members.member=普通成員
members.remove=移除成員
members.leave=離開組織
members.invite_desc=邀請新的用戶加入 %s
members.invite_now=立即邀請
teams.join=加入團隊
teams.leave=離開團隊
teams.read_access=讀取權限
teams.write_access=寫入權限
teams.no_desc=該團隊暫無描述
teams.settings=團隊設定
teams.members=團隊成員
teams.update_settings=更新團隊設定
teams.add_team_member=新增團隊成員
teams.delete_team_success=該團隊已被刪除。
teams.repositories=團隊儲存庫
teams.add_nonexistent_repo=您嘗試新增到團隊的儲存庫不存在,請先建立儲存庫!
[admin]
dashboard=控制面版
organizations=組織管理
repositories=儲存庫管理
config=應用設定管理
notices=系統提示管理
monitor=應用監控面版
first_page=首頁
last_page=末頁
total=總計:%d
dashboard.operation_name=操作名稱
dashboard.operation_switch=開關
dashboard.operation_run=執行
dashboard.clean_unbind_oauth=清理未綁定OAuth的連結
dashboard.clean_unbind_oauth_success=所有未綁定 OAuth 的連結已刪除。
dashboard.reinit_missing_repos=重新初始化所有遺失具已存在記錄的Git 儲存庫
dashboard.sync_external_users=同步外部使用者資料
dashboard.server_uptime=服務執行時間
dashboard.current_goroutine=當前 Goroutines 數量
dashboard.current_memory_usage=當前內存使用量
dashboard.total_memory_allocated=所有被分配的內存
dashboard.memory_obtained=內存佔用量
dashboard.pointer_lookup_times=指針查找次數
dashboard.current_heap_usage=當前 Heap 內存使用量
dashboard.heap_memory_obtained=Heap 內存佔用量
dashboard.heap_memory_idle=Heap 內存空閒量
dashboard.heap_memory_in_use=正在使用的 Heap 內存
dashboard.heap_memory_released=被釋放的 Heap 內存
dashboard.heap_objects=Heap 對象數量
dashboard.bootstrap_stack_usage=啟動 Stack 使用量
dashboard.stack_memory_obtained=被分配的 Stack 內存
dashboard.mspan_structures_usage=MSpan 結構內存使用量
dashboard.mspan_structures_obtained=被分配的 MSpan 結構內存
dashboard.mcache_structures_usage=MCache 結構內存使用量
dashboard.mcache_structures_obtained=被分配的 MCache 結構內存
dashboard.profiling_bucket_hash_table_obtained=被分配的剖析哈希表內存
dashboard.gc_metadata_obtained=被分配的垃圾收集元資料內存
dashboard.other_system_allocation_obtained=其它被分配的系統內存
dashboard.next_gc_recycle=下次垃圾收集內存回收量
dashboard.last_gc_time=距離上次垃圾收集時間
dashboard.total_gc_time=垃圾收集執行時間總量
dashboard.total_gc_pause=垃圾收集暫停時間總量
dashboard.last_gc_pause=上次垃圾收集暫停時間
dashboard.gc_times=垃圾收集執行次數
users.activated=已啟用
users.admin=管理員
users.repos=儲存庫數
users.created=建立時間
users.edit=編輯
users.auth_source=認證源
users.local=本地
orgs.org_manage_panel=組織管理
orgs.name=組織名稱
orgs.teams=團隊數
orgs.members=成員數
repos.repo_manage_panel=儲存庫管理
repos.owner=所有者
repos.name=儲存庫名稱
repos.private=私有庫
repos.watches=關註數
repos.stars=讚好數
repos.issues=問題數
repos.size=大小
auths.name=認證名稱
auths.type=認證類型
auths.enabled=已啟用
auths.updated=最後更新時間
auths.auth_type=認證類型
auths.auth_name=認證名稱
auths.security_protocol=安全協定
auths.domain=域名
auths.host=主機地址
auths.port=主機端口
auths.bind_dn=綁定DN
auths.bind_password=綁定密碼
auths.user_base=用戶搜尋基準
auths.user_dn=用戶 DN
auths.filter=使用者篩選器
auths.admin_filter=管理者篩選器
auths.smtp_auth=SMTP 驗證類型
auths.smtphost=SMTP 主機地址
auths.smtpport=SMTP 主機端口
auths.allowed_domains=域名白名單
auths.enable_tls=啟用 TLS 加密
auths.skip_tls_verify=忽略 TLS 驗證
auths.pam_service_name=PAM 服務名稱
auths.oauth2_provider=OAuth2 提供者
auths.oauth2_clientID=用戶端 ID (金鑰)
auths.oauth2_clientSecret=用戶端金鑰
auths.openIdConnectAutoDiscoveryURL=OpenID 連接自動探索 URL
auths.oauth2_authURL=授權 URL
auths.oauth2_profileURL=個人訊息 URL
auths.oauth2_emailURL=電子郵件 URL
auths.enable_auto_register=允許授權用戶自動註冊
auths.tips=幫助提示
auths.tips.oauth2.general=OAuth2 認證
auths.tips.oauth2.general.tip=當註冊一個新的 OAuth2 認證callback/redirect 網址應該是:<host>/user/oauth2/<Authentication Name>/callback
auths.tip.oauth2_provider=OAuth2 提供者
auths.tip.dropbox=建立新 App 在 https://www.dropbox.com/developers/apps
auths.tip.facebook=在 https://developers.facebook.com/apps 註冊一個新的應用,並且新增一個產品 "Facebook Login
auths.tip.github=在 https://github.com/settings/applications/new 註冊一個新的 OAuth 應用程式
auths.tip.gitlab=在 https://gitlab.com/profile/applications 註冊一個新的應用程式
auths.tip.openid_connect=使用 OpenID 連接探索 URL (<server>/.well-known/openid-configuration) 來指定節點
auths.new_success=已增加認證'%s'。
auths.delete_auth_title=刪除認證來源
config.server_config=伺服器設定
config.custom_conf=設定檔案路徑
config.disable_router_log=關閉路由日誌
config.run_mode=執行模式
config.git_version=Git 版本
config.repo_root_path=儲存庫目錄
config.lfs_root_path=LFS 根目錄
config.static_file_root_path=靜態檔案目錄
config.script_type=腳本類型
config.reverse_auth_user=反向代理認證
config.ssh_config=SSH 設定
config.ssh_enabled=已啟用
config.ssh_port=
config.ssh_listen_port=監聽埠
config.ssh_root_path=根路徑
config.ssh_key_test_path=金鑰測試路徑
config.ssh_keygen_path=金鑰產生 (' ssh-keygen ') 路徑
config.ssh_minimum_key_size_check=金鑰最小大小檢查
config.ssh_minimum_key_sizes=金鑰最小大小
config.db_config=資料庫設定
config.db_type=資料庫類型
config.db_host=主機地址
config.db_name=資料庫名稱
config.db_path=資料庫路徑
config.service_config=服務設定
config.show_registration_button=顯示註冊按鈕
config.disable_key_size_check=禁用金鑰最小長度檢查
config.active_code_lives=啟用用戶連結有效期
config.webhook_config=Webhook 設定
config.queue_length=隊列長度
config.deliver_timeout=推送超時
config.skip_tls_verify=略過 TLS 驗證
config.mailer_enabled=啟用服務
config.mailer_disable_helo=禁用 HELO 操作
config.mailer_name=發送者名稱
config.mailer_host=郵件主機地址
config.mailer_user=發送者帳號
config.oauth_config=社交帳號設定
config.oauth_enabled=啟用服務
config.cache_config=Cache 設定
config.cache_adapter=Cache 適配器
config.cache_interval=Cache 周期
config.cache_conn=Cache 連接字符串
config.session_config=Session 設定
config.session_provider=Session 提供者
config.provider_config=提供者設定
config.cookie_name=Cookie 名稱
config.enable_set_cookie=啟用設定 Cookie
config.gc_interval_time=垃圾收集周期
config.session_life_time=Session 生命周期
config.https_only=僅限 HTTPS
config.cookie_life_time=Cookie 生命周期
config.picture_service=圖片服務
config.disable_gravatar=禁用 Gravatar 頭像
config.enable_federated_avatar=開啟聯合頭像
config.git_config=Git 設定
config.git_disable_diff_highlight=禁用比較語法高亮
config.git_max_diff_lines=Max Diff 線 (對於單個檔)
config.git_max_diff_line_characters=最大比較的字元 (單行)
config.git_max_diff_files=Max Diff 檔 (顯示)
config.git_gc_args=GC 參數
config.git_migrate_timeout=移動超時
config.git_mirror_timeout=鏡像更新超時
config.git_clone_timeout=複製操作超時
config.git_pull_timeout=操作超時
config.git_gc_timeout=GC 操作超時
config.log_config=日誌設定
config.log_mode=日誌模式
monitor.cron=Cron 任務
monitor.name=任務名稱
monitor.schedule=任務安排
monitor.next=下次執行時間
monitor.previous=上次執行時間
monitor.process=執行中進程
monitor.desc=進程描述
monitor.start=開始時間
monitor.execute_time=已執行時間
notices.system_notice_list=系統提示管理
notices.view_detail_header=查看提示細節
notices.actions=操作
notices.select_all=選取全部
notices.deselect_all=取消所有選取
notices.inverse_selection=反向選取
notices.delete_selected=刪除選取項
notices.delete_all=刪除所有提示
notices.type=提示類型
notices.type_1=儲存庫
notices.desc=描述
notices.op=操作
notices.delete_success=已刪除系統提示。
[action]
create_repo=建立了儲存庫 <a href="%s">%s</a>
rename_repo=重新命名儲存庫 <code>%[1]s</code> 為 <a href="%[2]s">%[3]s</a>
create_issue=`建立了問題 <a href="%s/issues/%s">%s#%[2]s</a>`
close_issue=`已關閉問題 <a href="%s/issues/%s">%s#%[2]s</a>`
reopen_issue=`已重新開啟問題 <a href="%s/issues/%s">%s#%[2]s</a>`
create_pull_request=`建立了合併請求 <a href="%s/pulls/%s">%s#%[2]s</a>`
close_pull_request=`已關閉合併請求 <a href="%s/pulls/%s">%s#%[2]s</a>`
reopen_pull_request=`已重新開啟合併請求 <a href="%s/pulls/%s">%s#%[2]s</a>`
comment_issue=`評論了問題 <a href="%s/issues/%s">%s#%[2]s</a>`
merge_pull_request=`合併了合併請求 <a href="%s/pulls/%s">%s#%[2]s</a>`
transfer_repo=將儲存庫 <code>%s</code> 轉移至 <a href="%s">%s</a>
compare_commits=比較 %d 提交
[tool]
ago=%s之前
from_now=%s之後
now=現在
future=未來
1s=1 秒
1m=1 分鐘
1h=1 小時
1d=1 天
1w=1 周
1mon=1 月
1y=1 年
seconds=%d 秒
minutes=%d 分
hours=%d 小時
days=%d 天
weeks=%d 週
months=%d 月
years=%d 年
raw_seconds=
raw_minutes=分鐘
[dropzone]
file_too_big=檔案大小({{filesize}} MB) 超過了最大允許大小({{maxFilesize}} MB)
remove_file=移除文件
[notification]
notifications=訊息
unread=未讀
read=已讀
pin=固定通知
mark_as_read=標記為已讀
mark_as_unread=標記為未讀
[gpg]
error.extract_sign=無法提取簽署
error.generate_hash=無法產生提交的雜湊值
error.no_gpg_keys_found=沒有發現已知的金鑰在資料庫的簽署中
error.not_signed_commit=未簽名的提交
[units]

1410
conf/locale/locale_zh-TW.ini Normal file

File diff suppressed because it is too large Load Diff

4
linux.bat Normal file
View File

@ -0,0 +1,4 @@
set go111module=on
set GOOS=linux
set GOARCH=amd64
go build -tags='bindata' -o release\linux\gitea

5
mac.bat Normal file
View File

@ -0,0 +1,5 @@
set go111module=on
SET GOOS=darwin
SET GOARCH=amd64
go build -tags='bindata' -o release\mac\gitea

130
models/action_ext.go Normal file
View File

@ -0,0 +1,130 @@
package models
import "strings"
// GetFeedsOptions options for retrieving feeds
type GetContributorsOptionsExt struct {
RepoId int64
UserId int64
}
type ContributorsDto struct {
Contributions int64 `json:"contributions"`
ID int64 `json:"id"`
Login string `json:"login"`
Email string `json:"email"`
//Type string `json:"type"`
}
func GetContributors(opt GetContributorsOptionsExt) (interface{}, error) {
sql :=
`select a.act_user_id as id ,
u.name as login,
u.email as email,
count(act_user_id) as contributions
from action a
left join user u on a.act_user_id=u.id
where repo_id=? and user_id=?
group by repo_id,act_user_id `
result := make([]ContributorsDto, 0, 0)
err := x.SQL(sql, opt.RepoId, opt.UserId).Find(&result)
return result, err
}
type GetGetActivityOptions struct {
FromDateUnix int64 `json:"-"`
ToDateUnix int64 `json:"-"`
FromDate string `json:"from_date"`
ToDate string `json:"to_date"`
Top int64 `json:"-"`
}
type PlatformDTO struct {
Id int64 `json:"-"`
Name string `json:"-"`
TotalCount int64 `json:"total_count"`
ActiveCount int64 `json:"active_count"`
}
//平台所需数据;
func GetActivity(opt *GetGetActivityOptions) (interface{}, error) {
sql := `select a.id,a.name,ifNull(b.active_count,0) as active_count,b.total_count
from ( select 11 as id ,'PullRequest' name
union
select 5 as id, 'Commit' name
) a
left join (
select op_type,count(op_type) as total_count,
sum(case when a.created_unix>=? and a.created_unix<=?
then 1 else 0 end
) as active_count
from action a
where (a.op_type=11 or a.op_type=5)
group by a.op_type
) b on a.id=b.op_type`
datalist := make([]PlatformDTO, 0, 0)
err := x.SQL(sql, opt.FromDateUnix, opt.ToDateUnix).Find(&datalist)
if err != nil {
return nil, err
}
convertMap := make(map[string]interface{})
for i := 0; i <= len(datalist)-1; i++ {
convertMap[strings.ToLower(datalist[i].Name)] = datalist[i]
}
return convertMap, err
}
type ProjectDTO struct {
Id int64 `json:"-"`
Name string `json:"name"`
TotalCount int64 `json:"total_count"`
ActiveCount int64 `json:"active_count"`
}
//项目所需数据-按项目统计 top 5
func GetActivityProject(opt *GetGetActivityOptions) (interface{}, error) {
sql :=
`select repo_id as id,r.name,
count(op_type) as total_count,
sum(case when a.created_unix>=? and a.created_unix<=?
then 1 else 0 end
) as active_count
from action a
left join repository r on a.repo_id=r.id
where (a.op_type=5)
group by a.repo_id
order by total_count desc
limit ?
`
datalist := make([]ProjectDTO, 0, 0)
err := x.SQL(sql, opt.FromDateUnix, opt.ToDateUnix, opt.Top).Find(&datalist)
return datalist, err
}
//项目所需数据-按开发者统计 top 5
func GetActivityDevelop(opt *GetGetActivityOptions) (interface{}, error) {
sql :=
`select u.name as develop_name,
count(op_type) as total_count,
sum(case when (a.created_unix>=? and a.created_unix<=?) then 1 else 0 end ) as active_count
from action a
left join user u on a.act_user_id=u.id
where (a.op_type=5)
group by a.act_user_id
order by total_count desc
limit ? `
datalist := make([]DevelopDTO, 0, 0)
err := x.SQL(sql, opt.FromDateUnix, opt.ToDateUnix, opt.Top).Find(&datalist)
return datalist, err
}
type DevelopDTO struct {
DevelopName string `json:"develop_name"`
TotalCount int64 `json:"total_count"`
ActiveCount int64 `json:"active_count"`
}

View File

@ -192,6 +192,22 @@ func (err ErrUserInactive) Error() string {
return fmt.Sprintf("user is inactive [uid: %d, name: %s]", err.UID, err.Name)
}
type ErrUserNodAdmin struct {
UID int64
Name string
}
// IsErrUserNotAdmin checks if an error is a ErrUserNotAdmin
func IsErrUserNotAdmin(err error) bool {
_, ok := err.(ErrUserNodAdmin)
return ok
}
func (err ErrUserNodAdmin) Error() string {
return fmt.Sprintf("user does not admin [uid:%d, name:%s]", err.UID, err.Name)
}
// ErrEmailAlreadyUsed represents a "EmailAlreadyUsed" kind of error.
type ErrEmailAlreadyUsed struct {
Email string

View File

@ -7,8 +7,6 @@ package migrations
import (
"fmt"
"code.gitea.io/gitea/modules/setting"
"xorm.io/xorm"
)
@ -29,19 +27,19 @@ func renameTaskErrorsToMessage(x *xorm.Engine) error {
return fmt.Errorf("error on Sync2: %v", err)
}
switch {
case setting.Database.UseMySQL:
if _, err := sess.Exec("ALTER TABLE `task` CHANGE errors message text"); err != nil {
return err
}
case setting.Database.UseMSSQL:
if _, err := sess.Exec("sp_rename 'task.errors', 'message', 'COLUMN'"); err != nil {
return err
}
default:
if _, err := sess.Exec("ALTER TABLE `task` RENAME COLUMN errors TO message"); err != nil {
return err
}
}
// switch {
// case setting.Database.UseMySQL:
// if _, err := sess.Exec("ALTER TABLE `task` CHANGE errors message text"); err != nil {
// return err
// }
// case setting.Database.UseMSSQL:
// if _, err := sess.Exec("sp_rename 'task.errors', 'message', 'COLUMN'"); err != nil {
// return err
// }
// default:
// if _, err := sess.Exec("ALTER TABLE `task` RENAME COLUMN errors TO message"); err != nil {
// return err
// }
// }
return sess.Commit()
}

View File

@ -69,6 +69,10 @@ type PullRequest struct {
MergedUnix timeutil.TimeStamp `xorm:"updated INDEX"`
isHeadRepoLoaded bool `xorm:"-"`
// add configure
CommitNum int
ChangedFiles int
}
// MustHeadUserName returns the HeadRepo's username if failed return blank

View File

@ -242,6 +242,27 @@ func GetLatestReleaseByRepoID(repoID int64) (*Release, error) {
return rel, nil
}
// GetLatestReleaseByRepoID returns the latest release for a repository
func GetLatestReleaseByRepoIDExt(repoID int64) (*Release, error) {
cond := builder.NewCond().
And(builder.Eq{"repo_id": repoID}).
And(builder.Eq{"is_draft": false}).
And(builder.Eq{"is_prerelease": false})
rel := new(Release)
has, err := x.
Desc("created_unix", "id").
Where(cond).
Get(rel)
if err != nil {
return nil, err
} else if !has {
return nil, ErrReleaseNotExist{0, "latest"}
}
return rel, nil
}
// GetReleasesByRepoIDAndNames returns a list of releases of repository according repoID and tagNames.
func GetReleasesByRepoIDAndNames(ctx DBContext, repoID int64, tagNames []string) (rels []*Release, err error) {
err = ctx.e.

View File

@ -0,0 +1,17 @@
package models
import "code.gitea.io/gitea/modules/timeutil"
type TimestampOptions struct {
Start timeutil.TimeStamp
End timeutil.TimeStamp
}
func (opts *TimestampOptions) setDefaultValues() {
if opts.Start <= 0 {
opts.Start = timeutil.TimeStampNow() - 365*24*60*60
}
if opts.End <= 0 {
opts.End = timeutil.TimeStampNow()
}
}

View File

@ -67,3 +67,43 @@ func getUserHeatmapData(user *User, team *Team, doer *User) ([]*UserHeatmapData,
OrderBy("timestamp").
Find(&hdata)
}
func GetUserHeatMapDataByUserWithTimeStamp(user *User, opts TimestampOptions) ([]*UserHeatmapData, error) {
opts.setDefaultValues() // Setting the defaule value.
hdata := make([]*UserHeatmapData, 0) // initial value
if user.KeepActivityPrivate {
return hdata, nil
}
var groupBy string
var groupByName = "timestamp"
switch {
case setting.Database.UseSQLite3:
groupBy = "strftime('%s', strftime('%Y-%m-%d', created_unix, 'unixepoch'))"
case setting.Database.UseMySQL:
groupBy = "UNIX_TIMESTAMP(DATE(FROM_UNIXTIME(created_unix)))"
case setting.Database.UsePostgreSQL:
groupBy = "extract(epoch from data_trunc('day', to_timestamp(created_unix)))"
case setting.Database.UseMSSQL:
// groupBy = "datediff(SECOND, '19700101', dateadd(DAY, 0, datediff(day, 0, dateadd(s, created_unix, '19700101'))))"
groupBy = "datediff(SECOND, '19700101', dateadd(DAY, 0, datediff(day, 0, dateadd(s, created_unix, '19700101'))))"
groupByName = groupBy
}
sess := x.Select(groupBy+"AS timestamp, count(user_id) as contributions").
Table("action").
Where("user_id = ?", user.ID).
And(groupBy+">= ? ", opts.Start).
And(groupBy+"<= ?", opts.End)
if user.Type == UserTypeIndividual {
sess = sess.And("act_user_id = ?", user.ID)
}
err := sess.GroupBy(groupByName).
OrderBy("timestamp").
Find(&hdata)
return hdata, err
}

View File

@ -77,6 +77,13 @@ func IsValidHookContentType(name string) bool {
return ok
}
func IsValidHookHttpMethod(name string) bool {
if name == "POST" || name == "GET" {
return true
}
return false
}
// HookEvents is a set of web hook events
type HookEvents struct {
Create bool `json:"create"`
@ -151,6 +158,7 @@ type Webhook struct {
Type HookType `xorm:"VARCHAR(16) 'type'"`
Meta string `xorm:"TEXT"` // store hook-specific attributes
LastStatus HookStatus // Last delivery status
BranchFilter string `xorm:"TEXT"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
@ -647,16 +655,23 @@ type HookResponse struct {
// HookTask represents a hook task.
type HookTask struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX"`
HookID int64
UUID string
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX"`
HookID int64
UUID string
Type HookType
URL string `xorm:"TEXT"`
Signature string `xorm:"TEXT"`
HTTPMethod string `xorm:"http_method"`
ContentType HookContentType
api.Payloader `xorm:"-"`
PayloadContent string `xorm:"TEXT"`
EventType HookEventType
IsDelivered bool
Delivered int64
DeliveredString string `xorm:"-"`
IsSSL bool
// History info.
IsSucceed bool
@ -708,6 +723,18 @@ func (t *HookTask) simpleMarshalJSON(v interface{}) string {
return string(p)
}
func GetHookTasksByRepoIDAndHookID(repoID int64, hookID int64, listOptions ListOptions) ([]*HookTask, error) {
if listOptions.Page == 0 {
hookTasks := make([]*HookTask, 0, 5)
return hookTasks, x.Find(&hookTasks, &HookTask{RepoID: repoID, HookID: hookID})
}
sess := listOptions.getPaginatedSession()
hookTasks := make([]*HookTask, 0, listOptions.PageSize)
return hookTasks, sess.Find(&hookTasks, &HookTask{RepoID: repoID, HookID: hookID})
}
// HookTasks returns a list of hook tasks by given conditions.
func HookTasks(hookID int64, page int) ([]*HookTask, error) {
tasks := make([]*HookTask, 0, setting.Webhook.PagingNum)

View File

@ -105,6 +105,51 @@ func (ctx *APIContext) Error(status int, title string, obj interface{}) {
})
}
func (ctx *APIContext) FileNameError(objs ...interface{}) {
var message = "FileName too long"
var errors []string
for _, obj := range objs {
// Ignore nil
if obj == nil {
continue
}
if err, ok := obj.(error); ok {
errors = append(errors, err.Error())
} else {
message = obj.(string)
}
}
ctx.JSON(500, map[string]interface{}{
"message": message,
"documentation_url": setting.API.SwaggerURL,
"errors": errors,
})
}
func (ctx *APIContext) FileExistError(objs ...interface{}) {
var message = "file does not exist"
var errors []string
for _, obj := range objs {
// Ignore nil
if obj == nil {
continue
}
if err, ok := obj.(error); ok {
errors = append(errors, err.Error())
} else {
message = obj.(string)
}
}
ctx.JSON(500, map[string]interface{}{
"message": message,
"documentation_url": setting.API.SwaggerURL,
"errors": errors,
})
}
// InternalServerError responds with an error message to the client with the error as a message
// and the file and line of the caller.
func (ctx *APIContext) InternalServerError(err error) {

View File

@ -6,6 +6,7 @@
package convert
import (
"encoding/json"
"fmt"
"strconv"
"strings"
@ -29,8 +30,18 @@ func ToEmail(email *models.EmailAddress) *api.Email {
}
}
type BranchKind int
const (
None BranchKind = iota
DefaultBranch
ProtectedBranch
OtherBranch
)
// ToBranch convert a git.Commit and git.Branch to an api.Branch
func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit, bp *models.ProtectedBranch, user *models.User, isRepoAdmin bool) (*api.Branch, error) {
var branchKind BranchKind
if bp == nil {
var hasPerm bool
var err error
@ -41,6 +52,12 @@ func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit, bp *models.
}
}
if b.Name == repo.DefaultBranch {
branchKind = DefaultBranch
} else {
branchKind = OtherBranch
}
return &api.Branch{
Name: b.Name,
Commit: ToPayloadCommit(repo, c),
@ -50,16 +67,30 @@ func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit, bp *models.
StatusCheckContexts: []string{},
UserCanPush: hasPerm,
UserCanMerge: hasPerm,
CommitID: c.ID.String(), //add configure
CommitTime: c.Author.When.Format(time.RFC3339),
DefaultBranch: repo.DefaultBranch,
BranchKind: int(branchKind),
}, nil
}
if b.Name == repo.DefaultBranch {
branchKind = DefaultBranch
} else {
branchKind = ProtectedBranch
}
branch := &api.Branch{
Name: b.Name,
CommitID: c.ID.String(), //add configure
Commit: ToPayloadCommit(repo, c),
Protected: true,
RequiredApprovals: bp.RequiredApprovals,
EnableStatusCheck: bp.EnableStatusCheck,
StatusCheckContexts: bp.StatusCheckContexts,
CommitTime: c.Author.When.Format(time.RFC3339),
DefaultBranch: repo.DefaultBranch,
BranchKind: int(branchKind),
}
if isRepoAdmin {
@ -138,12 +169,27 @@ func ToTag(repo *models.Repository, t *git.Tag) *api.Tag {
Name: t.Name,
Message: strings.TrimSpace(t.Message),
ID: t.ID.String(),
Commit: ToCommitMeta(repo, t),
Commit: ToTagCommit(repo, t),
Tagger: ToCommitUser(t.Tagger),
ZipballURL: util.URLJoin(repo.HTMLURL(), "archive", t.Name+".zip"),
TarballURL: util.URLJoin(repo.HTMLURL(), "archive", t.Name+".tar.gz"),
}
}
func ToTagCommit(repo *models.Repository, t *git.Tag) *api.TagCommit {
commit, err := t.Commit()
if err != nil {
log.Error("Commit", err)
return &api.TagCommit{}
}
return &api.TagCommit{
CommitMeta: ToCommitMeta(repo, t),
Commiter: ToCommitUser(commit.Committer),
Author: ToCommitUser(commit.Author),
Message: commit.CommitMessage,
}
}
// ToVerification convert a git.Commit.Signature to an api.PayloadCommitVerification
func ToVerification(c *git.Commit) *api.PayloadCommitVerification {
verif := models.ParseCommitWithSignature(c)
@ -228,6 +274,7 @@ func ToHook(repoLink string, w *models.Webhook) *api.Hook {
config := map[string]string{
"url": w.URL,
"content_type": w.ContentType.Name(),
"http_method": w.HTTPMethod,
}
if w.Type == models.SLACK {
s := webhook.GetSlackHook(w)
@ -238,14 +285,45 @@ func ToHook(repoLink string, w *models.Webhook) *api.Hook {
}
return &api.Hook{
ID: w.ID,
Type: string(w.Type),
URL: fmt.Sprintf("%s/settings/hooks/%d", repoLink, w.ID),
Active: w.IsActive,
Config: config,
Events: w.EventsArray(),
Updated: w.UpdatedUnix.AsTime(),
Created: w.CreatedUnix.AsTime(),
ID: w.ID,
Type: string(w.Type),
URL: fmt.Sprintf("%s/settings/hooks/%d", repoLink, w.ID),
Active: w.IsActive,
Config: config,
Events: w.EventsArray(),
Updated: w.UpdatedUnix.AsTime(),
Created: w.CreatedUnix.AsTime(),
BranchFilter: w.HookEvent.BranchFilter,
}
}
func ToHookTask(t *models.HookTask) *api.HookTask {
config := map[string]string{
"url": t.URL,
"content_type": t.ContentType.Name(),
"http_method": t.HTTPMethod,
}
payloadContent := make(map[string]interface{})
requestContent := make(map[string]interface{})
responseContent := make(map[string]interface{})
_ = json.Unmarshal([]byte(t.PayloadContent), &payloadContent)
_ = json.Unmarshal([]byte(t.RequestContent), &requestContent)
_ = json.Unmarshal([]byte(t.ResponseContent), &responseContent)
return &api.HookTask{
ID: t.ID,
UUID: t.UUID,
Type: string(t.Type),
Config: config,
PayloadContent: payloadContent,
EventType: string(t.EventType),
IsSSL: t.IsSSL,
IsDelivered: t.IsDelivered,
Delivered: t.Delivered,
IsSucceed: t.IsSucceed,
RequestContent: requestContent,
ResponseContent: responseContent,
}
}
@ -276,6 +354,7 @@ func ToDeployKey(apiLink string, key *models.DeployKey) *api.DeployKey {
func ToOrganization(org *models.User) *api.Organization {
return &api.Organization{
ID: org.ID,
Name: org.Name,
AvatarURL: org.AvatarLink(),
UserName: org.Name,
FullName: org.FullName,
@ -360,3 +439,18 @@ func ToLFSLock(l *models.LFSLock) *api.LFSLock {
},
}
}
// ToOrganization convert models.User to api.Organization
func ToOrganizationExt(org *models.User) *api.OrganizationExt {
return &api.OrganizationExt{
ID: org.ID,
AvatarURL: org.AvatarLink(),
UserName: org.Name,
FullName: org.FullName,
Description: org.Description,
Website: org.Website,
Location: org.Location,
Visibility: org.Visibility.String(),
RepoAdminChangeTeamAccess: org.RepoAdminChangeTeamAccess,
}
}

View File

@ -146,6 +146,7 @@ func ToCommit(repo *models.Repository, commit *git.Commit, userCache map[string]
}
return &api.Commit{
CommitDate: commit.Committer.When.Format("2006-01-02"), // new time format, year-moon-day
CommitMeta: &api.CommitMeta{
URL: repo.APIURL() + "/git/commits/" + commit.ID.String(),
SHA: commit.ID.String(),

View File

@ -61,14 +61,17 @@ func ToAPIPullRequest(pr *models.PullRequest, doer *models.User) *api.PullReques
State: apiIssue.State,
IsLocked: apiIssue.IsLocked,
Comments: apiIssue.Comments,
HTMLURL: pr.Issue.HTMLURL(),
DiffURL: pr.Issue.DiffURL(),
PatchURL: pr.Issue.PatchURL(),
HasMerged: pr.HasMerged,
MergeBase: pr.MergeBase,
Deadline: apiIssue.Deadline,
Created: pr.Issue.CreatedUnix.AsTimePtr(),
Updated: pr.Issue.UpdatedUnix.AsTimePtr(),
CommitNum: pr.CommitNum,
ChangedFiles: pr.ChangedFiles,
HTMLURL: pr.Issue.HTMLURL(),
DiffURL: pr.Issue.DiffURL(),
PatchURL: pr.Issue.PatchURL(),
HasMerged: pr.HasMerged,
MergeBase: pr.MergeBase,
Deadline: apiIssue.Deadline,
Created: pr.Issue.CreatedUnix.AsTimePtr(),
Updated: pr.Issue.UpdatedUnix.AsTimePtr(),
Base: &api.PRBranchInfo{
Name: pr.BaseBranch,

View File

@ -20,6 +20,7 @@ func ToRelease(r *models.Release) *api.Release {
TagName: r.TagName,
Target: r.Target,
Title: r.Title,
Sha1: r.Sha1,
Note: r.Note,
URL: r.APIURL(),
HTMLURL: r.HTMLURL(),

View File

@ -37,3 +37,16 @@ func ToGitServiceType(value string) structs.GitServiceType {
return structs.PlainGitService
}
}
func ToBranchType(index int) structs.BranchKind {
switch index {
case 1:
return structs.DefaultBranch
case 2:
return structs.ProtectedBranch
case 3:
return structs.OtherBranch
default:
return structs.None
}
}

View File

@ -191,6 +191,11 @@ func (c *Commit) CommitsByRange(page, pageSize int) (*list.List, error) {
return c.repo.commitsByRange(c.ID, page, pageSize)
}
// CommitsByFileAndRange returns the specific page page commits before current revision and file, every page's number default by CommitsRangeSize
func (c *Commit) CommitsByFileAndRange(file string, page, pageSize int) (*list.List, error) {
return c.repo.CommitsByFileAndRange(c.ID.String(), file, page)
}
// CommitsBefore returns all the commits before current revision
func (c *Commit) CommitsBefore() (*list.List, error) {
return c.repo.getCommitsBefore(c.ID)

View File

@ -103,6 +103,31 @@ func GetBranchesByPath(path string, skip, limit int) ([]*Branch, int, error) {
return branches, countAll, nil
}
// GetBranchesByPath returns a branch by it's path
func GetBranchesByPathNoLimit(path string) ([]*Branch, int, error) {
gitRepo, err := OpenRepository(path)
if err != nil {
return nil, 0, err
}
defer gitRepo.Close()
brs, countAll, err := gitRepo.GetBranches(0, 0)
if err != nil {
return nil, 0, err
}
branches := make([]*Branch, len(brs))
for i := range brs {
branches[i] = &Branch{
Path: path,
Name: brs[i],
gitRepo: gitRepo,
}
}
return branches, countAll, nil
}
// DeleteBranchOptions Option(s) for delete branch
type DeleteBranchOptions struct {
Force bool

View File

@ -200,6 +200,19 @@ func (repo *Repository) FileCommitsCount(revision, file string) (int64, error) {
return CommitsCountFiles(repo.Path, []string{revision}, []string{file})
}
// GetFirstAndLastCommitByPath returns the first commit and the last commit of relative path.
func (repo *Repository) GetFirstAndLastCommitByPath(revision, relpath string) (*Commit, *Commit, error) {
stdout, err := NewCommand("log", revision, prettyLogFormat, "--", relpath).RunInDirBytes(repo.Path)
if err != nil {
return nil, nil, err
}
commits, err := repo.parsePrettyFormatLogToList(stdout)
if err != nil {
return nil, nil, err
}
return commits.Front().Value.(*Commit), commits.Back().Value.(*Commit), nil
}
// CommitsByFileAndRange return the commits according revision file and the page
func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) (*list.List, error) {
skip := (page - 1) * setting.Git.CommitsRangeSize

View File

@ -20,6 +20,16 @@ func IsTagExist(repoPath, name string) bool {
return IsReferenceExist(repoPath, TagPrefix+name)
}
func (repo *Repository) GetTagCount() (int64, error) {
stdout, err := NewCommand("tag").RunInDir(repo.Path)
if err != nil {
return 0, err
}
tagNames := strings.Split(strings.TrimRight(stdout, "\n"), "\n")
return int64(len(tagNames)), nil
}
// CreateTag create one tag in the repository
func (repo *Repository) CreateTag(name, revision string) error {
_, err := NewCommand("tag", "--", name, revision).RunInDir(repo.Path)

View File

@ -64,15 +64,15 @@ func setupComplexity(values []string) {
}
if len(requiredList) == 0 {
// No valid character classes found; use all classes as default
for _, complex := range charComplexities {
validChars += complex.ValidChars
requiredList = append(requiredList, complex)
}
// for _, complex := range charComplexities {
// validChars += complex.ValidChars
// requiredList = append(requiredList, complex)
// }
}
}
if validChars == "" {
// No complexities to check; provide a sensible default for password generation
validChars = charComplexities["lower"].ValidChars + charComplexities["upper"].ValidChars + charComplexities["digit"].ValidChars
// validChars = charComplexities["lower"].ValidChars + charComplexities["upper"].ValidChars + charComplexities["digit"].ValidChars
}
}

View File

@ -5,6 +5,7 @@
package repofiles
import (
"context"
"fmt"
"net/url"
"path"
@ -12,6 +13,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
api "code.gitea.io/gitea/modules/structs"
)
@ -37,7 +39,7 @@ func (ct *ContentType) String() string {
// GetContentsOrList gets the meta data of a file's contents (*ContentsResponse) if treePath not a tree
// directory, otherwise a listing of file contents ([]*ContentsResponse). Ref can be a branch, commit or tag
func GetContentsOrList(repo *models.Repository, treePath, ref string) (interface{}, error) {
func GetContentsOrList(ctx context.Context, repo *models.Repository, treePath, ref string) (interface{}, error) {
if repo.IsEmpty {
return make([]interface{}, 0), nil
}
@ -87,12 +89,38 @@ func GetContentsOrList(repo *models.Repository, treePath, ref string) (interface
if err != nil {
return nil, err
}
//add at 2021-12-27
commitsInfo, _, err := entries.GetCommitsInfo(ctx, commit, treePath, nil)
if err != nil {
return nil, err
}
// end
for _, e := range entries {
subTreePath := path.Join(treePath, e.Name())
name := e.Blob().Name()
log.Info(" entrie name = %s", name)
subTreePath := path.Join(treePath, name)
fileContentResponse, err := GetContents(repo, subTreePath, origRef, true)
for _, commitInfo := range commitsInfo {
if commitInfo.Entry.Name() == fileContentResponse.Name {
var entryCommit *git.Commit
entryCommit = commitInfo.Commit
if e.IsSubModule() {
entryCommit = commitInfo.SubModuleFile.Commit
}
fileContentResponse.LatestCommit = api.ContentsResponseCommit{
Message: entryCommit.CommitMessage,
LatestCommitSha: entryCommit.ID.String(),
Created: entryCommit.Author.When.Unix(),
}
break
}
}
if err != nil {
return nil, err
}
fileList = append(fileList, fileContentResponse)
}
return fileList, nil
@ -103,7 +131,7 @@ func GetContents(repo *models.Repository, treePath, ref string, forList bool) (*
if ref == "" {
ref = repo.DefaultBranch
}
origRef := ref
origRef := fmt.Sprintf("%s", url.PathEscape(ref))
// Check that the path given in opts.treePath is valid (not a git path)
cleanTreePath := CleanUploadFileName(treePath)
@ -188,6 +216,7 @@ func GetContents(repo *models.Repository, treePath, ref string, forList bool) (*
}
// Handle links
if entry.IsRegular() || entry.IsLink() {
ref = fmt.Sprintf("%s", url.PathEscape(ref))
downloadURL, err := url.Parse(fmt.Sprintf("%s/raw/%s/%s/%s", repo.HTMLURL(), refType, ref, treePath))
if err != nil {
return nil, err
@ -196,6 +225,7 @@ func GetContents(repo *models.Repository, treePath, ref string, forList bool) (*
contentsResponse.DownloadURL = &downloadURLString
}
if !entry.IsSubModule() {
ref = fmt.Sprintf("%s", url.PathEscape(ref))
htmlURL, err := url.Parse(fmt.Sprintf("%s/src/%s/%s/%s", repo.HTMLURL(), refType, ref, treePath))
if err != nil {
return nil, err

View File

@ -31,6 +31,10 @@ func GetBranches(repo *models.Repository, skip, limit int) ([]*git.Branch, int,
return git.GetBranchesByPath(repo.RepoPath(), skip, limit)
}
func GetBranchesNoLimit(repo *models.Repository) ([]*git.Branch, int, error) {
return git.GetBranchesByPathNoLimit(repo.RepoPath())
}
// checkBranchName validates branch name with existing repository branches
func checkBranchName(repo *models.Repository, name string) error {
gitRepo, err := git.OpenRepository(repo.RepoPath())

View File

@ -24,6 +24,7 @@ type CreateUserOption struct {
// EditUserOption edit user options
type EditUserOption struct {
NewName string `json:"new_name" binding:"MaxSize(40)"`
// required: true
SourceID int64 `json:"source_id"`
// required: true

View File

@ -20,18 +20,34 @@ var (
// Hook a hook is a web hook when one repository changed
type Hook struct {
ID int64 `json:"id"`
Type string `json:"type"`
URL string `json:"-"`
Config map[string]string `json:"config"`
Events []string `json:"events"`
Active bool `json:"active"`
ID int64 `json:"id"`
Type string `json:"type"`
URL string `json:"-"`
Config map[string]string `json:"config"`
Events []string `json:"events"`
Active bool `json:"active"`
BranchFilter string `json:"branch_filter"`
// swagger:strfmt date-time
Updated time.Time `json:"updated_at"`
// swagger:strfmt date-time
Created time.Time `json:"created_at"`
}
type HookTask struct {
ID int64 `json:"id"`
UUID string `json:"uuid"`
Type string `json:"type"`
Config map[string]string `json:"config"`
PayloadContent map[string]interface{} `json:"payload_content"`
EventType string `json:"event_type"`
IsSSL bool `json:"is_ssl"`
IsDelivered bool `json:"is_delivered"`
Delivered int64 `json:"delivered"`
IsSucceed bool `json:"is_succeed"`
RequestContent map[string]interface{} `json:"request_info"`
ResponseContent map[string]interface{} `json:"response_content"`
}
// HookList represents a list of API hook.
type HookList []*Hook

View File

@ -7,6 +7,7 @@ package structs
// Organization represents an organization
type Organization struct {
ID int64 `json:"id"`
Name string `json:"name"`
UserName string `json:"username"`
FullName string `json:"full_name"`
AvatarURL string `json:"avatar_url"`
@ -35,10 +36,12 @@ type CreateOrgOption struct {
// EditOrgOption options for editing an organization
type EditOrgOption struct {
Name string `json:"name"` // 添加对name的修改,lower_name 其值跟随name变化;
FullName string `json:"full_name"`
Description string `json:"description" binding:"MaxSize(255)"`
Website string `json:"website" binding:"ValidUrl;MaxSize(255)"`
Location string `json:"location" binding:"MaxSize(50)"`
// Website string `json:"website" binding:"ValidUrl;MaxSize(255)"`
Website string `json:"website" binding:"MaxSize(255)"`
Location string `json:"location" binding:"MaxSize(50)"`
// possible values are `public`, `limited` or `private`
// enum: public,limited,private
Visibility string `json:"visibility" binding:"In(,public,limited,private)"`

View File

@ -44,3 +44,28 @@ type EditTeamOption struct {
Units []string `json:"units"`
CanCreateOrgRepo *bool `json:"can_create_org_repo"`
}
type OrganizationExt struct {
ID int64 `json:"id"`
UserName string `json:"username"`
FullName string `json:"full_name"`
AvatarURL string `json:"avatar_url"`
Description string `json:"description"`
Website string `json:"website"`
Location string `json:"location"`
Visibility string `json:"visibility"`
RepoAdminChangeTeamAccess bool `json:"repo_admin_change_team_access"`
OwnerTeam interface{} `json:"owner_team"` //团队关系;
}
type EditOrgOptionExt struct {
Name string `json:"name"` // 添加对name的修改,lower_name 其值跟随name变化;
FullName string `json:"full_name"`
Description string `json:"description"`
Website string `json:"website"`
Location string `json:"location"`
// possible values are `public`, `limited` or `private`
// enum: public,limited,private
Visibility string `json:"visibility" binding:"In(,public,limited,private)"`
RepoAdminChangeTeamAccess bool `json:"repo_admin_change_team_access"`
}

View File

@ -48,6 +48,9 @@ type PullRequest struct {
Updated *time.Time `json:"updated_at"`
// swagger:strfmt date-time
Closed *time.Time `json:"closed_at"`
CommitNum int `json:"commit_num"`
ChangedFiles int `json:"changed_files"`
}
// PRBranchInfo information about a branch

View File

@ -27,6 +27,7 @@ type Release struct {
PublishedAt time.Time `json:"published_at"`
Publisher *User `json:"author"`
Attachments []*Attachment `json:"assets"`
Sha1 string `json:"sha"`
}
// CreateReleaseOption options when creating a release

View File

@ -5,6 +5,7 @@
package structs
import (
"strings"
"time"
)
@ -19,8 +20,57 @@ type Branch struct {
UserCanPush bool `json:"user_can_push"`
UserCanMerge bool `json:"user_can_merge"`
EffectiveBranchProtectionName string `json:"effective_branch_protection_name"`
CommitID string `json:"commit_id"` // add configure
CommitTime string `json:"commit_time"` // add configure
DefaultBranch string `json:"default_branch"`
BranchKind int `json:"branch_kind"`
}
type BranchKind int
const (
None BranchKind = iota
DefaultBranch
ProtectedBranch
OtherBranch
)
func (bk BranchKind) Name() string {
return strings.ToLower(bk.Title())
}
func (bk BranchKind) Title() string {
switch bk {
case DefaultBranch:
return "default"
case ProtectedBranch:
return "protected"
case OtherBranch:
return "other"
}
return ""
}
type BranchesSlice struct {
BranchName string `json:"branch_name"`
// BranchKind int `json:"branch_kind"`
Branches []Branch `json:"branches"`
}
// sort by branchkind
type SortBranch []Branch
func (s SortBranch) Len() int { return len(s) }
func (s SortBranch) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s SortBranch) Less(i, j int) bool { return s[i].BranchKind < s[j].BranchKind }
// sort by CommiTime of the branch
type SortBranchTime []Branch
func (s SortBranchTime) Len() int { return len(s) }
func (s SortBranchTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s SortBranchTime) Less(i, j int) bool { return s[i].CommitTime > s[j].CommitTime }
// BranchProtection represents a branch protection for a repository
type BranchProtection struct {
BranchName string `json:"branch_name"`

View File

@ -48,6 +48,7 @@ type Commit struct {
Committer *User `json:"committer"`
Parents []*CommitMeta `json:"parents"`
Files []*CommitAffectedFiles `json:"files"`
CommitDate string `json:"commit_date"`
}
// CommitDateOptions store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE
@ -62,3 +63,14 @@ type CommitDateOptions struct {
type CommitAffectedFiles struct {
Filename string `json:"filename"`
}
type CommitsSlice struct {
CommitDate string `json:"commit_date"`
Commits []Commit
}
type SortCommit []Commit
func (s SortCommit) Len() int { return len(s) }
func (s SortCommit) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s SortCommit) Less(i, j int) bool { return s[i].CommitDate > s[j].CommitDate }

View File

@ -57,6 +57,13 @@ type FileLinksResponse struct {
HTMLURL *string `json:"html"`
}
//add
type ContentsResponseCommit struct {
Message string `json:"message"`
LatestCommitSha string `json:"sha"`
Created int64 `json:"created_at"`
}
// ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content
type ContentsResponse struct {
Name string `json:"name"`
@ -76,8 +83,9 @@ type ContentsResponse struct {
GitURL *string `json:"git_url"`
DownloadURL *string `json:"download_url"`
// `submodule_git_url` is populated when `type` is `submodule`, otherwise null
SubmoduleGitURL *string `json:"submodule_git_url"`
Links *FileLinksResponse `json:"_links"`
SubmoduleGitURL *string `json:"submodule_git_url"`
Links *FileLinksResponse `json:"_links"`
LatestCommit ContentsResponseCommit `json:"latest_commit"`
}
// FileCommitResponse contains information generated from a Git commit for a repo's file.

View File

@ -6,12 +6,21 @@ package structs
// Tag represents a repository tag
type Tag struct {
Name string `json:"name"`
Message string `json:"message"`
ID string `json:"id"`
Commit *CommitMeta `json:"commit"`
ZipballURL string `json:"zipball_url"`
TarballURL string `json:"tarball_url"`
Name string `json:"name"`
Message string `json:"message"`
ID string `json:"id"`
Commit *TagCommit `json:"commit"`
ZipballURL string `json:"zipball_url"`
TarballURL string `json:"tarball_url"`
Tagger *CommitUser `json:"tagger"`
}
type TagCommit struct {
*CommitMeta
Commiter *CommitUser `json:"commiter"`
Author *CommitUser `json:"author"`
Message string `json:"message"`
}
// AnnotatedTag represents an annotated tag
@ -39,3 +48,8 @@ type CreateTagOption struct {
Message string `json:"message"`
Target string `json:"target"`
}
type RepoBranchAndTagCount struct {
BranchCount int `json:"branch_count"`
TagCount int `json:"tag_count"`
}

44
modules/structs/wiki.go Normal file
View File

@ -0,0 +1,44 @@
package structs
type WikiesResponse struct {
WikiMeta
WikiCloneLink CloneLink `json:"wiki_clone_link"`
}
type WikiMeta struct {
Name string `json:"name"`
Commit WikiCommit `json:"commit"`
FirstCommit WikiCommit `json:"-"`
//WikiCloneLink CloneLink `json:"wiki_clone_link"`
}
type WikiCommit struct {
ID string `json:"id"`
Message string `json:"message"`
Author WikiUser `json:"author"`
Commiter WikiUser `json:"-"`
}
type WikiUser struct {
Name string `json:"name"`
Email string `json:"email"`
When int64 `json:"when"`
}
type WikiResponse struct {
WikiMeta
CommitCounts int64 `json:"commit_counts"`
MdContent string `json:"md_content"`
SimpleContent string `json:"simple_content"`
WikiCloneLink CloneLink `json:"wiki_clone_link"`
}
type WikiOption struct {
Name string `json:"name"`
Content string `json:"content"`
CommitMessage string `json:"commit_message"`
}
type CloneLink struct {
SSH string `json:"ssh"`
HTTPS string `json:"https"`
}

View File

@ -0,0 +1,157 @@
木兰公共许可证, 第1版
2020年12月 http://license.coscl.org.cn/MulanPublicLicenseV1
您对"贡献"的复制、使用、修改及分发受木兰公共许可证, 第1版"本许可证")的如下条款的约束:
0. 定义
"贡献"是指由"贡献者"许可在"本许可证"下的受版权法保护的作品,包括最初"贡献者"许可在"本许可证"下的作品及后续"贡献者"许可在"本许可证"下的"衍生作品"。
"贡献者"是指将受版权法保护的作品许可在"本许可证"下的自然人或"法人实体"。
"法人实体"是指提交贡献的机构及其"关联实体"。
"关联实体"是指,对"本许可证"下的行为方而言控制、受控制或与其共同受控制的机构此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。
"衍生作品"是指基于"贡献"创作的作品,具体包括对全部或部分"贡献"进行修改、重写、翻译、注释、组合或与之链接(包括动态链接或静态链接)而形成的作品。仅与"贡献"进行进程间通信或系统调用的作品是独立作品,不属于"衍生作品"。
"对应源代码"是指生成、安装和(对于可执行作品)运行目标代码所需的所有源文件和与之关联的接口定义文件,以及控制这些活动的脚本,但不包括编译环境、编译工具、云服务平台(如果有)。
"分发"是指通过任何媒介向他人提供"贡献"或"衍生作品"的行为,以及利用"贡献"或"衍生作品"通过网络远程给用户提供服务的行为,例如通过利用"贡献"或"衍生作品"搭建的云服务平台提供在线服务的行为。
1. 授予版权许可
每个"贡献者"根据"本许可证"授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、"分发"其"贡献"或"衍生作品",不论修改与否。
2. 授予专利许可
每个"贡献者"根据"本许可证"授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其"贡献"或以其他方式转移其"贡献"。前述专利许可仅限于"贡献者"现在或将来拥有或控制的其"贡献"中的专利权利要求,不包括仅因您或他人修改"贡献"而将必然会侵犯到的专利权利要求。如果您或您的"关联实体"直接或间接地,就"贡献"对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则本许可证授予您对"贡献"的专利许可自您提起诉讼或发起维权行动之日终止。
3. 无商标许可
"本许可证"不提供对"贡献者"的商品名称、商标、服务标志或产品名称的商标许可但您为满足第4条规定的声明义务而必须使用除外。
4. 分发限制
您可以在任何媒介中将您接收到的"贡献"或您的"衍生作品"以源程序形式或可执行形式重新"分发",但必须满足下列条件:
1您必须向接收者提供"本许可证"的副本,并保留"贡献"中的版权、商标、专利及免责声明;并且,
2如果您"分发"您接收到的"贡献",您必须使用"本许可证"提供该"贡献"的源代码副本;如果您 "分发"您的"衍生作品",您必须:
i随"衍生作品"向接收者提供使用"本许可证""分发"的您的"衍生作品"的"对应源代码"。如果您通过下载链接提供前述"对应源代码",则您应将下载链接地址置于"衍生作品"或其随附文档中的明显位置,有效期不少于自该"衍生作品""分发"之日起三年,并确保接收者可以获得"对应源代码";或者,
ii随"衍生作品"向接收者提供一个书面要约,表明您愿意提供使用"本许可证""分发"的您"衍生作品"的"对应源代码"。书面要约应放在"衍生作品"中的明显位置,并确保接收者根据书面要约可获取"对应源代码"的时间从您接到该请求之日起不得超过三个月,且有效期不少于自该"衍生作品""分发"之日起三年。
5. 违约与终止
如果您违反"本许可证",任何"贡献者"有权书面通知您终止其依据"本许可证"授予您的许可。该"贡献者"授予您的许可从您接到其终止通知之日起终止。但在如下两种情形下,即使您收到"贡献者"的通知也并不终止您的许可:
1您在接到终止通知之前已停止所有违反行为
2您是首次收到该"贡献者"根据"本许可证"发出的书面终止通知您在收到该通知后30天内停止所有违反行为。
只要下游接收者遵守"本许可证"的相关规定,您在"本许可证"下的许可终止,不影响下游接收者根据"本许可证"享有的权利。
6. 例外
如果您将"贡献"或您的"衍生作品"与采用GPLv3、AGPLv3、或前述许可证的后续版本以下简称"GPL类许可证")的作品结合,且根据"GPL类许可证"的要求您有义务将形成的结合作品以对应的"GPL类许可证"许可的,您可以根据对应的"GPL类许可证"许可结合作品,只要您在分发该结合作品的同时向接收者提供"本许可证"的副本,并保留"贡献"中的版权、商标、专利及免责声明。任何"贡献者"不会因您根据前述原因选择"GPL类许可证"许可而授予该结合作品的接收者更多权利。
7. 免责声明与责任限制
"贡献"在提供时不带任何明示或默示的担保。在任何情况下,"贡献者"或版权所有者不对任何人因使用"贡献"而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。
8. 语言
"本许可证"以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。
条款结束
如何将木兰公共许可证第1版应用到您的软件
如果您希望将木兰公共许可证第1版应用到您的新软件为了方便接收者查阅建议您完成如下三步
1 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字;
2 请您在软件包的一级目录下创建以“LICENSE”为名的文件将整个许可证文本放入该文件中
3 请将如下声明文本放入每个源文件的头部注释中。
Copyright (c) [Year] [name of copyright holder]
[Software Name] is licensed under Mulan Public License v1.
You can use this software according to the terms and conditions of the Mulan Public License v1.
You may obtain a copy of Mulan Public License v1 at:
http://license.coscl.org.cn/MulanPublicLicenseV1
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan Public License v1 for more details.
Your reproduction, use, modification and Distribution of the Contribution shall be subject to Mulan Public License, Version 1 (this License) with following terms and conditions:
0. Definitions
Contribution means the copyrightable work licensed by a particular Contributor under this License, including the work licensed by the initial Contributor under this License and its Derivative Work licensed by any subsequent Contributor under this License.
Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License.
Legal Entity means the entity making a Contribution and all its Affiliates.
Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, control means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.
Derivative Work means works created based on Contribution, specifically including works formed by modifying, rewriting, translating, annotating, combining or linking to all or part of Contribution (including dynamic linking or static linking). Works which only communicate with Contribution through inter-process communication or system call, are independent works, rather than Derivative Work.
Corresponding Source Code means all the source code needed to generate, install, and (for an executable work) run the object code including the interface definition files associated with source files for the work, and scripts to control those activities, excluding of compilation environment and compilation tools, cloud services platform (if any).
Distribute (or Distribution) means the act of making the Contribution or Derivative Work available to others through any medium, and using the Contribution or Derivative Work to provide online services to users, such as the act of providing online services through a cloud service platform built using Contributions or Derivative Works.
1. Grant of copyright license
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or Distribute its Contribution or Derivative Work, with modification or not.
2. Grant of patent license
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, excluding of any patent claims solely be infringed by your modification. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that any Contribution infringes patents, then any patent license granted to you under this License for the Contribution shall terminate as of the date such litigation or activity is filed or taken.
3. No Trademark License
No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in Section 4.
4. Distribution Restriction
You may Distribute the Contribution you received or your Derivative Work through any medium with or without modification, whether in source or executable forms, provided that you meet the following conditions:
1) You must provide recipients with a copy of this License and retain copyright, trademark, patent and disclaimer statements in the Contribution; and,
2) If you Distribute the Contribution you received, you must provide copies of the Contributions source code under this License;
If you Distribute your Derivative Work, you have to:
(i) accompanying the Derivative work, provide recipients with Corresponding Source Code of your Derivative Work under this License. If you provide the Corresponding Source Code through a download link, you should place such link address prominently in the Derivative Work or its accompanying documents, and be valid no less than three years from your Distribution of the particular Derivative Work, and ensure that the recipients can acquire the Corresponding Source Code through the link; or,
(ii) accompanying the Derivative Work, provide recipients with a written offer indicating your willingness to provide the Corresponding Source Code of the Derivative Work licensed under this License. Such written offer shall be placed prominently in the Derivative Work or its accompanying documents. Without reasonable excuse, the recipient shall be able to acquire the Corresponding Source code of the Derivative work for no more than three months from your receipt of a valid request, and be valid no less than three years from your Distribution of the particular Derivative Work.
5. Breach and Termination
If you breach this License, any Contributor has the right to notify you in writing to terminate its license granted to you under this License. The license granted to you by such Contributor terminates upon your receipt of such notice of termination. Notwithstanding the foregoing, your license will not be terminated even if you receive a notice of termination from Contributor, provided that:
1) you have cured all the breaches prior to receiving such notice of termination; or,
2) its your first time to receive a notice of termination from such Contributor pursuant to this License, and you cured all the breaches within 30 days of receipt of such notice.
Termination of your license under this License shall not affect the downstream recipient's rights under this License, provided that the downstream recipient complies with this License.
6. Exceptions
If you combine Contribution or your Derivative Work with a work licensed under the GPLv3, AGPLv3 or subsequent versions of those licenses (hereinafter referred to as “GPL Style License”), and according to the GPL Style License, you have an obligation to make the combined work to be licensed under the corresponding GPL Style License, you can license such combined work under the GPL Style License, provided that when you Distribute the combined work, you also provide a copy of this License to the recipients, and retain copyright, trademarks, patents, and disclaimer statements in the Contribution. No Contributor will grant additional rights to the recipients of the combined work for your license under GPL Style License.
7. Disclaimer of Warranty and Limitation of liability
CONTRIBUTION ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE CONTRIBUTION, NO MATTER HOW ITS CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
8. Language
THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL.
End of the Terms and Conditions
How to apply the Mulan Public LicenseVersion 1 (Mulan PublicLicense v1), to your software
To apply the Mulan Public LicenseVersion 1 to your work, for easy identification by recipients, you are suggested to complete following three steps:
Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;
Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package;
Attach the statement to the appropriate annotated syntax at the beginning of each source file.
Copyright (c) [Year] [name of copyright holder]
[Software Name] is licensed under Mulan Public License v1.
You can use this software according to the terms and conditions of the Mulan Public License v1.
You may obtain a copy of Mulan Public License v1 at:
http://license.coscl.org.cn/MulanPublicLicenseV1
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan Public License v1 for more details.

18
options/license/PHengLEI Normal file
View File

@ -0,0 +1,18 @@
本协议是您(如下也称"用户")与中国空气动力研究与发展中心(以下简称"中心"关于国家数值风洞NNW"风雷PHengLEI"软件的协议,请认真阅读.
1. 申请者不得私自以拷贝、刻录等方式向第三者(包括同一单位内的其他人员)传播。所有用户均需填写本协议,向中心申请并获授权后方能免费获取.
2. 用户可以在"风雷PHengLEI"软件上添加、修改源代码,有权提出软件的使用反馈及意见,用户可以发表软件的使用体验及感受,但不得随意诽谤、中伤.
3. 用户享有其开发代码的知识产权。鼓励将开发成果返回至开发团队,或在"风雷PHengLEI"软件中开源,开发者将在代码中署名.
4. 若该软件被申请人用于学术研究,则相关论文成果中应引用国家数值风洞"风雷PHengLEI"软件; 若用于其它用途,需在显要处标注基于"风雷PHengLEI"软件开发.
5. 一旦申请使用本软件,即表示同意接受协议各项条件的约束。如果您不同意协议的条件,则不能获得使用本软件的权利.
6. "风雷PHengLEI"软件由中心开发,一切知识产权,以及与软件相关的所有信息内容,包括但不限于:文字表述及其组合、图标、图饰、图表、色彩、版面框架、有关数据、印刷材料、或电子文档等均受《中华人民共和国著作权法》、《中华人民共和国计算机软件保护条例》、《中华人民共和国商标法》、《中华人民共和国专利法》、反不正当竞争法和相应的国际条约以及其他知识产权法律法规的保护,除涉及第三方授权的软件或技术外,中心享有上述知识产权.
7. 您获得的只是本软件的使用权。本软件仅限中华人民共和国公民申请使用.
8. 本协议的最终解释权归中心.

View File

@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"net/http"
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
@ -154,12 +155,13 @@ func EditUser(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "422":
// "$ref": "#/responses/validationError"
log.Info("user setting begin :%s", ctx.User.Name)
form := web.GetForm(ctx).(*api.EditUserOption)
u := user.GetUserByParams(ctx)
if ctx.Written() {
return
}
parseLoginSource(ctx, u, form.SourceID, form.LoginName)
if ctx.Written() {
return
@ -193,6 +195,28 @@ func EditUser(ctx *context.APIContext) {
if form.MustChangePassword != nil {
u.MustChangePassword = *form.MustChangePassword
}
// Non-local users are not allowed to change their username.
if len(form.NewName) != 0 && u.IsLocal() {
// Check if user name has been changed
if err := models.ChangeUserName(u, form.NewName); err != nil {
switch {
case models.IsErrUserAlreadyExist(err):
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("user name is already taken [name: %s]", form.NewName), err)
case models.IsErrNameReserved(err):
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("user name is reserved [name:%s]", form.NewName), err)
case models.IsErrNamePatternNotAllowed(err):
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("user name's pattern is not allowed [name:%s]", form.NewName), err)
case models.IsErrNameCharsNotAllowed(err):
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("user name's chars is not allowed [name:%s]", form.NewName), err)
default:
ctx.Error(http.StatusUnprocessableEntity, "ChangeUserName", err)
}
return
}
u.Name = form.NewName
u.LowerName = strings.ToLower(form.NewName)
}
u.LoginName = form.LoginName
@ -243,14 +267,15 @@ func EditUser(ctx *context.APIContext) {
u.IsRestricted = *form.Restricted
}
if err := models.UpdateUser(u); err != nil {
if err := models.UpdateUserSetting(u); err != nil {
if models.IsErrEmailAlreadyUsed(err) || models.IsErrEmailInvalid(err) {
ctx.Error(http.StatusUnprocessableEntity, "", err)
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("the e-mail is not valid [name %s]", u.Email), err)
} else {
ctx.Error(http.StatusInternalServerError, "UpdateUser", err)
}
return
}
log.Trace("Account profile updated by admin (%s): %s", ctx.User.Name, u.Name)
ctx.JSON(http.StatusOK, convert.ToUser(u, ctx.User))
@ -405,7 +430,7 @@ func GetAllUsers(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
listOptions := utils.GetListOptions(ctx)
log.Info("user setting begin :%s", ctx.User.Name)
users, maxResults, err := models.SearchUsers(&models.SearchUserOptions{
Actor: ctx.User,
Type: models.UserTypeIndividual,

View File

@ -80,9 +80,11 @@ import (
"code.gitea.io/gitea/routers/api/v1/notify"
"code.gitea.io/gitea/routers/api/v1/org"
"code.gitea.io/gitea/routers/api/v1/repo"
report "code.gitea.io/gitea/routers/api/v1/reporter"
"code.gitea.io/gitea/routers/api/v1/settings"
_ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation
"code.gitea.io/gitea/routers/api/v1/user"
"code.gitea.io/gitea/routers/api/v1/viewfile"
"code.gitea.io/gitea/services/auth"
"code.gitea.io/gitea/services/forms"
@ -581,7 +583,7 @@ func Routes() *web.Route {
m.Use(context.ToggleAPI(&context.ToggleOptions{
SignInRequired: setting.Service.RequireSignInView,
}))
reqRepoCodeReader := context.RequireRepoReader(models.UnitTypeCode)
m.Group("", func() {
// Miscellaneous
if setting.API.EnableSwagger {
@ -600,6 +602,11 @@ func Routes() *web.Route {
m.Get("/repository", settings.GetGeneralRepoSettings)
})
m.Group("/activity", func() {
m.Get("", report.GetActivity)
m.Get("/project", report.GetActivityProject)
m.Get("/develop", report.GetActivityDevelop)
})
// Notifications
m.Group("/notifications", func() {
m.Combo("").
@ -739,6 +746,31 @@ func Routes() *web.Route {
Delete(repo.DeleteGitHook)
})
}, reqToken(), reqAdmin(), reqGitHook(), context.ReferencesGitRepo(true))
m.Group("/commits/count", func() {
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.GetCommitsCount)
m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.GetCommitsCount)
m.Get("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.GetCommitsCount)
})
m.Group("/pulls/{index}", func() {
m.Get("/commits", context.RepoRef(), repo.GetPullCommits)
m.Get("/files", context.RepoRef(), repo.GetPullFiles)
m.Get("/issues", context.RepoRef(), repo.GetPullIssues)
})
m.Get("/compare/*", repo.MustBeNotEmpty, reqRepoCodeReader,
repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.CompareDiff)
// m.Get("/src/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.GetFileContents)
m.Get("/src/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.GetFileContents)
//end by coder
m.Group("/contributors", func() {
m.Get("", report.GetContributors) //获取仓库的所有构建者信息 ****
})
m.Group("/count", func() {
m.Get("", viewfile.GetCommitCount) //****
})
m.Group("/file_commits", func() {
m.Get("/*", repo.GetFileAllCommits)
})
m.Group("/hooks", func() {
m.Combo("").Get(repo.ListHooks).
Post(bind(api.CreateHookOption{}), repo.CreateHook)
@ -747,6 +779,7 @@ func Routes() *web.Route {
Patch(bind(api.EditHookOption{}), repo.EditHook).
Delete(repo.DeleteHook)
m.Post("/tests", context.RepoRefForAPI, repo.TestHook)
m.Get("/hooktasks", repo.ListHookTask)
})
}, reqToken(), reqAdmin(), reqWebhooksEnabled())
m.Group("/collaborators", func() {
@ -765,10 +798,16 @@ func Routes() *web.Route {
}, reqToken())
m.Get("/raw/*", context.RepoRefForAPI, reqRepoReader(models.UnitTypeCode), repo.GetRawFile)
m.Get("/archive/*", reqRepoReader(models.UnitTypeCode), repo.GetArchive)
m.Get("/find", viewfile.FindFiles)
m.Group("/releases", func() {
m.Get("/latest", viewfile.LatestRelease)
})
m.Combo("/forks").Get(repo.ListForks).
Post(reqToken(), reqRepoReader(models.UnitTypeCode), bind(api.CreateForkOption{}), repo.CreateFork)
m.Group("/branches", func() {
m.Get("", repo.ListBranches)
m.Get("/branches_slice", repo.ListBranchesSlice)
m.Get("/*", repo.GetBranch)
m.Delete("/*", context.ReferencesGitRepo(false), reqRepoWriter(models.UnitTypeCode), repo.DeleteBranch)
m.Post("", reqRepoWriter(models.UnitTypeCode), bind(api.CreateBranchRepoOption{}), repo.CreateBranch)
@ -782,6 +821,24 @@ func Routes() *web.Route {
m.Delete("", repo.DeleteBranchProtection)
})
}, reqToken(), reqAdmin())
m.Group("/wikies", func() {
m.Combo("").Get(repo.ListWikiPages).
Post(bind(api.WikiOption{}), repo.CreateWiki)
m.Group("/{page}", func() {
m.Combo("").Get(repo.GetWiki).
Patch(bind(api.WikiOption{}), repo.EditWiki).
Delete(repo.DeleteWiki)
})
})
m.Group("/readme", func() {
m.Get("", repo.GetReadmeContents)
m.Get("/*", repo.GetReadmeContentsByPath)
})
m.Get("/commits_slice", repo.GetAllCommitsSliceByTime)
// m.Get("/branchtagcount", repo.BranchTagCount)
m.Group("/branch_tag_count", func() {
m.Get("", repo.BranchTagCount)
}, reqRepoReader(models.UnitTypeCode), context.ReferencesGitRepo(true))
m.Group("/tags", func() {
m.Get("", repo.ListTags)
m.Get("/*", repo.GetTag)
@ -910,7 +967,7 @@ func Routes() *web.Route {
m.Get(".diff", repo.DownloadPullDiff)
m.Get(".patch", repo.DownloadPullPatch)
m.Post("/update", reqToken(), repo.UpdatePullRequest)
m.Get("/commits", repo.GetPullRequestCommits)
// m.Get("/commits", repo.GetPullRequestCommits)
m.Combo("/merge").Get(repo.IsPullRequestMerged).
Post(reqToken(), mustNotBeArchived, bind(forms.MergePullRequestForm{}), repo.MergePullRequest)
m.Group("/reviews", func() {

View File

@ -8,6 +8,7 @@ package org
import (
"fmt"
"net/http"
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
@ -206,7 +207,21 @@ func Create(ctx *context.APIContext) {
return
}
ctx.JSON(http.StatusCreated, convert.ToOrganization(org))
// ctx.JSON(http.StatusCreated, convert.ToOrganization(org))
// 根据业务需要 自定义创建组织时将默认团队同时返回.
Team, err := models.GetTeam(org.ID, "")
if err != nil {
if models.IsErrUserNotExist(err) {
ctx.NotFound()
} else {
ctx.Error(http.StatusInternalServerError, "GetTeam", err)
}
return
}
apiOrg := convert.ToOrganizationExt(org)
apiOrg.OwnerTeam = convert.ToTeam(Team)
ctx.JSON(http.StatusCreated, apiOrg)
}
// Get get an organization
@ -258,23 +273,74 @@ func Edit(ctx *context.APIContext) {
// "$ref": "#/responses/Organization"
form := web.GetForm(ctx).(*api.EditOrgOption)
org := ctx.Org.Organization
if org.LowerName != strings.ToLower(form.Name) {
if len(form.Name) > 40 {
ctx.Error(http.StatusBadRequest, "EditOrganization", "name长度不能超过40个字符")
return
}
isExist, err := models.IsUserExist(org.ID, form.Name)
if err != nil {
ctx.Error(http.StatusConflict, "IsUserExist", "name already used")
return
} else if isExist {
ctx.Error(http.StatusConflict, "IsUserExist", "name already used")
return
}
if err := models.ChangeUserName(org, form.Name); err != nil {
if err == models.ErrUserNameIllegal {
ctx.Error(http.StatusBadRequest, "ErrUserNameIllegal", "only allowed '-' '_' '.' characters")
return
} else {
ctx.Error(http.StatusBadRequest, "ChangeUserName", "only allowed '-' '_' '.' characters")
return
}
}
org.Name = form.Name
org.LowerName = strings.ToLower(org.Name)
}
org.FullName = form.FullName
org.Description = form.Description
org.Website = form.Website
org.Location = form.Location
if form.Visibility != "" {
org.Visibility = api.VisibilityModes[form.Visibility]
}
if form.RepoAdminChangeTeamAccess != nil {
org.RepoAdminChangeTeamAccess = *form.RepoAdminChangeTeamAccess
}
if err := models.UpdateUserCols(org,
"full_name", "description", "website", "location",
"visibility", "repo_admin_change_team_access",
); err != nil {
ctx.Error(http.StatusInternalServerError, "EditOrganization", err)
// Update org data, update table of the user and repository
if err := models.UpdateUser(org); err != nil {
ctx.Error(http.StatusInternalServerError, "UpdateUser", err)
return
}
visibilityChanged := form.Visibility != org.Visibility.String()
// Update forks visiblity
if visibilityChanged {
if err := org.GetRepositories(models.ListOptions{Page: 1, PageSize: org.NumRepos}); err != nil {
ctx.Error(http.StatusInternalServerError, "GetRepositories", err)
return
}
for _, repo := range org.Repos {
if err := models.UpdateRepository(repo, true); err != nil {
ctx.Error(http.StatusInternalServerError, "UpdateRepository", err)
return
}
}
}
// if err := models.UpdateUserCols(org,
// "full_name", "description", "website", "location",
// "visibility", "repo_admin_change_team_access",
// ); err != nil {
// ctx.Error(http.StatusInternalServerError, "EditOrganization", err)
// return
// }
ctx.JSON(http.StatusOK, convert.ToOrganization(org))
}

View File

@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"net/http"
"sort"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
@ -288,6 +289,92 @@ func ListBranches(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, &apiBranches)
}
// ListBranches list all the branches of a repository
func ListBranchesSlice(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/branches/branches_slice repository repoListBranchesSlice
// ---
// summary: List a repository's branches, Group sort.
// 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
// responses:
// "200":
// "$ref": "#/responses/BranchList"
// listOptions := utils.GetListOptions(ctx)
// skip, _ := listOptions.GetStartEnd()
// branches, totalNumOfBranches, err := repo_module.GetBranches(ctx.Repo.Repository, skip, listOptions.PageSize)
branches, totalNumOfBranches, err := repo_module.GetBranchesNoLimit(ctx.Repo.Repository)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetBranches", err)
return
}
apiBranches := make([]*api.Branch, len(branches))
apiBranchesList := []api.Branch{}
for i := range branches {
c, err := branches[i].GetCommit()
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
return
}
branchProtection, err := ctx.Repo.Repository.GetBranchProtection(branches[i].Name)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetBranchProtection", err)
return
}
apiBranches[i], err = convert.ToBranch(ctx.Repo.Repository, branches[i], c, branchProtection, ctx.User, ctx.Repo.IsAdmin())
if err != nil {
ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err)
return
}
apiBranchesList = append(apiBranchesList, *apiBranches[i])
sort.Sort(api.SortBranch(apiBranchesList))
}
// ctx.SetLinkHeader(int(totalNumOfBranches), listOptions.PageSize)
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", totalNumOfBranches))
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link")
// ctx.JSON(http.StatusOK, &apiBranches)
ctx.JSON(http.StatusOK, BranchesSliceByProtection(ctx, apiBranchesList))
}
func BranchesSliceByProtection(ctx *context.APIContext, branchList []api.Branch) []api.BranchesSlice {
// group by protection
sort.Sort(api.SortBranch(branchList))
branchSlice := make([]api.BranchesSlice, 0)
i := 0
var j int
for {
if i >= len(branchList) {
break
}
for j = i + 1; j < len(branchList) && (branchList[i].BranchKind == branchList[j].BranchKind); j++ {
}
// get the same branches
sameBranchSlice := branchList[i:j]
// sort by time
sort.Sort(api.SortBranchTime(sameBranchSlice))
branchSlice = append(branchSlice, api.BranchesSlice{
BranchName: convert.ToBranchType(branchList[i].BranchKind).Name(),
Branches: sameBranchSlice,
})
i = j
}
return branchSlice
}
// GetBranchProtection gets a branch protection
func GetBranchProtection(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/branch_protections/{name} repository repoGetBranchProtection

View File

@ -9,6 +9,7 @@ import (
"fmt"
"math"
"net/http"
"sort"
"strconv"
"code.gitea.io/gitea/models"
@ -219,3 +220,318 @@ func GetAllCommits(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, &apiCommits)
}
func GetAllCommitsSliceByTime(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/commits_slice repository repoGetAllCommitsSlice
// ---
// summary: Get a list of all commits from a repository and sort by time
// 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: query
// description: SHA or branch to start listing commits from (usually 'master')
// type: string
// - name: page
// in: query
// description: page number of results to return (1-based)
// type: integer
// - name: limit
// in: query
// description: page size of results
// type: integer
// responses:
// "200":
// "$ref": "#/responses/CommitList"
// "404":
// "$ref": "#/responses/notFound"
// "409":
// "$ref": "#/responses/EmptyRepository"
if ctx.Repo.Repository.IsEmpty {
ctx.JSON(http.StatusConflict, api.APIError{
Message: "Git Repository is empty.",
URL: setting.API.SwaggerURL,
})
return
}
gitRepo, err := git.OpenRepository(ctx.Repo.Repository.RepoPath())
if err != nil {
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
return
}
defer gitRepo.Close()
listOptions := utils.GetListOptions(ctx)
if listOptions.Page <= 0 {
listOptions.Page = 1
}
if listOptions.PageSize > setting.Git.CommitsRangeSize {
listOptions.PageSize = setting.Git.CommitsRangeSize
}
sha := ctx.Query("sha")
var baseCommit *git.Commit
if len(sha) == 0 {
// no sha supplied - use default branch
head, err := gitRepo.GetHEADBranch()
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetHEADBranch", err)
return
}
baseCommit, err = gitRepo.GetBranchCommit(head.Name)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
return
}
} else {
// get commit specified by sha
baseCommit, err = gitRepo.GetCommit(sha)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
return
}
}
// Total commit count
commitsCountTotal, err := baseCommit.CommitsCount()
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetCommitsCount", err)
return
}
pageCount := int(math.Ceil(float64(commitsCountTotal) / float64(listOptions.PageSize)))
// Query commits
commits, err := baseCommit.CommitsByRange(listOptions.Page, listOptions.PageSize)
if err != nil {
ctx.Error(http.StatusInternalServerError, "CommitsByRange", err)
return
}
userCache := make(map[string]*models.User)
apiCommits := make([]*api.Commit, commits.Len())
apiCommitsList := []api.Commit{}
i := 0
for commitPointer := commits.Front(); commitPointer != nil; commitPointer = commitPointer.Next() {
commit := commitPointer.Value.(*git.Commit)
// Create json struct
apiCommits[i], err = convert.ToCommit(ctx.Repo.Repository, commit, userCache)
if err != nil {
ctx.Error(http.StatusInternalServerError, "toCommit", err)
return
}
apiCommitsList = append(apiCommitsList, *apiCommits[i])
i++
}
// kept for backwards compatibility
ctx.Header().Set("X-Page", strconv.Itoa(listOptions.Page))
ctx.Header().Set("X-PerPage", strconv.Itoa(listOptions.PageSize))
ctx.Header().Set("X-Total", strconv.FormatInt(commitsCountTotal, 10))
ctx.Header().Set("X-PageCount", strconv.Itoa(pageCount))
ctx.Header().Set("X-HasMore", strconv.FormatBool(listOptions.Page < pageCount))
ctx.SetLinkHeader(int(commitsCountTotal), listOptions.PageSize)
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", commitsCountTotal))
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, X-PerPage, X-Total, X-PageCount, X-HasMore, Link")
ctx.JSON(http.StatusOK, CommitSplitSlice(apiCommitsList))
}
func CommitSplitSlice(CommitsList []api.Commit) []api.CommitsSlice {
// sort by time
sort.Sort(api.SortCommit(CommitsList))
Commits := make([]api.CommitsSlice, 0)
i := 0
var j int
for {
if i >= len(CommitsList) {
break
}
// Detect equal CommitData,
for j = i + 1; j < len(CommitsList) && CommitsList[i].CommitDate == CommitsList[j].CommitDate; j++ {
}
// if equal, put commitdata in an array
commitDate := CommitsList[i].CommitDate
commitDatalist := CommitsList[i:j]
i = j // variable value
// get all the values,,,Commits
Commits = append(Commits, api.CommitsSlice{
CommitDate: commitDate,
Commits: commitDatalist,
})
}
return Commits
}
// 获取某一个分支或标签的 commits 数量
func GetCommitsCount(ctx *context.APIContext) {
var err error
// ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
// if err != nil {
// ctx.ServerError("GetBranchCommit", err)
// return
// }
ctx.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount()
if err != nil {
ctx.ServerError("GetCommitsCount", err)
return
}
ctx.JSON(http.StatusOK, &ctx.Repo)
}
// GetFileAllCommits get all commits by path on a repository
func GetFileAllCommits(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/file_commits/{filepath} repository repoGetFileAllCommits
// ---
// summary: Get a list of all commits by filepath 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: filepath
// in: path
// description: filepath of the file to get
// type: string
// required: true
// - name: sha
// in: query
// description: SHA or branch to start listing commits from (usually 'master')
// type: string
// - name: page
// in: query
// description: page number of results to return (1-based)
// type: integer
// - name: limit
// in: query
// description: page size of results
// type: integer
// responses:
// "200":
// "$ref": "#/responses/FileCommitList"
// "404":
// "$ref": "#/responses/notFound"
// "409":
// "$ref": "#/responses/EmptyRepository"
if ctx.Repo.Repository.IsEmpty {
ctx.JSON(http.StatusConflict, api.APIError{
Message: "Git Repository is empty",
URL: setting.API.SwaggerURL,
})
return
}
gitRepo, err := git.OpenRepository(ctx.Repo.Repository.RepoPath())
if err != nil {
ctx.Error(http.StatusInternalServerError, "Get the GitRepo", err)
return
}
defer gitRepo.Close()
listOptions := utils.GetListOptions(ctx)
if listOptions.Page <= 0 {
listOptions.Page = 1
}
if listOptions.PageSize > setting.Git.CommitsRangeSize {
listOptions.PageSize = setting.Git.CommitsRangeSize
}
sha := ctx.Query("sha")
treePath := ctx.Params(":*")
var baseCommit *git.Commit
var commitsCountTotal int64
if len(sha) == 0 {
head, err := gitRepo.GetHEADBranch()
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetHeadBranch", err)
return
}
baseCommit, err = gitRepo.GetBranchCommit(head.Name)
if err != nil {
ctx.Error(http.StatusInternalServerError, "Getcommit ", err)
return
}
commitsCountTotal, err = git.CommitsCountFiles(gitRepo.Path, []string{head.Name}, []string{treePath}) // get th commmit count by file
if err != nil {
ctx.Error(http.StatusInternalServerError, "CommmisCountFiles", err)
return
}
} else {
baseCommit, err = gitRepo.GetCommit(sha)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
return
}
commitsCountTotal, err = git.CommitsCountFiles(gitRepo.Path, []string{sha}, []string{treePath})
if err != nil {
ctx.Error(http.StatusInternalServerError, "CommitsCountFiles", err)
return
}
}
pageCount := int(math.Ceil(float64(commitsCountTotal) / float64(listOptions.PageSize)))
commits, err := baseCommit.CommitsByFileAndRange(treePath, listOptions.Page, listOptions.PageSize)
if err != nil {
ctx.Error(http.StatusInternalServerError, "CommitByFileAndRange", err)
return
}
userCache := make(map[string]*models.User)
apiCommits := make([]*api.Commit, commits.Len())
i := 0
for commitPointer := commits.Front(); commitPointer != nil; commitPointer = commitPointer.Next() {
commit := commitPointer.Value.(*git.Commit)
// Create json struct
apiCommits[i], err = convert.ToCommit(ctx.Repo.Repository, commit, userCache)
if err != nil {
ctx.Error(http.StatusInternalServerError, "toCommit", err)
return
}
i++
}
// kept for backwards compatibility
ctx.Header().Set("X-Page", strconv.Itoa(listOptions.Page))
ctx.Header().Set("X-PerPage", strconv.Itoa(listOptions.PageSize))
ctx.Header().Set("X-Total", strconv.FormatInt(commitsCountTotal, 10))
ctx.Header().Set("X-PageCount", strconv.Itoa(pageCount))
ctx.Header().Set("X-HasMore", strconv.FormatBool(listOptions.Page < pageCount))
ctx.SetLinkHeader(int(commitsCountTotal), listOptions.PageSize)
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", commitsCountTotal))
ctx.JSON(http.StatusOK, apiCommits)
}

View File

@ -6,12 +6,16 @@
package repo
import (
"code.gitea.io/gitea/modules/setting"
"encoding/base64"
"fmt"
"net/http"
"net/url"
"strings"
"time"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/repofiles"
@ -286,7 +290,7 @@ func UpdateFile(ctx *context.APIContext) {
// consumes:
// - application/json
// produces:
// - application/json
// - application/jsoncontent
// parameters:
// - name: owner
// in: path
@ -553,7 +557,7 @@ func GetContents(ctx *context.APIContext) {
treePath := ctx.Params("*")
ref := ctx.QueryTrim("ref")
if fileList, err := repofiles.GetContentsOrList(ctx.Repo.Repository, treePath, ref); err != nil {
if fileList, err := repofiles.GetContentsOrList(ctx, ctx.Repo.Repository, treePath, ref); err != nil {
if git.IsErrNotExist(err) {
ctx.NotFound("GetContentsOrList", err)
return
@ -596,3 +600,262 @@ func GetContentsList(ctx *context.APIContext) {
// same as GetContents(), this function is here because swagger fails if path is empty in GetContents() interface
GetContents(ctx)
}
// GetReadmeContents Get the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir
func GetReadmeContents(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/readme repository repoGetReadmeContents
// ---
// summary: Gets the README.md's contents (if a file) of an entry in 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: ref
// in: query
// description: "The name of the commit/branch/tag. Default the repositorys default branch (usually master)"
// type: string
// required: false
// responses:
// "200":
// "$ref": "#/responses/ContentsResponse"
// "404":
// "$ref": "#/responses/notFound"
if !canReadFiles(ctx.Repo) {
ctx.Error(http.StatusInternalServerError, "GetContentsOrList", models.ErrUserDoesNotHaveAccessToRepo{
UserID: ctx.User.ID,
RepoName: ctx.Repo.Repository.LowerName,
})
return
}
// treePath := ctx.Params("*")
ref := ctx.QueryTrim("ref")
if fileList, err := repofiles.GetContentsOrList(ctx, ctx.Repo.Repository, "README.md", ref); err != nil {
if git.IsErrNotExist(err) {
ctx.NotFound("GetContentsOrList", err)
return
}
ctx.Error(http.StatusInternalServerError, "GetContentsOrList", err)
} else {
ctx.JSON(http.StatusOK, fileList)
}
}
func GetReadmeContentsByPath(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/readme/{dir} repository repoGetReadmeContentsByPath
// ---
// summary: Gets the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir ***
// 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: dir
// in: path
// description: path of the dir, file, symlink or submodule in the repo
// type: string
// required: true
// - name: ref
// in: query
// description: "The name of the commit/branch/tag. Default the repositorys default branch (usually master)"
// type: string
// required: false
// responses:
// "200":
// "$ref": "#/responses/ContentsResponse"
// "404":
// "$ref": "#/responses/notFound"
if !canReadFiles(ctx.Repo) {
ctx.Error(http.StatusInternalServerError, "GetContentsOrList", models.ErrUserDoesNotHaveAccessToRepo{
UserID: ctx.User.ID,
RepoName: ctx.Repo.Repository.LowerName,
})
return
}
treePath := ctx.Params("*")
ref := ctx.QueryTrim("ref")
newTreePath := treePath + "/" + "README.md"
if fileList, err := repofiles.GetContentsOrList(ctx, ctx.Repo.Repository, newTreePath, ref); err != nil {
if git.IsErrNotExist(err) {
ctx.NotFound("GetContentsOrList", err)
return
}
ctx.Error(http.StatusInternalServerError, "GetContentsOrList", err)
} else {
ctx.JSON(http.StatusOK, fileList)
}
}
func safeURL(address string) string {
u, err := url.Parse(address)
if err != nil {
return address
}
u.User = nil
return u.String()
}
const (
tplMigrating base.TplName = "repo/migrating"
tplRepoEMPTY base.TplName = "repo/empty"
)
func GetFileContents(ctx *context.APIContext) {
if len(ctx.Repo.Units) > 0 {
if ctx.Repo.Repository.IsBeingCreated() {
task, err := models.GetMigratingTask(ctx.Repo.Repository.ID)
if err != nil {
ctx.ServerError("models.GetMigratingTask", err)
return
}
cfg, err := task.MigrateConfig()
if err != nil {
ctx.ServerError("task.MigrateConfig", err)
return
}
ctx.Data["Repo"] = ctx.Repo
ctx.Data["MigrateTask"] = task
ctx.Data["CloneAddr"] = safeURL(cfg.CloneAddr)
ctx.HTML(200, tplMigrating)
return
}
var firstUnit *models.Unit
for _, repoUnit := range ctx.Repo.Units {
if repoUnit.Type == models.UnitTypeCode {
renderCode(ctx.Context)
fileContent := struct {
Content interface{}
}{
Content: ctx.Data["FileContent"],
}
ctx.JSON(http.StatusOK, fileContent)
return
}
unit, ok := models.Units[repoUnit.Type]
if ok && (firstUnit == nil || !firstUnit.IsLessThan(unit)) {
firstUnit = &unit
}
}
if firstUnit != nil {
ctx.Redirect(fmt.Sprintf("%s/%s%s", setting.AppSubURL, ctx.Repo.Repository.FullName(), firstUnit.URI))
return
}
}
ctx.NotFound("Home", fmt.Errorf(ctx.Tr("units.error.no_unit_allowed_repo")))
}
func renderCode(ctx *context.Context) {
ctx.Data["PageIsViewCode"] = true
if ctx.Repo.Repository.IsEmpty {
ctx.HTML(200, tplRepoEMPTY)
return
}
title := ctx.Repo.Repository.Owner.Name + "/" + ctx.Repo.Repository.Name
if len(ctx.Repo.Repository.Description) > 0 {
title += ": " + ctx.Repo.Repository.Description
}
ctx.Data["Title"] = title
branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
treeLink := branchLink
// rawLink := ctx.Repo.RepoLink + "/raw/" + ctx.Repo.BranchNameSubURL()
if len(ctx.Repo.TreePath) > 0 {
treeLink += "/" + ctx.Repo.TreePath
}
// Get Topics of this repo
renderRepoTopics(ctx)
if ctx.Written() {
return
}
// Get current entry user currently looking at.
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
if err != nil {
return
}
renderLanguageStats(ctx)
if ctx.Written() {
return
}
if entry.IsDir() {
// renderDirectory(ctx, treeLink)
} else {
// renderFile(ctx, entry, treeLink, rawLink)
}
if ctx.Written() {
return
}
var treeNames []string
paths := make([]string, 0, 5)
if len(ctx.Repo.TreePath) > 0 {
treeNames = strings.Split(ctx.Repo.TreePath, "/")
for i := range treeNames {
paths = append(paths, strings.Join(treeNames[:i+1], "/"))
}
ctx.Data["HasParentPath"] = true
if len(paths)-2 >= 0 {
ctx.Data["ParentPath"] = "/" + paths[len(paths)-2]
}
}
ctx.Data["Paths"] = paths
ctx.Data["TreeLink"] = treeLink
ctx.Data["TreeNames"] = treeNames
ctx.Data["BranchLink"] = branchLink
// ctx.HTML(200, tplRepoHome)
}
func renderRepoTopics(ctx *context.Context) {
topics, err := models.FindTopics(&models.FindTopicOptions{
RepoID: ctx.Repo.Repository.ID,
})
if err != nil {
ctx.ServerError("models.FindTopics", err)
return
}
ctx.Data["Topics"] = topics
}
func renderLanguageStats(ctx *context.Context) {
langs, err := ctx.Repo.Repository.GetTopLanguageStats(5)
if err != nil {
ctx.ServerError("Repo.GetTopLanguageStats", err)
return
}
ctx.Data["LanguageStats"] = langs
}

View File

@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/webhook"
// "code.gitea.io/gitea/"
)
// ListHooks list all hooks of a repository
@ -269,3 +270,57 @@ func DeleteHook(ctx *context.APIContext) {
}
ctx.Status(http.StatusNoContent)
}
func ListHookTask(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/hooks/{id}/hooktasks repository repoGetHookTasks
// ---
// summary: Get a hooktasks ***
// 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: id
// in: path
// description: id of the hook
// type: integer
// format: int64
// required: true
// - name: page
// in: query
// description: page number of results to return (1-based)
// type: integer
// - name: limit
// in: query
// description: page size of results
// type: integer
// responses:
// "200":
// "$ref": "#/responses/HookTaskList"
hook, err := utils.GetRepoHook(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
if err != nil {
ctx.NotFound()
return
}
hookTasks, err := models.GetHookTasksByRepoIDAndHookID(ctx.Repo.Repository.ID, hook.ID, utils.GetListOptions(ctx))
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetHookTasksByRepoIDAndHookID", err)
return
}
apiHookTasks := make([]*api.HookTask, len(hookTasks))
for i := range hookTasks {
apiHookTasks[i] = convert.ToHookTask(hookTasks[i])
}
ctx.JSON(http.StatusOK, &apiHookTasks)
}

View File

@ -5,6 +5,7 @@
package repo
import (
"container/list"
"errors"
"fmt"
"math"
@ -19,11 +20,15 @@ import (
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/forms"
"code.gitea.io/gitea/services/gitdiff"
pull_prepare "code.gitea.io/gitea/routers/web/repo"
issue_service "code.gitea.io/gitea/services/issue"
pull_service "code.gitea.io/gitea/services/pull"
repo_service "code.gitea.io/gitea/services/repository"
@ -128,7 +133,7 @@ func ListPullRequests(ctx *context.APIContext) {
func GetPullRequest(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/pulls/{index} repository repoGetPullRequest
// ---
// summary: Get a pull request
// summary: Get a pull request ***
// produces:
// - application/json
// parameters:
@ -172,6 +177,68 @@ func GetPullRequest(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadHeadRepo", err)
return
}
// issue := checkPullInfo(ctx.Context)
issue := pr.Issue
if issue == nil {
ctx.NotFound()
return
}
if ctx.Written() {
return
}
pull := issue.PullRequest
// get pull commits nums
var commits *list.List
var prInfo *git.CompareInfo
if pull.HasMerged {
prInfo = pull_prepare.PrepareMergedViewPullInfo(ctx.Context, issue)
} else {
prInfo = pull_prepare.PrepareViewPullInfo(ctx.Context, issue)
}
if ctx.Written() {
return
} else if prInfo == nil {
ctx.NotFound("ViewPullCommits", nil)
return
}
var commitNum int
commits = prInfo.Commits
commits = models.ValidateCommitsWithEmails(commits)
commits = models.ParseCommitsWithSignature(commits, ctx.Repo.Repository)
commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)
commitNum = commits.Len()
//get pull changedfils
var (
// diffRepoPath string
startCommitID string
endCommitID string
gitRepo = ctx.Repo.GitRepo
)
gitRepo = ctx.Repo.GitRepo
headCommitId, err := gitRepo.GetRefCommitID(pull.GetGitRefName())
if err != nil {
ctx.ServerError("GetRefCommitID", err)
return
}
startCommitID = prInfo.MergeBase
endCommitID = headCommitId
ctx.Data["WhitespaceBehavior"] = ""
diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(gitRepo,
startCommitID, endCommitID, setting.Git.MaxGitDiffLines,
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles,
gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)))
if err != nil {
ctx.ServerError("GetDiffRangeWithWhitespaceBehavior", err)
return
}
var changedFiles int
changedFiles = diff.NumFiles
pr.CommitNum = commitNum
pr.ChangedFiles = changedFiles
ctx.JSON(http.StatusOK, convert.ToAPIPullRequest(pr, ctx.User))
}
@ -1264,3 +1331,194 @@ func GetPullRequestCommits(ctx *context.APIContext) {
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, X-PerPage, X-Total, X-PageCount, X-HasMore, Link")
ctx.JSON(http.StatusOK, &apiCommits)
}
type PullRequestCommit struct {
models.SignCommitWithStatuses
Sha string
}
func GetPullCommits(ctx *context.APIContext) {
issue := checkPullInfo(ctx.Context)
if issue == nil {
ctx.NotFound()
return
}
if ctx.Written() {
return
}
pull := issue.PullRequest
var commits *list.List
var prInfo *git.CompareInfo
if pull.HasMerged {
prInfo = pull_prepare.PrepareMergedViewPullInfo(ctx.Context, issue)
} else {
prInfo = pull_prepare.PrepareViewPullInfo(ctx.Context, issue)
}
if ctx.Written() {
return
} else if prInfo == nil {
ctx.NotFound("ViewPullCommits", nil)
return
}
ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
commits = prInfo.Commits
commits = models.ValidateCommitsWithEmails(commits)
commits = models.ParseCommitsWithSignature(commits, ctx.Repo.Repository)
commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)
result := make([]PullRequestCommit, 0)
// result := make([]models.SignCommitWithStatuses, 0)
for commit := commits.Front(); commit != nil; commit = commit.Next() {
temp := commit.Value.(models.SignCommitWithStatuses)
pullRequestCommit := PullRequestCommit{
temp,
temp.ID.String(),
}
result = append(result, pullRequestCommit)
}
ctx.JSON(200, result)
}
func GetPullFiles(ctx *context.APIContext) {
pr, err := models.GetPullRequestByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
issue := pr.Issue
// issue := checkPullInfo(ctx.Context)
log.Info("issue %s", issue)
if issue == nil {
ctx.NotFound("checkPullInfo", nil)
return
}
if ctx.Written() {
return
}
pull := issue.PullRequest
var (
// diffRepoPath
startCommitID string
endCommitID string
gitRepo *git.Repository
)
var prInfo *git.CompareInfo
if pull.HasMerged {
prInfo = pull_prepare.PrepareMergedViewPullInfo(ctx.Context, issue)
} else {
prInfo = pull_prepare.PrepareViewPullInfo(ctx.Context, issue)
}
if ctx.Written() {
return
} else if prInfo == nil {
ctx.NotFound("ViewPullFiles", nil)
return
}
// diffRepoPath = ctx.Repo.GitRepo.Path
gitRepo = ctx.Repo.GitRepo
headCommitID, err := gitRepo.GetRefCommitID(pull.GetGitRefName())
if err != nil {
ctx.ServerError("GetRefCommitID", err)
return
}
// diffRepoPath = ctx.Repo.GitRepo.Path
startCommitID = prInfo.MergeBase
endCommitID = headCommitID
ctx.Data["WhitespaceBehavior"] = ""
diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(gitRepo,
startCommitID, endCommitID, setting.Git.MaxGitDiffLines,
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles,
gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)))
if err != nil {
ctx.ServerError("GetDiffRangeWithWhitespaceBehavior", err)
return
}
if err = diff.LoadComments(issue, ctx.User); err != nil {
ctx.ServerError("LoadComments", err)
return
}
fileDiff := struct {
*gitdiff.Diff
LatestSha string
}{
Diff: diff,
LatestSha: endCommitID,
}
ctx.JSON(200, fileDiff)
}
func checkPullInfo(ctx *context.Context) *models.Issue {
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
if err != nil {
// if models.IsErrIssueNotExist(err) {
// ctx.NotFound("GetIssueByIndex", err)
// } else {
// ctx.ServerError("GetIssueByIndex", err)
// }
return nil
}
if err = issue.LoadPoster(); err != nil {
// ctx.ServerError("LoadPoster", err)
return nil
}
if err := issue.LoadRepo(); err != nil {
// ctx.ServerError("LoadRepo", err)
return nil
}
ctx.Data["Title"] = fmt.Sprintf("#%d - %s", issue.Index, issue.Title)
ctx.Data["Issue"] = issue
if !issue.IsPull {
// ctx.NotFound("ViewPullCommits", nil)
return nil
}
if err = issue.LoadPullRequest(); err != nil {
// ctx.ServerError("LoadPullRequest", err)
return nil
}
if err = issue.PullRequest.LoadHeadRepo(); err != nil {
// ctx.ServerError("LoadHeadRepo", err)
return nil
}
if ctx.IsSigned {
// Update issue-user.
if err = issue.ReadBy(ctx.User.ID); err != nil {
// ctx.ServerError("ReadBy", err)
return nil
}
}
return issue
}
func GetPullIssues(ctx *context.APIContext) {
issue := checkPullInfo(ctx.Context)
if issue == nil {
ctx.NotFound()
return
}
if ctx.Written() {
return
}
dependencies, err := issue.BlockingDependencies()
if err != nil {
ctx.ServerError("BlockingDependencies", err)
return
}
ctx.JSON(200, dependencies)
}

View File

@ -22,6 +22,7 @@ import (
"code.gitea.io/gitea/modules/validation"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/gitdiff"
repo_service "code.gitea.io/gitea/services/repository"
)
@ -1050,3 +1051,533 @@ func GetIssueTemplates(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, ctx.IssueTemplatesFromDefaultBranch())
}
// MustBeNotEmpty render when a repo is a empty git dir
func MustBeNotEmpty(ctx *context.Context) {
if ctx.Repo.Repository.IsEmpty {
ctx.NotFound("MustBeNotEmpty", nil)
}
}
//SetEditorConfigIfExists set editor config as render variable
func SetEditorconfigIfExists(ctx *context.Context) {
if ctx.Repo.Repository.IsEmpty {
ctx.Data["Edidorconfig"] = nil
return
}
ec, err := ctx.Repo.GetEditorconfig()
if err != nil && !git.IsErrNotExist(err) {
description := fmt.Sprintf("Error while getting .Editconfig file: %v", err)
if err := models.CreateRepositoryNotice(description); err != nil {
ctx.ServerError("CreateRepositoryNotice", err)
}
return
}
ctx.Data["Editorconfig"] = ec
}
// SetdiffViewStyle set diff style as render variable
func SetDiffViewStyle(ctx *context.Context) {
queryStyle := ctx.Query("style")
if !ctx.IsSigned {
ctx.Data["IsSplitStyle"] = queryStyle == "split"
return
}
var (
userStyle = ctx.User.DiffViewStyle
style string
)
if queryStyle == "unified" || queryStyle == "split" {
style = queryStyle
} else if userStyle == "unified" || userStyle == "split" {
style = userStyle
} else {
style = "unified"
}
ctx.Data["IsSplitStyle"] = style == "split"
if err := ctx.User.UpdateDiffViewStyle(style); err != nil {
ctx.ServerError("ErrUpdateDiffViewStyle", err)
}
}
// PrepareCompareDiff renders compare diff page
func PrepareCompareDiff(
ctx *context.Context,
headUser *models.User,
headRepo *models.Repository,
headGitRepo *git.Repository,
compareInfo *git.CompareInfo,
baseBranch, headBranch string) bool {
var (
err error
)
// Get diff information.
ctx.Data["CommitRepoLink"] = headRepo.Link()
headCommitID := headBranch
if ctx.Data["HeadIsCommit"] == false {
if ctx.Data["HeadIsTag"] == true {
headCommitID, err = headGitRepo.GetTagCommitID(headBranch)
} else {
headCommitID, err = headGitRepo.GetBranchCommitID(headBranch)
}
if err != nil {
ctx.ServerError("GetRefCommitID", err)
return false
}
}
ctx.Data["AfterCommitID"] = headCommitID
if headCommitID == compareInfo.MergeBase {
ctx.Data["IsNothingToCompare"] = true
return true
}
repoPath := models.RepoPath(headUser.Name, headRepo.Name)
// gitRepo, _ := git.OpenRepository(repoPath)
gitRepo, _ := git.OpenRepository(repoPath)
diff, err := gitdiff.GetDiffRange(gitRepo,
compareInfo.MergeBase, headCommitID, setting.Git.MaxGitDiffLines,
setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles)
if err != nil {
ctx.ServerError("GetDiffRange", err)
return false
}
if diff.NumFiles == 0 {
ctx.Data["Diff"] = nil
ctx.Data["DiffNotAvailable"] = true
} else {
ctx.Data["Diff"] = diff
ctx.Data["DiffNotAvailable"] = false
}
return false
}
type CompareCommit struct {
*git.Commit
Sha string
ParentShas []string
}
func CompareDiff(ctx *context.APIContext) {
headUser, headRepo, headGitRepo, compareInfo, baseBranch, headBranch := ParseCompareInfo(ctx.Context)
if ctx.Written() {
return
}
defer headGitRepo.Close()
_ = PrepareCompareDiff(ctx.Context, headUser, headRepo, headGitRepo, compareInfo, baseBranch, headBranch)
if ctx.Written() {
return
}
result := make([]CompareCommit, 0)
for commit := compareInfo.Commits.Front(); commit != nil; commit = commit.Next() {
temp := commit.Value.(*git.Commit)
compareCommit := CompareCommit{
temp,
temp.ID.String(),
make([]string, 0),
}
for i := 0; i < len(temp.Parents); i++ {
compareCommit.ParentShas = append(compareCommit.ParentShas, temp.Parents[i].String())
}
result = append(result, compareCommit)
}
different := struct {
Commits []CompareCommit
Diff interface{}
LatestSha string
}{
Commits: result,
Diff: ctx.Context.Data["Diff"],
}
if len(different.Commits) != 0 {
different.LatestSha = different.Commits[0].Sha
}
ctx.JSON(200, different)
}
// ParseCompareInfo parse compare info between two commit for preparing comparing references
func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *git.Repository, *git.CompareInfo, string, string) {
baseRepo := ctx.Repo.Repository
// Get compared branches information
// A full compare url is of the form:
//
// 1. /{:baseOwner}/{:baseRepoName}/compare/{:baseBranch}...{:headBranch}
// 2. /{:baseOwner}/{:baseRepoName}/compare/{:baseBranch}...{:headOwner}:{:headBranch}
// 3. /{:baseOwner}/{:baseRepoName}/compare/{:baseBranch}...{:headOwner}/{:headRepoName}:{:headBranch}
//
// Here we obtain the infoPath "{:baseBranch}...[{:headOwner}/{:headRepoName}:]{:headBranch}" as ctx.Params("*")
// with the :baseRepo in ctx.Repo.
//
// Note: Generally :headRepoName is not provided here - we are only passed :headOwner.
//
// How do we determine the :headRepo?
//
// 1. If :headOwner is not set then the :headRepo = :baseRepo
// 2. If :headOwner is set - then look for the fork of :baseRepo owned by :headOwner
// 3. But... :baseRepo could be a fork of :headOwner's repo - so check that
// 4. Now, :baseRepo and :headRepos could be forks of the same repo - so check that
//
// format: <base branch>...[<head repo>:]<head branch>
// base<-head: master...head:feature
// same repo: master...feature
var (
headUser *models.User
headRepo *models.Repository
headBranch string
isSameRepo bool
infoPath string
err error
)
infoPath = ctx.Params("*")
infos := strings.SplitN(infoPath, "...", 2)
if len(infos) != 2 {
log.Trace("ParseCompareInfo[%d]: not enough compared branches information %s", baseRepo.ID, infos)
ctx.NotFound("CompareAndPullRequest", nil)
return nil, nil, nil, nil, "", ""
}
ctx.Data["BaseName"] = baseRepo.OwnerName
baseBranch := infos[0]
ctx.Data["BaseBranch"] = baseBranch
// If there is no head repository, it means compare between same repository.
headInfos := strings.Split(infos[1], ":")
if len(headInfos) == 1 {
isSameRepo = true
headUser = ctx.Repo.Owner
headBranch = headInfos[0]
} else if len(headInfos) == 2 {
headInfosSplit := strings.Split(headInfos[0], "/")
if len(headInfosSplit) == 1 {
headUser, err = models.GetUserByName(headInfos[0])
if err != nil {
if models.IsErrUserNotExist(err) {
ctx.NotFound("GetUserByName", nil)
} else {
ctx.ServerError("GetUserByName", err)
}
return nil, nil, nil, nil, "", ""
}
headBranch = headInfos[1]
isSameRepo = headUser.ID == ctx.Repo.Owner.ID
if isSameRepo {
headRepo = baseRepo
}
} else {
headRepo, err = models.GetRepositoryByOwnerAndName(headInfosSplit[0], headInfosSplit[1])
if err != nil {
if models.IsErrRepoNotExist(err) {
ctx.NotFound("GetRepositoryByOwnerAndName", nil)
} else {
ctx.ServerError("GetRepositoryByOwnerAndName", err)
}
return nil, nil, nil, nil, "", ""
}
if err := headRepo.GetOwner(); err != nil {
if models.IsErrUserNotExist(err) {
ctx.NotFound("GetUserByName", nil)
} else {
ctx.ServerError("GetUserByName", err)
}
return nil, nil, nil, nil, "", ""
}
headBranch = headInfos[1]
headUser = headRepo.Owner
isSameRepo = headRepo.ID == ctx.Repo.Repository.ID
}
} else {
ctx.NotFound("CompareAndPullRequest", nil)
return nil, nil, nil, nil, "", ""
}
ctx.Data["HeadUser"] = headUser
ctx.Data["HeadBranch"] = headBranch
ctx.Repo.PullRequest.SameRepo = isSameRepo
if ctx.Repo.GitRepo == nil && !baseRepo.IsEmpty {
var err error
ctx.Repo.GitRepo, err = git.OpenRepository(ctx.Repo.Repository.RepoPath())
if err != nil {
ctx.Error(http.StatusInternalServerError, "Unable to OpenRepository", err.Error())
return nil, nil, nil, nil, "", ""
}
defer ctx.Repo.GitRepo.Close()
}
// Check if base branch is valid.
baseIsCommit := ctx.Repo.GitRepo.IsCommitExist(baseBranch)
baseIsBranch := ctx.Repo.GitRepo.IsBranchExist(baseBranch)
baseIsTag := ctx.Repo.GitRepo.IsTagExist(baseBranch)
if !baseIsCommit && !baseIsBranch && !baseIsTag {
// Check if baseBranch is short sha commit hash
if baseCommit, _ := ctx.Repo.GitRepo.GetCommit(baseBranch); baseCommit != nil {
baseBranch = baseCommit.ID.String()
ctx.Data["BaseBranch"] = baseBranch
baseIsCommit = true
} else {
ctx.NotFound("IsRefExist", nil)
return nil, nil, nil, nil, "", ""
}
}
ctx.Data["BaseIsCommit"] = baseIsCommit
ctx.Data["BaseIsBranch"] = baseIsBranch
ctx.Data["BaseIsTag"] = baseIsTag
// Now we have the repository that represents the base
// The current base and head repositories and branches may not
// actually be the intended branches that the user wants to
// create a pull-request from - but also determining the head
// repo is difficult.
// We will want therefore to offer a few repositories to set as
// our base and head
// 1. First if the baseRepo is a fork get the "RootRepo" it was
// forked from
var rootRepo *models.Repository
if baseRepo.IsFork {
err = baseRepo.GetBaseRepo()
if err != nil {
if !models.IsErrRepoNotExist(err) {
ctx.ServerError("Unable to find root repo", err)
return nil, nil, nil, nil, "", ""
}
} else {
rootRepo = baseRepo.BaseRepo
}
}
// 2. Now if the current user is not the owner of the baseRepo,
// check if they have a fork of the base repo and offer that as
// "OwnForkRepo"
var ownForkRepo *models.Repository
if ctx.User != nil && baseRepo.OwnerID != ctx.User.ID {
repo, has := models.HasForkedRepo(ctx.User.ID, baseRepo.ID)
if has {
ownForkRepo = repo
ctx.Data["OwnForkRepo"] = ownForkRepo
}
}
has := headRepo != nil
// 3. If the base is a forked from "RootRepo" and the owner of
// the "RootRepo" is the :headUser - set headRepo to that
if !has && rootRepo != nil && rootRepo.OwnerID == headUser.ID {
headRepo = rootRepo
has = true
}
// 4. If the ctx.User has their own fork of the baseRepo and the headUser is the ctx.User
// set the headRepo to the ownFork
if !has && ownForkRepo != nil && ownForkRepo.OwnerID == headUser.ID {
headRepo = ownForkRepo
has = true
}
// 5. If the headOwner has a fork of the baseRepo - use that
if !has {
headRepo, has = models.HasForkedRepo(headUser.ID, baseRepo.ID)
}
// 6. If the baseRepo is a fork and the headUser has a fork of that use that
if !has && baseRepo.IsFork {
headRepo, has = models.HasForkedRepo(headUser.ID, baseRepo.ForkID)
}
// 7. Otherwise if we're not the same repo and haven't found a repo give up
if !isSameRepo && !has {
ctx.Data["PageIsComparePull"] = false
}
// 8. Finally open the git repo
var headGitRepo *git.Repository
if isSameRepo {
headRepo = ctx.Repo.Repository
headGitRepo = ctx.Repo.GitRepo
} else if has {
headGitRepo, err = git.OpenRepository(headRepo.RepoPath())
if err != nil {
ctx.ServerError("OpenRepository", err)
return nil, nil, nil, nil, "", ""
}
defer headGitRepo.Close()
}
ctx.Data["HeadRepo"] = headRepo
// Now we need to assert that the ctx.User has permission to read
// the baseRepo's code and pulls
// (NOT headRepo's)
permBase, err := models.GetUserRepoPermission(baseRepo, ctx.User)
if err != nil {
ctx.ServerError("GetUserRepoPermission", err)
return nil, nil, nil, nil, "", ""
}
if !permBase.CanRead(models.UnitTypeCode) {
if log.IsTrace() {
log.Trace("Permission Denied: User: %-v cannot read code in Repo: %-v\nUser in baseRepo has Permissions: %-+v",
ctx.User,
baseRepo,
permBase)
}
ctx.NotFound("ParseCompareInfo", nil)
return nil, nil, nil, nil, "", ""
}
// If we're not merging from the same repo:
if !isSameRepo {
// Assert ctx.User has permission to read headRepo's codes
permHead, err := models.GetUserRepoPermission(headRepo, ctx.User)
if err != nil {
ctx.ServerError("GetUserRepoPermission", err)
return nil, nil, nil, nil, "", ""
}
if !permHead.CanRead(models.UnitTypeCode) {
if log.IsTrace() {
log.Trace("Permission Denied: User: %-v cannot read code in Repo: %-v\nUser in headRepo has Permissions: %-+v",
ctx.User,
headRepo,
permHead)
}
ctx.NotFound("ParseCompareInfo", nil)
return nil, nil, nil, nil, "", ""
}
}
// If we have a rootRepo and it's different from:
// 1. the computed base
// 2. the computed head
// then get the branches of it
if rootRepo != nil &&
rootRepo.ID != headRepo.ID &&
rootRepo.ID != baseRepo.ID {
perm, branches, err := getBranchesForRepo(ctx.User, rootRepo)
if err != nil {
ctx.ServerError("GetBranchesForRepo", err)
return nil, nil, nil, nil, "", ""
}
if perm {
ctx.Data["RootRepo"] = rootRepo
ctx.Data["RootRepoBranches"] = branches
}
}
// If we have a ownForkRepo and it's different from:
// 1. The computed base
// 2. The computed hea
// 3. The rootRepo (if we have one)
// then get the branches from it.
if ownForkRepo != nil &&
ownForkRepo.ID != headRepo.ID &&
ownForkRepo.ID != baseRepo.ID &&
(rootRepo == nil || ownForkRepo.ID != rootRepo.ID) {
perm, branches, err := getBranchesForRepo(ctx.User, ownForkRepo)
if err != nil {
ctx.ServerError("GetBranchesForRepo", err)
return nil, nil, nil, nil, "", ""
}
if perm {
ctx.Data["OwnForkRepo"] = ownForkRepo
ctx.Data["OwnForkRepoBranches"] = branches
}
}
// Check if head branch is valid.
headIsCommit := headGitRepo.IsCommitExist(headBranch)
headIsBranch := headGitRepo.IsBranchExist(headBranch)
headIsTag := headGitRepo.IsTagExist(headBranch)
if !headIsCommit && !headIsBranch && !headIsTag {
// Check if headBranch is short sha commit hash
if headCommit, _ := headGitRepo.GetCommit(headBranch); headCommit != nil {
headBranch = headCommit.ID.String()
ctx.Data["HeadBranch"] = headBranch
headIsCommit = true
} else {
ctx.NotFound("IsRefExist", nil)
return nil, nil, nil, nil, "", ""
}
}
ctx.Data["HeadIsCommit"] = headIsCommit
ctx.Data["HeadIsBranch"] = headIsBranch
ctx.Data["HeadIsTag"] = headIsTag
// Treat as pull request if both references are branches
if ctx.Data["PageIsComparePull"] == nil {
ctx.Data["PageIsComparePull"] = headIsBranch && baseIsBranch
}
if ctx.Data["PageIsComparePull"] == true && !permBase.CanReadIssuesOrPulls(true) {
if log.IsTrace() {
log.Trace("Permission Denied: User: %-v cannot create/read pull requests in Repo: %-v\nUser in baseRepo has Permissions: %-+v",
ctx.User,
baseRepo,
permBase)
}
ctx.NotFound("ParseCompareInfo", nil)
return nil, nil, nil, nil, "", ""
}
baseBranchRef := baseBranch
if baseIsBranch {
baseBranchRef = git.BranchPrefix + baseBranch
} else if baseIsTag {
baseBranchRef = git.TagPrefix + baseBranch
}
headBranchRef := headBranch
if headIsBranch {
headBranchRef = git.BranchPrefix + headBranch
} else if headIsTag {
headBranchRef = git.TagPrefix + headBranch
}
compareInfo, err := headGitRepo.GetCompareInfo(baseRepo.RepoPath(), baseBranchRef, headBranchRef)
if err != nil {
ctx.ServerError("GetCompareInfo", err)
return nil, nil, nil, nil, "", ""
}
ctx.Data["BeforeCommitID"] = compareInfo.MergeBase
return headUser, headRepo, headGitRepo, compareInfo, baseBranch, headBranch
}
func getBranchesForRepo(user *models.User, repo *models.Repository) (bool, []string, error) {
perm, err := models.GetUserRepoPermission(repo, user)
if err != nil {
return false, nil, err
}
if !perm.CanRead(models.UnitTypeCode) {
return false, nil, nil
}
gitRepo, err := git.OpenRepository(repo.RepoPath())
if err != nil {
return false, nil, err
}
defer gitRepo.Close()
branches, _, err := gitRepo.GetBranches(0, 0)
if err != nil {
return false, nil, err
}
return true, branches, nil
}
// end by qiubing

View File

@ -7,11 +7,14 @@ package repo
import (
"errors"
"fmt"
"math"
"net/http"
"strconv"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert"
repo_module "code.gitea.io/gitea/modules/repository"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils"
@ -61,6 +64,21 @@ func ListTags(ctx *context.APIContext) {
apiTags[i] = convert.ToTag(ctx.Repo.Repository, tags[i])
}
tagsCountTotal, err := ctx.Repo.GitRepo.GetTagCount()
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetTagCount", err)
return
}
pageCount := int(math.Ceil(float64(tagsCountTotal) / float64(listOpts.PageSize)))
ctx.Header().Set("X-Page", strconv.Itoa(listOpts.Page))
ctx.Header().Set("X-PerPage", strconv.Itoa(listOpts.PageSize))
ctx.Header().Set("X-Total", strconv.FormatInt(tagsCountTotal, 10))
ctx.Header().Set("X-PageCount", strconv.Itoa(pageCount))
ctx.Header().Set("X-HasMore", strconv.FormatBool(listOpts.Page < pageCount))
ctx.SetLinkHeader(int(tagsCountTotal), listOpts.PageSize)
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", tagsCountTotal))
ctx.JSON(http.StatusOK, &apiTags)
}
@ -260,3 +278,42 @@ func DeleteTag(ctx *context.APIContext) {
ctx.Status(http.StatusNoContent)
}
func BranchTagCount(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/branch_tag_count repository repoBranchTagCount
// ---
// summary: List a repository's tags***
// 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
// responses:
// "200":
// "$ref": "#/responses/RepoBranchAndTagCount"
tags, err := ctx.Repo.GitRepo.GetTagInfos(0, 0) // tags info
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetTags", err)
return
}
repo := ctx.Repo.Repository
_, countAll, err := repo_module.GetBranches(repo, -1, -1) //get count of the branch
if err != nil {
ctx.ServerError("GetBranches", err)
return
}
result := api.RepoBranchAndTagCount{
BranchCount: countAll,
TagCount: len(tags),
}
ctx.JSON(http.StatusOK, result)
}

475
routers/api/v1/repo/wiki.go Normal file
View File

@ -0,0 +1,475 @@
package repo
import (
"bytes"
"net/http"
"sort"
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web"
webWiki "code.gitea.io/gitea/routers/web/repo"
wiki_service "code.gitea.io/gitea/services/wiki"
)
func ListWikiPages(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/wikies repository repoWikiList
// ---
// summary: List the wikies in 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
// responses:
// "200":
// "$ref": "#/responses/WikiList"
if !ctx.Repo.Repository.HasWiki() {
return
}
wikiCloneWiki := ctx.Repo.Repository.WikiCloneLink()
wikiRepo, commit, err := webWiki.FindWikiRepoCommit(ctx.Context)
if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
return
}
defer func() {
if wikiRepo != nil {
wikiRepo.Close()
}
}()
entries, err := commit.ListEntries()
if err != nil {
ctx.ServerError("entries", err)
return
}
pages := make([]api.WikiesResponse, 0, len(entries))
for _, entry := range entries {
if !entry.IsRegular() {
continue
}
lastCommit, firstCommit, _ := wikiRepo.GetFirstAndLastCommitByPath("master", entry.Name())
if err != nil {
ctx.ServerError("GetCommitByPath", err)
return
}
wikiName, err := wiki_service.FilenameToName(entry.Name())
if err != nil {
if models.IsErrWikiInvalidFileName(err) {
continue
}
ctx.ServerError("FilenameToName", err)
return
}
pages = append(pages, api.WikiesResponse{
WikiCloneLink: api.CloneLink{
HTTPS: wikiCloneWiki.HTTPS,
SSH: wikiCloneWiki.SSH,
},
WikiMeta: api.WikiMeta{
Name: wikiName,
Commit: api.WikiCommit{
Author: api.WikiUser{
Name: lastCommit.Author.Name,
Email: lastCommit.Author.Email,
When: lastCommit.Author.When.Unix(),
},
Commiter: api.WikiUser{
Name: lastCommit.Committer.Name,
Email: lastCommit.Committer.Email,
When: lastCommit.Author.When.Unix(),
},
ID: lastCommit.ID.String(),
Message: lastCommit.Message(),
},
FirstCommit: api.WikiCommit{
Author: api.WikiUser{
Name: firstCommit.Author.Name,
Email: firstCommit.Author.Email,
When: firstCommit.Author.When.Unix(),
},
Commiter: api.WikiUser{
Name: firstCommit.Committer.Name,
Email: firstCommit.Committer.Email,
When: firstCommit.Author.When.Unix(),
},
ID: firstCommit.ID.String(),
Message: firstCommit.Message(),
},
},
})
}
//sort by time
sort.Slice(pages, func(i, j int) bool {
return pages[i].FirstCommit.Author.When > pages[j].FirstCommit.Author.When
})
ctx.JSON(http.StatusOK, pages)
}
func CreateWiki(ctx *context.APIContext) {
// swagger:operation POST /repos/{owner}/{repo}/wikies repository repoCreateWiki
// ---
// summary: Create a wiki in 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: body
// in: body
// schema:
// "$ref": "#/definitions/WikiOption"
// responses:
// "200":
// "$ref": "#/responses/Wiki"
form := web.GetForm(ctx).(*api.WikiOption)
err := wiki_service.CheckFile(form.Name)
if err != nil {
ctx.FileNameError()
return
}
wikiName := wiki_service.NormalizeWikiName(form.Name)
wikiCloneLink := ctx.Repo.Repository.WikiCloneLink()
if err := wiki_service.AddWikiPage(ctx.User, ctx.Repo.Repository, wikiName, form.Content, form.CommitMessage); err != nil {
if models.IsErrWikiReservedName(err) {
ctx.Error(http.StatusInternalServerError, "WikiNameIsReservedPage", "wiki名称是被保留的.")
} else if models.IsErrWikiAlreadyExist(err) {
ctx.Error(http.StatusConflict, "WikiNameAlreadyExist", "wiki名称已存在")
} else {
ctx.Error(http.StatusInternalServerError, "AddWikiPage", err)
}
return
}
wikiRepo, commit, _ := webWiki.FindWikiRepoCommit(ctx.Context)
data, entry, pageFilename, _ := webWiki.WikiContentsByName(ctx.Context, commit, form.Name)
metas := ctx.Repo.Repository.ComposeDocumentMetas()
var rctx = &markup.RenderContext{
URLPrefix: ctx.Repo.RepoLink,
Metas: metas,
IsWiki: true,
}
var buf strings.Builder
if err := markdown.Render(rctx, bytes.NewReader(data), &buf); err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
ctx.ServerError("Render", err)
return
}
commitsCount, _ := wikiRepo.FileCommitsCount("master", pageFilename)
c, err := wikiRepo.GetCommitByPath(entry.Name())
if err != nil {
if models.IsErrWikiInvalidFileName(err) {
return
}
}
wiki := api.WikiResponse{
WikiCloneLink: api.CloneLink{
HTTPS: wikiCloneLink.HTTPS,
SSH: wikiCloneLink.SSH,
},
WikiMeta: api.WikiMeta{
Name: form.Name,
Commit: api.WikiCommit{
Author: api.WikiUser{
Name: c.Author.Name,
Email: c.Author.Email,
When: c.Author.When.Unix(),
},
Commiter: api.WikiUser{
Name: c.Committer.Name,
Email: c.Committer.Email,
When: c.Author.When.Unix(),
},
ID: c.ID.String(),
Message: c.Message(),
},
},
CommitCounts: commitsCount,
MdContent: string(data),
SimpleContent: buf.String(),
}
ctx.JSON(http.StatusOK, wiki)
}
func GetWiki(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/wikies/{pagename} repository repoGetWiki
// ---
// summary: Get a Wiki
// 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: pagename
// in: path
// description: name of the wikipage
// type: string
// required: true
// responses:
// "200":
// "$ref": "#/responses/Wiki"
wikiRepo, commit, _ := webWiki.FindWikiRepoCommit(ctx.Context)
wikiCloneWiki := ctx.Repo.Repository.WikiCloneLink()
// pageName := wiki_service.NormalizeWikiName(ctx.Context.Params(":page"))
pageName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
if len(pageName) == 0 {
pageName = "Home"
}
data, entry, pageFilename, noEntry := webWiki.WikiContentsByName(ctx.Context, commit, pageName)
if noEntry {
ctx.NotFound()
return
}
if entry == nil || ctx.Written() {
if wikiRepo != nil {
wikiRepo.Close()
}
}
metas := ctx.Repo.Repository.ComposeDocumentMetas()
var rctx = &markup.RenderContext{
URLPrefix: ctx.Repo.RepoLink,
Metas: metas,
IsWiki: true,
}
var buf strings.Builder
if err := markdown.Render(rctx, bytes.NewReader(data), &buf); err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
ctx.ServerError("Render", err)
return
}
c, err := wikiRepo.GetCommitByPath(entry.Name())
if err != nil {
if models.IsErrWikiInvalidFileName(err) {
return
}
}
commitsCount, _ := wikiRepo.FileCommitsCount("master", pageFilename)
wiki := api.WikiResponse{
WikiCloneLink: api.CloneLink{
HTTPS: wikiCloneWiki.HTTPS,
SSH: wikiCloneWiki.SSH,
},
WikiMeta: api.WikiMeta{
Name: pageName,
Commit: api.WikiCommit{
Author: api.WikiUser{
Name: c.Author.Name,
Email: c.Author.Email,
When: c.Author.When.Unix(),
},
Commiter: api.WikiUser{
Name: c.Committer.Name,
Email: c.Committer.Email,
When: c.Author.When.Unix(),
},
ID: c.ID.String(),
Message: c.Message(),
},
},
CommitCounts: commitsCount,
MdContent: string(data),
SimpleContent: buf.String(),
}
ctx.JSON(http.StatusOK, wiki)
}
func EditWiki(ctx *context.APIContext) {
// swagger:operation PATCH /repos/{owner}/{repo}/wikies/{pagename} repository repoEditWiki
// ---
// summary: Edit a wiki in 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: pagename
// in: path
// description: name of the wiki
// type: string
// required: true
// - name: body
// in: body
// schema:
// "$ref": "#/definitions/WikiOption"
// responses:
// "201":
// "$ref": "#/responses/Wiki"
form := web.GetForm(ctx).(*api.WikiOption)
oldWikiName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
newWikiName := wiki_service.NormalizeWikiName(form.Name)
err1 := wiki_service.CheckFile(newWikiName)
if err1 != nil {
ctx.FileNameError()
return
}
wikiRepo, commit, _ := webWiki.FindWikiRepoCommit(ctx.Context)
if _, _, _, noEntry := webWiki.WikiContentsByName(ctx.Context, commit, oldWikiName); noEntry {
ctx.Error(http.StatusNotFound, "WikiNotFound", "wiki不存在")
return
}
if _, _, _, noEntry := webWiki.WikiContentsByName(ctx.Context, commit, newWikiName); oldWikiName != newWikiName && !noEntry {
ctx.Error(http.StatusConflict, "WikiNameAlreadyExist", "wiki名称已存在")
return
}
if len(form.CommitMessage) == 0 {
form.CommitMessage = ctx.Tr("repo.editor.update", form.Name)
}
if err := wiki_service.EditWikiPage(ctx.User, ctx.Repo.Repository, oldWikiName, newWikiName, form.Content, form.CommitMessage); err != nil {
ctx.Error(http.StatusInternalServerError, "EditWikiPage", err)
return
}
_, newCommit, _ := webWiki.FindWikiRepoCommit(ctx.Context)
data, entry, pageFilename, _ := webWiki.WikiContentsByName(ctx.Context, newCommit, newWikiName)
c, err := wikiRepo.GetCommitByPath(entry.Name())
if err != nil {
if models.IsErrWikiInvalidFileName(err) {
return
}
}
metas := ctx.Repo.Repository.ComposeDocumentMetas()
// PageContent := markdown.RenderWiki(data, ctx.Repo.RepoLink, metas)
var rctx = &markup.RenderContext{
URLPrefix: ctx.Repo.RepoLink,
Metas: metas,
IsWiki: true,
}
var buf strings.Builder
if err := markdown.Render(rctx, bytes.NewReader(data), &buf); err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
ctx.ServerError("Render", err)
return
}
commitsCount, _ := wikiRepo.FileCommitsCount("master", pageFilename)
wiki := api.WikiResponse{
WikiMeta: api.WikiMeta{
Name: form.Name,
Commit: api.WikiCommit{
Author: api.WikiUser{
Name: c.Author.Name,
Email: c.Author.Email,
When: c.Author.When.Unix(),
},
Commiter: api.WikiUser{
Name: c.Committer.Name,
Email: c.Committer.Email,
When: c.Author.When.Unix(),
},
ID: c.ID.String(),
Message: c.Message(),
},
},
CommitCounts: commitsCount,
MdContent: string(data),
SimpleContent: buf.String(),
}
ctx.JSON(http.StatusOK, wiki)
}
func DeleteWiki(ctx *context.APIContext) {
// swagger:operation DELETE /repos/{owner}/{repo}/wikies/{pagename} repository repoDeleteWiki
// ---
// summary: Delete a wiki in 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: pagename
// in: path
// description: name of the wiki
// type: string
// required: true
// responses:
// "204":
// "$ref": "#/responses/empty"
// "500":
// "$ref": "#/responses/noFound"
wikiName := wiki_service.NormalizeWikiName(ctx.Params(":page"))
if len(wikiName) == 0 {
wikiName = "Home"
}
err2 := wiki_service.DeleteWikiPage(ctx.User, ctx.Repo.Repository, wikiName)
if err2 != nil {
ctx.FileExistError()
return
}
}

View File

@ -0,0 +1,228 @@
package reporter
import (
"fmt"
"net/http"
"strconv"
"time"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
)
func GetActivity(ctx *context.APIContext) {
// swagger:operation GET /activity activity activity
// ---
// summary: Statistics of commit and pull request data,Platform required data **
// produces:
// - application/json
// parameters:
// - name: from
// in: query
// description: Query begin timestamp
// type: string
// required: false
// - name: to
// in: query
// description: Query end timestamp
// type: string
// required: false
// responses:
// "200":
// "$ref": "#/responses/PlatformDTO"
// "404":
// "$ref": "#/responses/notFound"
opt := GetParamOption(ctx)
if opt == nil {
return
}
list, err := models.GetActivity(opt)
fmt.Println("-==========list====\n", list)
if err != nil {
ctx.ServerError("GetActivity", err)
return
}
ctx.JSON(http.StatusOK, list)
}
type PrjectDTO struct {
Project interface{} `json:"project"`
}
func GetActivityProject(ctx *context.APIContext) {
// swagger:operation GET /activity/project activity project
// ---
// summary: Statistics of submitted data by project **
// produces:
// - application/json
// parameters:
// - name: from
// in: query
// description: Query begin timestamp
// type: string
// required: false
// - name: to
// in: query
// description: Query end timestamp
// type: string
// required: false
// - name: top
// in: query
// description: Display the previous n records
// type: integer
// required: false
// responses:
// "200":
// "$ref": "#/responses/PlatformDTO"
// "404":
// "$ref": "#/responses/notFound"
opt := GetParamOption(ctx)
if opt == nil {
return
}
list, err := models.GetActivityProject(opt)
if err != nil {
ctx.ServerError("GetActivityProject", err)
return
}
data := PrjectDTO{
Project: list,
}
ctx.JSON(http.StatusOK, data)
}
type DevelopDTO struct {
Develop interface{} `json:"develop"`
}
func GetActivityDevelop(ctx *context.APIContext) {
// swagger:operation GET /activity/develop activity develop
// ---
// summary: Statistics of submitted data by developers **
// produces:
// - application/json
// parameters:
// - name: from
// in: query
// description: Query begin timestamp
// type: string
// required: false
// - name: to
// in: query
// description: Query end timestamp
// type: string
// required: false
// - name: top
// in: query
// description: Display the previous n records
// type: integer
// required: false
// responses:
// "200":
// "$ref": "#/responses/PlatformDTO"
// "404":
// "$ref": "#/responses/notFound"
opt := GetParamOption(ctx)
if opt == nil {
return
}
list, err := models.GetActivityDevelop(opt)
if err != nil {
ctx.ServerError("GetActivityDevelop", err)
return
}
data := DevelopDTO{
Develop: list,
}
ctx.JSON(http.StatusOK, data)
}
func GetParamOption(ctx *context.APIContext) (opt *models.GetGetActivityOptions) {
Layout := "2006-01-02 15:04:05"
//##top
top := ctx.QueryInt64("top")
if top <= 0 {
top = 5
} else if top >= 20 {
top = 20
}
//##from
FromDate, err := strconv.ParseInt(ctx.QueryTrim("from"), 10, 64)
if err != nil {
ctx.Error(http.StatusBadRequest, "param.from", err)
return
}
if FromDate <= 0 {
ctx.Error(http.StatusBadRequest, "param.from", fmt.Errorf("请指定from参数"))
return
//from=time.Now().Format("2006-01-02")
}
from := time.Unix(FromDate, 0).Format(Layout)
//fmt.Println("********from:",from," ", FromDate," convert:",time.Unix( FromDate,0).Format("2006-01-02 15:04:05"))
//##to
ToDate, err := strconv.ParseInt(ctx.QueryTrim("to"), 10, 64)
if err != nil {
ctx.Error(http.StatusBadRequest, "param.to ", err)
return
}
if ToDate <= 0 {
ctx.Error(http.StatusBadRequest, "param.to", fmt.Errorf("请指定to参数"))
return
}
to := time.Unix(ToDate, 0).Format(Layout)
//fmt.Println("********to:",to ," ", ToDate," convert:",time.Unix( ToDate,0).Format(Layout))
opt = &models.GetGetActivityOptions{
FromDateUnix: FromDate,
ToDateUnix: ToDate,
FromDate: from,
ToDate: to,
Top: top,
}
return opt
}
func GetContributors(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/contributors repository contributors
// ---
// summary: Get all builder information in the 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
// responses:
// "200":
// "$ref": "#/responses/ContributorsDtoList"
// "404":
// "$ref": "#/responses/noFound"
opts := models.GetContributorsOptionsExt{
UserId: ctx.Repo.Owner.ID,
RepoId: ctx.Repo.Repository.ID,
}
list, err := models.GetContributors(opts)
if err != nil {
ctx.Error(http.StatusNotFound, "not found the contributors", err)
return
}
ctx.JSON(http.StatusOK, list)
}

View File

@ -5,6 +5,7 @@
package swagger
import (
"code.gitea.io/gitea/models"
api "code.gitea.io/gitea/modules/structs"
)
@ -21,3 +22,10 @@ type swaggerResponseAccessToken struct {
// in:body
Body api.AccessToken `json:"body"`
}
// PlatformDTO
// swagger:response PlatformDTO
type swaggerReponsePlatformDTO struct {
//in:body
Body models.PlatformDTO `json:"body"`
}

View File

@ -23,6 +23,9 @@ type swaggerParameterBodies struct {
// in:body
DeleteEmailOption api.DeleteEmailOption
// in:body
WikiOption api.WikiOption
// in:body
CreateHookOption api.CreateHookOption
// in:body

View File

@ -5,7 +5,9 @@
package swagger
import (
"code.gitea.io/gitea/models"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/viewfile"
)
// Repository
@ -50,6 +52,26 @@ type swaggerResponseBranchProtectionList struct {
Body []api.BranchProtection `json:"body"`
}
// Wiki
// swagger:response Wiki
type swaggerResponseWiki struct {
// in:body
Body api.WikiResponse `json:"body"`
}
// WikiList
// swagger:response WikiList
type swaggerResponseWikiList struct {
// in:body
Body api.WikiesResponse `json:"body"`
}
// RepoBranchAndTagCount
// swagger:response RepoBranchAndTagCount
type swaggerResponseRepoBranchAndTagCount struct {
Body api.RepoBranchAndTagCount `json:"body"`
}
// TagList
// swagger:response TagList
type swaggerResponseTagList struct {
@ -99,6 +121,13 @@ type swaggerResponseHookList struct {
Body []api.Hook `json:"body"`
}
// HookTaskList
// swagger:response HookTaskList
type swaggerResponseHookTaskList struct {
// in:body
Body []api.HookTask `json:"body"`
}
// GitHook
// swagger:response GitHook
type swaggerResponseGitHook struct {
@ -254,6 +283,28 @@ type swaggerCommitList struct {
Body []api.Commit `json:"body"`
}
// FileCommitList
// swagger:response FileCommitList
type swaggerFileCommitList struct {
// The current page
Page int `json:"X-Page"`
// Commits per page
PerPage int `json:"X-PerPage"`
// Total commit count
Total int `json:"X-Total"`
// Total number of pages
PageCount int `json:"X-PageCount"`
// True if there is another page
HasMore bool `json:"X-HasMore"`
// in: body
Body []api.Commit `json:"body"`
}
// EmptyRepository
// swagger:response EmptyRepository
type swaggerEmptyRepository struct {
@ -316,3 +367,24 @@ type swaggerCombinedStatus struct {
// in: body
Body api.CombinedStatus `json:"body"`
}
// SearchFileItemList
// swagger:response SearchFileItem
type swaggerSearchFileItemList struct {
// in: body
Body []viewfile.SearchFileItem `json:"body"`
}
// ContributorsDtoList
// swagger:response ContributorsDto
type swaggerResponseContributorsDtoList struct {
// in: body
Body []models.ContributorsDto `json:"body"`
}
// CountDTO
// swagger:response CountDTO
type swaggerCountDTO struct {
//in: body
Body viewfile.CountDTO `json:"body"`
}

View File

@ -132,7 +132,7 @@ func GetAuthenticatedUser(ctx *context.APIContext) {
func GetUserHeatmapData(ctx *context.APIContext) {
// swagger:operation GET /users/{username}/heatmap user userGetHeatmapData
// ---
// summary: Get a user's heatmap
// summary: Get a user's heatmap ***
// produces:
// - application/json
// parameters:
@ -141,18 +141,41 @@ func GetUserHeatmapData(ctx *context.APIContext) {
// description: username of user to get
// type: string
// required: true
// - name: start
// in: query
// description: Query start timestamp
// type: string
// required: false
// - name: end
// in: query
// description: Query end timestamp
// type: string
// required: false
// responses:
// "200":
// "$ref": "#/responses/UserHeatmapData"
// "404":
// "$ref": "#/responses/notFound"
user := GetUserByParams(ctx)
if ctx.Written() {
// user := GetUserByParams(ctx)
timeStampOptions := utils.GetTimestampOptions(ctx)
// get the user to throw a err if it does not exist
// user, err := models.GetUserByName(ctx.Params(":username"))
user, err := models.GetUserByName(ctx.Params(":username"))
if err != nil {
if models.IsErrUserNotExist(err) {
ctx.Status(http.StatusNotFound)
} else {
ctx.Error(http.StatusInternalServerError, "GetUserByName", err)
}
return
}
heatmap, err := models.GetUserHeatmapDataByUser(user, ctx.User)
// heatmap, err := models.GetUserHeatmapDataByUser(user, ctx.User)
heatmap, err := models.GetUserHeatMapDataByUserWithTimeStamp(user, timeStampOptions)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetUserHeatmapDataByUser", err)
return

View File

@ -66,6 +66,10 @@ func CheckCreateHookOption(ctx *context.APIContext, form *api.CreateHookOption)
ctx.Error(http.StatusUnprocessableEntity, "", "Invalid content type")
return false
}
if !models.IsValidHookHttpMethod(form.Config["http_method"]) {
ctx.Error(http.StatusUnprocessableEntity, "", "Invalid http method")
return false
}
return true
}
@ -212,6 +216,10 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *models.Webho
if url, ok := form.Config["url"]; ok {
w.URL = url
}
if secret, ok := form.Config["secret"]; ok {
w.Secret = secret
}
if ct, ok := form.Config["content_type"]; ok {
if !models.IsValidHookContentType(ct) {
ctx.Error(http.StatusUnprocessableEntity, "", "Invalid content type")
@ -220,6 +228,14 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *models.Webho
w.ContentType = models.ToHookContentType(ct)
}
if hw, ok := form.Config["http_method"]; ok {
if !models.IsValidHookHttpMethod(hw) {
ctx.Error(http.StatusUnprocessableEntity, "", "Invalid http method")
return false
}
w.HTTPMethod = hw
}
if w.Type == models.SLACK {
if channel, ok := form.Config["channel"]; ok {
json := jsoniter.ConfigCompatibleWithStandardLibrary
@ -248,16 +264,29 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *models.Webho
w.Create = util.IsStringInSlice(string(models.HookEventCreate), form.Events, true)
w.Push = util.IsStringInSlice(string(models.HookEventPush), form.Events, true)
w.PullRequest = util.IsStringInSlice(string(models.HookEventPullRequest), form.Events, true)
w.Create = util.IsStringInSlice(string(models.HookEventCreate), form.Events, true)
// w.Create = util.IsStringInSlice(string(models.HookEventCreate), form.Events, true)
w.Delete = util.IsStringInSlice(string(models.HookEventDelete), form.Events, true)
w.Fork = util.IsStringInSlice(string(models.HookEventFork), form.Events, true)
w.Issues = util.IsStringInSlice(string(models.HookEventIssues), form.Events, true)
w.IssueComment = util.IsStringInSlice(string(models.HookEventIssueComment), form.Events, true)
w.Issues = issuesHook(form.Events, "issues_only")
w.IssueAssign = issuesHook(form.Events, string(models.HookEventIssueAssign))
w.IssueLabel = issuesHook(form.Events, string(models.HookEventIssueLabel))
w.IssueMilestone = issuesHook(form.Events, string(models.HookEventIssueMilestone))
w.IssueComment = issuesHook(form.Events, string(models.HookEventIssueComment))
// w.IssueComment = util.IsStringInSlice(string(models.HookEventIssueComment), form.Events, true)
w.Push = util.IsStringInSlice(string(models.HookEventPush), form.Events, true)
w.PullRequest = util.IsStringInSlice(string(models.HookEventPullRequest), form.Events, true)
// w.PullRequest = util.IsStringInSlice(string(models.HookEventPullRequest), form.Events, true)
w.PullRequest = pullHook(form.Events, "pull_request_only")
w.PullRequestAssign = pullHook(form.Events, string(models.HookEventPullRequestAssign))
w.PullRequestLabel = pullHook(form.Events, string(models.HookEventPullRequestLabel))
w.PullRequestMilestone = pullHook(form.Events, string(models.HookEventPullRequestMilestone))
w.PullRequestComment = pullHook(form.Events, string(models.HookEventPullRequestComment))
w.PullRequestReview = pullHook(form.Events, "pull_request_review")
w.PullRequestSync = pullHook(form.Events, string(models.HookEventPullRequestSync))
w.Repository = util.IsStringInSlice(string(models.HookEventRepository), form.Events, true)
w.Release = util.IsStringInSlice(string(models.HookEventRelease), form.Events, true)
w.BranchFilter = form.BranchFilter
w.HookEvent.BranchFilter = form.BranchFilter
if err := w.UpdateEvent(); err != nil {
ctx.Error(http.StatusInternalServerError, "UpdateEvent", err)

View File

@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert"
"code.gitea.io/gitea/modules/timeutil"
)
// GetQueryBeforeSince return parsed time (unix format) from URL query's before and since
@ -66,3 +67,11 @@ func GetListOptions(ctx *context.APIContext) models.ListOptions {
PageSize: convert.ToCorrectPageSize(ctx.QueryInt("limit")),
}
}
// GetTimestampOptions returns list options using the start to end
func GetTimestampOptions(ctx *context.APIContext) models.TimestampOptions {
return models.TimestampOptions{
Start: timeutil.TimeStamp(ctx.QueryInt("start")),
End: timeutil.TimeStamp(ctx.QueryInt("end")),
}
}

View File

@ -0,0 +1,334 @@
package viewfile
import (
"fmt"
"net/http"
"net/url"
"path/filepath"
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/repofiles"
repo_module "code.gitea.io/gitea/modules/repository"
)
func FindFiles(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/find repository find
// ---
// summary: The search file contains subdirectories, which is a custom interface *****
// 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: ref
// in: query
// description: "The name of the commit/branch/tag. Default the repositorys default branch (usually master)"
// type: string
// required: false
// - name: q
// in: query
// description: "Search keywords"
// type: string
// required: false
// responses:
// "200":
// "$ref": "#/responses/SearchFileItemList"
// "404":
// "$ref": "#/responses/notFound"
treePath := ctx.Repo.TreePath
ref := ctx.Query("ref")
if ref == "" {
ref = ctx.Repo.Repository.DefaultBranch
}
keyWords := ctx.Query("q")
if keyWords == "" {
}
fileList, err := FindFileFromPathEtx(ctx, treePath, ref, keyWords)
if err != nil {
ctx.ServerError("FindFileFromPathEtx", err)
return
}
ctx.JSON(http.StatusOK, fileList)
}
type SearchFileItem struct {
Name string `json:"name"`
Path string `json:"path"`
SHA string `json:"sha"`
Type string `json:"type"`
Size int64 `json:"size"`
URL *string `json:"url"`
HTMLURL *string `json:"html_url"`
}
func FindFileFromPathEtx(ctx *context.APIContext, treePath, ref, key string) (fileList []*SearchFileItem, err error) {
if ctx.Repo.GitRepo == nil {
repoPath := models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
ctx.Repo.GitRepo, err = git.OpenRepository(repoPath)
if err != nil {
ctx.ServerError("OpenRepository", err)
return nil, err
}
defer func() {
if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
}
}()
}
// get the commit object for the ref
commit, err := ctx.Repo.GitRepo.GetCommit(ref)
if err != nil {
ctx.ServerError("GetCommit", err)
return nil, err
}
tree, err2 := commit.SubTree(treePath)
if err2 != nil {
ctx.ServerError("SubTree", err)
return nil, err2
}
entries, err3 := tree.ListEntriesRecursive()
if err3 != nil {
ctx.ServerError("ListEntries", err3)
return nil, err3
}
fileList = make([]*SearchFileItem, 0, 0)
for _, entry := range entries {
if entry.IsDir() {
continue
}
filename := filepath.Base(entry.Name())
if strings.Contains(strings.ToLower(filename), strings.ToLower(key)) || key == "" {
name := entry.Name()
treePath = name
selfURL, err := url.Parse(fmt.Sprintf("%s/contents/%s?ref=%s", ctx.Repo.Repository.APIURL(), treePath, ref))
if err != nil {
return nil, err
}
selfURLString := selfURL.String()
refType := ctx.Repo.GitRepo.GetRefType(ref)
if refType == "invalid" {
return nil, fmt.Errorf("no commit found for the ref [ref: %s]", ref)
}
htmlURL, err := url.Parse(fmt.Sprintf("%s/src/%s/%s/%s", ctx.Repo.Repository.HTMLURL(), refType, ref, treePath))
if err != nil {
return nil, err
}
htmlURLString := htmlURL.String()
item := &SearchFileItem{
Name: filename,
Path: treePath,
SHA: entry.ID.String(),
Type: entry.Type(),
Size: entry.Size(),
URL: &selfURLString,
HTMLURL: &htmlURLString,
}
// Now populate the rest of the ContentsResponse based on entry type
if entry.IsRegular() || entry.IsExecutable() {
item.Type = string(repofiles.ContentTypeRegular)
} else if entry.IsDir() {
item.Type = string(repofiles.ContentTypeDir)
} else if entry.IsLink() {
item.Type = string(repofiles.ContentTypeLink)
} else if entry.IsSubModule() {
item.Type = string(repofiles.ContentTypeSubmodule)
}
fileList = append(fileList, item)
}
}
return
}
func LatestRelease(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/releases/latest repository latest
// ---
// summary: Get the last updated Release version of the repository., which is a custom interface ****
// 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
// responses:
// "200":
// "$ref": "#/responses/release"
// "404":
// "$ref": "#/responses/notFound"
var err error
if ctx.Repo.GitRepo == nil {
repoPath := models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
ctx.Repo.GitRepo, err = git.OpenRepository(repoPath)
if err != nil {
ctx.ServerError("Reporef Invalid repo"+repoPath, err)
return
}
defer func() {
if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
}
}()
}
release, err := models.GetLatestReleaseByRepoIDExt(ctx.Repo.Repository.ID)
fmt.Println("****************ctx.Repo.Repository.ID:", ctx.Repo.Repository.ID, " ", release, " ", err)
if err != nil {
if models.IsErrReleaseNotExist(err) {
ctx.NotFound("LatestRelease", err)
return
}
ctx.ServerError("GetLatestReleaseByRepoIDExt", err)
return
}
if err := release.LoadAttributes(); err != nil {
ctx.ServerError("LoadAttributes", err)
return
}
release.Publisher.Passwd = ""
ctx.JSON(http.StatusOK, release)
}
type CountDTO struct {
Branch struct {
CommitCount int64 `json:"commit_count"`
BranchName string `json:"branch_name"`
} `json:"branch"`
ReleaseCount int64 `json:"release_count"`
TagCount int64 `json:"tag_count"`
BranchCount int64 `json:"branch_count"`
}
func GetCommitCount(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/count repository Count
// ---
// summary: Get commit quantity by branch which is a custom interface ****
// 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: ref
// in: query
// description: "The name of the commit/branch/tag. Default the repositorys default branch (usually master)"
// type: string
// required: false
// responses:
// "200":
// "$ref": "#/responses/CountDTO"
// "404":
// "$ref": "#/responses/notFound"
ref := ctx.QueryTrim("ref") // determine whether the ref empty
if ref == "" {
ref = ctx.Params(":ref")
if ref == "" {
ref = ctx.Repo.Repository.DefaultBranch
}
}
var err error
if ctx.Repo.GitRepo == nil {
repoPath := models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
ctx.Repo.GitRepo, err = git.OpenRepository(repoPath)
if err != nil {
ctx.Error(http.StatusInternalServerError, "RepoRef Invalid repo"+repoPath, err)
return
}
defer func() {
// If it's been set to nil then assume someone else has closed it
if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
}
}()
}
//Get the commit object of the ref
commit, err2 := ctx.Repo.GitRepo.GetCommit(ref)
if err2 != nil {
ctx.Error(http.StatusInternalServerError, "ctx.Repo.GitRepo.GetCommit", err)
return
}
ctx.Repo.Commit = commit
// Get the count of the commit
CommitCount, err := ctx.Repo.Commit.CommitsCount()
if err != nil {
ctx.Error(http.StatusInternalServerError, "Get the CommitsCount", err)
return
}
opts := models.FindReleasesOptions{
ListOptions: models.ListOptions{
Page: 1,
PageSize: 1000,
},
IncludeDrafts: true,
IncludeTags: true,
}
// Get the release object of the ref
ReleaseCount, err3 := models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, opts)
if err3 != nil {
ctx.Error(http.StatusInternalServerError, "GetReleaseCountByRepoId", err)
return
}
branches, _, err := repo_module.GetBranchesNoLimit(ctx.Repo.Repository)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetBranches", err)
return
}
// Get the tag object
Tags, err4 := ctx.Repo.GitRepo.GetTags()
if err4 != nil {
ctx.Error(http.StatusInternalServerError, "GetTags", err)
return
}
countDTO := &CountDTO{}
countDTO.Branch.CommitCount = CommitCount
countDTO.Branch.BranchName = ref
countDTO.BranchCount = int64(len(branches))
countDTO.TagCount = int64(len(Tags))
countDTO.ReleaseCount = ReleaseCount
ctx.JSON(http.StatusOK, countDTO)
}

View File

@ -87,7 +87,7 @@ func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error)
return commit.GetTreeEntryByPath(unescapedTarget)
}
func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) {
func FindWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) {
wikiRepo, err := git.OpenRepository(ctx.Repo.Repository.WikiPath())
if err != nil {
ctx.ServerError("OpenRepository", err)
@ -120,7 +120,7 @@ func wikiContentsByEntry(ctx *context.Context, entry *git.TreeEntry) []byte {
// wikiContentsByName returns the contents of a wiki page, along with a boolean
// indicating whether the page exists. Writes to ctx if an error occurs.
func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName string) ([]byte, *git.TreeEntry, string, bool) {
func WikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName string) ([]byte, *git.TreeEntry, string, bool) {
pageFilename := wiki_service.NameToFilename(wikiName)
entry, err := findEntryForFile(commit, pageFilename)
if err != nil && !git.IsErrNotExist(err) {
@ -133,7 +133,7 @@ func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName strin
}
func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
wikiRepo, commit, err := findWikiRepoCommit(ctx)
wikiRepo, commit, err := FindWikiRepoCommit(ctx)
if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
@ -190,7 +190,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
ctx.Data["RequireHighlightJS"] = true
//lookup filename in wiki - get filecontent, gitTree entry , real filename
data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
data, entry, pageFilename, noEntry := WikiContentsByName(ctx, commit, pageName)
if noEntry {
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
}
@ -201,7 +201,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
return nil, nil
}
sidebarContent, _, _, _ := wikiContentsByName(ctx, commit, "_Sidebar")
sidebarContent, _, _, _ := WikiContentsByName(ctx, commit, "_Sidebar")
if ctx.Written() {
if wikiRepo != nil {
wikiRepo.Close()
@ -209,7 +209,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
return nil, nil
}
footerContent, _, _, _ := wikiContentsByName(ctx, commit, "_Footer")
footerContent, _, _, _ := WikiContentsByName(ctx, commit, "_Footer")
if ctx.Written() {
if wikiRepo != nil {
wikiRepo.Close()
@ -263,7 +263,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
}
func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
wikiRepo, commit, err := findWikiRepoCommit(ctx)
wikiRepo, commit, err := FindWikiRepoCommit(ctx)
if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
@ -288,7 +288,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
//lookup filename in wiki - get filecontent, gitTree entry , real filename
data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
data, entry, pageFilename, noEntry := WikiContentsByName(ctx, commit, pageName)
if noEntry {
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
}
@ -337,7 +337,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
}
func renderEditPage(ctx *context.Context) {
wikiRepo, commit, err := findWikiRepoCommit(ctx)
wikiRepo, commit, err := FindWikiRepoCommit(ctx)
if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
@ -365,7 +365,7 @@ func renderEditPage(ctx *context.Context) {
ctx.Data["RequireHighlightJS"] = true
//lookup filename in wiki - get filecontent, gitTree entry , real filename
data, entry, _, noEntry := wikiContentsByName(ctx, commit, pageName)
data, entry, _, noEntry := WikiContentsByName(ctx, commit, pageName)
if noEntry {
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/_pages")
}
@ -472,7 +472,7 @@ func WikiPages(ctx *context.Context) {
ctx.Data["PageIsWiki"] = true
ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(models.UnitTypeWiki) && !ctx.Repo.Repository.IsArchived
wikiRepo, commit, err := findWikiRepoCommit(ctx)
wikiRepo, commit, err := FindWikiRepoCommit(ctx)
if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
@ -521,7 +521,7 @@ func WikiPages(ctx *context.Context) {
// WikiRaw outputs raw blob requested by user (image for example)
func WikiRaw(ctx *context.Context) {
wikiRepo, commit, err := findWikiRepoCommit(ctx)
wikiRepo, commit, err := FindWikiRepoCommit(ctx)
defer func() {
if wikiRepo != nil {
wikiRepo.Close()

View File

@ -174,6 +174,20 @@ func SignInPost(ctx *context.Context) {
}
form := web.GetForm(ctx).(*forms.SignInForm)
if user, err := models.GetUserByName(form.UserName); models.IsErrUserNotExist(err) {
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplSignIn, &form)
log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
return
} else {
// If this user not is administrator
// Instead, tip error
if !user.IsAdmin {
ctx.RenderWithErr(ctx.Tr("form.User is not an administrator"), tplSignIn, &form)
log.Info("Failed authentiation attempt for %s from %s ", form.UserName, ctx.RemoteAddr())
return
}
}
u, err := models.UserSignIn(form.UserName, form.Password)
if err != nil {
if models.IsErrUserNotExist(err) {

View File

@ -1210,6 +1210,13 @@ func readFileName(rd *strings.Reader) (string, bool) {
return name[2:], ambiguity
}
// GetDiffRange builds a Diff between two commits of a repository.
// passing the empty string as beforeCommitID returns a diff from the
// parent commit.
func GetDiffRange(gitRepo *git.Repository, beforeCommitID, afterCommitID string, maxLines, maxLineCharacters, maxFiles int) (*Diff, error) {
return GetDiffRangeWithWhitespaceBehavior(gitRepo, beforeCommitID, afterCommitID, maxLines, maxLineCharacters, maxFiles, "")
}
// GetDiffRangeWithWhitespaceBehavior builds a Diff between two commits of a repository.
// Passing the empty string as beforeCommitID returns a diff from the parent commit.
// The whitespaceBehavior is either an empty string or a git flag

View File

@ -6,17 +6,17 @@
package wiki
import (
"fmt"
"net/url"
"os"
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/sync"
"code.gitea.io/gitea/modules/util"
"errors"
"fmt"
"net/url"
"os"
"strings"
)
var (
@ -64,6 +64,16 @@ func FilenameToName(filename string) (string, error) {
return NormalizeWikiName(unescaped), nil
}
// check filename
func CheckFile(filename string) error {
if len(filename) <= 150 {
return nil
} else {
err := errors.New("The name is too long, please be less than 200 bytes")
return err
}
}
// InitWiki initializes a wiki for repository,
// it does nothing when repository already has wiki.
func InitWiki(repo *models.Repository) error {

File diff suppressed because it is too large Load Diff