我们来学一下如何PR

以我当时第一次PR给forever218大佬的hexo magzine主题为例

虽然我用AI把他的项目改的面目全非,不过大佬每次都接纳了......感觉有时间还得再看看

不过确实学到了很多新知识,非常感谢大佬,因为借助他设计的blog我也接触到和吸引到了很多大佬

PR用到的相关命令

功能命令(新 Git 写法)命令(旧 Git 写法)说明
克隆仓库git clone <仓库地址>同上克隆远程仓库到本地
进入项目cd <项目文件夹>同上进入本地仓库
查看远程git remote -v同上查看 origin/upstream 等远程地址
添加上游git remote add upstream <地址>同上第一次配置原作者仓库,地址是HTTPS或SSH
修改远程地址git remote set-url <name> <地址>同上改 SSH/HTTPS,或更新远程地址,name一般为origin/upstream
切换到已有分支git switch devgit checkout dev切换本地已有分支
创建并切换新分支git switch -c 分支名git checkout -b 分支名基于当前分支创建新分支并切换过去
查看当前状态git status同上查看修改、暂存和分支状态
查看改动内容git diff同上查看未暂存的改动
查看暂存区改动git diff --cached同上查看已 add 但未提交的内容
暂存改动git add .同上把所有改动加入暂存区
提交改动git commit -m "说明"同上提交到本地仓库
拉取远程分支信息git fetch upstream同上获取上游分支更新,不合并
合并远程分支到本地git merge upstream/dev同上把上游 dev 合并到本地分支
推送到远程git push -u origin 分支名同上-u 建立跟踪关系,可选;首次推送新分支建议加
推送已有分支git push同上如果分支已和远程跟踪,直接推送即可
查看分支列表git branch同上查看本地所有分支,* 表示当前分支
查看分支和远程跟踪关系git branch -vv同上显示本地分支和对应远程分支、最后提交
查看远程分支git branch -r同上显示远程分支列表
查看本地 + 远程分支git branch -a同上显示所有分支
删除分支git branch -d <分支> / git push origin --delete <分支>同上清理完成的分支

这里有几个注意点

git push -u origin 分支名

-u 等同于 --set-upstream,用于建立本地分支和远程分支的跟踪关系

示例:

powershell
1
git push -u origin fix-imagezoom
  • 这里的意思是:
    • 把本地 fix-imagezoom 分支推到 origin 上
    • 同时告诉 Git:以后本地 fix-imagezoom 默认跟踪远程 origin/fix-imagezoom
  • 后续再推送或拉取时,只需要:
powershell
12
 git push
 git pull

Git 会自动知道你想推/拉 origin/fix-imagezoom。

如果不加 -u:推送也能成功,但以后每次都得写:

powershell
12
git push origin fix-imagezoom
git pull origin fix-imagezoom

需要遵循的规范---Conventional Commits(约定式提交)

可能踩到的坑---github多账号ssh混淆

由于我github有两个账号即huyangpahuo和funingna-wakawaka,之前在两个账号都创建了ssh就遇到这个问题

你可以在C:\Users\用户名\.ssh找到它们

  • 其中有一个config,用于存储配置
  • 以及私钥id_rsa和公钥id_rsa.pub,用于远程连接(当然名字不一定是这个,默认创建都是id_rsa)
  • 还有一个known_hosts,用于在客户端存储已连接过的远程服务器的公钥,从而验证服务器的身份并防止中间人攻击
  • 有的时候会出现known_hosts.old文件,一般可以删掉因为这个只是对known_hosts更新后的备份

这个是在git bash里使用如下命令生成的

bash
123
git config --global user.name "GitHub用户名"   
git config --global user.email "GitHub邮箱"
ssh-keygen -t rsa -C "GitHub邮箱"

当然你也可以验证一下

bash
12345
#查看用户名:
git config user.name

#查看邮箱:
git config user.email

其中私钥绝不能泄露,公钥则需要粘贴到github里的ssh配置区

但是当我们使用

bash
1
ssh git@github.com

得到funingna-wakawaka

bash
123
PTY allocation request failed on channel 0
Hi funingna-wakawaka! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.

同样的也是

bash
1
ssh -T git@github.com

得到funingna-wakawaka

bash
1
Hi funingna-wakawaka! You've successfully authenticated, but GitHub does not provide shell access.

甚至使用git@github.com:huyangpahuo/hexo-theme-magzine.git时也是funingna-wakawaka

我们使用这个打印出所有配置的参数

bash
1
ssh -G git@github.com

可以看到用的是22端口而非github默认的443端口

bash
12345678
host github.com
user git
hostname github.com
port 22
addressfamily any
batchmode no
canonicalizefallbacklocal yes
......

这说明一个问题,此时github是自动使用的是funingna-wakawaka,而我们如果要使用huyangpahuo的账号就不能再使用git@github.com这种写法

解决方法

不过假设你和我一样不小心配置了一堆github ssh甚至对应的账号不同例如rsa_second,rsa_third

powershell
12
ssh-keygen -t rsa_second -C "GitHub邮箱"
ssh-keygen -t rsa_third -C "GitHub邮箱"

那么就需要修改config文件(如果你只有一个那就不用改默认即可)

bash
123456789101112131415161718192021222324252627282930
# Global defaults (safe)
Host *
  ServerAliveInterval 30
  ServerAliveCountMax 120
  AddKeysToAgent no
  IdentitiesOnly yes

# Account 1: funingna-wakawaka
Host github-funingna
  HostName ssh.github.com
  Port 443
  User git
  IdentityFile ~/.ssh/id_rsa           # funingna key
  IdentitiesOnly yes

# Account 2: huyangpahuo
Host github-huyang-01
  HostName ssh.github.com
  Port 443
  User git
  IdentityFile ~/.ssh/id_rsa_second    # huyang key 
  IdentitiesOnly yes

# Account 3: huyangpahuo
Host github-huyang-02
  HostName ssh.github.com
  Port 443
  User git
  IdentityFile ~/.ssh/id_rsa_third    # huyang key 
  IdentitiesOnly yes

相关参数

参数作用当前的值
Host定义一组连接规则/别名*、github-funingna
HostName真正要连接的服务器地址ssh.github.com
PortSSH 连接端口443
User登录时使用的用户名git
IdentityFile指定使用的 SSH 私钥~/.ssh/id_rsa
IdentitiesOnly是否只使用明确指定的密钥yes
ServerAliveInterval多久发送一次 SSH 保活请求30 秒
ServerAliveCountMax保活失败多少次后断开120
AddKeysToAgent是否自动把私钥加入 SSH Agentno

这里我分别为三个ssh取别名为github-funingna ,github-huyang-01,github-huyang-02表示这是github的ssh

并分别指定对应的私钥文件

ssh验证

我们必须用git@github-huyang-01:huyangpahuo/hexo-theme-magzine.git这种指定别名的方式才能验证

我们可以用ssh验证

bash
1
ssh git@github-huyang-01

得到huyangpahuo

bash
123
PTY allocation request failed on channel 0
Hi huyangpahuo! You've successfully authenticated, but GitHub does not provide shell access.
Connection to ssh.github.com closed.

也就是我们要使用的这个

PR实例

这里我们分成好几种情况,由于这个仓库有两个分支,一个叫做master(主分支),一个叫做dev(实验分支)

主分支是正式版本,副分支为实验版本

首先先复刻仓库并clone复刻仓库的项目到本地

powershell
123456789
# 克隆你 fork 的仓库
git clone git@github-huyang-01:huyangpahuo/hexo-theme-magzine.git
cd hexo-theme-magzine

# 添加 upstream(原作者仓库)
git remote add upstream git@github-huyang-01:forever218/hexo-theme-magzine.git

# 查看远程仓库是否正确
git remote -v

一,PR到原作者仓库的Main/Master主分支(例如Master)

二,PR到原作者仓库的其他副分支(例如Dev)

① 只同步和维护自己 fork 的分支(例如dev)

情况 A:本地和远程都没有同步(第一次更新或本地删除过)
powershell
123456
# 创建并切换到本地 dev,跟踪 upstream/dev
git switch -c dev --track upstream/dev
# 老写法:git checkout -b dev --track upstream/dev

# 把本地 dev 推到你的 fork(第一次)
git push -u origin dev
情况 B:本地 dev 已经存在,远程 fork dev 已同步(继续维护)
powershell
1234567
# 切换到本地 dev
git switch dev
# 老写法:git checkout dev

# 拉取 upstream 最新 dev
git fetch upstream
git merge upstream/dev

然后修改上传到自己复刻的仓库

powershell
123456789101112131415161718
# --- 开始开发 ---
# 修改项目文件

# 改完查看状态
git status
git diff      # 可选:查看未暂存改动

# 暂存改动
git add .

# 查看已暂存内容(可选)
git diff --cached

# 提交到本地 dev
git commit -m "更新说明"

# 推送到你的 fork dev
git push

② 给作者发 PR 的流程

情况 A:本地和远程都没有同步(第一次做 PR)
powershell
123456789101112
# 创建并切换本地 dev
git switch -c dev --track upstream/dev
# 老写法:git checkout -b dev --track upstream/dev

# 更新到最新 dev
git fetch upstream
git merge upstream/dev
git push -u origin dev   # 更新 fork 的 dev(可选)

# 基于最新 dev 创建新功能分支
git switch -c 你的新分支名
# 老写法:git checkout -b 你的新分支名
情况 B:本地 dev 已存在,远程 fork dev 已同步(继续做 PR)
powershell
1234567891011
# 切换到本地 dev
git switch dev
# 老写法:git checkout dev

# 拉取 upstream 最新 dev
git fetch upstream
git merge upstream/dev

# 基于 dev 创建新功能分支
git switch -c 你的新分支名
# 老写法:git checkout -b 你的新分支名

然后修改上传

powershell
12345678910
# --- 开始开发 ---
git status
git diff

git add .
git diff --cached
git commit -m "更新说明"

# 推送功能分支到 fork
git push -u origin 你的新分支名

上传之后若作者合并了,此时可以在github里删除掉这个分支,然后更新自己复刻的仓库即可

bash
1234
# 在 GitHub 上发 PR,PR 合并后删分支,当然最好在Github里删除,不要使用命令行
git switch dev  #切到dev分支
git branch -d 你的新分支名         # 删除本地分支
git push origin --delete 你的新分支名 # 删除远程分支