GIT · GITHUB · GITHUB PAGES · GH · 2026 年 9 月

网站上线手记

从一个本地的 HTML 文件,到任何人都能打开的 dfangkai.github.io:这次具体做了哪些事、每一步为什么这样做,以及以后怎么自己维护这个网站。写给之前没接触过 git、GitHub Pages 和 gh 的人。

网站 dfangkai.github.io本地文件夹 ~/code/dfangkai.github.iogh 2.101.0上线日期 2026-09-25

以后更新网站就是走一遍这条路:在本地改文件 → 用 git 提交并推送 → GitHub 自动部署 → 一两分钟后网站更新。

目录

一、先认识它们
二、这次做了什么(12 步)
三、以后怎么用
四、出问题怎么办
五、命令速查表

第一部分先认识它们git、GitHub、GitHub Pages、gh 名字很像,其实是四样不同的东西。先弄清楚各自是什么。

六个概念

静态网站static site

网站就是一堆文件:HTML(内容和结构)、CSS(样式)、JavaScript(交互)。"静态"的意思是服务器只负责把这些文件原样发给浏览器,不在服务器上运行任何程序。

这个网站就是静态网站:几个 index.html,样式和脚本都写在文件里面。好处是简单、免费、几乎不会出故障;代价是没有登录、数据库、评论这类需要服务器运行程序的功能。

git版本管理工具

装在你电脑上的程序,用来记录文件的每一次改动,像游戏存档一样可以随时回到过去的任意版本。几个术语:

  • 仓库(repository):被 git 管理的文件夹。里面有个隐藏的 .git 目录,存着全部历史。
  • 提交(commit):一次存档。每次提交都有一个编号(比如 e6aad1f)和一句说明。
  • 分支(branch):一条独立的存档线。这个网站只用一条,叫 main。
  • 远程(remote):同一个仓库在别处的副本。这个网站的远程叫 origin,指向 GitHub 上的仓库。
  • 推送(push)/ 拉取(pull):把本地的新提交上传到远程 / 把远程的新提交下载到本地。
GitHubgithub.com

一个存放 git 仓库的网站(公司),外加协作功能:在网页上浏览代码、看改动历史、讨论问题等。git 和 GitHub 的关系,类似"文档"和"网盘":git 是工具,GitHub 是放仓库的地方。

仓库分公开(public)和私有(private)两种。公开仓库的所有内容,包括每一次提交的历史,任何人都能看到。

GitHub Pages网站托管

GitHub 提供的免费静态网站托管:你把 HTML 文件放进仓库,它就把这些文件发布成一个网站。有两种站点:

用户站点(本站用的这种)项目站点
仓库名必须是 用户名.github.io任意仓库
网址https://用户名.github.io/https://用户名.github.io/仓库名/
数量每个账号只能有一个每个仓库都可以有一个

免费账号需要用公开仓库;私有仓库发布 Pages 需要付费计划(以 GitHub 当前文档为准)。

ghGitHub CLI

GitHub 官方的命令行工具。GitHub 网页上能做的大部分事情(建仓库、看部署状态、改设置),都能在终端里用 gh 完成。它还负责帮你登录 GitHub。

没有 gh 也能用 GitHub,只是这些操作要去网页上点。这次用 gh,是为了让整个流程都能在终端里一步步完成,并把每一步的结果记录下来。

GitHub Actions自动化

GitHub 的自动化流水线:仓库里发生某件事(比如有新提交)时,自动在 GitHub 的服务器上执行一系列任务。GitHub Pages 就是用它来部署的:每次你推送,都会自动运行一个叫 pages build and deployment 的任务,把新文件发布出去。你不需要自己配置它。

还有三个会碰到的词

token(令牌):登录 GitHub 后得到的一串"通行证",gh 用它代表你操作 GitHub,这样就不用每次都输入密码。

钥匙串(Keychain):macOS 自带的密码保险箱。登录后的 token 就保存在这里,而不是明文写在某个文件里。

SSH 密钥:git 推送时用来证明"我是 dfangkai"的一对文件。私钥 ~/.ssh/id_ed25519 只留在自己电脑上,绝不外传;公钥 id_ed25519.pub 登记在 GitHub 账号里。GitHub 用公钥核对私钥,对得上就放行,全程不用输密码。

谁负责什么

最容易搞混的是 git 和 gh。简单说:git 管文件,gh 管 GitHub 网站上的东西。

要做的事用什么这次用到的命令
记录改动(存档)gitgit add、git commit
上传到 GitHubgitgit push
登录 GitHubghgh auth login
推送时证明身份SSH 密钥不用命令;ssh -T git@github.com 可以测试
在 GitHub 上建仓库ghgh repo create
查看、修改仓库设置(比如 Pages)ghgh api
查看部署进度ghgh run list、gh run watch
把文件发布成网站GitHub Pages(自动)不需要命令,推送后自动发生
第二部分这次做了什么按实际发生的顺序记录。这个网站是我在 AI 编程助手 Claude 的帮助下搭建的。标签 Claude 表示由 Claude 执行,我 表示由我亲自操作。命令输出都是当时的原样(个人路径和邮箱有省略)。

12 个步骤

  1. Claude把教程包装成完整网页

    uv 教程原本是 Artifact 页面。Artifact 平台在显示时会自动给页面套上一层外壳(<!doctype html>、<head>、<body>,还有几行基础样式),所以原文件里并没有这些。GitHub Pages 不会自动加,所以要先补上:

    补上的外壳(节选)
    <!doctype html>
    <html lang="zh-CN">
    <head>
    <meta charset="utf-8">                  <!-- 否则中文可能乱码 -->
    <meta name="viewport" content="width=device-width, initial-scale=1">  <!-- 手机上正常缩放 -->
    <style>body{margin:0} …</style>       <!-- 平台原本提供的基础样式 -->
    …原来的页面内容…
    </body>
    </html>

    要记住的:Artifact 版和网站版是两份独立的文件。改了其中一份,另一份不会自动同步。

  2. Claude用 Homebrew 装 gh:失败了

    Homebrew 是 macOS 上最常用的软件安装工具,通常 brew install gh 一条命令就能装好。但这次:

    $ brew install gh
    Warning: You are using macOS 27.
    We do not provide support for this pre-release version.
    Error: gh: no bottle available!

    原因:我用的 macOS 27 是预览版。Homebrew 的"bottle"是为每个系统版本预先编译好的安装包,它还没有为 macOS 27 准备。虽然可以从源代码自己编译,但要额外装 Go 语言编译环境,太重了,所以换了个办法。

  3. Claude改用 GitHub 官方安装包,并核对校验和

    gh 的开发者在 github.com/cli/cli/releases 发布了编译好的安装包,适用于所有 macOS 版本。步骤是:查到最新版本号 → 下载 Apple 芯片版的压缩包 → 同时下载官方公布的校验和清单 → 核对:

    $ curl -fsSLO https://github.com/cli/cli/releases/download/v2.101.0/gh_2.101.0_macOS_arm64.zip
    $ curl -fsSL  https://github.com/cli/cli/releases/download/v2.101.0/gh_2.101.0_checksums.txt -o gh_checksums.txt
    $ grep " gh_2.101.0_macOS_arm64.zip$" gh_checksums.txt > gh_expected.txt   # 从清单里取出这个文件的那一行
    $ shasum -a 256 -c gh_expected.txt                                          # 自己算一遍,和清单对比
    gh_2.101.0_macOS_arm64.zip: OK

    校验和是什么:每个文件都能算出一个唯一的"指纹"(SHA-256 值)。下载后自己算一遍,和官方公布的对比,一致就说明文件完整,没有在下载途中损坏或被篡改。从网上下载可执行程序时,这是一个好习惯。

    然后解压,把 gh 程序复制到 ~/.local/bin/:

    $ cp gh_unz/*/bin/gh ~/.local/bin/gh
    $ which gh
    ~/.local/bin/gh
    $ gh --version
    gh version 2.101.0 (2026-09-15)

    为什么放在 ~/.local/bin:终端只会在 PATH 环境变量列出的几个文件夹里找命令。我的 ~/.zshrc 里有一句 export PATH="$HOME/.local/bin:$PATH",把这个文件夹加进了 PATH(uv 也装在这里)。放进去之后,在任何位置输入 gh 都能找到它,而且不需要管理员密码。

  4. 我登录 GitHub

    登录必须由账号主人在浏览器里授权,所以这一步是我自己在新终端窗口里完成的:

    $ gh auth login --hostname github.com --git-protocol https --web
    --hostname github.com
    登录的是 github.com(而不是公司自建的 GitHub)
    --git-protocol https
    git 用 HTTPS 方式和 GitHub 通信(另一种是 SSH)
    --web
    用浏览器授权:终端显示一个一次性验证码,你在网页上输入它,确认"是我本人"

    登录后的状态(token 已被遮住):

    $ gh auth status
    github.com
      ✓ Logged in to github.com account dfangkai (keyring)
      - Active account: true
      - Git operations protocol: https
      - Token: gho_************************************
      - Token scopes: 'gist', 'read:org', 'repo', 'workflow'

    怎么读:(keyring) 表示 token 存在 macOS 钥匙串里。Token scopes 是这个 token 被允许做的事:repo 可以读写你的仓库,workflow 可以改 Actions 配置,read:org 能读取组织信息,gist 能管理代码片段。建仓库、推送、开 Pages 主要靠 repo。

  5. Claude让 git 使用 gh 的登录信息

    $ gh auth setup-git

    它在 git 全局配置(~/.gitconfig)里加了几项设置,用 git config --global --get-regexp credential 可以看到:

    credential.https://github.com.helper
    credential.https://github.com.helper !~/.local/bin/gh auth git-credential
    credential.https://gist.github.com.helper
    credential.https://gist.github.com.helper !~/.local/bin/gh auth git-credential

    作用:以后 git 访问 github.com 需要身份验证时(比如 push),会去问 gh 要 token,而 gh 从钥匙串里取出来交给它。所以你推送时不用输入任何密码。另外,GitHub 早就不接受用账号密码推送了,不配置这一步的话,就得手动生成 token 并粘贴。

    后来:9 月 26 日改用了 SSH 推送(SSH 密钥之前就配好了):仓库地址换成 git@github.com:dfangkai/dfangkai.github.io.git,上面这几项设置也删掉了。现在的用法见第三部分的换电脑和第四部分的常见问题。

  6. Claude建网站文件夹和文件

    ~/code/dfangkai.github.io
    .
    ├── .nojekyll            # 空文件:告诉 GitHub Pages 不要用 Jekyll 处理
    ├── index.html           # 首页 → https://dfangkai.github.io/
    └── uv-guide/
        └── index.html       # 教程 → https://dfangkai.github.io/uv-guide/

    为什么都叫 index.html:网址指向一个文件夹时,服务器默认返回里面的 index.html。所以 /uv-guide/ 打开的就是 uv-guide/index.html,网址里不用写文件名。

    .nojekyll 是什么:Jekyll 是一个网站生成器,GitHub Pages 默认会先用它处理仓库里的文件(比如把 Markdown 转成网页)。这个网站是写好的 HTML,不需要这一步。加一个名为 .nojekyll 的空文件就会跳过它,部署更快,也避免 Jekyll 意外忽略以下划线开头的文件。

  7. Claude初始化 git 仓库,做第一次提交

    $ git init -b main          # 把这个文件夹变成 git 仓库,主分支叫 main
    $ git add -A                # 把所有文件放进"待提交"区
    $ git status --short        # 看看准备提交什么
    A  .nojekyll                  # A = Added,新增的文件
    A  index.html
    A  uv-guide/index.html
    $ git commit -m "Add homepage and uv guide"
    $ git log --oneline
    e6aad1f Add homepage and uv guide

    add 和 commit 为什么分两步:git add 是挑选"这次存档要包含哪些改动",git commit 才是真正存档。分开是为了让你可以只提交一部分改动。日常用 git add -A(全部)就行。

    提交者是谁:git 用全局配置里的 user.name 和 user.email 标记每次提交的作者,我之前已经设置过(名字是 dfangkai)。这些信息会随仓库公开。

  8. Claude在 GitHub 上建仓库并推送

    一条 gh 命令完成三件事:在 GitHub 上建仓库、把它登记为本地仓库的远程、推送:

    $ gh repo create dfangkai/dfangkai.github.io --public --source=. --remote=origin --push --description "dfangkai 的学习笔记"
    https://github.com/dfangkai/dfangkai.github.io
    To https://github.com/dfangkai/dfangkai.github.io.git
     * [new branch]      HEAD -> main
    branch 'main' set up to track 'origin/main'.
    dfangkai/dfangkai.github.io
    "所有者/仓库名"。仓库名是用户名 + .github.io,GitHub 才会把它当作用户站点
    --public
    公开仓库(免费账号的 Pages 需要)
    --source=.
    用当前文件夹(.)作为这个仓库的内容
    --remote=origin
    在本地把 GitHub 上的仓库登记为名叫 origin 的远程
    --push
    建好后立刻把本地提交推送上去

    输出怎么读:[new branch] HEAD -> main 表示 GitHub 上新建了 main 分支,内容是本地当前的提交;set up to track 表示本地 main 和远程 main 关联好了,以后直接 git push 就知道往哪推。

  9. Claude确认 Pages 已开启

    用户站点仓库一推送,GitHub 通常会自动开启 Pages。用 gh api 查询 Pages 设置:

    $ gh api repos/dfangkai/dfangkai.github.io/pages
    {"https":true,"source":{"branch":"main","path":"/"},"status":"building","url":"https://dfangkai.github.io/"}

    怎么读:从 main 分支的根目录(/)发布;强制使用 HTTPS;状态 building 表示正在部署。如果查询结果是"未开启",就用同一个接口发一个开启请求(gh api -X POST …/pages),这次不需要。

    gh api 是什么:GitHub 网页上的所有功能背后都有对应的 API(程序接口)。gh api 让你带着登录身份直接调用它们,适合 gh 没有专门命令的操作。等价的网页操作是:仓库 → Settings → Pages。

  10. Claude等待部署完成

    $ gh run list --limit 1          # 找到最新的部署任务
    $ gh run watch 36155490862       # 盯着它,直到结束
    …
    # 结束后查询结果:pages build and deployment → completed,结论 success

    部署过程中还出现了两条提示:

    ! Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24 …
    - "The ubuntu-latest label will migrate to Ubuntu 26 beginning October 19, 2026 …"

    要不要管:不用。这是 GitHub 自己的部署任务在提醒它内部使用的软件版本要升级,和网站文件无关,也不影响部署结果。

  11. Claude验证网站可以访问

    $ curl -s -o /dev/null -w "%{http_code}" https://dfangkai.github.io/
    200                     # 200 = 访问成功(404 = 找不到)
    $ curl -s https://dfangkai.github.io/uv-guide/ | cmp -s - uv-guide/index.html && echo "一致"
    一致                    # 线上的教程和本地文件逐字节相同

    curl 是一个在终端里访问网址的工具,相当于没有界面的浏览器。cmp 逐字节比较两个文件。这样验证比"打开看一眼"更可靠:能确认线上确实是最新版本,而不是浏览器缓存里的旧页面。

  12. Claude更新首页:第一次"日常更新"

    后来重新设计了首页。这次的流程,就是以后每次更新网站要走的流程:

    $ git add index.html
    $ git commit -m "Redesign homepage as a learning notebook"
    $ git push
    To https://github.com/dfangkai/dfangkai.github.io.git
       e6aad1f..1eb91a4  main -> main        # 远程的 main 从 e6aad1f 前进到 1eb91a4
    $ gh run watch …
    # 部署记录:success,开始 15:50:24,结束 15:51:59(UTC),从推送到上线约 1.5 分钟

    注意这次只需要 git push,不用再写 origin 和 main,因为第 8 步已经把两边关联好了。

第三部分以后怎么用日常维护网站需要的所有操作。所有命令都在网站文件夹里运行,先 cd ~/code/dfangkai.github.io。

更新网站:四步

每次更新都是这四步
$ cd ~/code/dfangkai.github.io
# 1. 用编辑器修改文件(比如 VS Code:code .)
$ git status                          # 2. 看看改了哪些文件
$ git add -A                          # 3. 挑选全部改动 …
$ git commit -m "说明这次改了什么"      #    … 存档
$ git push                            # 4. 推送,一两分钟后网站自动更新

三个帮你"看清楚"的命令,改动之前、之后都可以随时用:

命令告诉你什么
git status哪些文件被改了、哪些还没提交、本地是否领先于 GitHub
git diff具体改了哪几行(按 q 退出)
git log --oneline历史提交列表,最新的在最上面
提交说明怎么写写清楚"做了什么",比如"修正 uv 教程第 9 课的错别字""新增 git 入门笔记"。以后翻历史时,这句话是你唯一的线索。

加一篇新笔记

每篇笔记一个文件夹,文件夹里放一个 index.html。文件夹名就是网址的一部分:

index.html→https://dfangkai.github.io/
uv-guide/index.html→https://dfangkai.github.io/uv-guide/
git-basics/index.html→https://dfangkai.github.io/git-basics/
  1. 新建文件夹,比如 git-basics/,把网页存成里面的 index.html。文件夹名用小写英文和连字符,不要用空格和中文,网址会更干净。
  2. 如果网页来自 Artifact,记得像第 1 步那样补上完整的外壳。
  3. 在新页面顶部加上返回首页的导航条(每篇笔记只放这一个返回入口):从 uv-guide/index.html 里复制 <nav class="sitebar"> 那一行和对应的样式。链接写 href="../",意思是"上一级文件夹",也就是首页。这个导航条会吸在页面顶部,高度记在 --sitebar-h 里;如果新页面也有吸在顶部的目录,把目录的 top 加上 var(--sitebar-h),免得被导航条挡住。
  4. 再从 uv-guide/index.html 末尾复制"页内跳转不新增历史记录"那段 <script>,放在新页面的 </body> 前面。有了它,在笔记里点多少次目录,按一次浏览器"后退"都能直接回到首页。
  5. 不要引用 Google Fonts 之类的外链字体:国内经常打不开,会让页面白屏好几秒。字体直接写系统自带的,比如 "PingFang SC","Microsoft YaHei",sans-serif,等宽字体写 "SF Mono",Menlo,Consolas,monospace。
  6. 在首页 index.html 的"笔记"列表里加一项:复制已有的那个 <li>,改掉标题、简介、标签、日期和链接(写 href="git-basics/",相对路径,不用写完整网址)。再把"笔记"旁边的数字加一,在"学习日志"最上面加一行。
  7. 在浏览器里直接打开本地的 index.html 检查一遍,然后按上面的四步提交、推送。

这些步骤也可以直接交给 Claude:"把这个页面加到我的网站上"。

查看部署状态

在终端里
$ gh run list --limit 5       # 最近 5 次部署:✓ 成功,X 失败,* 进行中
$ gh run watch                # 挑一个进行中的任务,实时跟踪到结束
$ gh browse                   # 在浏览器里打开这个仓库的 GitHub 页面

在网页上看:打开仓库页面,点顶部的 Actions 标签,每次推送对应一条 pages build and deployment 记录。绿色对勾表示成功,红色叉号表示失败,点进去能看到详细日志。

换电脑、重装系统

网站的全部内容和历史都在 GitHub 上,本地文件夹只是一个副本。在新电脑上恢复:

在新电脑上
# 1. 安装 gh(新电脑如果是正式版 macOS,Homebrew 一般就能装)
$ brew install gh
# 2. 登录 GitHub。过程中 gh 会问要不要上传 SSH 公钥,选 Yes
#    (新电脑上还没有密钥的话,它会提出帮你生成一个)
$ gh auth login --hostname github.com --git-protocol ssh --web
# 3. 测试 SSH 能否连上。第一次连接会问 continue connecting,输入 yes
$ ssh -T git@github.com
Hi dfangkai! You've successfully authenticated, but GitHub does not provide shell access.
# 4. 把仓库下载到本地(clone = 克隆,连同全部历史一起下载)
$ gh repo clone dfangkai/dfangkai.github.io ~/code/dfangkai.github.io

也可以把旧电脑上的 ~/.ssh/id_ed25519 和 id_ed25519.pub 拷过来继续用,这样第 2 步就不用上传新公钥。私钥相当于密码,拷贝时不要经过网盘或聊天软件。

别忘了在新电脑上设置 git 的作者信息:git config --global user.name "dfangkai" 和 git config --global user.email "你的邮箱"。

撤销改动

情况怎么办效果
改乱了一个文件,还没提交git restore 文件名文件回到上次提交时的样子(这次的修改会丢失)
已经 git add,但还没提交git restore --staged 文件名从"待提交"区撤出来,文件内容不变
已经推送上线,想退回上一个版本git revert HEAD,然后 git push新建一个"反向"提交,抵消上一次的改动,网站回到之前的样子
为什么用 revert 而不是删除历史git revert 不改写历史,只是再加一个提交,最安全。网上有些教程会教 git reset --hard 加 git push --force,那会改写已经公开的历史,容易出问题,初学阶段不要用。

升级 gh

gh 发现有新版本时,会在命令输出的最后提示你。因为它是手动安装的,升级就是重复第 3 步:下载新版本的安装包,核对校验和,覆盖 ~/.local/bin/gh。也可以直接让 Claude 来做。

等 Homebrew 开始支持 macOS 27 后,可以改用 Homebrew 管理:先删掉手动装的版本 rm ~/.local/bin/gh,再 brew install gh,以后用 brew upgrade gh 升级。

$ gh --version          # 查看当前版本

安全须知

  • 公开仓库的一切都是公开的,包括历史。一个文件即使后来删掉了,之前的提交里仍然能找到它。所以 API Key、密码、.env 这类东西永远不要放进这个仓库,放进去之后再删掉也不算安全。
  • token 等同于你的账号权限。它保存在 macOS 钥匙串里,不要把 gh auth token 的输出发给任何人或贴到任何地方。
  • 不用了可以退出登录:gh auth logout。
  • 彻底撤销授权:在 GitHub 网页上进入 Settings → Applications → Authorized OAuth Apps,找到 GitHub CLI,点 Revoke。
  • GitHub Pages 的使用规则:不能用来经营网店、提供商业服务,也不能处理密码、信用卡号这类敏感信息。个人笔记、作品展示完全没问题。

免费额度对个人笔记网站绰绰有余(来自 GitHub 官方文档):

项目限制
发布的网站大小不超过 1 GB(仓库建议也不超过 1 GB)
流量每月 100 GB(软限制)
部署次数每小时 10 次(软限制)
单次部署时间超过 10 分钟会失败

以后可能用到

自定义域名

买了自己的域名(比如 dfangkai.com)后,可以让它指向这个网站:在仓库 Settings → Pages → Custom domain 填写域名,再到域名服务商那里添加 DNS 记录。GitHub 会自动配置 HTTPS。

自定义 404 页面(已加上)

仓库根目录的 404.html 就是它:访客打开不存在的网址时会看到这一页,而不是 GitHub 默认的英文错误页。它会出现在任意网址下,所以里面的链接要写 / 开头的绝对路径(比如 href="/"),不能写 ../。

项目站点

其他仓库也能开 Pages,网址是 dfangkai.github.io/仓库名/。比如以后给某个项目写文档,可以放在那个项目自己的仓库里,而不用塞进这个笔记网站。

直接在网页上改

在 GitHub 仓库页面点开文件,再点铅笔图标,可以直接在线编辑并提交,同样会触发部署。之后回到电脑上,记得先 git pull 把这次改动拉下来(见下方常见问题)。

第四部分出问题怎么办按症状查找。

常见问题

git push 被拒绝,提示 rejected … (fetch first)

原因:GitHub 上有你本地没有的提交,比如你在网页上直接改过文件,或者在另一台电脑上推送过。git 为了不覆盖它们,拒绝了这次推送。

解决:先把远程的提交拉下来,接到你的提交之前,再推送:

$ git pull --rebase
$ git push
推送成功了,但网站上看到的还是旧内容
  1. 等一两分钟,部署需要时间。用 gh run list --limit 1 看看最新一次部署是否已经成功。
  2. 浏览器可能用了缓存。按 ⌘ ⇧ R 强制刷新,或者用无痕窗口打开。
  3. 确认改的是网站文件夹里的文件,而不是别处的副本(比如 Artifact 版)。
打开网址显示 404

检查三点:文件名是不是 index.html(全小写);文件夹名和网址是否完全一致(GitHub Pages 区分大小写);链接末尾有没有少写 /。刚推送的新页面也可能只是还没部署完。

部署失败(Actions 里是红色叉号)

查看失败原因:

$ gh run list --limit 3                  # 找到失败的那次,记下编号
$ gh run view 编号 --log-failed          # 只看出错部分的日志

纯 HTML 网站很少失败。偶尔是 GitHub 自身的临时故障,这种情况下再推送一次(或者在 Actions 页面点 Re-run)通常就好了。

终端提示 command not found: gh

gh 装在 ~/.local/bin,靠 ~/.zshrc 里的 PATH 设置才能找到。可以关掉终端重新打开,或者运行 source ~/.zshrc。如果还不行,检查文件是否还在:ls ~/.local/bin/gh。

推送时提示 Permission denied (publickey),或者要求输入密码

说明 GitHub 没认出你的 SSH 密钥,或者仓库地址不是 SSH 形式。依次检查:

$ ssh -T git@github.com     # 成功会显示 Hi dfangkai!
$ ls ~/.ssh                 # 私钥 id_ed25519 还在不在
$ git remote -v             # 地址应该以 git@github.com: 开头

如果地址是 https:// 开头,用 git remote set-url origin git@github.com:dfangkai/dfangkai.github.io.git 改回来。如果密钥丢了,用 ssh-keygen -t ed25519 生成一对新的(一路回车即可),再把公钥加到 GitHub:

$ gh auth refresh -h github.com -s admin:public_key   # 给 gh 加上管理公钥的权限,会打开浏览器确认
$ gh ssh-key add ~/.ssh/id_ed25519.pub --title "MacBook"

另一种情况是 ssh -T 一直卡住没反应:有些校园网或公司网络会封掉 SSH 用的 22 端口。GitHub 在 443 端口也提供 SSH,可以用 ssh -T -p 443 git@ssh.github.com 试试,能通的话让 Claude 帮你改配置。

不小心把密钥提交并推送了

第一件事是去对应平台作废这个密钥,重新生成一个新的。比如 TypeSafe 的 API Key,就去它的控制台删除旧 key。因为仓库是公开的,推送的那一刻就应该当作已经泄露;从历史里删除记录比较复杂,而且无法保证期间没有人看到过。

第五部分速查

命令速查表

日常更新(git)
git status看改了什么、有没有没提交的
git diff看具体改了哪几行
git add -A挑选全部改动
git commit -m "说明"存档
git push上传到 GitHub,触发部署
git pull --rebase先拉取远程的新提交
git log --oneline看历史
git revert HEAD撤销上一次提交(再 push)
git remote -v看远程仓库地址
ssh -T git@github.com测试 SSH 能否连上 GitHub
GitHub 相关(gh)
gh auth status看登录状态
gh auth login --web登录
gh run list --limit 5最近的部署记录
gh run watch实时跟踪部署
gh browse在浏览器打开仓库页面
gh repo clone dfangkai/dfangkai.github.io在新电脑上下载仓库
三个地址

网站:https://dfangkai.github.io/

仓库:https://github.com/dfangkai/dfangkai.github.io

本地:~/code/dfangkai.github.io