GitHub 协作开发:Fork、Clone、PR 与 Upstream 同步详解

GitHub 协作开发:Fork、Clone、PR 与 Upstream 同步详解

·16 分钟阅读

很多朋友刚刚接触Github的时候,一些基本概念都比较难以理解,我刚刚开始也是一样的,但是掌握Github的使用又是一个很有用的能力。还是整理一份完整一点的内容来说明一下吧。 本文旨在帮助你理解 Fork 与 Clone 的本质区别、PR 的标准流程、如何在不覆盖本地代码的情况下安全同步源项目(upstream)的更新。

🧱 一、Fork 与 Clone 的区别

Column 1Column 2Column 3
操作说明场景
Fork在 GitHub 上复制他人的项目到你自己的账户下想参与开发或修改并保留关联关系
Clone把 GitHub 上的代码复制到你本地电脑想运行、测试或修改代码

✅ Fork 特点:

  • 在 GitHub 上操作
  • 会在你自己的 GitHub 账户下创建一份“副本”
  • 可与原项目保持更新(通过 upstream)
  • 可提交 Pull Request 给原项目

✅ Clone 特点:

  • 在本地操作
  • 可用于你自己的项目,也可以 clone 别人的项目
  • 不会建立 GitHub 上的“关系”
  • 没法直接提交 PR(除非配合 fork)

✍️ 二、开发流程(基于 Fork)

✅ 第一步:Fork 源项目(在 GitHub 上)

打开想参与的项目 → 点击右上角 Fork → fork 到你的账户下

生成的仓库地址如:

https://github.com/你的用户名/项目名.git

✅ 第二步:Clone 到本地

git clone https://github.com/你的用户名/项目名.git
cd 项目名
code .
 

建议立刻创建一个开发分支(避免污染主分支):

git checkout -b feature/my-change
 

✅ 第三步:修改、提交并推送

# 添加并提交
git add .
git commit -m "修复了 xxx 问题"
 
# 推送到你自己的 GitHub fork 仓库
git push origin feature/my-change
 

✅ 第四步:发起 Pull Request(PR)

  1. 打开你 GitHub 上 fork 的仓库页面
  2. 系统会提示你创建 PR(或点击 “Compare & Pull Request”)
  3. 填写标题与说明 → 选择要合并到原项目的哪个分支(通常是 main
  4. 点击 Create Pull Request PR 提交后,原项目维护者可以进行 review 和合并。

🔄 三、如何同步原项目更新(不覆盖你自己的改动)

你 fork 的项目不会自动同步原仓库的更新,需要手动执行以下操作。

✅ 第一步:添加 upstream 远程地址

git remote add upstream https://github.com/原作者用户名/项目名.git
 

验证是否添加成功:

git remote -v
 

应看到:

origin    https://github.com/你的用户名/项目名.git
upstream  https://github.com/原作者用户名/项目名.git

✅ 第二步:拉取源项目更新

git fetch upstream
 

✅ 第三步:合并 upstream 分支到本地

git checkout main
git merge upstream/main
 

此操作会尝试自动合并两边的内容。

⚠️ 出现冲突时怎么办?

你会看到类似:

CONFLICT (content): Merge conflict in xxx.js
 

VSCode 会高亮冲突区域:

<<<<<<< HEAD
你本地的代码
=======
upstream 的代码
>>>>>>> upstream/main

你需要手动编辑冲突内容,然后:

git add .
git commit
 

✅ 第四步:推送到你自己的 GitHub

git push origin main
 

🛡 安全建议与技巧

Column 1Column 2
需求推荐做法
不确定是否会覆盖先新建一个分支:git checkout -b sync-upstream 再 merge
修改未提交但想同步使用 git stash 临时保存,合并后 git stash pop
想要更干净的历史使用 git rebase upstream/main(高级用法)

📌 总结命令速查表

🧱 初始化阶段(只做一次)

# clone 自己的 fork
git clone https://github.com/你的用户名/项目名.git
cd 项目名
 
# 添加原项目作为 upstream
git remote add upstream https://github.com/原作者用户名/项目名.git
 

🛠 日常开发

# 创建功能分支
git checkout -b feature/xxx
 
# 修改并提交
git add .
git commit -m "说明"
git push origin feature/xxx
 

🚀 发起 PR

去 GitHub 网页点 Create Pull Request

🔄 同步更新(每次想获取 upstream 最新代码时)

git fetch upstream
git checkout main
git merge upstream/main
git push origin main
 

🧰 可选自动化脚本(bash 版)

#!/bin/bash
echo "正在同步 upstream..."
git checkout main
git fetch upstream
git merge upstream/main
git push origin main
echo "✅ 同步完成。"
 

保存为 sync-upstream.sh,运行:

bash sync-upstream.sh
 

✅ 推荐:配合 VSCode 插件使用

  • GitHub Pull Requests and Issues:可在 VSCode 里发起/管理 PR
  • Git Graph:可视化查看分支和历史
  • GitLens:高亮每一行代码的提交者、改动历史

如果只是clone不是fork的项目,更新源项目的方法是不是一样的?

结论先讲:

是的,更新方式基本一样,只要你设置了 upstream,就能同步源项目的更新。

🧭 具体说明:

🚩情况A:你是 clone 别人的项目(没有 fork)

比如你执行了:

git clone https://github.com/原作者/项目.git
 

此时你本地的 origin 就是原作者的仓库,而不是你自己的。

那你要做两件事:

✅ 方法一:你只是想保持更新,不用提交或贡献代码

这时候 你可以直接拉取源项目的更新

# 假设你在 main 分支
git pull origin main
 

因为 origin 就是源项目,它当然能更新。

✅ 简单明了,不需要设置 upstream

✅ 方法二:你想自己修改代码、但又不想影响原作者

这时候就建议:

  1. 先 clone(别人项目)
  2. 然后把这个项目变成你自己的(在 GitHub 上新建仓库)
  3. 修改远程地址(重设 origin)
# 原来 clone 的是别人的
git remote remove origin
git remote add origin https://github.com/你的用户名/新仓库.git
git push -u origin main
 

然后,如果你还想保留“跟源项目保持更新的能力”,你可以:

git remote add upstream https://github.com/原作者/项目.git
git fetch upstream
git merge upstream/main
 

所以就变成:

Column 1Column 2
远程名指向
origin你自己的仓库
upstream原始项目(别人)

📌 总结一下:

Column 1Column 2Column 3Column 4
操作方式能否更新源项目?是否需要 fork?推荐用法
clone 原项目(不 fork)✅ 可以,直接 pull origin❌ 否学习、自己用
fork + clone✅ 可以(通过设置 upstream✅ 是想贡献代码、提 PR
clone + 改 remote + 加 upstream✅ 可以❌ 否想独立开发又保持更新

🧠 什么时候推荐 fork 而不是直接 clone?

Column 1Column 2
如果你想...建议
改完代码提给别人合并✅ Fork 然后 PR(标准开源流程)
只是自己学习或临时用✅ 直接 Clone 就够了
发展成自己的版本项目✅ Clone + 改 remote + 加 upstream 更灵活

喜欢这篇文章?

Avatar 01Avatar 02Avatar 03Avatar 04Avatar 05
永不错过更新!

获取快董认知圈前沿技术资讯和实用教程

*Sponsor
Build The Site You Want!

Your website should be an asset, not an engineering challenge.