diff options
author | 2024-03-09 20:27:23 +0800 | |
---|---|---|
committer | 2024-03-09 20:43:10 +0800 | |
commit | 85e45504af742098c5ebbfd662bd2e399974b9e3 (patch) | |
tree | 3c31e10d669842bf27b90c0ecc15c65ce22be10f | |
parent | 81248a94826e3ecc05cd6fdd7126078f3f2fc06b (diff) | |
download | myweb-85e45504af742098c5ebbfd662bd2e399974b9e3.tar.gz myweb-85e45504af742098c5ebbfd662bd2e399974b9e3.zip |
Add cgit for git-server web ui, record its method in gitserver.md
-rw-r--r-- | code/linux/gitserver.html | 434 | ||||
-rw-r--r-- | code/linux/gitserver.md | 485 | ||||
-rw-r--r-- | common/CSS/pandoc.css | 2 | ||||
-rw-r--r-- | common/script4works.html | 4 | ||||
-rw-r--r-- | common/script4works.js | 4 |
5 files changed, 884 insertions, 45 deletions
diff --git a/code/linux/gitserver.html b/code/linux/gitserver.html index ac3f07a..d0badaf 100644 --- a/code/linux/gitserver.html +++ b/code/linux/gitserver.html | |||
@@ -5,7 +5,7 @@ | |||
5 | <meta charset="utf-8" /> | 5 | <meta charset="utf-8" /> |
6 | <meta name="generator" content="pandoc" /> | 6 | <meta name="generator" content="pandoc" /> |
7 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> | 7 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> |
8 | <title>自己的git托管</title> | 8 | <title>自己的 git 托管</title> |
9 | <link rel="stylesheet" href="https://www.qin-juan-ge-zhu.top/common/CSS/pandoc.css"> | 9 | <link rel="stylesheet" href="https://www.qin-juan-ge-zhu.top/common/CSS/pandoc.css"> |
10 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/js/myhighlight.js"></script> | 10 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/js/myhighlight.js"></script> |
11 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/script4code.js"></script> | 11 | <script type="text/javascript" src="https://www.qin-juan-ge-zhu.top/common/script4code.js"></script> |
@@ -14,7 +14,7 @@ | |||
14 | <body> | 14 | <body> |
15 | <div class="pandoc"> | 15 | <div class="pandoc"> |
16 | <div class="main"> | 16 | <div class="main"> |
17 | <p class="title">自己的git托管</p> | 17 | <p class="title">自己的 git 托管</p> |
18 | <!-- git 远程存储 --> | 18 | <!-- git 远程存储 --> |
19 | <blockquote> | 19 | <blockquote> |
20 | <p>争名夺利几时休,早起迟眠不自由。</p> | 20 | <p>争名夺利几时休,早起迟眠不自由。</p> |
@@ -44,7 +44,7 @@ | |||
44 | <li>方便使用。创建专门用户后,我们可以为之配置 ssh 密钥,从而实现免密登陆,而且创建新仓库、clone 仓库都较为简单(因为直接托管在家目录之下,不需要记较长的路径名)</li> | 44 | <li>方便使用。创建专门用户后,我们可以为之配置 ssh 密钥,从而实现免密登陆,而且创建新仓库、clone 仓库都较为简单(因为直接托管在家目录之下,不需要记较长的路径名)</li> |
45 | </ul> | 45 | </ul> |
46 | <p>当然,创建单独用户的理由不止这么简单,它在我们使用 http 来托管仓库的时候有专门的作用,下文会讨论到。</p> | 46 | <p>当然,创建单独用户的理由不止这么简单,它在我们使用 http 来托管仓库的时候有专门的作用,下文会讨论到。</p> |
47 | <p>我为其创建了一个名为<code>git</code>的用户,家目录<code>/home/git</code>,但不授予 sudo 权限。</p> | 47 | <p>我为其创建了一个名为<code>git</code>的用户,家目录<code>/home/git</code>,但<strong>不授予 sudo 权限</strong>。</p> |
48 | <h1 id="ssh-服务">ssh 服务</h1> | 48 | <h1 id="ssh-服务">ssh 服务</h1> |
49 | <p>首先,本方法要求有一个本地 git 存储库,并且已经有 commit。如果是本地新建的仓库,需要先有一个 commit,然后继续操作。这个 commit | 49 | <p>首先,本方法要求有一个本地 git 存储库,并且已经有 commit。如果是本地新建的仓库,需要先有一个 commit,然后继续操作。这个 commit |
50 | 可以用编写<code>.gitignore</code>或者<code>push.sh</code>等不甚重要的文件来凑数。</p> | 50 | 可以用编写<code>.gitignore</code>或者<code>push.sh</code>等不甚重要的文件来凑数。</p> |
@@ -70,8 +70,8 @@ bash push.sh</code></pre> | |||
70 | read -p "Local repo name: " local_name | 70 | read -p "Local repo name: " local_name |
71 | read -p "Remote repo name: " remote_name | 71 | read -p "Remote repo name: " remote_name |
72 | 72 | ||
73 | # 远程仓库创建 | 73 | # 远程仓库创建,用的时候记得改服务器地址 |
74 | tmp="ssh aliyun-git git init --bare $remote_name.git" | 74 | tmp="ssh your-server git init --bare $remote_name.git" |
75 | eval "$tmp" | 75 | eval "$tmp" |
76 | 76 | ||
77 | # 本地仓库创建 | 77 | # 本地仓库创建 |
@@ -123,7 +123,7 @@ echo "Success!"</code></pre> | |||
123 | <p>于是,我发现了一篇<a | 123 | <p>于是,我发现了一篇<a |
124 | href="https://www.aneasystone.com/archives/2018/12/build-your-own-git-server.html">教程</a>,照葫芦画瓢起来。 | 124 | href="https://www.aneasystone.com/archives/2018/12/build-your-own-git-server.html">教程</a>,照葫芦画瓢起来。 |
125 | </p> | 125 | </p> |
126 | <p>需要注意的是,<strong>上面的 ssh 服务不一定需要专门创建用户,但 http(s)服务这里我推荐新建用户</strong>。</p> | 126 | <p>需要注意的是,<strong>仍然建议为 git 仓库专门建用户</strong>。</p> |
127 | <h2 id="配套软件安装">配套软件安装</h2> | 127 | <h2 id="配套软件安装">配套软件安装</h2> |
128 | <p>首先,我们需要安装<code>git</code>和<code>nginx</code>,这里不再赘述。除此之外,我们会用到以下软件:</p> | 128 | <p>首先,我们需要安装<code>git</code>和<code>nginx</code>,这里不再赘述。除此之外,我们会用到以下软件:</p> |
129 | <ul> | 129 | <ul> |
@@ -212,16 +212,16 @@ admin [27/Nov/2018:22:19:33] "POST /test.git/git-receive-pack HTTP/1.1" | |||
212 | <pre><code>server | 212 | <pre><code>server |
213 | { | 213 | { |
214 | listen 80; | 214 | listen 80; |
215 | server_name git.qin-juan-ge-zhu.top; | 215 | server_name git.player.com; |
216 | return 301 https://$host$request_uri; | 216 | return 301 https://$host$request_uri; |
217 | } | 217 | } |
218 | server | 218 | server |
219 | { | 219 | { |
220 | server_name git.qin-juan-ge-zhu.top; | 220 | server_name git.player.com; |
221 | listen 443 ssl; | 221 | listen 443 ssl; |
222 | 222 | ||
223 | ssl_certificate /etc/letsencrypt/live/git.qin-juan-ge-zhu.top/fullchain.pem; | 223 | ssl_certificate /etc/letsencrypt/live/git.player.com/fullchain.pem; |
224 | ssl_certificate_key /etc/letsencrypt/live/git.qin-juan-ge-zhu.top/privkey.pem; | 224 | ssl_certificate_key /etc/letsencrypt/live/git.player.com/privkey.pem; |
225 | 225 | ||
226 | location @auth { | 226 | location @auth { |
227 | auth_basic "Git Server"; | 227 | auth_basic "Git Server"; |
@@ -337,26 +337,410 @@ fatal: repository 'https://git.player.com/test.git/' not found</code></p | |||
337 | <pre><code>usermod -aG git root | 337 | <pre><code>usermod -aG git root |
338 | usermod -aG git www-data</code></pre> | 338 | usermod -aG git www-data</code></pre> |
339 | <p>此时再进行测试,应该就可以正常使用了。</p> | 339 | <p>此时再进行测试,应该就可以正常使用了。</p> |
340 | <h2 id="其他存在的问题">其他存在的问题</h2> | 340 | <h1 id="cgit-拥抱图形化">cgit 拥抱图形化</h1> |
341 | <p>到了 http(s)服务这里,我们在命令行里进行 git 操作的需求已经基本得到了满足。但是,生命不息,折腾不止,我们发现有一个能图形化显示仓库的界面、并且要仍然能在命令行里进行仓库操作,最是舒坦。</p> | ||
342 | <ul> | ||
343 | <li>GitList 的界面看起来不错,而且能展示源码、clone 链接之类的,整体非常像 github 的界面,可惜使用的是我不会的 php 语言,而且没有找到详细一些的安装使用教程</li> | ||
344 | <li>cgit 是一个用纯 C 语言开发的一个 git 裸库展示,虽然界面看起来比较古早,但功能简单、强大,能展示源码、自由切换分支、方便地查看提交历史(diss 一下 github,github | ||
345 | 查看提交历史看起来真的很不方便很不直观)。诸如<a href="https://git.kernel.org">Linux 内核</a>等项目都在使用。</li> | ||
346 | </ul> | ||
347 | <p>选择了 cgit,我找到了又一位大佬的<a | ||
348 | href="https://blog.dejavu.moe/posts/hosting-minimal-git-server-with-cgit">博客</a>,非常详细。需要注意的是,<strong>我们仍然需要一个专门的用户。</strong> | ||
349 | </p> | ||
350 | <h2 id="依赖">依赖</h2> | ||
351 | <p><code>nginx</code>/<code>git</code>/<code>vim</code>等工具不必赘述,还有一些依赖项需要安装:</p> | ||
352 | <pre><code># apache2-utils是用其htpasswd命令创建认证文件的 | ||
353 | # fcgiwrap是用于将 FastCGI 转换为 HTTP 协议的工具 | ||
354 | # 这两个工具上文均已提到和使用,不再赘述 | ||
355 | sudo apt update | ||
356 | sudo apt install -y apache2-utils fcgiwrap | ||
357 | |||
358 | # 编译过程中需要openssl的头文件 | ||
359 | sudo apt install -y libssl-dev | ||
360 | |||
361 | # 建议为cgit提供lua支持,用来进行个性化的设置 | ||
362 | # 本文以 lua5.1 为例 | ||
363 | sudo apt install liblua5.1-0 liblua5.1-0-dbg liblua5.1-dev lua5.1</code></pre> | ||
364 | <h2 id="cgit-安装">cgit 安装</h2> | ||
365 | <p>cgit 最近的正式发行版已经好几年了,但是它的开发仍然很活跃,所以建议从它的 git 仓库中获取最新的代码,而非直接安装:</p> | ||
366 | <pre><code>git clone https://git.zx2c4.com/cgit | ||
367 | cd cgit | ||
368 | git submodule init | ||
369 | git submodule update</code></pre> | ||
370 | <p>在仓库目录下创建<code>cgit.conf</code>文件,用来存放 cgit 构建时可以覆盖的配置:</p> | ||
371 | <pre><code>sed -n '3,31p' Makefile > cgit.conf</code></pre> | ||
372 | <p>我们可以按需编辑之:</p> | ||
373 | <pre><code>CGIT_VERSION = v1.2.3 | ||
374 | CGIT_SCRIPT_NAME = cgit.cgi | ||
375 | CGIT_SCRIPT_PATH = /var/www/cgit # 本文只改了这里 | ||
376 | CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH) | ||
377 | CGIT_CONFIG = /etc/cgitrc # 默认配置文件路径 | ||
378 | CACHE_ROOT = /var/cache/cgit | ||
379 | prefix = /usr/local | ||
380 | libdir = $(prefix)/lib | ||
381 | filterdir = $(libdir)/cgit/filters | ||
382 | docdir = $(prefix)/share/doc/cgit | ||
383 | htmldir = $(docdir) | ||
384 | pdfdir = $(docdir) | ||
385 | mandir = $(prefix)/share/man | ||
386 | SHA1_HEADER = <openssl/sha.h> | ||
387 | GIT_VER = 2.39.0 | ||
388 | GIT_URL = https://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.xz | ||
389 | INSTALL = install | ||
390 | COPYTREE = cp -r | ||
391 | MAN5_TXT = $(wildcard *.5.txt) | ||
392 | MAN_TXT = $(MAN5_TXT) | ||
393 | DOC_MAN5 = $(patsubst %.txt,%,$(MAN5_TXT)) | ||
394 | DOC_HTML = $(patsubst %.txt,%.html,$(MAN_TXT)) | ||
395 | DOC_PDF = $(patsubst %.txt,%.pdf,$(MAN_TXT)) | ||
396 | |||
397 | ASCIIDOC = asciidoc | ||
398 | ASCIIDOC_EXTRA = | ||
399 | ASCIIDOC_HTML = xhtml11 | ||
400 | ASCIIDOC_COMMON = $(ASCIIDOC) $(ASCIIDOC_EXTRA) | ||
401 | TXT_TO_HTML = $(ASCIIDOC_COMMON) -b $(ASCIIDOC_HTML)</code></pre> | ||
402 | <p>编译 && 安装:</p> | ||
403 | <pre><code># 如果不需要lua支持 | ||
404 | make NO_LUA=1 | ||
405 | # 有lua支持的话 | ||
406 | make LUA_PKGCONFIG=lua5.1 | ||
407 | |||
408 | # 安装,注意一下安装路径 | ||
409 | # 不妨将输出写到日志里,以便查看 | ||
410 | sudo make install | tee install.log</code></pre> | ||
411 | <h2 id="nginx-配置">nginx 配置</h2> | ||
412 | <p>首先,参照<a href="认证文件">这里</a>生成一个自己的认证文件,再继续往下看。</p> | ||
413 | <p>在<code>/etc/nginx/git-http-backend.conf</code>中写入以下内容,注意把域名、ssl 路径、htpasswd 认证文件换成自己的:</p> | ||
414 | <pre><code># /etc/nginx/git-http-backend.conf | ||
415 | fastcgi_pass unix:/var/run/fcgiwrap.socket; | ||
416 | include fastcgi_params; | ||
417 | fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend; | ||
418 | fastcgi_param GIT_HTTP_EXPORT_ALL ""; | ||
419 | fastcgi_param GIT_PROJECT_ROOT /home/git; | ||
420 | fastcgi_param PATH_INFO $1; | ||
421 | fastcgi_param REMOTE_USER $remote_user;</code></pre> | ||
422 | <p>而后,在<code>/etc/nginx/conf.d/cgit.conf</code>中写:</p> | ||
423 | <pre><code># /etc/nginx/conf.d/cgit.conf | ||
424 | server { | ||
425 | listen 80; | ||
426 | server_name git.player.com; | ||
427 | return 301 https://$server_name$request_uri; | ||
428 | } | ||
429 | |||
430 | server { | ||
431 | server_name git.player.com; | ||
432 | listen 443 ssl http2; | ||
433 | |||
434 | ssl_certificate /etc/letsencrypt/live/git.player.com/fullchain.pem; | ||
435 | ssl_certificate_key /etc/letsencrypt/live/git.player.com/privkey.pem; | ||
436 | |||
437 | # SSL Security | ||
438 | ssl_protocols TLSv1.2 TLSv1.3; | ||
439 | ssl_prefer_server_ciphers on; | ||
440 | ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256; | ||
441 | |||
442 | ssl_session_timeout 1d; | ||
443 | ssl_session_cache shared:SSL:10m; | ||
444 | |||
445 | # Site Log path | ||
446 | access_log /var/log/nginx/cgit-access.log; | ||
447 | error_log /var/log/nginx/cgit-error.log; | ||
448 | |||
449 | root /var/www/cgit; | ||
450 | try_files $uri @cgit; | ||
451 | client_max_body_size 10m; | ||
452 | |||
453 | location @cgit { | ||
454 | include fastcgi_params; | ||
455 | # cgit's CGI script path | ||
456 | fastcgi_param SCRIPT_FILENAME /var/www/cgit/cgit.cgi; | ||
457 | fastcgi_param DOCUMENT_ROOT /usr/lib/git-core; | ||
458 | fastcgi_pass unix:/var/run/fcgiwrap.socket; | ||
459 | fastcgi_param PATH_INFO $uri; | ||
460 | fastcgi_param QUERY_STRING $args; | ||
461 | fastcgi_param HTTP_HOST $server_name; | ||
462 | fastcgi_param GIT_HTTP_EXPORT_ALL ""; | ||
463 | fastcgi_param GIT_PROJECT_ROOT /home/git; | ||
464 | |||
465 | if ($arg_service = git-receive-pack) { | ||
466 | rewrite (/.*) /git_write/$1 last; | ||
467 | } | ||
468 | |||
469 | if ($uri ~ ^/.*/git-receive-pack$) { | ||
470 | rewrite (/.*) /git_write/$1 last; | ||
471 | } | ||
472 | |||
473 | if ($arg_service = git-upload-pack) { | ||
474 | rewrite (/.*) /git_read/$1 last; | ||
475 | } | ||
476 | |||
477 | if ($uri ~ ^/.*/git-upload-pack$) { | ||
478 | rewrite (/.*) /git_read/$1 last; | ||
479 | } | ||
480 | } | ||
481 | |||
482 | location ~ /git_read/(.*) { | ||
483 | include git-http-backend.conf; | ||
484 | } | ||
485 | |||
486 | location ~ /git_write/(.*) { | ||
487 | # HTTP Basic Authentication | ||
488 | auth_basic "Authentication Required To Push"; | ||
489 | auth_basic_user_file /etc/nginx/conf.d/git.htpasswd; | ||
490 | include git-http-backend.conf; | ||
491 | } | ||
492 | }</code></pre> | ||
493 | <p>最后,重启 nginx 服务:</p> | ||
494 | <pre><code>sudo nginx -s reload</code></pre> | ||
495 | <p><em>看吧,一个个仓库,向我们列队走来!</em></p> | ||
496 | <h2 id="cgit-高级配置">cgit 高级配置</h2> | ||
497 | <p>可以安装一些包,用于 cgit 的代码高亮、Markdown 渲染、Gravatar 头像渲染等:</p> | ||
498 | <pre><code>sudo apt install -y python3-docutils python3-markdown highlight python3-pygments | ||
499 | |||
500 | # 编译安装 LuaoSSL | ||
501 | # https://25thandclement.com/~william/projects/luaossl.html | ||
502 | git clone https://github.com/wahern/luaossl.git && cd luaossl | ||
503 | make LUAPKG=lua5.1 | ||
504 | sudo make install LUAPKG=lua5.1 | ||
505 | |||
506 | sudo mkdir -p /usr/local/share/cgit | ||
507 | sudo ln -s /usr/local/lib/cgit/filters /usr/local/share/cgit/filters | ||
508 | sudo chown -R www-data:www-data /usr/local/share/cgit/ | ||
509 | |||
510 | # 给下面使用 filter api 的脚本赋予可执行权限,比如 | ||
511 | sudo chmod +x /usr/local/share/cgit/filters/email-gravatar.lua</code></pre> | ||
512 | <p>然后编辑上边我们已经指定的配置文件<code>/etc/cgitrc</code>,更多配置项参见<a | ||
513 | href="https://git.zx2c4.com/cgit/tree/cgitrc.5.txt">cgitrc.5.txt</a>。</p> | ||
514 | <pre><code># /etc/cgitrc | ||
515 | # 包含 cgit 的所有运行时设置 | ||
516 | # 格式 NAME=VALUE | ||
517 | # 以 "#" 开头的行是注释 | ||
518 | |||
519 | # 全局配置 | ||
520 | css=/cgit.css | ||
521 | logo=/cgit.png | ||
522 | favicon=/favicon.ico | ||
523 | #footer= | ||
524 | virtual-root=/ | ||
525 | # 禁用哑克隆 | ||
526 | enable-http-clone=0 | ||
527 | |||
528 | # Smart HTTP | ||
529 | # 记得改成自己的链接 | ||
530 | clone-url=https://git.player.com/$CGIT_REPO_URL | ||
531 | # 首页标题显示的内容,改成你想要的 | ||
532 | root-title=GIT.PLAYER.COM | ||
533 | root-desc=YOUR.WORDS | ||
534 | # 在首页展示的介绍信息,可用md/man/html等 | ||
535 | # 详参/usr/local/share/cgit/filters/about-formatting.sh | ||
536 | root-readme=/var/www/cgit/README.md | ||
537 | |||
538 | # 建议配置 | ||
539 | enable-index-owner=1 | ||
540 | enable-index-links=1 | ||
541 | enable-blame=1 | ||
542 | enable-log-filecount=1 | ||
543 | enable-log-linecount=1 | ||
544 | enable-commit-graph=1 | ||
545 | |||
546 | # 禁止搜素引擎索引 | ||
547 | robots=noindex, nofollow | ||
548 | |||
549 | branch-sort=age | ||
550 | commit-sort=date | ||
551 | max-stats=quarter | ||
552 | snapshots=tar.gz zip | ||
553 | |||
554 | # 使用 RAM 的缓存大小 单位 MB | ||
555 | cache-size=1024 | ||
556 | |||
557 | # 代码高亮 | ||
558 | source-filter=/usr/local/share/cgit/filters/syntax-highlighting.py | ||
559 | |||
560 | # 格式化贡献者,显示Gravatar头像 | ||
561 | email-filter=lua:/usr/local/share/cgit/filters/email-gravatar.lua | ||
562 | |||
563 | # 格式化 about 页面 | ||
564 | about-filter=/usr/local/share/cgit/filters/about-formatting.sh | ||
565 | readme=:README.md | ||
566 | readme=:readme.md | ||
567 | readme=:README.txt | ||
568 | readme=:readme.txt | ||
569 | readme=:README | ||
570 | readme=:readme | ||
571 | |||
572 | # MIME 类型 | ||
573 | mimetype.html=text/html | ||
574 | mimetype.gif=image/gif | ||
575 | mimetype.jpg=image/jpeg | ||
576 | mimetype.jpeg=image/jpeg | ||
577 | mimetype.png=image/png | ||
578 | mimetype.webp=image/webp | ||
579 | mimetype.pdf=application/pdf | ||
580 | mimetype.svg=image/svg+xml | ||
581 | |||
582 | # 移除 .git 后缀,很有必要 | ||
583 | remove-suffix=1 | ||
584 | |||
585 | # 扫描路径 | ||
586 | scan-path=/home/git | ||
587 | |||
588 | # 每个存储库配置 | ||
589 | #repo.url=reponame | ||
590 | #repo.path=/home/git/reponame.git | ||
591 | #repo.desc=Some description here | ||
592 | #repo.owner=Owner Name | ||
593 | #repo.logo=/repo-logo.png</code></pre> | ||
594 | <h3 id="高亮风格">高亮风格</h3> | ||
595 | <p>在上面的配置文件里,我们使用了<a href="https://pygments.org/styles/">Pygments</a>的代码高亮。其默认使用的高亮是 | ||
596 | pastie,我们可以根据自己的喜好修改高亮风格。</p> | ||
597 | <p>首先,看看有哪些可用的高亮风格。</p> | ||
598 | <pre><code># 查看可用的高亮风格 | ||
599 | pygmentize -L styles | ||
600 | |||
601 | # 编辑我们使用的代码高亮脚本 | ||
602 | sudo vim /usr/local/share/cgit/filters/syntax-highlighting.py</code></pre> | ||
603 | <h3 id="gravatar-头像">Gravatar 头像</h3> | ||
604 | <p>在上述配置中,我们使用了 Gravatar 头像。<a href="https://cn.gravatar.com/">Gravatar</a> | ||
605 | 是一个全球通用的头像服务,根据你使用的邮箱(而非用户身份)来为你提供头像。换言之,只要你的邮箱注册了 Gravatar,那么你在任何一个支持 Gravatar 的网站上都可以使用你的 Gravatar | ||
606 | 头像。这对于我们这种不想做登录、又想展示用户的网站来说,是一个很好的选择。</p> | ||
607 | <ul> | ||
608 | <li><a href="https://cn.gravatar.com/">中文官网</a></li> | ||
609 | <li><a href="https://gravatar.com/">英文官网</a></li> | ||
610 | </ul> | ||
611 | <p>由于 Gravatar 中文官网访问比较慢(不知道为什么,英文官网我挂了梯子还上不去),我们可以使用国内的镜像服务。这里有一篇常用镜像服务的<a | ||
612 | href="https://luoxx.top/archives/gravatar-mirror-2022">博客</a>。我使用的是<a | ||
613 | href="https://cravatar.cn/">Cravatar</a>。</p> | ||
614 | <p>使用流程都是基本一致的,在这个网站上注册账号,上传头像,然后根据网站提供的 API | ||
615 | 来获取。一般方式为<code>https://域名.com/avatar/邮箱的md5值</code>。在我们使用的脚本<code>/usr/local/share/cgit/filters/email-gravatar.lua</code>中,将原有的域名替换为我们使用的域名即可。 | ||
616 | </p> | ||
617 | <p>cgit 的<a href="https://git.zx2c4.com/cgit/">官网</a>上不仅能实现 Gravatar 头像,还能在鼠标移动到头像上的时候以大图显示。这不是原生功能,而是需要动 | ||
618 | lua 脚本自己实现。原博客大佬在 cgit 的<a | ||
619 | href="https://lists.zx2c4.com/pipermail/cgit/2014-March/002036.html">邮件列表</a>找到了实现方式。</p> | ||
620 | <pre><code>sudo vim /usr/local/share/cgit/filters/email-libravatar-korg.lua</code></pre> | ||
621 | <p>在脚本中写入以下内容:</p> | ||
622 | <pre><code>-- This script may be used with the email-filter or repo.email-filter settings in cgitrc. | ||
623 | -- It adds gravatar icons to author names. It is designed to be used with the lua: | ||
624 | -- prefix in filters. It is much faster than the corresponding python script. | ||
625 | -- | ||
626 | -- Requirements: | ||
627 | -- luaossl | ||
628 | -- <http://25thandclement.com/~william/projects/luaossl.html> | ||
629 | -- | ||
630 | |||
631 | local digest = require("openssl.digest") | ||
632 | |||
633 | function md5_hex(input) | ||
634 | local b = digest.new("md5"):final(input) | ||
635 | local x = "" | ||
636 | for i = 1, #b do | ||
637 | x = x .. string.format("%.2x", string.byte(b, i)) | ||
638 | end | ||
639 | return x | ||
640 | end | ||
641 | |||
642 | function filter_open(email, page) | ||
643 | buffer = "" | ||
644 | md5 = md5_hex(email:sub(2, -2):lower()) | ||
645 | end | ||
646 | |||
647 | function filter_close() | ||
648 | html("<span class='libravatar'>" .. | ||
649 | "<img class='inline' src='//www.gravatar.com/avatar/" .. md5 .. "?s=13&d=retro' />" .. | ||
650 | "<img class='onhover' src='//www.gravatar.com/avatar/" .. md5 .. "?s=128&d=retro' />" .. | ||
651 | "</span>" .. buffer) | ||
652 | return 0 | ||
653 | end | ||
654 | |||
655 | function filter_write(str) | ||
656 | buffer = buffer .. str | ||
657 | end</code></pre> | ||
658 | <p>只有 lua 还不够,我们需要将以下内容添加到<code>/var/www/cgit/cgit.css</code>中:</p> | ||
659 | <pre><code>/* libgravatar */ | ||
660 | div#cgit span.libravatar img.onhover { | ||
661 | display: none; | ||
662 | border: 1px solid gray; | ||
663 | padding: 0px; | ||
664 | -webkit-border-radius: 4px; | ||
665 | -moz-border-radius: 4px; | ||
666 | border-radius: 4px; | ||
667 | width: 128px; | ||
668 | height: 128px; | ||
669 | } | ||
670 | |||
671 | div#cgit span.libravatar img.inline { | ||
672 | -webkit-border-radius: 3px; | ||
673 | -moz-border-radius: 3px; | ||
674 | border-radius: 3px; | ||
675 | width: 13px; | ||
676 | height: 13px; | ||
677 | margin-right: 0.4em; | ||
678 | opacity: 0.9; | ||
679 | } | ||
680 | |||
681 | div#cgit span.libravatar:hover > img.onhover { | ||
682 | display: block; | ||
683 | position: absolute; | ||
684 | margin-left: 1.5em; | ||
685 | background-color: #eeeeee; | ||
686 | box-shadow: 5px 5px 3px #bbb; | ||
687 | }</code></pre> | ||
688 | <p>而后,修改<code>/etc/cgitrc</code>中的<code>email-filter</code>的值为我们新建的脚本<code>lua:/usr/local/share/cgit/filters/email-libravatar-korg.lua</code>,就好了。 | ||
689 | </p> | ||
690 | <h3 id="添加-readme">添加 README</h3> | ||
691 | <p>在<code>/etc/cgitrc</code>中,我们指定了<code>root-readme</code>,这是用来在网站主页展示 README 的。我们可以编写一个 README | ||
692 | 文件,然后在<code>/etc/cgitrc</code>中指明它的路径。README | ||
693 | 可以使用<code>markdown</code>/<code>man</code>/<code>rst</code>/html<code>/</code>txt`等格式。</p> | ||
694 | <p>我使用的是<code>markdown</code>格式,在<code>/var/www/cgit/</code>中创建了一个<code>README.md</code>文件,然后在<code>/etc/cgitrc</code>中指明了路径。 | ||
695 | </p> | ||
696 | <h3 id="样式修改">样式修改</h3> | ||
697 | <p>对于 cgit 显示出来的界面,你可能并不太满意(比如我就嫌界面的字太小、颜色不舒适啥的)。修改办法也很简单,找到<code>/var/www/cgit/cgit.css</code>文件,然后修改之。</p> | ||
698 | <p>而对于我们的 Markdown 或者别的什么语言写的 README,如果觉得渲染效果不好,都是可以自己去修改的。</p> | ||
699 | <p>找到<code>/usr/local/share/cgit/filters/about-formatting.sh</code>文件,我们会看到以下内容:</p> | ||
700 | <pre><code>#!/bin/sh | ||
701 | |||
702 | # This may be used with the about-filter or repo.about-filter setting in cgitrc. | ||
703 | # It passes formatting of about pages to differing programs, depending on the usage. | ||
704 | |||
705 | # Markdown support requires python and markdown-python. | ||
706 | # RestructuredText support requires python and docutils. | ||
707 | # Man page support requires groff. | ||
708 | |||
709 | # The following environment variables can be used to retrieve the configuration | ||
710 | # of the repository for which this script is called: | ||
711 | # CGIT_REPO_URL ( = repo.url setting ) | ||
712 | # CGIT_REPO_NAME ( = repo.name setting ) | ||
713 | # CGIT_REPO_PATH ( = repo.path setting ) | ||
714 | # CGIT_REPO_OWNER ( = repo.owner setting ) | ||
715 | # CGIT_REPO_DEFBRANCH ( = repo.defbranch setting ) | ||
716 | # CGIT_REPO_SECTION ( = section setting ) | ||
717 | # CGIT_REPO_CLONE_URL ( = repo.clone-url setting ) | ||
718 | |||
719 | cd "$(dirname $0)/html-converters/" | ||
720 | case "$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')" in | ||
721 | *.markdown|*.mdown|*.md|*.mkd) exec ./md2html; ;; | ||
722 | *.rst) exec ./rst2html; ;; | ||
723 | *.[1-9]) exec ./man2html; ;; | ||
724 | *.htm|*.html) exec cat; ;; | ||
725 | *.txt|*) exec ./txt2html; ;; | ||
726 | esac</code></pre> | ||
727 | <p>从这里可以看到,负责渲染的是<code>/usr/local/share/cgit/filters/html-converters</code>文件夹中的对于脚本。我们可以自己修改这些脚本,或者自己添加新的脚本,来实现自己想要的渲染效果。 | ||
728 | </p> | ||
729 | <p>当然,除了网站主页的 README,我们还可以在每个仓库的主页上添加 README。只需要在仓库的根目录下添加 README 文件即可。然后网页上仓库的标签页就会有“About”标签页,显示 README.md | ||
730 | 的内容。</p> | ||
731 | <p>到这里,cgit 的配置就基本完成了。重启 nginx 服务,然后访问你的域名,就可以看到一个很漂亮的界面了;命令行里,也可以 clone、push、fetch、pull 我们托管的仓库。大功告成!</p> | ||
732 | <h1 id="其他存在的问题">其他存在的问题</h1> | ||
341 | <p>除了上述问题已经解决之外,还有一些问题依然存在:</p> | 733 | <p>除了上述问题已经解决之外,还有一些问题依然存在:</p> |
342 | <ul> | 734 | <ul> |
343 | <li>不管是 nginx 还是 git,在使用 http 上传的时候都会有一定的缓冲区限制,如果上传文件过大或累计多个 commit 才上传,很可能被拒收导致上传失败。这个问题在 github | 735 | <li>不管是 nginx 还是 git,在使用 http 上传的时候都会有一定的<strong>缓冲区限制,如果上传文件过大或累计多个 commit |
344 | 上也存在,但是 github 的缓冲区限制比较大,一般不会出现这个问题。但是我们的服务器配置比较低,所以这个问题就比较严重了。解决办法是在 nginx | 736 | 才上传,很可能被拒收导致上传失败</strong>。这个问题在 github 上也存在,但是 github |
737 | 的缓冲区限制比较大,一般不会出现这个问题;我们的服务器配置比较低,所以这个问题就比较严重了。解决办法是在 nginx | ||
345 | 的配置文件中添加<code>client_max_body_size 100m;</code>,这样就可以将缓冲区限制扩大到 100M,一般来说足够了。</li> | 738 | 的配置文件中添加<code>client_max_body_size 100m;</code>,这样就可以将缓冲区限制扩大到 100M,一般来说足够了。</li> |
346 | <li>即使解决了缓冲区大小,偶尔也会被拒收,原因尚未查清</li> | 739 | <li>即使解决了缓冲区大小,偶尔也会被拒收,原因尚未查清</li> |
347 | <li>尚未能通过访问特定链接来实现 git 仓库的创建。据说是用 nginx 调用脚本,但暂时没弄出来</li> | 740 | <li><strong>尚未能通过访问特定链接来实现 git 仓库的创建。</strong>据说是用 nginx 调用脚本,但暂时没弄出来</li> |
348 | <li>没有一个比较好用且功能较为完备的图形化界面(就像 github 那样)。 | ||
349 | <ul> | ||
350 | <li>GitList 的界面看起来不错,而且能展示源码、clone 链接之类的,整体非常像 github 的界面,可惜使用的是我不会的 php 语言,而且没有找到详细一些的安装使用教程 | ||
351 | </li> | ||
352 | <li>cgit 是一个用纯 C 语言开发的一个 git 裸库展示,虽然界面看起来比较古早,但功能也很不错,能展示源码、自由切换分支、方便地查看提交历史(diss 一下 | ||
353 | github,github 查看提交历史看起来真的很不方便很不直观)。美中不足的是<strong>无法在界面上提供 clone | ||
354 | 和源码下载功能</strong>。不过毕竟是个开源软件,而且是我比较熟悉的 C,等有时间有能力了看看自己能不能实现这个功能吧。</li> | ||
355 | </ul> | ||
356 | </li> | ||
357 | </ul> | 741 | </ul> |
358 | <p>这篇博客前前后后有二十多天了,该结。闲言少叙,看电视去也~</p> | 742 | <p>这篇博客前前后后有二十多天了,折腾吧。看电视去也~</p> |
359 | <p class="time">2024.1.3</p> | 743 | <!-- 2024.1.3 --> |
360 | <script src="https://www.qin-juan-ge-zhu.top/common/js/comment.js"></script> | 744 | <script src="https://www.qin-juan-ge-zhu.top/common/js/comment.js"></script> |
361 | </div> | 745 | </div> |
362 | </div> | 746 | </div> |
diff --git a/code/linux/gitserver.md b/code/linux/gitserver.md index d0ed6d9..53add30 100644 --- a/code/linux/gitserver.md +++ b/code/linux/gitserver.md | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | 当然,创建单独用户的理由不止这么简单,它在我们使用 http 来托管仓库的时候有专门的作用,下文会讨论到。 | 31 | 当然,创建单独用户的理由不止这么简单,它在我们使用 http 来托管仓库的时候有专门的作用,下文会讨论到。 |
32 | 32 | ||
33 | 我为其创建了一个名为`git`的用户,家目录`/home/git`,但不授予 sudo 权限。 | 33 | 我为其创建了一个名为`git`的用户,家目录`/home/git`,但**不授予 sudo 权限**。 |
34 | 34 | ||
35 | # ssh 服务 | 35 | # ssh 服务 |
36 | 36 | ||
@@ -70,8 +70,8 @@ bash push.sh | |||
70 | read -p "Local repo name: " local_name | 70 | read -p "Local repo name: " local_name |
71 | read -p "Remote repo name: " remote_name | 71 | read -p "Remote repo name: " remote_name |
72 | 72 | ||
73 | # 远程仓库创建 | 73 | # 远程仓库创建,用的时候记得改服务器地址 |
74 | tmp="ssh aliyun-git git init --bare $remote_name.git" | 74 | tmp="ssh your-server git init --bare $remote_name.git" |
75 | eval "$tmp" | 75 | eval "$tmp" |
76 | 76 | ||
77 | # 本地仓库创建 | 77 | # 本地仓库创建 |
@@ -121,7 +121,7 @@ echo "Success!" | |||
121 | 121 | ||
122 | 于是,我发现了一篇[教程](https://www.aneasystone.com/archives/2018/12/build-your-own-git-server.html),照葫芦画瓢起来。 | 122 | 于是,我发现了一篇[教程](https://www.aneasystone.com/archives/2018/12/build-your-own-git-server.html),照葫芦画瓢起来。 |
123 | 123 | ||
124 | 需要注意的是,**上面的 ssh 服务不一定需要专门创建用户,但 http(s)服务这里我推荐新建用户**。 | 124 | 需要注意的是,**仍然建议为 git 仓库专门建用户**。 |
125 | 125 | ||
126 | ## 配套软件安装 | 126 | ## 配套软件安装 |
127 | 127 | ||
@@ -224,16 +224,16 @@ admin [27/Nov/2018:22:19:33] "POST /test.git/git-receive-pack HTTP/1.1" 200 63 " | |||
224 | server | 224 | server |
225 | { | 225 | { |
226 | listen 80; | 226 | listen 80; |
227 | server_name git.qin-juan-ge-zhu.top; | 227 | server_name git.player.com; |
228 | return 301 https://$host$request_uri; | 228 | return 301 https://$host$request_uri; |
229 | } | 229 | } |
230 | server | 230 | server |
231 | { | 231 | { |
232 | server_name git.qin-juan-ge-zhu.top; | 232 | server_name git.player.com; |
233 | listen 443 ssl; | 233 | listen 443 ssl; |
234 | 234 | ||
235 | ssl_certificate /etc/letsencrypt/live/git.qin-juan-ge-zhu.top/fullchain.pem; | 235 | ssl_certificate /etc/letsencrypt/live/git.player.com/fullchain.pem; |
236 | ssl_certificate_key /etc/letsencrypt/live/git.qin-juan-ge-zhu.top/privkey.pem; | 236 | ssl_certificate_key /etc/letsencrypt/live/git.player.com/privkey.pem; |
237 | 237 | ||
238 | location @auth { | 238 | location @auth { |
239 | auth_basic "Git Server"; | 239 | auth_basic "Git Server"; |
@@ -354,15 +354,470 @@ usermod -aG git www-data | |||
354 | 354 | ||
355 | 此时再进行测试,应该就可以正常使用了。 | 355 | 此时再进行测试,应该就可以正常使用了。 |
356 | 356 | ||
357 | ## 其他存在的问题 | 357 | # cgit 拥抱图形化 |
358 | |||
359 | 到了 http(s)服务这里,我们在命令行里进行 git 操作的需求已经基本得到了满足。但是,生命不息,折腾不止,我们发现有一个能图形化显示仓库的界面、并且要仍然能在命令行里进行仓库操作,最是舒坦。 | ||
360 | |||
361 | - GitList 的界面看起来不错,而且能展示源码、clone 链接之类的,整体非常像 github 的界面,可惜使用的是我不会的 php 语言,而且没有找到详细一些的安装使用教程 | ||
362 | - cgit 是一个用纯 C 语言开发的一个 git 裸库展示,虽然界面看起来比较古早,但功能简单、强大,能展示源码、自由切换分支、方便地查看提交历史(diss 一下 github,github 查看提交历史看起来真的很不方便很不直观)。诸如[Linux 内核](https://git.kernel.org)等项目都在使用。 | ||
363 | |||
364 | 选择了 cgit,我找到了又一位大佬的[博客](https://blog.dejavu.moe/posts/hosting-minimal-git-server-with-cgit),非常详细。需要注意的是,**我们仍然需要一个专门的用户。** | ||
365 | |||
366 | ## 依赖 | ||
367 | |||
368 | `nginx`/`git`/`vim`等工具不必赘述,还有一些依赖项需要安装: | ||
369 | |||
370 | ```bash | ||
371 | # apache2-utils是用其htpasswd命令创建认证文件的 | ||
372 | # fcgiwrap是用于将 FastCGI 转换为 HTTP 协议的工具 | ||
373 | # 这两个工具上文均已提到和使用,不再赘述 | ||
374 | sudo apt update | ||
375 | sudo apt install -y apache2-utils fcgiwrap | ||
376 | |||
377 | # 编译过程中需要openssl的头文件 | ||
378 | sudo apt install -y libssl-dev | ||
379 | |||
380 | # 建议为cgit提供lua支持,用来进行个性化的设置 | ||
381 | # 本文以 lua5.1 为例 | ||
382 | sudo apt install liblua5.1-0 liblua5.1-0-dbg liblua5.1-dev lua5.1 | ||
383 | ``` | ||
384 | |||
385 | ## cgit 安装 | ||
386 | |||
387 | cgit 最近的正式发行版已经好几年了,但是它的开发仍然很活跃,所以建议从它的 git 仓库中获取最新的代码,而非直接安装: | ||
388 | |||
389 | ```bash | ||
390 | git clone https://git.zx2c4.com/cgit | ||
391 | cd cgit | ||
392 | git submodule init | ||
393 | git submodule update | ||
394 | ``` | ||
395 | |||
396 | 在仓库目录下创建`cgit.conf`文件,用来存放 cgit 构建时可以覆盖的配置: | ||
397 | |||
398 | ```bash | ||
399 | sed -n '3,31p' Makefile > cgit.conf | ||
400 | ``` | ||
401 | |||
402 | 我们可以按需编辑之: | ||
403 | |||
404 | ```plaintext | ||
405 | CGIT_VERSION = v1.2.3 | ||
406 | CGIT_SCRIPT_NAME = cgit.cgi | ||
407 | CGIT_SCRIPT_PATH = /var/www/cgit # 本文只改了这里 | ||
408 | CGIT_DATA_PATH = $(CGIT_SCRIPT_PATH) | ||
409 | CGIT_CONFIG = /etc/cgitrc # 默认配置文件路径 | ||
410 | CACHE_ROOT = /var/cache/cgit | ||
411 | prefix = /usr/local | ||
412 | libdir = $(prefix)/lib | ||
413 | filterdir = $(libdir)/cgit/filters | ||
414 | docdir = $(prefix)/share/doc/cgit | ||
415 | htmldir = $(docdir) | ||
416 | pdfdir = $(docdir) | ||
417 | mandir = $(prefix)/share/man | ||
418 | SHA1_HEADER = <openssl/sha.h> | ||
419 | GIT_VER = 2.39.0 | ||
420 | GIT_URL = https://www.kernel.org/pub/software/scm/git/git-$(GIT_VER).tar.xz | ||
421 | INSTALL = install | ||
422 | COPYTREE = cp -r | ||
423 | MAN5_TXT = $(wildcard *.5.txt) | ||
424 | MAN_TXT = $(MAN5_TXT) | ||
425 | DOC_MAN5 = $(patsubst %.txt,%,$(MAN5_TXT)) | ||
426 | DOC_HTML = $(patsubst %.txt,%.html,$(MAN_TXT)) | ||
427 | DOC_PDF = $(patsubst %.txt,%.pdf,$(MAN_TXT)) | ||
428 | |||
429 | ASCIIDOC = asciidoc | ||
430 | ASCIIDOC_EXTRA = | ||
431 | ASCIIDOC_HTML = xhtml11 | ||
432 | ASCIIDOC_COMMON = $(ASCIIDOC) $(ASCIIDOC_EXTRA) | ||
433 | TXT_TO_HTML = $(ASCIIDOC_COMMON) -b $(ASCIIDOC_HTML) | ||
434 | ``` | ||
435 | |||
436 | 编译 && 安装: | ||
437 | |||
438 | ```bash | ||
439 | # 如果不需要lua支持 | ||
440 | make NO_LUA=1 | ||
441 | # 有lua支持的话 | ||
442 | make LUA_PKGCONFIG=lua5.1 | ||
443 | |||
444 | # 安装,注意一下安装路径 | ||
445 | # 不妨将输出写到日志里,以便查看 | ||
446 | sudo make install | tee install.log | ||
447 | ``` | ||
448 | |||
449 | ## nginx 配置 | ||
450 | |||
451 | 首先,参照[这里](认证文件)生成一个自己的认证文件,再继续往下看。 | ||
452 | |||
453 | 在`/etc/nginx/git-http-backend.conf`中写入以下内容,注意把域名、ssl 路径、htpasswd 认证文件换成自己的: | ||
454 | |||
455 | ```conf | ||
456 | # /etc/nginx/git-http-backend.conf | ||
457 | fastcgi_pass unix:/var/run/fcgiwrap.socket; | ||
458 | include fastcgi_params; | ||
459 | fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend; | ||
460 | fastcgi_param GIT_HTTP_EXPORT_ALL ""; | ||
461 | fastcgi_param GIT_PROJECT_ROOT /home/git; | ||
462 | fastcgi_param PATH_INFO $1; | ||
463 | fastcgi_param REMOTE_USER $remote_user; | ||
464 | ``` | ||
465 | |||
466 | 而后,在`/etc/nginx/conf.d/cgit.conf`中写: | ||
467 | |||
468 | ```conf | ||
469 | # /etc/nginx/conf.d/cgit.conf | ||
470 | server { | ||
471 | listen 80; | ||
472 | server_name git.player.com; | ||
473 | return 301 https://$server_name$request_uri; | ||
474 | } | ||
475 | |||
476 | server { | ||
477 | server_name git.player.com; | ||
478 | listen 443 ssl http2; | ||
479 | |||
480 | ssl_certificate /etc/letsencrypt/live/git.player.com/fullchain.pem; | ||
481 | ssl_certificate_key /etc/letsencrypt/live/git.player.com/privkey.pem; | ||
482 | |||
483 | # SSL Security | ||
484 | ssl_protocols TLSv1.2 TLSv1.3; | ||
485 | ssl_prefer_server_ciphers on; | ||
486 | ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256; | ||
487 | |||
488 | ssl_session_timeout 1d; | ||
489 | ssl_session_cache shared:SSL:10m; | ||
490 | |||
491 | # Site Log path | ||
492 | access_log /var/log/nginx/cgit-access.log; | ||
493 | error_log /var/log/nginx/cgit-error.log; | ||
494 | |||
495 | root /var/www/cgit; | ||
496 | try_files $uri @cgit; | ||
497 | client_max_body_size 10m; | ||
498 | |||
499 | location @cgit { | ||
500 | include fastcgi_params; | ||
501 | # cgit's CGI script path | ||
502 | fastcgi_param SCRIPT_FILENAME /var/www/cgit/cgit.cgi; | ||
503 | fastcgi_param DOCUMENT_ROOT /usr/lib/git-core; | ||
504 | fastcgi_pass unix:/var/run/fcgiwrap.socket; | ||
505 | fastcgi_param PATH_INFO $uri; | ||
506 | fastcgi_param QUERY_STRING $args; | ||
507 | fastcgi_param HTTP_HOST $server_name; | ||
508 | fastcgi_param GIT_HTTP_EXPORT_ALL ""; | ||
509 | fastcgi_param GIT_PROJECT_ROOT /home/git; | ||
510 | |||
511 | if ($arg_service = git-receive-pack) { | ||
512 | rewrite (/.*) /git_write/$1 last; | ||
513 | } | ||
514 | |||
515 | if ($uri ~ ^/.*/git-receive-pack$) { | ||
516 | rewrite (/.*) /git_write/$1 last; | ||
517 | } | ||
518 | |||
519 | if ($arg_service = git-upload-pack) { | ||
520 | rewrite (/.*) /git_read/$1 last; | ||
521 | } | ||
522 | |||
523 | if ($uri ~ ^/.*/git-upload-pack$) { | ||
524 | rewrite (/.*) /git_read/$1 last; | ||
525 | } | ||
526 | } | ||
527 | |||
528 | location ~ /git_read/(.*) { | ||
529 | include git-http-backend.conf; | ||
530 | } | ||
531 | |||
532 | location ~ /git_write/(.*) { | ||
533 | # HTTP Basic Authentication | ||
534 | auth_basic "Authentication Required To Push"; | ||
535 | auth_basic_user_file /etc/nginx/conf.d/git.htpasswd; | ||
536 | include git-http-backend.conf; | ||
537 | } | ||
538 | } | ||
539 | ``` | ||
540 | |||
541 | 最后,重启 nginx 服务: | ||
542 | |||
543 | ```bash | ||
544 | sudo nginx -s reload | ||
545 | ``` | ||
546 | |||
547 | _看吧,一个个仓库,向我们列队走来!_ | ||
548 | |||
549 | ## cgit 高级配置 | ||
550 | |||
551 | 可以安装一些包,用于 cgit 的代码高亮、Markdown 渲染、Gravatar 头像渲染等: | ||
552 | |||
553 | ```bash | ||
554 | sudo apt install -y python3-docutils python3-markdown highlight python3-pygments | ||
555 | |||
556 | # 编译安装 LuaoSSL | ||
557 | # https://25thandclement.com/~william/projects/luaossl.html | ||
558 | git clone https://github.com/wahern/luaossl.git && cd luaossl | ||
559 | make LUAPKG=lua5.1 | ||
560 | sudo make install LUAPKG=lua5.1 | ||
561 | |||
562 | sudo mkdir -p /usr/local/share/cgit | ||
563 | sudo ln -s /usr/local/lib/cgit/filters /usr/local/share/cgit/filters | ||
564 | sudo chown -R www-data:www-data /usr/local/share/cgit/ | ||
565 | |||
566 | # 给下面使用 filter api 的脚本赋予可执行权限,比如 | ||
567 | sudo chmod +x /usr/local/share/cgit/filters/email-gravatar.lua | ||
568 | ``` | ||
569 | |||
570 | 然后编辑上边我们已经指定的配置文件`/etc/cgitrc`,更多配置项参见[cgitrc.5.txt](https://git.zx2c4.com/cgit/tree/cgitrc.5.txt)。 | ||
571 | |||
572 | ```plaintext | ||
573 | # /etc/cgitrc | ||
574 | # 包含 cgit 的所有运行时设置 | ||
575 | # 格式 NAME=VALUE | ||
576 | # 以 "#" 开头的行是注释 | ||
577 | |||
578 | # 全局配置 | ||
579 | css=/cgit.css | ||
580 | logo=/cgit.png | ||
581 | favicon=/favicon.ico | ||
582 | #footer= | ||
583 | virtual-root=/ | ||
584 | # 禁用哑克隆 | ||
585 | enable-http-clone=0 | ||
586 | |||
587 | # Smart HTTP | ||
588 | # 记得改成自己的链接 | ||
589 | clone-url=https://git.player.com/$CGIT_REPO_URL | ||
590 | # 首页标题显示的内容,改成你想要的 | ||
591 | root-title=GIT.PLAYER.COM | ||
592 | root-desc=YOUR.WORDS | ||
593 | # 在首页展示的介绍信息,可用md/man/html等 | ||
594 | # 详参/usr/local/share/cgit/filters/about-formatting.sh | ||
595 | root-readme=/var/www/cgit/README.md | ||
596 | |||
597 | # 建议配置 | ||
598 | enable-index-owner=1 | ||
599 | enable-index-links=1 | ||
600 | enable-blame=1 | ||
601 | enable-log-filecount=1 | ||
602 | enable-log-linecount=1 | ||
603 | enable-commit-graph=1 | ||
604 | |||
605 | # 禁止搜素引擎索引 | ||
606 | robots=noindex, nofollow | ||
607 | |||
608 | branch-sort=age | ||
609 | commit-sort=date | ||
610 | max-stats=quarter | ||
611 | snapshots=tar.gz zip | ||
612 | |||
613 | # 使用 RAM 的缓存大小 单位 MB | ||
614 | cache-size=1024 | ||
615 | |||
616 | # 代码高亮 | ||
617 | source-filter=/usr/local/share/cgit/filters/syntax-highlighting.py | ||
618 | |||
619 | # 格式化贡献者,显示Gravatar头像 | ||
620 | email-filter=lua:/usr/local/share/cgit/filters/email-gravatar.lua | ||
621 | |||
622 | # 格式化 about 页面 | ||
623 | about-filter=/usr/local/share/cgit/filters/about-formatting.sh | ||
624 | readme=:README.md | ||
625 | readme=:readme.md | ||
626 | readme=:README.txt | ||
627 | readme=:readme.txt | ||
628 | readme=:README | ||
629 | readme=:readme | ||
630 | |||
631 | # MIME 类型 | ||
632 | mimetype.html=text/html | ||
633 | mimetype.gif=image/gif | ||
634 | mimetype.jpg=image/jpeg | ||
635 | mimetype.jpeg=image/jpeg | ||
636 | mimetype.png=image/png | ||
637 | mimetype.webp=image/webp | ||
638 | mimetype.pdf=application/pdf | ||
639 | mimetype.svg=image/svg+xml | ||
640 | |||
641 | # 移除 .git 后缀,很有必要 | ||
642 | remove-suffix=1 | ||
643 | |||
644 | # 扫描路径 | ||
645 | scan-path=/home/git | ||
646 | |||
647 | # 每个存储库配置 | ||
648 | #repo.url=reponame | ||
649 | #repo.path=/home/git/reponame.git | ||
650 | #repo.desc=Some description here | ||
651 | #repo.owner=Owner Name | ||
652 | #repo.logo=/repo-logo.png | ||
653 | ``` | ||
654 | |||
655 | ### 高亮风格 | ||
656 | |||
657 | 在上面的配置文件里,我们使用了[Pygments](https://pygments.org/styles/)的代码高亮。其默认使用的高亮是 pastie,我们可以根据自己的喜好修改高亮风格。 | ||
658 | |||
659 | 首先,看看有哪些可用的高亮风格。 | ||
660 | |||
661 | ```bash | ||
662 | # 查看可用的高亮风格 | ||
663 | pygmentize -L styles | ||
664 | |||
665 | # 编辑我们使用的代码高亮脚本 | ||
666 | sudo vim /usr/local/share/cgit/filters/syntax-highlighting.py | ||
667 | ``` | ||
668 | |||
669 | ### Gravatar 头像 | ||
670 | |||
671 | 在上述配置中,我们使用了 Gravatar 头像。[Gravatar](https://cn.gravatar.com/) 是一个全球通用的头像服务,根据你使用的邮箱(而非用户身份)来为你提供头像。换言之,只要你的邮箱注册了 Gravatar,那么你在任何一个支持 Gravatar 的网站上都可以使用你的 Gravatar 头像。这对于我们这种不想做登录、又想展示用户的网站来说,是一个很好的选择。 | ||
672 | |||
673 | - [中文官网](https://cn.gravatar.com/) | ||
674 | - [英文官网](https://gravatar.com/) | ||
675 | |||
676 | 由于 Gravatar 中文官网访问比较慢(不知道为什么,英文官网我挂了梯子还上不去),我们可以使用国内的镜像服务。这里有一篇常用镜像服务的[博客](https://luoxx.top/archives/gravatar-mirror-2022)。我使用的是[Cravatar](https://cravatar.cn/)。 | ||
677 | |||
678 | 使用流程都是基本一致的,在这个网站上注册账号,上传头像,然后根据网站提供的 API 来获取。一般方式为`https://域名.com/avatar/邮箱的md5值`。在我们使用的脚本`/usr/local/share/cgit/filters/email-gravatar.lua`中,将原有的域名替换为我们使用的域名即可。 | ||
679 | |||
680 | cgit 的[官网](https://git.zx2c4.com/cgit/)上不仅能实现 Gravatar 头像,还能在鼠标移动到头像上的时候以大图显示。这不是原生功能,而是需要动 lua 脚本自己实现。原博客大佬在 cgit 的[邮件列表](https://lists.zx2c4.com/pipermail/cgit/2014-March/002036.html)找到了实现方式。 | ||
681 | |||
682 | ```bash | ||
683 | sudo vim /usr/local/share/cgit/filters/email-libravatar-korg.lua | ||
684 | ``` | ||
685 | |||
686 | 在脚本中写入以下内容: | ||
687 | |||
688 | ```lua | ||
689 | -- This script may be used with the email-filter or repo.email-filter settings in cgitrc. | ||
690 | -- It adds gravatar icons to author names. It is designed to be used with the lua: | ||
691 | -- prefix in filters. It is much faster than the corresponding python script. | ||
692 | -- | ||
693 | -- Requirements: | ||
694 | -- luaossl | ||
695 | -- <http://25thandclement.com/~william/projects/luaossl.html> | ||
696 | -- | ||
697 | |||
698 | local digest = require("openssl.digest") | ||
699 | |||
700 | function md5_hex(input) | ||
701 | local b = digest.new("md5"):final(input) | ||
702 | local x = "" | ||
703 | for i = 1, #b do | ||
704 | x = x .. string.format("%.2x", string.byte(b, i)) | ||
705 | end | ||
706 | return x | ||
707 | end | ||
708 | |||
709 | function filter_open(email, page) | ||
710 | buffer = "" | ||
711 | md5 = md5_hex(email:sub(2, -2):lower()) | ||
712 | end | ||
713 | |||
714 | function filter_close() | ||
715 | html("<span class='libravatar'>" .. | ||
716 | "<img class='inline' src='//www.gravatar.com/avatar/" .. md5 .. "?s=13&d=retro' />" .. | ||
717 | "<img class='onhover' src='//www.gravatar.com/avatar/" .. md5 .. "?s=128&d=retro' />" .. | ||
718 | "</span>" .. buffer) | ||
719 | return 0 | ||
720 | end | ||
721 | |||
722 | function filter_write(str) | ||
723 | buffer = buffer .. str | ||
724 | end | ||
725 | ``` | ||
726 | |||
727 | 只有 lua 还不够,我们需要将以下内容添加到`/var/www/cgit/cgit.css`中: | ||
728 | |||
729 | ```css | ||
730 | /* libgravatar */ | ||
731 | div#cgit span.libravatar img.onhover { | ||
732 | display: none; | ||
733 | border: 1px solid gray; | ||
734 | padding: 0px; | ||
735 | -webkit-border-radius: 4px; | ||
736 | -moz-border-radius: 4px; | ||
737 | border-radius: 4px; | ||
738 | width: 128px; | ||
739 | height: 128px; | ||
740 | } | ||
741 | |||
742 | div#cgit span.libravatar img.inline { | ||
743 | -webkit-border-radius: 3px; | ||
744 | -moz-border-radius: 3px; | ||
745 | border-radius: 3px; | ||
746 | width: 13px; | ||
747 | height: 13px; | ||
748 | margin-right: 0.4em; | ||
749 | opacity: 0.9; | ||
750 | } | ||
751 | |||
752 | div#cgit span.libravatar:hover > img.onhover { | ||
753 | display: block; | ||
754 | position: absolute; | ||
755 | margin-left: 1.5em; | ||
756 | background-color: #eeeeee; | ||
757 | box-shadow: 5px 5px 3px #bbb; | ||
758 | } | ||
759 | ``` | ||
760 | |||
761 | 而后,修改`/etc/cgitrc`中的`email-filter`的值为我们新建的脚本`lua:/usr/local/share/cgit/filters/email-libravatar-korg.lua`,就好了。 | ||
762 | |||
763 | ### 添加 README | ||
764 | |||
765 | 在`/etc/cgitrc`中,我们指定了`root-readme`,这是用来在网站主页展示 README 的。我们可以编写一个 README 文件,然后在`/etc/cgitrc`中指明它的路径。README 可以使用`markdown`/`man`/`rst`/html`/`txt`等格式。 | ||
766 | |||
767 | 我使用的是`markdown`格式,在`/var/www/cgit/`中创建了一个`README.md`文件,然后在`/etc/cgitrc`中指明了路径。 | ||
768 | |||
769 | ### 样式修改 | ||
770 | |||
771 | 对于 cgit 显示出来的界面,你可能并不太满意(比如我就嫌界面的字太小、颜色不舒适啥的)。修改办法也很简单,找到`/var/www/cgit/cgit.css`文件,然后修改之。 | ||
772 | |||
773 | 而对于我们的 Markdown 或者别的什么语言写的 README,如果觉得渲染效果不好,都是可以自己去修改的。 | ||
774 | |||
775 | 找到`/usr/local/share/cgit/filters/about-formatting.sh`文件,我们会看到以下内容: | ||
776 | |||
777 | ```bash | ||
778 | #!/bin/sh | ||
779 | |||
780 | # This may be used with the about-filter or repo.about-filter setting in cgitrc. | ||
781 | # It passes formatting of about pages to differing programs, depending on the usage. | ||
782 | |||
783 | # Markdown support requires python and markdown-python. | ||
784 | # RestructuredText support requires python and docutils. | ||
785 | # Man page support requires groff. | ||
786 | |||
787 | # The following environment variables can be used to retrieve the configuration | ||
788 | # of the repository for which this script is called: | ||
789 | # CGIT_REPO_URL ( = repo.url setting ) | ||
790 | # CGIT_REPO_NAME ( = repo.name setting ) | ||
791 | # CGIT_REPO_PATH ( = repo.path setting ) | ||
792 | # CGIT_REPO_OWNER ( = repo.owner setting ) | ||
793 | # CGIT_REPO_DEFBRANCH ( = repo.defbranch setting ) | ||
794 | # CGIT_REPO_SECTION ( = section setting ) | ||
795 | # CGIT_REPO_CLONE_URL ( = repo.clone-url setting ) | ||
796 | |||
797 | cd "$(dirname $0)/html-converters/" | ||
798 | case "$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')" in | ||
799 | *.markdown|*.mdown|*.md|*.mkd) exec ./md2html; ;; | ||
800 | *.rst) exec ./rst2html; ;; | ||
801 | *.[1-9]) exec ./man2html; ;; | ||
802 | *.htm|*.html) exec cat; ;; | ||
803 | *.txt|*) exec ./txt2html; ;; | ||
804 | esac | ||
805 | ``` | ||
806 | |||
807 | 从这里可以看到,负责渲染的是`/usr/local/share/cgit/filters/html-converters`文件夹中的对于脚本。我们可以自己修改这些脚本,或者自己添加新的脚本,来实现自己想要的渲染效果。 | ||
808 | |||
809 | 当然,除了网站主页的 README,我们还可以在每个仓库的主页上添加 README。只需要在仓库的根目录下添加 README 文件即可。然后网页上仓库的标签页就会有“About”标签页,显示 README.md 的内容。 | ||
810 | |||
811 | 到这里,cgit 的配置就基本完成了。重启 nginx 服务,然后访问你的域名,就可以看到一个很漂亮的界面了;命令行里,也可以 clone、push、fetch、pull 我们托管的仓库。大功告成! | ||
812 | |||
813 | # 其他存在的问题 | ||
358 | 814 | ||
359 | 除了上述问题已经解决之外,还有一些问题依然存在: | 815 | 除了上述问题已经解决之外,还有一些问题依然存在: |
360 | 816 | ||
361 | - 不管是 nginx 还是 git,在使用 http 上传的时候都会有一定的缓冲区限制,如果上传文件过大或累计多个 commit 才上传,很可能被拒收导致上传失败。这个问题在 github 上也存在,但是 github 的缓冲区限制比较大,一般不会出现这个问题。但是我们的服务器配置比较低,所以这个问题就比较严重了。解决办法是在 nginx 的配置文件中添加`client_max_body_size 100m;`,这样就可以将缓冲区限制扩大到 100M,一般来说足够了。 | 817 | - 不管是 nginx 还是 git,在使用 http 上传的时候都会有一定的**缓冲区限制,如果上传文件过大或累计多个 commit 才上传,很可能被拒收导致上传失败**。这个问题在 github 上也存在,但是 github 的缓冲区限制比较大,一般不会出现这个问题;我们的服务器配置比较低,所以这个问题就比较严重了。解决办法是在 nginx 的配置文件中添加`client_max_body_size 100m;`,这样就可以将缓冲区限制扩大到 100M,一般来说足够了。 |
362 | - 即使解决了缓冲区大小,偶尔也会被拒收,原因尚未查清 | 818 | - 即使解决了缓冲区大小,偶尔也会被拒收,原因尚未查清 |
363 | - 尚未能通过访问特定链接来实现 git 仓库的创建。据说是用 nginx 调用脚本,但暂时没弄出来 | 819 | - **尚未能通过访问特定链接来实现 git 仓库的创建。**据说是用 nginx 调用脚本,但暂时没弄出来 |
364 | - 没有一个比较好用且功能较为完备的图形化界面(就像 github 那样)。 | 820 | |
365 | - GitList 的界面看起来不错,而且能展示源码、clone 链接之类的,整体非常像 github 的界面,可惜使用的是我不会的 php 语言,而且没有找到详细一些的安装使用教程 | 821 | 这篇博客前前后后有二十多天了,有空再折腾吧。看电视去也~ |
366 | - cgit 是一个用纯 C 语言开发的一个 git 裸库展示,虽然界面看起来比较古早,但功能也很不错,能展示源码、自由切换分支、方便地查看提交历史(diss 一下 github,github 查看提交历史看起来真的很不方便很不直观)。美中不足的是**无法在界面上提供 clone 和源码下载功能**。不过毕竟是个开源软件,而且是我比较熟悉的 C,等有时间有能力了看看自己能不能实现这个功能吧。 | ||
367 | 822 | ||
368 | 这篇博客前前后后有二十多天了,该结束了。闲言少叙,看电视去也~ \ No newline at end of file | 823 | <!-- 2024.1.3 --> |
diff --git a/common/CSS/pandoc.css b/common/CSS/pandoc.css index b376205..a7e500b 100644 --- a/common/CSS/pandoc.css +++ b/common/CSS/pandoc.css | |||
@@ -533,7 +533,7 @@ nav a { | |||
533 | text-decoration: none; | 533 | text-decoration: none; |
534 | color: #4183c4; | 534 | color: #4183c4; |
535 | display: block; | 535 | display: block; |
536 | margin-left: 10px; | 536 | margin-left: 15px; |
537 | } | 537 | } |
538 | 538 | ||
539 | a:hover { | 539 | a:hover { |
diff --git a/common/script4works.html b/common/script4works.html index 478adc9..330cb42 100644 --- a/common/script4works.html +++ b/common/script4works.html | |||
@@ -100,7 +100,7 @@ | |||
100 | d="M923.2 289.6c0 354.4-232.8 609.6-575.2 620.8-144.8 11.2-244-32.8-332.8-99.2 99.2 11.2 232.8-21.6 298.4-88.8-99.2 0-155.2-56-188-132h88.8C125.6 556.8 58.4 490.4 58.4 380c21.6 11.2 44 21.6 88.8 21.6-77.6-44-121.6-188-66.4-276.8 99.2 110.4 220.8 210.4 421.6 220.8-56-220.8 232.8-332.8 354.4-188 56-11.2 88.8-32.8 132-56-11.2 56-44 88.8-88.8 110.4 44 0 77.6-11.2 110.4-32.8-10.4 44-54.4 88.8-87.2 110.4z" | 100 | d="M923.2 289.6c0 354.4-232.8 609.6-575.2 620.8-144.8 11.2-244-32.8-332.8-99.2 99.2 11.2 232.8-21.6 298.4-88.8-99.2 0-155.2-56-188-132h88.8C125.6 556.8 58.4 490.4 58.4 380c21.6 11.2 44 21.6 88.8 21.6-77.6-44-121.6-188-66.4-276.8 99.2 110.4 220.8 210.4 421.6 220.8-56-220.8 232.8-332.8 354.4-188 56-11.2 88.8-32.8 132-56-11.2 56-44 88.8-88.8 110.4 44 0 77.6-11.2 110.4-32.8-10.4 44-54.4 88.8-87.2 110.4z" |
101 | fill="" p-id="3318"></path> | 101 | fill="" p-id="3318"></path> |
102 | </svg></a> | 102 | </svg></a> |
103 | <a target="_blank" href="3205135446@qq.com" data-tooltip="勤倦阁主"><svg t="1603709790743" class="icon" | 103 | <a target="_blank" href="mailto:3205135446@qq.com" data-tooltip="勤倦阁主"><svg t="1603709790743" class="icon" |
104 | viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5171" width="128" | 104 | viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5171" width="128" |
105 | height="128"> | 105 | height="128"> |
106 | <path | 106 | <path |
@@ -153,13 +153,13 @@ | |||
153 | <a href="https://www.qin-juan-ge-zhu.top/code/highlight.html">代码高亮与复制</a> | 153 | <a href="https://www.qin-juan-ge-zhu.top/code/highlight.html">代码高亮与复制</a> |
154 | <a href="https://www.qin-juan-ge-zhu.top/code/index.html">C的小零件</a> | 154 | <a href="https://www.qin-juan-ge-zhu.top/code/index.html">C的小零件</a> |
155 | <a href="https://www.qin-juan-ge-zhu.top/code/cpppp.html">C++ Primer Plus基础</a> | 155 | <a href="https://www.qin-juan-ge-zhu.top/code/cpppp.html">C++ Primer Plus基础</a> |
156 | <a href="https://www.qin-juan-ge-zhu.top/code/fileop(cpp).html">C++文件操作</a> | ||
157 | <a href="https://www.qin-juan-ge-zhu.top/code/experiment.html">大物实验MATLAB</a> | 156 | <a href="https://www.qin-juan-ge-zhu.top/code/experiment.html">大物实验MATLAB</a> |
158 | <a href="https://www.qin-juan-ge-zhu.top/code/zeal.html">Zeal文档下载</a> | 157 | <a href="https://www.qin-juan-ge-zhu.top/code/zeal.html">Zeal文档下载</a> |
159 | </div> | 158 | </div> |
160 | <a onclick="clickit('grandson23')">-功能网页</a> | 159 | <a onclick="clickit('grandson23')">-功能网页</a> |
161 | <div class="grandson" id="grandson23" style="display:none"> | 160 | <div class="grandson" id="grandson23" style="display:none"> |
162 | <a href="https://code.qin-juan-ge-zhu.top">VSCode Online</a> | 161 | <a href="https://code.qin-juan-ge-zhu.top">VSCode Online</a> |
162 | <a href="https://git.qin-juan-ge-zhu.top">Git托管存储室</a> | ||
163 | <a href="https://file.qin-juan-ge-zhu.top">服务器文件浏览</a> | 163 | <a href="https://file.qin-juan-ge-zhu.top">服务器文件浏览</a> |
164 | </div> | 164 | </div> |
165 | </div> | 165 | </div> |
diff --git a/common/script4works.js b/common/script4works.js index 3327557..9199217 100644 --- a/common/script4works.js +++ b/common/script4works.js | |||
@@ -101,7 +101,7 @@ document.writeln(" <path"); | |||
101 | document.writeln(" d=\"M923.2 289.6c0 354.4-232.8 609.6-575.2 620.8-144.8 11.2-244-32.8-332.8-99.2 99.2 11.2 232.8-21.6 298.4-88.8-99.2 0-155.2-56-188-132h88.8C125.6 556.8 58.4 490.4 58.4 380c21.6 11.2 44 21.6 88.8 21.6-77.6-44-121.6-188-66.4-276.8 99.2 110.4 220.8 210.4 421.6 220.8-56-220.8 232.8-332.8 354.4-188 56-11.2 88.8-32.8 132-56-11.2 56-44 88.8-88.8 110.4 44 0 77.6-11.2 110.4-32.8-10.4 44-54.4 88.8-87.2 110.4z\""); | 101 | document.writeln(" d=\"M923.2 289.6c0 354.4-232.8 609.6-575.2 620.8-144.8 11.2-244-32.8-332.8-99.2 99.2 11.2 232.8-21.6 298.4-88.8-99.2 0-155.2-56-188-132h88.8C125.6 556.8 58.4 490.4 58.4 380c21.6 11.2 44 21.6 88.8 21.6-77.6-44-121.6-188-66.4-276.8 99.2 110.4 220.8 210.4 421.6 220.8-56-220.8 232.8-332.8 354.4-188 56-11.2 88.8-32.8 132-56-11.2 56-44 88.8-88.8 110.4 44 0 77.6-11.2 110.4-32.8-10.4 44-54.4 88.8-87.2 110.4z\""); |
102 | document.writeln(" fill=\"\" p-id=\"3318\"></path>"); | 102 | document.writeln(" fill=\"\" p-id=\"3318\"></path>"); |
103 | document.writeln(" </svg></a>"); | 103 | document.writeln(" </svg></a>"); |
104 | document.writeln(" <a target=\"_blank\" href=\"3205135446@qq.com\" data-tooltip=\"勤倦阁主\"><svg t=\"1603709790743\" class=\"icon\""); | 104 | document.writeln(" <a target=\"_blank\" href=\"mailto:3205135446@qq.com\" data-tooltip=\"勤倦阁主\"><svg t=\"1603709790743\" class=\"icon\""); |
105 | document.writeln(" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"5171\" width=\"128\""); | 105 | document.writeln(" viewBox=\"0 0 1024 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"5171\" width=\"128\""); |
106 | document.writeln(" height=\"128\">"); | 106 | document.writeln(" height=\"128\">"); |
107 | document.writeln(" <path"); | 107 | document.writeln(" <path"); |
@@ -154,13 +154,13 @@ document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code | |||
154 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/highlight.html\">代码高亮与复制</a>"); | 154 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/highlight.html\">代码高亮与复制</a>"); |
155 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/index.html\">C的小零件</a>"); | 155 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/index.html\">C的小零件</a>"); |
156 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/cpppp.html\">C++ Primer Plus基础</a>"); | 156 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/cpppp.html\">C++ Primer Plus基础</a>"); |
157 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/fileop(cpp).html\">C++文件操作</a>"); | ||
158 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/experiment.html\">大物实验MATLAB</a>"); | 157 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/experiment.html\">大物实验MATLAB</a>"); |
159 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/zeal.html\">Zeal文档下载</a>"); | 158 | document.writeln(" <a href=\"https://www.qin-juan-ge-zhu.top/code/zeal.html\">Zeal文档下载</a>"); |
160 | document.writeln(" </div>"); | 159 | document.writeln(" </div>"); |
161 | document.writeln(" <a onclick=\"clickit(\'grandson23\')\">-功能网页</a>"); | 160 | document.writeln(" <a onclick=\"clickit(\'grandson23\')\">-功能网页</a>"); |
162 | document.writeln(" <div class=\"grandson\" id=\"grandson23\" style=\"display:none\">"); | 161 | document.writeln(" <div class=\"grandson\" id=\"grandson23\" style=\"display:none\">"); |
163 | document.writeln(" <a href=\"https://code.qin-juan-ge-zhu.top\">VSCode Online</a>"); | 162 | document.writeln(" <a href=\"https://code.qin-juan-ge-zhu.top\">VSCode Online</a>"); |
163 | document.writeln(" <a href=\"https://git.qin-juan-ge-zhu.top\">Git托管存储室</a>"); | ||
164 | document.writeln(" <a href=\"https://file.qin-juan-ge-zhu.top\">服务器文件浏览</a>"); | 164 | document.writeln(" <a href=\"https://file.qin-juan-ge-zhu.top\">服务器文件浏览</a>"); |
165 | document.writeln(" </div>"); | 165 | document.writeln(" </div>"); |
166 | document.writeln(" </div>"); | 166 | document.writeln(" </div>"); |