git多人工作之个人规范使用【ai+个人理解】

一、为什么需要这套流程?原理是什么?

1. 传统模式的问题(你之前习惯的 commit → push

  • 如果你和同事都在同一个仓库的主分支(如 main)上直接 push,后 push 的人必须先解决冲突,很容易覆盖别人的代码。

  • 没有代码审查(Code Review),任何错误都可能直接上线。

  • 无法进行持续集成(CI)自动测试,问题难以提前发现。

2. Fork + PR 模式的优点

  • Fork(派生):将主仓库完整复制一份到你自己的账号下,相当于你的"私人工作区"。你可以在自己的 fork 里任意修改,不会影响主仓库。

  • 分支(Branch):每个新功能或修复都在独立的分支上开发,避免不同任务之间的代码混杂。

  • Pull Request(PR) :向原仓库发起合并请求。它提供了代码审查自动化测试的触发点。只有经过审查和测试的分支才能合并到主分支。

  • 保护主分支 :主分支(如 main)只接受经过 PR 合并的代码,始终保持稳定可发布状态。

3. 完整流程的逻辑链条

text

复制代码
1. 主仓库(上游) ← 2. Fork(你的副本) ← 3. Clone 到本地
4. 创建新分支 → 5. 开发 + 测试 → 6. Push 到你的远程 fork
7. 发起 PR → 8. 团队成员 Review → 9. 根据反馈修改 → 10. 合并

完整操作步骤(以 GitHub 为例)

1. Fork (派生,分支)原仓库
  • 打开上游仓库页面,点击右上角 Fork 按钮

  • 选择 fork 到你的账号下

2. 克隆你的 fork 到本地
bash 复制代码
git clone https://github.com/你的用户名/仓库名.git
cd 仓库名
复制代码

cd 仓库名 就是让你 进入这个仓库的根目录,让后续所有 Git 命令能够正确运行

添加上游仓库地址(git remote add upstream ...)的本质是:修改当前仓库的配置 (写入 .git/config 文件)。

  • 只有当你身处该仓库的根目录时,git remote 命令才知道要修改哪个仓库的配置。

  • 如果你没 cd 进去,Git 找不到仓库,自然无法添加 upstream

即:

cd 仓库名 是为了让你站在 Git 仓库的"内部",这样所有 Git 命令才能知道要操作哪个仓库,添加 upstream 地址是仓库级别的配置,必须先 cd 进去。

3. 添加上游仓库地址(用于同步)
bash 复制代码
git remote add upstream https://github.com/原仓库拥有者/仓库名.git
git remote -v   # 验证:origin 是你的 fork,upstream 是原仓库

背景知识

当你 clone 你自己的 fork 时,Git 会自动创建一个默认的远程仓库,名字叫 origin,指向 你的 fork你的用户名/仓库名.git)。

但你的本地仓库并不认识 原始项目(上游仓库)的地址,所以你需要手动告诉它。

第一个命令:

给你的本地仓库添加一个指向原始项目仓库 的远程地址,并给它起个名字叫 upstream

这条命令的组成部分

  • git remote add → 添加一个远程仓库记录

  • upstream → 你给这个远程仓库起的名字(可以任意,但社区约定俗成用 upstream

  • https://github.com/原仓库拥有者/仓库名.git → 原始项目的真实地址

执行完后,你的本地仓库就知道:

  • origin 是 我的 fork

  • upstream 是 原作者的项目

二、为什么需要添加 upstream

因为原始项目(上游仓库)会不断更新(比如别人合并了新的 PR)。

如果没有 upstream,你就无法从原始项目拉取最新代码,你的 fork 会逐渐落后,将来你提交 PR 时就会产生很多冲突。

有了 upstream,你可以随时运行:

bash

复制代码
git fetch upstream          # 拉取原始项目的最新代码
git merge upstream/main     # 将原始项目的 main 分支合并到你的本地 main

从而保持你的代码和原始项目同步。

第二个命令:git remote -v

-v--verbose 的缩写,意思是 显示所有远程仓库的详细地址

执行后会输出类似:

text

bash 复制代码
origin    https://github.com/你的用户名/仓库名.git (fetch)
origin    https://github.com/你的用户名/仓库名.git (push)
upstream  https://github.com/原仓库拥有者/仓库名.git (fetch)
upstream  https://github.com/原仓库拥有者/仓库名.git (push)

验证的目的

  • 确认 upstream 确实添加成功,并且 URL 写对了(没有拼错用户名或仓库名)。

  • 确认 origin 仍然指向你自己的 fork(确保后续 push 不会推到错误的地方)。

4. 创建新分支(基于上游最新 main)

bash

bash 复制代码
git fetch upstream                     # 获取上游最新代码
git checkout -b my-feature upstream/main   # 创建并切换到新分支

一、git fetch upstream

这条命令的作用是:从你添加的 upstream 远程仓库(即原始项目仓库)下载所有最新的内容(新提交、分支、标签等),但不会合并到你当前的任何本地分支中

执行后,Git 会在本地生成一组"远程跟踪分支",比如 upstream/mainupstream/develop 等。这些分支代表了上游仓库各个分支的最新状态。

为什么需要这一步?

因为你的本地仓库原本只知道 origin/main(你自己的 fork 的主分支)和可能旧的本地 main。如果不先 fetch,你的本地就没有 upstream/main 这个"指针",也就无法基于上游最新代码创建新分支。它并不是"存为一个文件",而是更新 Git 内部的一个指针,指向上游 main 分支最新提交的位置。

可以认为:执行后,upstream/main 就代表了上游 main 的最新状态

git fetch upstream 就是去上游仓库看了一眼,把"上游各分支现在长什么样"的信息记在本地的笔记本里(即 upstream/main 等指针),但你的工作区(你正在编辑的代码文件)不会有任何变化

这个"笔记本"就是 .git/refs/remotes/upstream/ 下的文件

二、git checkout -b my-feature upstream/main

这条命令做了两件事:

  • checkout -b my-feature:创建一个新分支 ,名字叫 my-feature,并立即切换到这个分支。

  • upstream/main:指定了新分支的起点 (基准),也就是基于上游仓库的 main 分支当前的最新状态来创建。

等价于:

bash

bash 复制代码
git branch my-feature upstream/main   # 创建分支,但不切换
git checkout my-feature               # 切换到该分支

为什么不能用 git checkout -b my-feature main

  • 如果你用 main(本地 main)作为起点,而你的本地 main 可能已经落后于上游(因为别人合并了 PR 你没有同步),那么你创建的新分支就会基于一个过时的版本,后续提交 PR 时会产生额外的合并冲突。

  • upstream/main 可以确保你的新分支直接基于上游仓库的最新代码,这样将来提交 PR 时,差异最干净,冲突最少。

三、整个流程的逻辑链条

text

bash 复制代码
1. git fetch upstream
   → 将上游的最新状态同步到本地(存为 upstream/main)

2. git checkout -b my-feature upstream/main
   → 基于刚刚获取的上游 main 分支,创建一个新的本地分支

这样,你的 my-feature 分支就等同于从上游的 main 分出来的 ,就像是你在上游仓库直接创建了一个分支一样。之后再开发、提交、push 到 origin(你自己的 fork),然后发起 PR,PR 的目标分支就是上游的 main,GitHub 会自动发现你的分支是基于上游最新代码的,不会有额外的合并提交

总结

fetch 刷新笔记本里的 upstream/main 指针,checkout -b 则读取这个指针作为新分支的起点

,即上游仓库 main 分支的最新代码

5. 开发 + 本地测试
  • 使用编辑器修改代码

  • 运行项目要求的测试 (如 npm testpytest 等),确保全部通过

6. 提交并推送到你的 fork

bash

bash 复制代码
git add .
git commit -m "feat: 添加某个功能"
git push origin my-feature    # 推送到你的 fork 仓库的对应分支

git push origin my-feature:
推送到你自己的远程 fork 仓库
(即 origin 指向的那个 GitHub 仓库)。这个仓库是你的副本,你有完全的写权限

  1. git push origin my-feature :将本地 my-feature 分支上的提交推送到你自己的远程 fork 仓库 (即 origin 指向的那个 GitHub 仓库)。这个仓库是你的副本,你有完全的写权限。

    • 问题问"提交到自己的远程私有仓库?"

      • 如果原仓库是公开的,你的 fork 默认也是公开的(不是私有),但只有你有写权限。

      • 如果你手动把 fork 设为私有,那才是私有仓库。

      • 通常我们称它为"你自己的远程仓库"(或者"你的 fork"),不一定私有,但归你控制。

  2. 推送之后 ,你的 my-feature 分支就会出现在 GitHub 上你自己的 fork 仓库里,然后你就可以去发起 Pull Request(从 origin/my-featureupstream/main)。

现在只剩下最后一步"发起 PR"和"审查合并"。如果你现在就想尝试,可以实际 push 一次,然后在 GitHub 上点 "Compare & pull request" 按钮

7. 创建 Pull Request
  • 打开你的 fork 仓库页面(GitHub)

  • 你会看到一个提示:"my-feature had recent pushes",旁边有 Compare & pull request 按钮

  • 点击 Compare & pull request 按钮

  • 填写 PR 标题和描述(说明改动内容、测试情况)

  • 点击 Create pull request

8. 代码审查与修改
  • 维护者或团队成员在 PR 下评论,提出修改意见

  • 你回到本地,切换到该分支:

bash

bash 复制代码
git checkout my-feature
# 根据意见修改代码,再次本地测试
git add .
git commit -m "fix: 根据 review 意见修改"
git push origin my-feature   # PR 会自动更新
  • 重复直到审查通过
9. 合并
  • 当所有人都 审查通过approve(批准)且所有自动化测试(CI)绿色通过后,维护者会点击 Merge pull request 按钮,将你的分支合并进主分支。

  • 你的代码正式合并到上游主分支

  • 合并后,你可以删除自己的远程分支(可选),并同步更新本地仓库。

10. 同步你的 fork(可选但推荐)

bash

bash 复制代码
git checkout main
git pull upstream main          # 拉取上游最新 main
git push origin main            # 同步到你的 fork
git branch -d my-feature        # 删除本地分支
git push origin --delete my-feature   # 删除远程分支

关键要点提醒

  • 不要直接在上游仓库 push → 使用 fork + PR

  • 每个功能一个独立分支 → 保持隔离,方便回滚

  • 提交前必须本地测试 → 避免浪费 CI 资源

  • PR 内可以多次 push → 自动更新,无需重新建 PR

  • 定期同步 upstream → 减少合并冲突


二·、一些小提示

  • 为什么要先 fork 而不是直接 clone 原仓库?

    因为你没有原仓库的写入权限,fork 让你有自己可写的一份拷贝,然后通过 PR 提出贡献。

  • 为什么要在新分支开发?

    如果直接用 main 分支,当你提交 PR 后又想开发另一个功能,两个功能会混在一起。分支保持了功能隔离。

  • 测试一定要在本地跑:这是你描述中强调的"自己跑一下测试",避免 CI 流水线浪费资源。

  • Review 后再更改:PR 评论系统会自动组织多次修改的会话,最终合并前会确保所有讨论都 resolved。


三、你可以尝试的练习

  1. 找一个你喜欢的开源项目(或创建一个测试仓库),按照上面的步骤模拟一次 PR 流程。

  2. 你甚至可以和自己协作:用两个 GitHub 账号,或者让一个朋友扮演 reviewer。

  3. 使用 git log --oneline --graph 查看分支演变,加深理解。

最后

Fork 和 clone 整个仓库只做一次。之后每天加新模块,只需要"同步上游 → 切新分支 → 开发 → push → 开 PR → 等合并"。

其中 第 1-3 步 (主仓库 → Fork → Clone 到本地 + 添加 upstream)只需要在刚开始接触项目时做一次

之后的每一次新增小模块、修 bug 或加功能,只需要重复 第 4-10 步中的一部分


一、一次性初始化(只做一次)

当你第一次给某个项目贡献代码时,需要做这些准备:

  1. Fork 主仓库(在 GitHub 网页上点一下按钮)

  2. Clone 你的 fork 到本地

  3. 添加 upstream 远程地址(git remote add upstream ...

做完这三步,你的本地环境和远程 fork 就都准备好了。以后不用再做。


二、每天新增模块时的日常流程(可以简化成 6 步)

假设你已经完成了上面的初始化。现在你每天要开发一个新模块(新功能或修复),需要重复的步骤是:

  1. 同步上游最新代码(避免冲突)

    bash

    复制代码
    git fetch upstream
    git checkout main
    git merge upstream/main
    git push origin main
  2. 基于最新的 main 创建新分支

    bash

    复制代码
    git checkout -b feat/新模块名 main
  3. 在分支上开发 + 本地测试

  4. 提交并 push 到自己的远程 fork

    bash

    复制代码
    git add .
    git commit -m "feat: 添加新模块"
    git push origin feat/新模块名
  5. 发起 PR(在 GitHub 网页上点按钮)

  6. 根据 review 反馈修改 (只需继续 push 到同一个分支,PR 自动更新)

    → 等待维护者合并

不需要重新 fork,不需要重新 clone,不需要重新添加 upstream。


三、对比表格(更清晰)

步骤 描述 初次接触项目时 每天新增模块时
1 主仓库 ← Fork ✅ 需要(一次) ❌ 不需要
2 Clone 到本地 ✅ 需要(一次) ❌ 不需要
3 添加 upstream ✅ 需要(一次) ❌ 不需要
4 创建新分支 ✅ 每次都需要 ✅ 每次都需要
5 开发 + 测试 ✅ 每次都需要 ✅ 每次都需要
6 Push 到你的远程 fork ✅ 每次都需要 ✅ 每次都需要
7 发起 PR ✅ 每次都需要 ✅ 每次都需要
8 Review ✅ 每次都需要 ✅ 每次都需要
9 根据反馈修改 ✅ 每次都需要 ✅ 每次都需要
10 合并 ✅ 每次都需要 ✅ 每次都需要

第二次、第三次......开发新模块时,你只需要做:

text

复制代码
4. git fetch upstream
   git checkout -b new-feature upstream/main
5. 开发 + 测试
6. git add . && git commit -m "..." && git push origin new-feature
7. 创建 PR
8. 根据 review 修改
9. 等待合并
10. (合并后) git checkout main && git pull upstream main && git push origin main
相关推荐
CVer儿9 小时前
git简单操作
git
Andya_net10 小时前
Git | Git 核心命令深入解析:从原理到实战
大数据·git·elasticsearch
wh_xia_jun11 小时前
给小白的 Maven 命令行执行测试 完整指南
git·maven·intellij-idea
专业白嫖怪11 小时前
H3C UniServer R4950 G5 服务器压测实战:13根内存条24小时压力测试全流程
git
我先去打把游戏先11 小时前
Ubuntu虚拟机(服务器版本)Git安装教程(附常用命令)——从零开始掌握版本控制
服务器·c语言·c++·git·嵌入式硬件·物联网·ubuntu
咸鱼永不翻身11 小时前
Git Hooks 功能与作用详解
git·git-hooks·git钩子
闪电悠米11 小时前
黑马点评短信登录01_session_sms_login
java·spring boot·redis·git·spring·面试
少司府11 小时前
Tools相关:深入浅出学Git
大数据·c++·git·gitee·github·仓库·分支
cen__y1 天前
Linux12(Git01)
linux·运维·服务器·c语言·开发语言·git