<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>RGC Blog</title><description>代码、笔记与一些正在发生的想法</description><link>https://r-gc.github.io/</link><language>zh_CN</language><item><title>这个博客的笔记结构</title><link>https://r-gc.github.io/posts/notes/blog-note-architecture/</link><guid isPermaLink="true">https://r-gc.github.io/posts/notes/blog-note-architecture/</guid><description>先给笔记系统定一个轻量规则：分类保持简单，标签负责表达主题和用途。</description><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;这个博客会以笔记为主，所以先把笔记的结构定下来。&lt;/p&gt;
&lt;p&gt;第一版不打算做得太复杂。Fuwari 本身已经有文章、归档、标签、分类、搜索和 RSS。与其重新做一套知识库系统，不如先复用它的文章模型，再用一点约定把内容组织清楚。&lt;/p&gt;
&lt;h2&gt;分类只回答一件事&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;category&lt;/code&gt; 只用来说明这篇内容属于哪种大类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;笔记&lt;/li&gt;
&lt;li&gt;项目&lt;/li&gt;
&lt;li&gt;博客&lt;/li&gt;
&lt;li&gt;实验&lt;/li&gt;
&lt;li&gt;随笔&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样分类不会越来越碎。比如一篇 Cloudflare Workers 部署记录，它的分类是“笔记”，而不是“Cloudflare”。&lt;/p&gt;
&lt;h2&gt;标签负责具体主题&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;tags&lt;/code&gt; 用来描述具体内容和用途：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Cloudflare&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Workers&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;部署&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;排错&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Frappe&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Docker&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;速查&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以后想按技术栈、问题类型或者使用场景找内容，都可以靠标签。&lt;/p&gt;
&lt;h2&gt;笔记类型&lt;/h2&gt;
&lt;p&gt;当前先按这些类型整理：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;速查：命令、参数、步骤和常用片段&lt;/li&gt;
&lt;li&gt;排错：报错原因、排查路径和最后的修复方法&lt;/li&gt;
&lt;li&gt;配置：环境、工具链、部署和服务配置&lt;/li&gt;
&lt;li&gt;学习：读文档、看源码、学框架时留下的理解&lt;/li&gt;
&lt;li&gt;项目笔记：项目推进过程里的设计、接口、测试和取舍&lt;/li&gt;
&lt;li&gt;阅读摘记：文章、文档、书和资料里值得回看的内容&lt;/li&gt;
&lt;li&gt;实验记录：动画、音乐、视频和交互效果的试验过程&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些类型目前先作为标签使用。等内容多起来之后，再决定要不要单独做成更强的字段。&lt;/p&gt;
&lt;h2&gt;写作原则&lt;/h2&gt;
&lt;p&gt;笔记不追求一次写成完美文章。&lt;/p&gt;
&lt;p&gt;对这个博客来说，更重要的是先把有用的信息放下来：当时的问题是什么，怎么查的，最后怎么解决，以及下次遇到时应该从哪里开始。&lt;/p&gt;
&lt;p&gt;如果一篇短笔记后来变得很重要，再把它扩展成完整文章也不迟。&lt;/p&gt;
</content:encoded></item><item><title>博客开始了</title><link>https://r-gc.github.io/posts/hello-blog/</link><guid isPermaLink="true">https://r-gc.github.io/posts/hello-blog/</guid><description>这个博客的第一篇记录，也算是给这个站点定一个方向。</description><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;这是这个博客的第一篇文章，也算是给它留一个起点。&lt;/p&gt;
&lt;p&gt;我不太想把它做成一个只摆成品的地方。更想让它像一个可以慢慢堆东西的工作台：项目做到一半的想法、某次配置踩过的坑、一个后来终于跑通的接口、或者某个突然想试试的页面效果，都可以先放进来。&lt;/p&gt;
&lt;p&gt;大概会先写这些内容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;项目里真正值得回看的设计和问题&lt;/li&gt;
&lt;li&gt;平时用到的配置、命令和代码片段&lt;/li&gt;
&lt;li&gt;学习过程中还没完全吃透、但值得记录的东西&lt;/li&gt;
&lt;li&gt;一些带动画、音乐、视频或交互效果的小实验&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第一版先用 Astro 和 Fuwari 搭起来。它现在还很朴素，但这也挺好：先让内容有地方落脚，再一点点把样子和结构调成自己喜欢的状态。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const blog = {
  stack: [&quot;Astro&quot;, &quot;Fuwari&quot;, &quot;Markdown&quot;],
  purpose: &quot;write first, polish later&quot;,
};
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>在 Frappe / ERPNext 上折腾一个业务网关</title><link>https://r-gc.github.io/posts/project-frappe-erpnext-myapp/</link><guid isPermaLink="true">https://r-gc.github.io/posts/project-frappe-erpnext-myapp/</guid><description>记录 myapp 在 Frappe / ERPNext Docker 环境里的接口、前端、移动端和测试整理。</description><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;一开始只是想把 Frappe / ERPNext 的 Docker 环境跑顺。跑起来之后，问题就变成了另一个：如果真的要围绕 ERPNext 做一个自己的业务系统，代码应该怎么组织才不至于越写越散？&lt;/p&gt;
&lt;p&gt;于是有了这个 &lt;code&gt;myapp&lt;/code&gt;。它现在更像一组持续整理中的实践：后端有自定义 App 和业务网关，前端有 Web 和移动端方向，旁边还放着接口集合、HTTP 测试和一些性能记录。&lt;/p&gt;
&lt;h2&gt;为什么要加一层网关&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;myapp&lt;/code&gt; 是一个基于 Frappe / ERPNext 的业务系统扩展。它没有直接让前端散落调用 ERPNext 原生接口，而是用 &lt;code&gt;myapp.api.gateway.*&lt;/code&gt; 组织出一层更稳定的业务网关。&lt;/p&gt;
&lt;p&gt;这层网关覆盖了商品、客户、销售、采购、供应商、结算、报表、媒体上传和移动端版本信息等能力。&lt;/p&gt;
&lt;p&gt;这样做的价值在于，前端看到的是业务动作，而不是 ERPNext 里面更底层的 DocType 细节：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;前端面对的是业务语义，而不是 ERPNext 的底层 DocType 细节&lt;/li&gt;
&lt;li&gt;错误码、响应格式和权限处理可以统一&lt;/li&gt;
&lt;li&gt;销售、采购等主链路可以围绕幂等和真实 HTTP 测试做回归&lt;/li&gt;
&lt;li&gt;后续替换图片存储、打印服务或移动端能力时，接口契约更稳定&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;现在的结构&lt;/h2&gt;
&lt;p&gt;从目录和文档看，项目大概分成三块：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;apps/myapp&lt;/code&gt;：自定义 Frappe App，放业务接口和测试&lt;/li&gt;
&lt;li&gt;&lt;code&gt;frontend/myapp-web&lt;/code&gt;：Web 管理端，基于 React、Umi Max、Ant Design Pro&lt;/li&gt;
&lt;li&gt;&lt;code&gt;frontend/myapp-mobile&lt;/code&gt;：移动端，基于 Expo、React Native、expo-router&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这让我比较在意的一点是：它不是只停留在后台配置页面，而是开始往“业务现场怎么用”这个方向走。比如移动端依赖里已经出现了相机、图片、打印、PDF、图表这些能力，这些都更接近收货、上传、查看和现场处理。&lt;/p&gt;
&lt;h2&gt;接口怎么组织&lt;/h2&gt;
&lt;p&gt;文档里把接口按业务域组织，而不是按“原生接口 / 自定义接口”划分。这一点很重要，因为调用方真正关心的是“销售要调哪些接口”“采购要调哪些接口”“报表要调哪些接口”。&lt;/p&gt;
&lt;p&gt;当前网关包含这些方向：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;商品搜索、商品创建、商品详情、图片上传&lt;/li&gt;
&lt;li&gt;客户与供应商主数据&lt;/li&gt;
&lt;li&gt;销售订单、发货、开票、收款、退货&lt;/li&gt;
&lt;li&gt;采购订单、收货、采购发票、供应商付款、采购退货&lt;/li&gt;
&lt;li&gt;经营总览、销售分析、采购分析、应收应付、资金流水&lt;/li&gt;
&lt;li&gt;移动端版本信息与认证&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;接口返回也统一成类似这样的包络：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;ok&quot;: true,
  &quot;status&quot;: &quot;success&quot;,
  &quot;code&quot;: &quot;ORDER_CREATED&quot;,
  &quot;message&quot;: &quot;业务提示信息&quot;,
  &quot;data&quot;: {},
  &quot;meta&quot;: {}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;错误响应也做了统一错误码，例如认证、权限、资源不存在、库存不足、参数校验失败等。这个细节很容易被忽略，但对前端开发很友好：不用在每个页面里猜后端到底抛了什么异常。&lt;/p&gt;
&lt;h2&gt;采购链路里一个值得记的点&lt;/h2&gt;
&lt;p&gt;采购模块的设计文档比较完整。它把采购拆成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;创建采购订单&lt;/li&gt;
&lt;li&gt;按实际到货生成采购收货单&lt;/li&gt;
&lt;li&gt;按实际收货生成采购发票&lt;/li&gt;
&lt;li&gt;供应商付款登记&lt;/li&gt;
&lt;li&gt;采购退货&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里有一个关键设计原则：采购订单表示“预期采购”，真正库存入账以 &lt;code&gt;Purchase Receipt&lt;/code&gt; 为准。也就是说，如果供应商实际到货数量和订单数量不一致，系统应该允许按实收数量收货和结算。&lt;/p&gt;
&lt;p&gt;这比“采购订单一建就默认全部到货”的实现更接近真实业务。以后如果单独写采购模块，这个点值得展开讲。&lt;/p&gt;
&lt;h2&gt;测试体系&lt;/h2&gt;
&lt;p&gt;项目文档强调优先使用 HTTP 测试，而不是在宿主机里直接导入 Frappe 服务层。&lt;/p&gt;
&lt;p&gt;原因是 HTTP 测试更接近真实调用路径，可以覆盖：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;鉴权&lt;/li&gt;
&lt;li&gt;权限&lt;/li&gt;
&lt;li&gt;路由&lt;/li&gt;
&lt;li&gt;响应包装&lt;/li&gt;
&lt;li&gt;真实主数据&lt;/li&gt;
&lt;li&gt;devcontainer 网络环境&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;文档中记录了多组测试：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;销售与采购主链路&lt;/li&gt;
&lt;li&gt;商品工作台与销售状态聚合&lt;/li&gt;
&lt;li&gt;采购快捷链路&lt;/li&gt;
&lt;li&gt;幂等、并发和不同数据重放&lt;/li&gt;
&lt;li&gt;单位换算与库存结算回归&lt;/li&gt;
&lt;li&gt;性能基线脚本&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这部分我觉得很值得继续保留。很多项目写到后面乱，不只是代码问题，也是缺少一套能确认“这次改动没有把主链路弄坏”的方法。&lt;/p&gt;
&lt;h2&gt;接下来想补什么&lt;/h2&gt;
&lt;p&gt;这篇先把轮廓记下来。后面更值得写的是这些具体问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Frappe / ERPNext 自定义业务网关设计&lt;/li&gt;
&lt;li&gt;采购链路如何处理“订单数量”和“实际到货”的差异&lt;/li&gt;
&lt;li&gt;移动端如何对接 ERPNext 业务接口&lt;/li&gt;
&lt;li&gt;商品图片上传、临时文件绑定和清理策略&lt;/li&gt;
&lt;li&gt;HTTP 测试如何覆盖 ERPNext 自定义接口&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目前最应该补的，是截图和一条完整业务链路的可视化流程图。只有文字会有点干，等把图补上，这个项目才会更像一篇可以回看的博客文章。&lt;/p&gt;
</content:encoded></item><item><title>这个博客是怎么搭起来的</title><link>https://r-gc.github.io/posts/project-rgc-blog-architecture/</link><guid isPermaLink="true">https://r-gc.github.io/posts/project-rgc-blog-architecture/</guid><description>从选 Astro、Fuwari，到部署到 Cloudflare Workers，记录这个博客的第一版。</description><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;这个站点现在还很早期，但总算从“想弄个博客”变成了“已经有地方可以写东西”。&lt;/p&gt;
&lt;p&gt;我对它的期待不是一次性做成一个很完整的网站，而是先把结构搭出来，然后边写边改。技术文章、项目记录、学习笔记、代码片段，还有一些动画、音乐、视频相关的小实验，都可以慢慢往里放。&lt;/p&gt;
&lt;h2&gt;为什么选这套&lt;/h2&gt;
&lt;p&gt;第一版选的是 Astro + Fuwari。&lt;/p&gt;
&lt;p&gt;Astro 适合内容型站点。默认静态生成，部署简单，后面如果想加一些交互组件，也不用把整个博客变成一个复杂的前端应用。&lt;/p&gt;
&lt;p&gt;Fuwari 则省掉了很多博客基础设施：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页文章流&lt;/li&gt;
&lt;li&gt;文章详情&lt;/li&gt;
&lt;li&gt;归档&lt;/li&gt;
&lt;li&gt;分类和标签&lt;/li&gt;
&lt;li&gt;搜索&lt;/li&gt;
&lt;li&gt;深色模式&lt;/li&gt;
&lt;li&gt;页面转场&lt;/li&gt;
&lt;li&gt;RSS 和 sitemap&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些东西自己从零写当然也能做，但博客的第一目标还是写内容。先用一个成熟主题把底座搭好，会更容易进入“开始写”的状态。&lt;/p&gt;
&lt;h2&gt;现在怎么部署&lt;/h2&gt;
&lt;p&gt;当前部署链路是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;本地开发
  -&amp;gt; git push
  -&amp;gt; GitHub 仓库
  -&amp;gt; Cloudflare Workers 构建部署
  -&amp;gt; blog.rgcdev.top
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;同时保留 GitHub Pages：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GitHub Actions
  -&amp;gt; pnpm build
  -&amp;gt; dist
  -&amp;gt; r-gc.github.io
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样做的好处是：主站可以走 Cloudflare，自定义域名和后续 R2 / Workers 能力都在一个体系里；GitHub Pages 则作为备用访问和对照环境。&lt;/p&gt;
&lt;h2&gt;先把栏目放出来&lt;/h2&gt;
&lt;p&gt;现在先放了几个顶层栏目：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页：最新文章&lt;/li&gt;
&lt;li&gt;归档：按时间、分类、标签浏览&lt;/li&gt;
&lt;li&gt;项目：记录做过、正在做、还想继续整理的东西&lt;/li&gt;
&lt;li&gt;笔记：保存短内容、配置备忘和学习记录&lt;/li&gt;
&lt;li&gt;实验室：放动画、音乐、视频和交互 demo&lt;/li&gt;
&lt;li&gt;关于：个人介绍和站点说明&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;项目页目前是数据驱动的，项目数据统一放在 &lt;code&gt;src/data/projects.ts&lt;/code&gt;。这不是为了炫技，只是为了以后新增项目时不用每次都改页面结构。&lt;/p&gt;
&lt;h2&gt;第一版先到这里&lt;/h2&gt;
&lt;p&gt;第一版已经完成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;站点初始化&lt;/li&gt;
&lt;li&gt;中文配置&lt;/li&gt;
&lt;li&gt;Cloudflare Workers 部署&lt;/li&gt;
&lt;li&gt;GitHub Pages 备用部署&lt;/li&gt;
&lt;li&gt;自定义域名&lt;/li&gt;
&lt;li&gt;项目、笔记、实验室栏目&lt;/li&gt;
&lt;li&gt;项目页数据化&lt;/li&gt;
&lt;li&gt;第一批项目复盘文章&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;后面会慢慢补：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;替换头像和 favicon&lt;/li&gt;
&lt;li&gt;补真实项目截图&lt;/li&gt;
&lt;li&gt;为重点项目建立详情页&lt;/li&gt;
&lt;li&gt;优化首页布局&lt;/li&gt;
&lt;li&gt;增加音乐和视频实验&lt;/li&gt;
&lt;li&gt;把大图和媒体资源迁移到 Cloudflare R2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;现在最重要的不是把页面一次性做漂亮，而是开始积累内容。样式、结构、动画和媒体能力都可以跟着内容慢慢长出来。&lt;/p&gt;
</content:encoded></item><item><title>Cloudflare Workers 部署博客的记录</title><link>https://r-gc.github.io/posts/notes/cloudflare-workers-deploy-note/</link><guid isPermaLink="true">https://r-gc.github.io/posts/notes/cloudflare-workers-deploy-note/</guid><description>记录这个 Astro 博客接入 Cloudflare Workers Static Assets 时用到的构建和部署配置。</description><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;这个博客目前主部署放在 Cloudflare Workers，GitHub Pages 作为备用。&lt;/p&gt;
&lt;p&gt;当前 Cloudflare 侧的构建命令是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pnpm run build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;部署命令是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npx wrangler deploy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;项目里保留了 &lt;code&gt;wrangler.jsonc&lt;/code&gt;，核心配置是把 Astro 构建后的 &lt;code&gt;dist&lt;/code&gt; 作为静态资源目录：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;r-gc-github-io&quot;,
  &quot;compatibility_date&quot;: &quot;2026-05-20&quot;,
  &quot;assets&quot;: {
    &quot;directory&quot;: &quot;./dist/&quot;,
    &quot;not_found_handling&quot;: &quot;404-page&quot;,
    &quot;html_handling&quot;: &quot;auto-trailing-slash&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;后续如果接入 R2 放图片、音频或视频，Workers 会比单纯 GitHub Pages 更方便一些。现在先保持静态博客形态，等媒体资源真的多起来再迁移。&lt;/p&gt;
</content:encoded></item><item><title>Git 多账号配置速查</title><link>https://r-gc.github.io/posts/notes/git-ssh/git-account-config/</link><guid isPermaLink="true">https://r-gc.github.io/posts/notes/git-ssh/git-account-config/</guid><description>记录 Git 全局账号、单仓库账号、远程地址和多 GitHub 账号的常用配置命令。</description><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;这篇用来复制 Git 账号相关命令。&lt;/p&gt;
&lt;h2&gt;查看当前配置&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;git config --list
git config --global --list
git config --local --list
git config --show-origin --list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;--show-origin&lt;/code&gt; 会显示配置来自哪个文件，排查“为什么这个仓库用错账号”时很有用。&lt;/p&gt;
&lt;h2&gt;设置全局账号&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;git config --global user.name &quot;Your Name&quot;
git config --global user.email &quot;you@example.com&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;全局配置会写入：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;~/.gitconfig
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;适合主力账号。比如一台机器主要用 &lt;code&gt;rgc318&lt;/code&gt; 工作，就把全局账号设成 &lt;code&gt;rgc318&lt;/code&gt; 对应的用户名和邮箱。&lt;/p&gt;
&lt;h2&gt;设置当前仓库账号&lt;/h2&gt;
&lt;p&gt;在仓库目录里执行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config user.name &quot;Blog Account&quot;
git config user.email &quot;blog@example.com&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这会写入当前仓库的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.git/config
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;适合某个仓库需要使用另一个身份的情况。&lt;/p&gt;
&lt;h2&gt;查看某个配置最终生效值&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;git config user.name
git config user.email
git config --show-origin user.name
git config --show-origin user.email
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Git 配置优先级大致是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;仓库 local &amp;gt; 用户 global &amp;gt; 系统 system
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;所以仓库里设置过 &lt;code&gt;user.name&lt;/code&gt;，就会覆盖全局配置。&lt;/p&gt;
&lt;h2&gt;修改远程仓库地址&lt;/h2&gt;
&lt;p&gt;查看远程地址：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote -v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;改成普通 GitHub SSH 地址：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote set-url origin git@github.com:USER/REPO.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;改成 HTTPS 地址：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote set-url origin https://github.com/USER/REPO.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;改成 SSH Host 别名地址：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote set-url origin git@github-r-gc:r-gc/r-gc.github.io.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的 &lt;code&gt;github-r-gc&lt;/code&gt; 不是 GitHub 官方域名，而是 &lt;code&gt;~/.ssh/config&lt;/code&gt; 里自己定义的 Host 别名。&lt;/p&gt;
&lt;h2&gt;单仓库指定 SSH key&lt;/h2&gt;
&lt;p&gt;在仓库目录里执行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config core.sshCommand &quot;ssh -i ~/.ssh/id_ed25519_r_gc -o IdentitiesOnly=yes&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看是否生效：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config --local core.sshCommand
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;取消：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config --unset core.sshCommand
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个方式适合“默认 GitHub 账号保持主力账号，但某个仓库固定使用另一把 key”。&lt;/p&gt;
&lt;h2&gt;常用参数解释&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;--global&lt;/code&gt;：写入当前用户的全局 Git 配置。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--local&lt;/code&gt;：只看或只改当前仓库配置。默认在仓库中执行 &lt;code&gt;git config&lt;/code&gt; 时就是 local。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--show-origin&lt;/code&gt;：显示配置来源文件，排查配置覆盖时常用。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;remote set-url&lt;/code&gt;：修改已有 remote 的 URL，不会重建 remote。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;core.sshCommand&lt;/code&gt;：让当前仓库执行 Git SSH 操作时使用指定 SSH 命令。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-i ~/.ssh/id_ed25519_r_gc&lt;/code&gt;：指定 SSH 私钥文件。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-o IdentitiesOnly=yes&lt;/code&gt;：只使用显式指定的 key，避免 SSH 把其它 key 也拿去尝试。&lt;/p&gt;
</content:encoded></item><item><title>Git 代理配置速查</title><link>https://r-gc.github.io/posts/notes/git-ssh/git-proxy-config/</link><guid isPermaLink="true">https://r-gc.github.io/posts/notes/git-ssh/git-proxy-config/</guid><description>记录 Git HTTP/HTTPS 代理的设置、查看、取消和按域名配置方式。</description><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;这篇用来复制 Git 代理相关命令。&lt;/p&gt;
&lt;h2&gt;查看当前 Git 代理&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;git config --global --get http.proxy
git config --global --get https.proxy
git config --show-origin --get http.proxy
git config --show-origin --get https.proxy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看所有代理相关配置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config --global --list | grep -i proxy
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;设置 HTTP/HTTPS 代理&lt;/h2&gt;
&lt;p&gt;HTTP 代理：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config --global http.proxy http://127.0.0.1:10808
git config --global https.proxy http://127.0.0.1:10808
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SOCKS5 代理：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config --global http.proxy socks5://127.0.0.1:10808
git config --global https.proxy socks5://127.0.0.1:10808
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果代理软件同时提供 HTTP 和 SOCKS5 端口，Git 的 HTTP/HTTPS 拉取通常用 HTTP 代理更直接。&lt;/p&gt;
&lt;h2&gt;只给 GitHub 设置代理&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;git config --global http.https://github.com.proxy http://127.0.0.1:10808
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;取消 GitHub 单独代理：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config --global --unset http.https://github.com.proxy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这种写法只影响访问 &lt;code&gt;https://github.com&lt;/code&gt; 的 Git HTTP 请求。&lt;/p&gt;
&lt;h2&gt;取消全局代理&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;git config --global --unset http.proxy
git config --global --unset https.proxy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果不确定是否存在：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config --global --unset-all http.proxy
git config --global --unset-all https.proxy
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;临时使用代理执行一次 Git 命令&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;git -c http.proxy=http://127.0.0.1:10808 -c https.proxy=http://127.0.0.1:10808 pull
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个不会写入配置文件，只对这一次命令生效。&lt;/p&gt;
&lt;h2&gt;注意 SSH remote 不走 Git HTTP 代理&lt;/h2&gt;
&lt;p&gt;如果 remote 是 HTTPS：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://github.com/USER/REPO.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Git 的 &lt;code&gt;http.proxy&lt;/code&gt; / &lt;code&gt;https.proxy&lt;/code&gt; 会生效。&lt;/p&gt;
&lt;p&gt;如果 remote 是 SSH：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git@github.com:USER/REPO.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Git 的 HTTP 代理不会生效，需要配置 SSH 代理，也就是 &lt;code&gt;~/.ssh/config&lt;/code&gt; 里的 &lt;code&gt;ProxyCommand&lt;/code&gt;。&lt;/p&gt;
&lt;h2&gt;常用参数解释&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;http.proxy&lt;/code&gt;：Git 访问 HTTP 地址时使用的代理。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;https.proxy&lt;/code&gt;：Git 访问 HTTPS 地址时使用的代理。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;http.https://github.com.proxy&lt;/code&gt;：只给指定 URL 前缀设置代理。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--get&lt;/code&gt;：只读取某个配置值。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--unset&lt;/code&gt;：删除某个配置值。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--unset-all&lt;/code&gt;：删除同名配置的所有值。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-c key=value&lt;/code&gt;：只在当前这次 Git 命令里临时覆盖配置。&lt;/p&gt;
</content:encoded></item><item><title>SSH 密钥生成与 GitHub 配置速查</title><link>https://r-gc.github.io/posts/notes/git-ssh/ssh-key-generation/</link><guid isPermaLink="true">https://r-gc.github.io/posts/notes/git-ssh/ssh-key-generation/</guid><description>记录生成 SSH key、启动 ssh-agent、添加公钥到 GitHub 和测试连接的常用命令。</description><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;这篇用来复制 SSH key 相关命令。&lt;/p&gt;
&lt;h2&gt;生成 ed25519 key&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;ssh-keygen -t ed25519 -C &quot;you@example.com&quot; -f ~/.ssh/id_ed25519_github
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果是给另一个 GitHub 账号单独生成 key，可以换文件名：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh-keygen -t ed25519 -C &quot;blog@example.com&quot; -f ~/.ssh/id_ed25519_r_gc
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;查看公钥&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;cat ~/.ssh/id_ed25519_github.pub
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;把输出内容复制到 GitHub：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GitHub -&amp;gt; Settings -&amp;gt; SSH and GPG keys -&amp;gt; New SSH key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意复制的是 &lt;code&gt;.pub&lt;/code&gt; 公钥，不是没有后缀的私钥。&lt;/p&gt;
&lt;h2&gt;设置权限&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519_github
chmod 644 ~/.ssh/id_ed25519_github.pub
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果权限太开放，SSH 可能会拒绝使用私钥。&lt;/p&gt;
&lt;h2&gt;启动 ssh-agent 并添加 key&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;eval &quot;$(ssh-agent -s)&quot;
ssh-add ~/.ssh/id_ed25519_github
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看 agent 里已有 key：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh-add -l
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;从 agent 删除某个 key：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh-add -d ~/.ssh/id_ed25519_github
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;清空 agent 中所有 key：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh-add -D
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;测试 GitHub SSH&lt;/h2&gt;
&lt;p&gt;普通测试：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh -T git@github.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果 &lt;code&gt;~/.ssh/config&lt;/code&gt; 里配置了 Host 别名：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh -T git@github-r-gc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;成功时通常会看到类似：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Hi USER! You&apos;ve successfully authenticated, but GitHub does not provide shell access.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;常用参数解释&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ssh-keygen&lt;/code&gt;：生成 SSH 密钥。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-t ed25519&lt;/code&gt;：指定密钥算法。现在一般优先用 ed25519。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-C &quot;you@example.com&quot;&lt;/code&gt;：给 key 加注释，常用邮箱或用途，方便以后识别。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-f ~/.ssh/id_ed25519_github&lt;/code&gt;：指定生成文件路径和文件名。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.pub&lt;/code&gt;：公钥文件，可以上传到 GitHub。&lt;/p&gt;
&lt;p&gt;没有 &lt;code&gt;.pub&lt;/code&gt; 后缀的文件：私钥文件，不能公开。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ssh-agent&lt;/code&gt;：本地密钥代理，可以记住已添加的私钥。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ssh-add&lt;/code&gt;：把私钥加入 agent。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ssh -T&lt;/code&gt;：测试 SSH 认证，不打开远程 shell。&lt;/p&gt;
</content:encoded></item><item><title>SSH 代理与多 GitHub 账号配置速查</title><link>https://r-gc.github.io/posts/notes/git-ssh/ssh-proxy-and-config/</link><guid isPermaLink="true">https://r-gc.github.io/posts/notes/git-ssh/ssh-proxy-and-config/</guid><description>记录 SSH config、ProxyCommand、GitHub 443 端口、多账号 Host 别名和常用参数。</description><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;这篇用来复制 SSH 代理和多账号配置。&lt;/p&gt;
&lt;h2&gt;基础 GitHub SSH 配置&lt;/h2&gt;
&lt;p&gt;编辑：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nano ~/.ssh/config
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;普通 GitHub SSH：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_github
  IdentitiesOnly yes
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;GitHub SSH 走 443 端口&lt;/h2&gt;
&lt;p&gt;有些网络环境下，22 端口不稳定，可以改用 GitHub 提供的 SSH over HTTPS 端口：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Host github.com
  HostName ssh.github.com
  User git
  Port 443
  IdentityFile ~/.ssh/id_ed25519_github
  IdentitiesOnly yes
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh -T git@github.com
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;SSH 通过 SOCKS5 代理&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;Host github.com
  HostName ssh.github.com
  User git
  Port 443
  IdentityFile ~/.ssh/id_ed25519_github
  IdentitiesOnly yes
  ProxyCommand nc -X 5 -x 127.0.0.1:10808 %h %p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里适合本地代理监听在 &lt;code&gt;127.0.0.1:10808&lt;/code&gt; 的情况。&lt;/p&gt;
&lt;h2&gt;多 GitHub 账号 Host 别名&lt;/h2&gt;
&lt;p&gt;默认账号：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Host github.com
  HostName ssh.github.com
  User git
  Port 443
  IdentityFile ~/.ssh/id_ed25519_github
  IdentitiesOnly yes
  ProxyCommand nc -X 5 -x 127.0.0.1:10808 %h %p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;博客账号：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Host github-r-gc
  HostName ssh.github.com
  User git
  Port 443
  IdentityFile ~/.ssh/id_ed25519_r_gc
  IdentitiesOnly yes
  ProxyCommand nc -X 5 -x 127.0.0.1:10808 %h %p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用别名测试：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh -T git@github-r-gc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;仓库 remote 使用别名：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote set-url origin git@github-r-gc:r-gc/r-gc.github.io.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样默认 &lt;code&gt;github.com&lt;/code&gt; 可以继续给主力账号使用，&lt;code&gt;github-r-gc&lt;/code&gt; 专门给博客账号使用。&lt;/p&gt;
&lt;h2&gt;查看 SSH 实际使用的配置&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;ssh -G github.com | less
ssh -G github-r-gc | less
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;调试连接过程：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh -vT git@github.com
ssh -vT git@github-r-gc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果信息不够，再增加 &lt;code&gt;v&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh -vvvT git@github.com
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;常用参数解释&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Host&lt;/code&gt;：本地别名。Git remote 里写的主机名会匹配它。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;HostName&lt;/code&gt;：真实连接的服务器地址。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;User git&lt;/code&gt;：GitHub SSH 固定使用 &lt;code&gt;git&lt;/code&gt; 用户。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Port 443&lt;/code&gt;：使用 443 端口连接 GitHub SSH，适合 22 端口不通或不稳定时。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;IdentityFile&lt;/code&gt;：指定私钥路径。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;IdentitiesOnly yes&lt;/code&gt;：只使用 &lt;code&gt;IdentityFile&lt;/code&gt; 指定的 key，避免 SSH 尝试一堆其它 key。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ProxyCommand&lt;/code&gt;：连接目标服务器前，先通过这个命令建立网络通道。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;nc&lt;/code&gt;：netcat，用来建立代理连接。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-X 5&lt;/code&gt;：告诉 &lt;code&gt;nc&lt;/code&gt; 使用 SOCKS5 代理。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-x 127.0.0.1:10808&lt;/code&gt;：指定代理地址和端口。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;%h&lt;/code&gt;：SSH 会替换成目标主机，也就是 &lt;code&gt;HostName&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;%p&lt;/code&gt;：SSH 会替换成目标端口，也就是 &lt;code&gt;Port&lt;/code&gt;。&lt;/p&gt;
</content:encoded></item></channel></rss>