1. 为什么我会在Windows上折腾Gitea:需求与选型
先说个场景。团队里的代码仓库一直放在第三方托管平台上,平时push pull倒也没什么大问题,但代码越堆越多,又涉及大文件,公网绕一圈的延迟实在让人难受。加上部分项目有内网隔离要求,不能往公网放,所以“在内网Windows机器上自建一套Git服务”这个需求就提上了日程。当时摆在桌面上有两条路:GitLab和Gitea。
GitLab我倒不陌生,功能确实全,CI/CD、Issue跟踪、代码评审全都有。但一个很现实的问题是——它太重了。官方推荐配置是4核8G起步,实测在2核4G的Windows机器上跑GitLab,内存直接吃掉一半以上,启动还慢,动不动就要等一会儿才响应。对于五六个人的小团队来说,这个代价有点不值当。
Gitea就不一样了。它用Go写的,整个程序就一个可执行文件,不依赖Java运行时,不依赖一堆动态库,拷贝到Windows服务器上直接就能跑。官方给的资源门槛极低,1核512M内存就能带起来,实测在4G内存的Windows Server上跑得相当舒服。功能上虽然和GitLab比有些差距,但常用的:仓库管理、Issue、Pull Request、Web编辑器、内置CI(Gitea Actions)、Webhook,全都有。
在Gogs和Gitea之间我也纠结了一下。Gogs是老前辈,轻量是它的标签,但维护节奏和社区活跃度明显不如Gitea。Gitea是Gogs的社区分支发展起来的,迭代快、插件多、Git LFS支持更完善,中文文档也全。所以最终选型就定了:Windows Server + Gitea,一个exe搞定,部署和维护成本都极低。
写这篇文章的初衷也简单,网上关于Windows下部署Gitea的教程不少,但很多都只写到“双击exe然后浏览器打开”就完了,真正涉及生产可用的问题——反向代理怎么做、服务怎么注册、数据怎么备份、升级怎么操作——都讲得不够透。这篇文章把我从选型到上线,再到跑了几个月之后所有踩过的坑、验证过的方法都记录下来,给大家一个可以直接照着操作的完整方案。
2. 部署前的准备:两种安装路径和依赖规划
2.1 二进制直装与Docker方式怎么选
Gitea在Windows下的部署方式有两种主流选择:直接下载Windows二进制exe运行,或者用Docker Desktop起容器。
如果你是个人开发者,机器上连Docker都没装,或者只有一台Windows物理机不想引入额外依赖,那直接二进制安装最省事。一个exe就是全部程序,数据目录、配置文件都在外面挂在,升级的时候替换一个exe就完事,逻辑非常清晰。
用Docker的好处是隔离性和可移植性好,配置挂在docker-compose.yml里,理论上可以完整复刻到任何装Docker的机器上。但代价也很明显:Windows的Docker Desktop本身就需要WSL2或Hyper-V做底层,这几层虚拟化套下来,磁盘占用好几个G,性能也有损耗。我就遇到过Docker Desktop和Hyper-V抢占资源导致Gitea容器响应变慢的情况。而且Windows重启后Docker Desktop经常需要手动启动,一忘掉服务就挂了,比Windows服务方式麻烦不少。
我的结论是:生产环境跑在纯Windows服务器上,选二进制直装;如果是开发测试,或者以后要迁到Linux服务器,那用Docker Compose定义一套配置文件更合适。两者其实也互不冲突,你可以先用Docker在本地快速验证一下Gitea的功能,确认能满足需求后再用二进制方式部署到生产机器上。
2.2 数据库选型:SQLite与MySQL的边界在哪里
Gitea安装时有一个数据库选择环节,支持SQLite、MySQL、PostgreSQL、MSSQL。很多新手在这里纠结,其实不用。
如果你只是个人使用,或者团队规模在十个人以内,并发量不高,直接用SQLite就够了。SQLite是嵌入式数据库,数据就存在一个文件里,Gitea官方也是默认推荐SQLite。好处是零配置、零维护,备份的时候直接把整个数据目录拷走就行,不需要额外的数据库服务。
但有几个场景建议换MySQL或PostgreSQL:一是团队人数多、并发上来了,SQLite的锁机制会成为瓶颈;二是你本身已经有MySQL服务器在跑,不想在Gitea里再多维护一套数据文件;三是需要做更细粒度的在线备份和恢复。我选择的是MySQL,原因很实际——内网本来就有MySQL实例,直接在MySQL里建一个gitea库就行,省去了SQLite文件单独管理的麻烦。
如果你决定用MySQL,记得在安装前就先建好数据库。Gitea需要一个空库,字符集建议utf8mb4,否则遇到特殊字符会报错或乱码。登录MySQL执行这几条命令:
CREATE DATABASE gitea CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER 'gitea'@'localhost' IDENTIFIED BY '这里填一个强密码'; GRANT ALL PRIVILEGES ON gitea.* TO 'gitea'@'localhost'; FLUSH PRIVILEGES;权限不用给太大,gitea库的增删改查就够用了。
2.3 目录规划与端口规划:提前想好能省一堆事
Windows下装Gitea,目录规划是很多人忽略但特别重要的一步。我第一次装的时候图省事,所有东西都堆在Gitea程序目录下,结果后来数据越来越大,系统盘差点被塞满,迁移数据又费了不少劲。
建议至少把程序和数据分开。我的规划是这样的:
C:\Gitea\ -- 程序目录,放gitea.exe和内置资源 D:\GiteaData\ -- 数据目录,放仓库、数据库、配置文件 ├── custom -- 自定义配置目录 │ └── conf │ └── app.ini -- 核心配置文件 ├── data -- 仓库存储、LFS、附件等 ├── log -- 日志目录 └── repos -- 代码仓库根目录端口规划上,Gitea默认的Web端口是3000,SSH端口是22。3000这个端口一般没什么冲突,但SSH的22端口在Windows上很可能被系统的OpenSSH Server占用了。如果不想改Gitea的SSH端口,就得先把Windows自带的OpenSSH Server停掉。我在部署时就遇到了这个问题,后面会专门说。
还有一个更稳妥的做法:把Gitea的SSH端口改成222或别的端口,在客户端连接时指定端口。对于小团队来说,多打一个端口号没什么大不了的。但内网其他服务如果依赖22端口,那就只能换端口。我建议提前把端口在配置文件里定好,避免事后改端口导致克隆地址全变、团队成员一脸懵。
3. 从零到可用:Gitea安装的完整操作记录
3.1 下载安装包与首次启动
从Gitea官网的下载页面选择Windows平台的二进制包,文件名一般是gitea-版本号-windows-4.0-amd64.exe,直接下载最新稳定版就行,不用追新。下载完把exe放到你规划好的程序目录C:\Gitea下,改名成gitea.exe,方便后期命令输入。
首次启动前,先配置一下环境变量。打开“此电脑 -> 高级系统设置 -> 环境变量”,新建或编辑GITEA_WORK_DIR,值填你的数据目录,比如D:\GiteaData。这个环境变量告诉Gitea把数据写到哪。如果不设,Gitea默认会把数据放在当前用户目录下,到时候找数据还得翻半天,很麻烦。
然后是Git的安装。Gitea的仓库操作底层依赖Git,Windows下需要先装Git for Windows,并确保git命令在系统PATH里。装完后在cmd里验证一下:
git --version能输出版本号就没问题了。
万事俱备,在cmd里切换到程序目录,执行前台启动:
cd C:\Gitea gitea.exe web --port 3000如果一切正常,终端窗口里会滚动日志,最后提示监听在3000端口。这一步只是在验证程序能跑起来,不用急着关掉,先打开浏览器访问http://localhost:3000,能看到Gitea的界面就说明程序本身没问题。
注意:第一次访问会进入安装引导页,但在这个阶段先不要急着填,建议直接关掉浏览器、回到cmd按Ctrl+C停掉服务。因为我们要先把Windows服务注册好,再用服务方式启动来走安装流程,这样日志输出、服务生命周期管理会更干净。
3.2 用NSSM把Gitea注册成Windows服务
让Gitea以Windows服务方式运行是关键一步。如果不注册成服务,每次都要手动开一个cmd窗口跑gitea.exe,关机重启后还得重新启动,这显然不叫“部署完成”。
Windows下配置exe程序为服务,常用的有sc命令、srvany、NSSM。我强烈推荐NSSM(Non-Sucking Service Manager),它把服务名称、程序路径、启动参数、日志重定向都封装在一个界面里,配置起来非常直观。
下载NSSM时注意选对系统位数,解压后得到一个nssm.exe文件。建议把它复制到C:\Gitea目录下,和gitea.exe放一起,方便后续调用。
管理员权限打开cmd,执行:
cd C:\Gitea nssm install Gitea这时会弹出NSSM的服务配置窗口。主要填这几个地方:
- Path:选择C:\Gitea\gitea.exe
- Startup directory:C:\Gitea
- Arguments:填
web --port 3000
切到“I/O”标签页,把Output和Error的日志文件路径设到D:\GiteaData\log\gitea-out.log和D:\GiteaData\log\gitea-err.log。这一步平时看着不起眼,但出问题排查时全靠这些日志救命了。
点击Install service完成注册,然后回到cmd执行:
nssm start Gitea到这一步,Gitea已经以服务方式运行了。你可以在Windows服务管理器里看到名叫Gitea的服务,状态是“正在运行”。现在打开浏览器访问http://localhost:3000,才是真正进入安装引导页的时机。
这里有个容易踩的坑:注册服务时,路径里如果有空格,NSSM一般会自动处理,但Arguments里的参数最好用引号整体包住。另外,如果NSSM提示注册失败,多半是权限不够,务必用管理员身份打开cmd。
3.3 安装页面配置的关键选项
进入安装引导页后,有几个配置项必须认真对待,直接关系到后边能不能正常使用。
数据库设置:按我前面说的,选择MySQL,填上数据库主机、用户名、密码、数据库名。如果选SQLite,只需要填数据库文件路径,比如D:\GiteaData\data\gitea.db,其他不用管。
常规设置:
- 站点标题:随意填,会显示在浏览器标题栏和页头。
- 仓库根目录:填D:\GiteaData\repos,这是所有代码仓库存放的位置。
- LFS根路径:如果要支持大文件,填D:\GiteaData\data\lfs,装了LFS插件后大文件会存在这里。
- 运行用户名:这个字段在Windows下一般保持为空,不用动。
服务器设置:
- SSH服务器端口:我改成2222,避开22端口冲突。
- Gitea基础URL:这里填最终用户访问的地址。例如后面要用
http://git.example.com:3000/访问,那就填这个。如果后续接Nginx做反向代理,直接填反向代理对外暴露的地址。
管理员账号设置:在安装页底部可以设置管理员用户名、邮箱、密码。建议在这里就创建一个专属管理员账号,不要等到注册流程再创建——安装页直接创建的账号数据更干净,而且邮箱和密码密码强度记得拉高一点。
全部填完,点击“安装Gitea”,页面会自动跳到初始化,完成后就能看到Gitea的管理界面了。安装流程本身很快,一般几秒钟就完成。
如果你在安装页面填错了配置,或者装完想改设置,可以直接打开D:\GiteaData\custom\conf\app.ini进行修改。注意:修改配置文件后需要重启Gitea服务才生效:
nssm restart Gitea4. 配置反向代理:域名访问与HTTPS落地
4.1 为什么一定要上反向代理
Gitea自带的HTTP服务监听在3000端口,直接IP加端口访问也不是不行,但生产环境跑一段时间就会发现,这么干有几个麻烦。
一是浏览器地址栏老带端口号,不美观不说,团队成员很难记住;二是想加HTTPS证书的时候,还得直接在Gitea里配证书,Gitea对证书文件路径、权限的要求比较严格,配起来不省心;三是以后想加访问控制、做请求日志统计、做缓存控制,直接在Gitea里搞很别扭。
反向代理就是专门解决这些问题的。客户端访问80/443端口,反向代理把请求转发给Gitea的3000端口,一切对用户透明。我在团队部署时用的是Nginx,Windows下有官方编译好的Windows版,直接解压就能跑。Caddy也可以,配置更简单,自动申请Let’s Encrypt证书,但当时手头Nginx的配置模板多,就直接沿用了Nginx。
4.2 Nginx配置实录
下载Nginx Windows版,解压到C:\nginx,打开conf\nignx.conf配置文件,在http块里添加一个server块:
server { listen 80; server_name git.example.com; client_max_body_size 512m; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }有几个细节需要注意。client_max_body_size必须调大,不然push大文件或上传附件时会被Nginx拦截,默认1m的配置会让你push一个几十MB的包就报413错误。proxy_set_header里的这四个header也很关键,Gitea会根据X-Forwarded-For来做访问日志审计,根据X-Forwarded-Proto来判断请求是HTTP还是HTTPS,不加的话Gitea里生成的链接会变成http,HTTPS配置就白做了。
配置好之后,每次修改Nginx配置后要执行nginx -s reload让配置生效,不需要重启Nginx进程。检查Nginx是否启动,访问http://git.example.com,能看到Gitea页面就成功了。
4.3 HTTPS证书配置与注意点
在此之前我建议把HTTP全部切到HTTPS。自建Git服务虽然在内网,但代码就是资产,传输过程明文裸奔总归不放心。
Nginx下的配置也很简单。如果你有正规证书,直接在server块里加:
server { listen 443 ssl; server_name git.example.com; ssl_certificate C:/nginx/certs/git.example.com.pem; ssl_certificate_key C:/nginx/certs/git.example.com.key; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } server { listen 80; server_name git.example.com; return 301 https://$host$request_uri; }内网环境如果要上HTTPS,可以用自签证书。Windows上生成自签证书很方便,用PowerShell就能搞定:
New-SelfSignedCertificate -DnsName "git.example.com" -CertStoreLocation Cert:\LocalMachine\My生成之后导出PFX或PEM格式,再配置到Nginx里。需要注意:自签证书在客户端会有警告提示,团队成员需要手动信任一次。如果你有内网CA,用内网CA签发证书体验会好很多,Windows域环境下还能自动下发到所有域内机器,基本无感。
还有一个容易忽略的地方:配置完HTTPS后,记得同步修改Gitea的app.ini里的ROOT_URL。把http://git.example.com:3000/改成https://git.example.com/,不然Gitea页面里所有克隆地址、HTTP链接还是Http的,用户复制地址后会连不上。
5. 日常运维与备份恢复:长期稳定运行的关键
5.1 app.ini核心配置项解读与常见调整
Gitea的配置文件在D:\GiteaData\custom\conf\app.ini,几乎所有关键行为都在这一个文件里控着。花几分钟读一遍这个文件,比在网上搜各种“Gitea怎么改XX设置”要高效得多。
几个我实际改过的配置项,列出来供参考:
[server] PROTOCOL = http DOMAIN = git.example.com HTTP_PORT = 3000 ROOT_URL = https://git.example.com/ SSH_PORT = 2222 DISABLE_SSH = false START_SSH_SERVER = falseDOMAIN和ROOT_URL:改成最终访问的域名和URL。切换HTTPS后必须同步修改,否则生成的克隆地址是错的。SSH_PORT:设为2222,避开系统SSH占用的22端口。START_SSH_SERVER:默认是false,使用系统自带的SSH服务。如果你没有单独装OpenSSH,需要设为true并配置SSH_KEYGEN_PATH,比较麻烦,我建议保持false,用系统SSH。
[repository] DEFAULT_PRIVATE = private DEFAULT_BRANCH = main MAX_CREATION_LIMIT = 10DEFAULT_PRIVATE:建议默认仓库可见性设为private,防止团队成员创建的仓库默认公开,在内网环境下无所谓,但保持习惯不是坏事。DEFAULT_BRANCH:新版推荐用main,团队成员创建仓库时默认分支就是main,避免混用master/main的混乱。
[service] REQUIRE_SIGNIN_VIEW = true ENABLE_REGISTRATION = falseENABLE_REGISTRATION:如果只是团队内部使用,强烈建议设成false,禁止自助注册。账号由管理员在后台添加,权限可控、避免无关人员钻空子。
每次改完app.ini,记得重启Gitea服务:
nssm restart Gitea5.2 备份方案设计:比你想的更要重视
备份是运维环节里最容易被忽略却最致命的部分。Gitea的数据分三块:配置文件、代码仓库、数据库。这三样缺一不可,必须打包在一起才算完整备份。
我的备份思路是这样的:
配置文件:D:\GiteaData\custom\目录整个拷走,就包含了app.ini。
代码仓库:D:\GiteaData\repos目录,所有仓库的裸仓库都在这。这个目录是整个备份里最占空间的部分。
数据库:如果是SQLite,备份就是data目录下的gitea.db文件,直接拷走就行。如果是MySQL,需要执行mysqldump导出:
mysqldump -u gitea -p gitea > d:\backup\gitea-db.sql建议把三者打包到一个目录,用日期做后缀。我在服务器上写了个简单的批处理脚本,计划任务每天凌晨执行一次:
@echo off set BACKUP_DIR=D:\GiteaBackup set DATE_STR=%date:~0,4%%date:~5,2%%date:~8,2% mkdir %BACKUP_DIR%\%DATE_STR% xcopy /E /I /Y D:\GiteaData\repos %BACKUP_DIR%\%DATE_STR%\repos xcopy /E /I /Y D:\GiteaData\custom %BACKUP_DIR%\%DATE_STR%\custom "C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqldump.exe" -u gitea -p密码 gitea > %BACKUP_DIR%\%DATE_STR%\gitea.sql备份完成之后,我还会保留最近7天的备份,再往前的就手动归档。数据量如果不大,也可以直接压缩成一个zip包再拷贝到NAS或云盘,免得仓库多了占本地盘。
5.3 恢复流程:从备份中找回服务
备份做好了,恢复也得有谱。有次我误删了一个仓库,还好备份是完整的,恢复流程走了一遍,确认有效。
恢复分两种情况:
仓库整库恢复:把备份里的repos目录覆盖回D:\GiteaData\repos,重启Gitea服务,仓库就回来了。Gitea会在启动时自动识别仓库目录,不需要手动导入,前提是目录名没变。
数据库+仓库整体恢复:先恢复数据库,执行:
mysql -u gitea -p gitea < d:\backup\gitea-db.sql再把repos目录覆盖回去,最后重启Gitea。注意顺序,先库后仓,确保数据库里的仓库记录能对应上磁盘上的裸仓库。
如果只是Gitea本身出问题需要重装,新配置的app.ini里的ROOT_URL、数据库配置必须和原来的保持一致,否则恢复后页面里的链接会乱。Nginx的proxy配置同理,必须能把请求转发到Gitea的3000端口。
5.4 升级Gitea的正确姿势
Gitea的升级不频繁但也不罕见,三五个月出一个版本很正常。升级流程不复杂,但有几个细节必须注意。
第一步,备份(按5.2完整备份)。第二步,停服务:nssm stop Gitea。第三步,备份旧的gitea.exe,再把新版exe放到程序目录覆盖。第四步,重启服务:nssm start Gitea。第五步,在浏览器里访问,Gitea会自动执行数据库迁移,页面可能会提示“数据迁移中”,等它跑完就行。
升级过程中遇到过一个问题:新版Gitea启动后提示数据库版本过旧,需要执行gitea migrate命令。遇到这种情况,在cmd里切换到程序目录执行:
gitea.exe migrate然后重启服务就好了。这个命令本质是手动触发数据库迁移,正常升级时服务启动会自动执行,只有异常情况才需要手动。
升级后记得在后台管理页面检查一下版本号,确认升级成功。如果升级后页面样式错乱或功能异常,多半是缓存问题,重启Nginx和Gitea都能解决,不用太紧张。
6. 使用中的避坑心得与性能表现
6.1 我踩过的几个典型的Windows环境坑
坑一:SSH端口被OpenSSH占掉
Windows 10/Server 2016以上的系统默认自带OpenSSH Server,监听22端口。Gitea默认也监听22,俩服务撞车,Gitea启动失败。我当时查日志才定位到问题。两个解决办法:停掉系统OpenSSH服务,或者改Gitea的SSH端口为2222。我选了后者,因为系统里还有其他操作需要SSH。改了端口后,团队成员clone地址会自动带上端口号,Gitea页面里生成的SSH克隆地址也会自动变成ssh://git@git.example.com:2222/user/repo.git这种格式,不用手动改。
坑二:Windows防火墙拦截端口
服务器第一次部署后,本机能访问Gitea,但同事电脑打不开页面。排查了一圈,发现是防火墙拦了3000端口和2222端口。Windows上开放端口要用管理员cmd执行:
netsh advfirewall firewall add rule name="Gitea Web Port" dir=in action=allow protocol=TCP localport=3000 netsh advfirewall firewall add rule name="Gitea SSH Port" dir=in action=allow protocol=TCP localport=2222如果走了Nginx,Nginx监听的80/443端口也需要同步放行。
坑三:文件权限问题导致克隆异常
Windows下文件权限偶尔会闹脾气,表现为:匿名访问正常,但带认证的某用户访问仓库时403;或者后端日志里出现Permission denied。大多数情况下和Git仓库所在目录的NTFS权限有关。把整个D:\GiteaData目录授权给运行NSSM服务的用户,并且确保管理员账号对目录有完全控制权,问题基本能解决。
坑四:push大文件超时
团队里有同事喜欢把编译产物直接推进仓库,几十MB的包还好,但上到几百MB时,Nginx默认的proxy_read_timeout会导致push中途断开,报“Connection reset by peer”。需要调整Nginx的超时配置:
location / { proxy_connect_timeout 600; proxy_send_timeout 600; proxy_read_timeout 600; }同时也提醒团队成员:大文件该用Git LFS就用Git LFS,别硬塞普通Git仓库里,除非想看到仓库体积失控。
6.2 性能表现和团队使用实测
Gitea跑在4G内存的Windows Server 2022上,给了2G虚拟内存,系统硬盘是SSD。日常用下来,仓库操作响应很快,push pull基本秒开。后台管理页面偶尔稍慢,但也在可接受范围内。团队五六个人同时开发,并发push频繁时段,Gitea的CPU占用也没有突然飙升,整体维持得很平稳。
内存占用方面,Gitea进程稳定在300M左右,比GitLab动辄2G+的内存占用舒服太多。算上Nginx和MySQL,整个服务栈加起来不到1G内存,完全可以在别的服务共存的机器上部署,资源压力很小。
6.3 后续可以扩展的方向
Gitea部署稳定之后,我又陆续加了两块东西。
一个是Gitea Actions,在仓库里放个.gitea/workflows目录,定义好CI任务,每次push后自动跑编译和测试。虽然是刚需但不复杂,市面上关于Actions的在线Runner资料很多,照着配置就行。Windows环境重点看Runner服务怎么注册成Windows服务,方法和NSSM注册Gitea一模一样,套路都是现成的。
另一个是Webhook通知。Gitea支持Webhook,把这几个常用事件的Webhook挂上之后,代码push、Issue变更、PR操作都会自动通知到团队群里(比如企业微信、钉钉、飞书机器人),成员不用天天打开Gitea网页刷动态。
还有一个可以研究的是LDAP集成。如果团队用的是Windows域账号,Gitea的LDAP认证配置好以后,直接用域账号登录,省去单独管理Gitea账号的麻烦。这块我还没实际接入,但Gitea后台管理里就有相关配置入口,等团队规模再大一点,大概率会把这个提上日程。
7. 最后,几条实在的运维建议
部署稳定跑了快半年,有些体会值得唠一唠。
首先,Windows下跑Gitea完全可以当生产环境用,关键是把服务注册、反向代理、备份这老三样做好。我这个团队规模不大,现在这套方案和以前用商业平台相比,体验几乎没有差别,代码内网化之后传输速度和安全性反而是加分项。
其次,日志和监控不要省。NSSM输出日志、Gitea的日志文件,建议定期看一眼。很多问题出现之前,日志里已经有征兆了。什么时候磁盘满了、什么时候某个仓库异常大了,都躲不过日志。
再有,版本升级不要追新。Gitea的社区更新快,但也不是每次大版本都适合你。我一般会等新版本发布两三周、社区没什么大面积问题反馈后再动手升级。升级前备份永远是第一步,别以为小版本就无所谓,有一次从1.20升到1.21,光数据库迁移就跑了十分钟,数据多的时候真不是瞬间完成的事。
最后再分享一个小技巧:如果团队里有人不会用Git命令,Gitea的Web界面本身也能上传文件、编辑文件、创建分支、发起PR,完全可以通过网页操作完成大部分工作,这给团队里的新人降低了不小的入门门槛。我最初部署Gitea时,就是靠这一点说服了原本抗拒代码工具改革的同事。