目录
[一、Git 的三大区域(概念层)](#一、Git 的三大区域(概念层))
[二、核心 Git 命令如何让文件在这"四区"之间流转](#二、核心 Git 命令如何让文件在这“四区”之间流转)
[1. 从工作区 → 暂存区(开始追踪改动)](#1. 从工作区 → 暂存区(开始追踪改动))
[2. 从暂存区 → 本地仓库(形成版本记录)](#2. 从暂存区 → 本地仓库(形成版本记录))
[3. 从本地仓库 → 远程仓库(分享给队友)](#3. 从本地仓库 → 远程仓库(分享给队友))
[4. 从远程仓库 → 本地仓库(获取别人更新)](#4. 从远程仓库 → 本地仓库(获取别人更新))
[5. 撤销/回退操作(重要)](#5. 撤销/回退操作(重要))
[1. 为什么会发生?](#1. 为什么会发生?)
[2. 解决流程(三步走)](#2. 解决流程(三步走))
[3. 更安全的替代(推荐新手用 rebase)](#3. 更安全的替代(推荐新手用 rebase))
[4. 如果你已经 push 了但被拒(经典报错)](#4. 如果你已经 push 了但被拒(经典报错))
[1. 查看工作区和暂存区的文件状态(最常用)](#1. 查看工作区和暂存区的文件状态(最常用))
[2. 查看所有被 Git 追踪的文件(不显示未追踪的)](#2. 查看所有被 Git 追踪的文件(不显示未追踪的))
[3. 查看当前目录下的所有文件(Linux/Mac/Git Bash 通用)](#3. 查看当前目录下的所有文件(Linux/Mac/Git Bash 通用))
[4. 查看历史版本中的文件(某个 commit 里有什么)](#4. 查看历史版本中的文件(某个 commit 里有什么))
[5. 快速对比:工作区和最近一次 commit 的差异](#5. 快速对比:工作区和最近一次 commit 的差异)
一、Git 的三大区域(概念层)
这是所有 Git 操作的基础。你可以把文件的状态变化想象成"搬家":
| 区域 | 说明 | 对应 Git 概念 |
|---|---|---|
| 工作区 (Working Directory) | 你电脑上能直接看到的项目文件夹,就是你正在编辑文件的地方。 | 未跟踪 (Untracked) / 已修改 (Modified) |
| 暂存区 (Staging Area / Index) | 一个临时的"待提交清单"。你决定哪些修改要保存到仓库,就先 add 到这里。 | 已暂存 (Staged) |
| 本地仓库 (Local Repository) | 在你电脑上的 .git 隐藏目录。这里的提交是安全的、版本受控的。 |
已提交 (Committed) |
| 远程仓库 (Remote Repository) | 放在 GitHub、GitLab 等服务器上的公共/协作仓库。 | 已推送 (Pushed) |
二、核心 Git 命令如何让文件在这"四区"之间流转
下面这张图是灵魂,建议收藏:
text
工作区 ──git add──> 暂存区 ──git commit──> 本地仓库 ──git push──> 远程仓库
│ │ │
└──────git restore────┘ │
└────────────git reset HEAD─────────────────── ┘
└────────────────git fetch/git pull─────────────────────┘
1. 从工作区 → 暂存区(开始追踪改动)
-
命令 :
git add <文件名>或git add .(添加所有改动) -
作用:把修改过的文件"打标签",告诉 Git 我准备提交这些。
2. 从暂存区 → 本地仓库(形成版本记录)
-
命令 :
git commit -m "提交说明" -
作用:把暂存区的所有内容打包成一个快照,永久存入本地仓库,并生成一个 commit ID。
3. 从本地仓库 → 远程仓库(分享给队友)
-
命令 :
git push origin <分支名>(如git push origin main) -
作用:把本地仓库的提交上传到 GitHub 服务器。
4. 从远程仓库 → 本地仓库(获取别人更新)
-
命令:
-
git fetch(仅下载,不合并) -
git pull(下载并自动合并到当前分支,相当于 fetch + merge)
-
5. 撤销/回退操作(重要)
-
丢弃工作区改动 :
git restore <文件名>(回到最近一次 commit 或 add 的状态) -
从暂存区撤出 :
git restore --staged <文件名>(文件改动还在,但不再暂存) -
回退本地提交 :
git reset --soft HEAD~1(撤回 commit,改动回到暂存区) 或git reset --hard HEAD~1(彻底丢弃改动,慎用)
三、状态表
| 文件状态 | 所在区域 | 你能做什么 |
|---|---|---|
| Untracked / Modified | 工作区 | git add → 暂存区 |
| Staged | 暂存区 | git commit → 本地仓库;或 git restore --staged 撤回 |
| Committed | 本地仓库 | git push → 远程仓库;或 git reset 回退 |
| Pushed | 远程仓库 | 队友可通过 git clone / git pull 获取 |
当你准备 push 之前,建议按这个顺序检查:
远程仓库比本地仓库新(如何解决冲突)
这是 Git 协作中最常见的场景。你 teammate 先 push 了代码,而你不知道,现在你想 push,Git 会报错拒绝。
1. 为什么会发生?
-
远程仓库的 commit 历史 比你的本地仓库 多出了几个新节点。
-
Git 不允许你直接 push,因为那样会覆盖掉队友的提交。
2. 解决流程(三步走)
第一步:把远程的新内容拉下来
git pull origin main
(main 是你的分支名,如果是 master 就写 master)
第二步:处理合并(两种情况)
情况A:没有冲突(幸运)
-
Git 自动把远程的新内容和你的本地修改合并好了。
-
你只需要 重新 commit 并 push 即可:
git push origin main
情况B:有冲突(常见)
-
Git 会提示:
CONFLICT (content): Merge conflict in xxx.txt -
你需要手动解决冲突:
-
打开冲突文件,你会看到类似这样的标记:
text
<<<<<<< HEAD 这是你本地写的代码 ======= 这是远程仓库队友写的代码 >>>>>>> origin/main -
手动编辑 :删除
<<<<<<<、=======、>>>>>>>这些标记,保留你最终想要的代码(可以全留,可以只留一边,也可以组合)。 -
保存文件。
-
告诉 Git 冲突已解决:
bashgit add 冲突文件名 git commit -m "解决了与远程仓库的冲突" git push origin main
3. 更安全的替代(推荐新手用 rebase)
如果你不想在历史中留下一个"合并提交"(Merge Commit),可以用 rebase:
bash
# 1. 拉取远程最新代码,并把自己的提交"挪"到最新提交之后
git pull --rebase origin main
# 2. 如果有冲突,解决方式同上(手动改文件 + git add)
# 3. 继续 rebase 流程
git rebase --continue
# 4. 最后 push(因为历史被重写了,必须加 --force-with-lease)
git push --force-with-lease origin main
⚠️ 注意 :--force-with-lease 比 --force 更安全,它会检查远程是否有人又 push 了新东西,如果有就停止,防止覆盖别人的工作。
4. 如果你已经 push 了但被拒(经典报错)
bash
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'github.com:...'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
解决方案 :重复上面的 git pull → 解决冲突 → git push 流程即可。
第二部分:如何查看本地仓库有什么文件
分两个维度:查看当前工作区的文件列表 和 查看历史版本中的文件。
1. 查看工作区和暂存区的文件状态(最常用)
git status
输出示例:
bash
On branch main
Your branch is behind 'origin/main' by 2 commits.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: README.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
modified: src/app.py
Untracked files:
(use "git add <file>..." to include in what will be committed)
new_file.txt
-
红色 = 工作区有修改,还没 add
-
绿色 = 已 add,等待 commit
-
Untracked = 全新文件,Git 还没开始追踪
什么是"未追踪文件"(Untracked)?
想象 Git 是一个保安,他只负责看管"登记在册"的文件。
-
已追踪(Tracked) :你的文件在保安的花名册上(已经被
git add过或commit过)。保安会盯着这些文件的每一次改动。 -
未追踪(Untracked) :你的文件不在 保安的花名册上。保安看到这个文件,只会提醒你"嘿,这有个新文件,你要不要让我管?",但他不会管它,也不会自动把它加入版本控制。
2. 查看所有被 Git 追踪的文件(不显示未追踪的)
bash
git ls-files
输出所有已经纳入版本控制的文件列表(带完整路径)。
3. 查看当前目录下的所有文件(Linux/Mac/Git Bash 通用)
bash
ls -la
-
-l:显示详细信息 -
-a:显示隐藏文件(包括.git文件夹)
4. 查看历史版本中的文件(某个 commit 里有什么)
查看最近一次提交包含哪些文件:
bash
git show --name-only
查看某次具体 commit 的文件列表:
bash
# 先找到 commit ID
git log --oneline
# 输出类似:
# a1b2c3d (HEAD -> main) 修复了登录bug
# d4e5f6g 增加了用户管理模块
# 然后查看该 commit 的文件
git show --name-only a1b2c3d
5. 快速对比:工作区和最近一次 commit 的差异
git diff --name-only
只显示哪些文件被修改了,不显示具体改了什么内容。
其他:怎么不克隆整个仓库,只克隆仓库下的某个文件或者目录
git clone 和 git pull 都和"获取远程代码"有关,但作用完全不一样,本质区别是:一个是第一次拿代码,一个是在已有代码基础上更新。
git merge vs git rebase 对比表
| 对比项 | merge | rebase |
|---|---|---|
| 是否改写历史 | 不改历史 | 会改写提交历史 |
| commit 数量 | 产生一个 merge commit | 不额外增加 merge commit |
| 历史结构 | 保留分叉结构(非线性) | 变成线性历史 |
| 可读性 | 分支结构清晰,但复杂 | 历史更干净、线性 |
| 安全性 | 高(安全,不影响已有 commit) | 中(可能改变 commit hash) |
| 冲突处理 | 一次性处理 merge 冲突 | 每个 commit 可能都要处理冲突 |
| 推荐场景 | 团队协作、共享分支 | 本地分支整理、提交前优化历史 |
命令式创建远程仓库
gh repo create Multi_Threads_Process --public --source=. --remote=origin --push
--source=.
指定本地项目目录作为源码来源:
. 表示当前目录
也就是说:把你现在这个文件夹里的所有代码作为仓库内容
使用"当前目录(.)"作为仓库内容来源
如果这个目录还不是 Git 仓库:
会自动执行 git init
自动 git add .
自动 git commit
--remote=origin
给本地 git 仓库添加远程地址,并命名为:origin
--push
创建完成后,自动帮你 push 到 GitHub