介绍:从原理入手,快速上手Git。
工作流程
Git是一个版本控制工具,用于文件备份、恢复。它可以在本地备份也可以在远程备份,也就是说Git支持一个项目文件有多个不同版本的备份,不同的版本之间互不影响地进行修改,然后多个版本之间可以自由地进行合并,所以对开发人员来说,GIT是一款分布式的、可以用于多人并行开发、跟踪开发过程的必备工具。
Git 的设计哲学:获取 -> 修改 -> 存档 ->分享。
Git通过这些概念来实现版本管理:
-
工作区(Working Directory):你写代码的地方。
-
暂存区(Staging Area):你整理代码的地方(防止把垃圾代码也提交了)。
-
版本库(Repository):代码保险柜。

整个"获取、修改、存档、分享" 工作流程如下:
(1)第一阶段:获取代码(从云端到本地)
在你开始工作之前,你需要一份代码副本。
git clone:如果你是第一次加入项目,你会把整个远程仓库(包含所有历史记录)完整地下载到你的电脑。
git pull:如果你已经有项目了,你会拉取远程仓库的最新改动,合并到你的"未修改"状态中,确保你的开发基础是最新的。
(2)第二阶段:工作区开发(代码的诞生与变化)
这是你最常待的地方,即你的编辑器(VS Code, IntelliJ 等)。
未修改 (Unmodified):代码刚从仓库取出,干净整洁。
修改 (Modified):你动了代码。此时 Git 会检测到文件变化,但这些变化仅存在于你的磁盘上,非常脆弱(一旦断电或误删就找不回来了)。
(3)第三阶段:暂存与提交(本地存档)
这是 Git 的精髓,通过两步走确保提交质量。
已暂存 (Staged):**通过 git add,你把改动放进"暂存区"。**这就像是在照相前安排站位,你可以选择只提交一部分修改,而不是全部。
已提交 (Committed):通过 git commit,改动被正式打上快照,存入你本地的"版本库"。
此时代码依然只在你的电脑里,你的同事看不见它们。
(4)第四阶段:远程同步(团队共享)
已推送 (Pushed):执行 git push。这时,你本地的一系列 Commit 记录会被上传到远程仓库(GitHub/GitLab)。
只有到了这一步,你的工作才算真正"同步"给了团队,代码也才有了云端备份。
(5)闭环路径:撤销与回滚
git checkout / restore:如果你在修改过程中发现写乱了,或者想看看之前的某个版本,你可以通过这个命令从"版本库"中拉取旧代码,覆盖掉当前的"工作区"。这给了你"吃后悔药"的机会。
可以把 git checkout 想象成代码仓库里的"传送门"或"时光机",让你在不同的代码状态(分支、提交、文件版本)之间来回穿梭。
什么是分支呢?
分支
分支(Branch)是指,把某个版本作为参考点 创建的开发版本路径。
-
本地分支:你正在写的代码。
-
远程分支:团队共享的代码(在云端)。
-
远程跟踪分支 :你本地电脑里存的一份"云端代码快照",它告诉你:"上次我联网查看时,云端代码是长这样的"。

A. 本地分支 (Local Branch)
定义:完全存在于你本地电脑上的分支。
位置:.git/refs/heads/ 目录下。
特点:你在上面写代码、提交 (commit)。它是你的私人工作空间,除非你执行 push,否则别人看不见。
示例:main, dev, feature-login。
B. 远程分支 (Remote Branch)
定义:存在于远程服务器(如 GitHub、GitLab)上的分支。
位置:服务器的磁盘上。
特点:它是团队协作的"最终真相"。你不能直接在上面修改代码,必须通过推送 (push) 或合并请求 (PR/MR) 来更新它。
示例:远程仓库里的 main 分支。
C. 远程跟踪分支 (Remote-tracking Branch)
定义:它是远程分支在你本地仓库中的"只读镜像"。
位置:.git/refs/remotes/ 目录下。
命名习惯:通常是 <remote>/<branch>,如 origin/main。
特点:
它位于你的本地,但你不能直接移动它(不能在上面 commit)。
当你执行 git fetch 或 git pull 时,Git 会自动更新这个分支,以反映远程仓库的最新的状态。
它是连接本地和远程的"中转站"。
分支相关的操作:
(1)使用git branch创建新分支:
bash
git branch new_branch
(2)使用git checkout可以切换分支:
bash
git checkout new_branch
(3)融合某个分支到当前活动分支:
bash
git checkout master
git merge new_branch //将new_branch合并到当前活动的master分支
回头总结一下,git checkout 的功能主要可以分为以下三大类:
A. 分支切换 (Switching Branches)
这是最常用的场景。当你工作在 feature 分支,想去 main 分支看看时:
bash
git checkout main
作用: 更新你的工作目录,使其与目标分支的快照保持一致,并将 HEAD 指针指向该分支。
B. 创建并切换新分支
如果你想开启一个新任务,通常需要先建分支再切过去。这个组合动作可以一步到位:
bash
git checkout -b new-feature
等同于: 先运行 git branch new-feature 再运行 git checkout new-feature。
C. 撤销/恢复文件 (Restoring Files)
如果你不小心改乱了一个文件,想把它还原到最近一次提交时的样子:
git checkout -- index.html
注意: 这里的 -- 是为了防止文件名和分支名重名。这个操作会抹掉你在该文件上未提交的所有修改,且不可撤销,使用时请务必小心。
解决冲突
如果将代码git push推送到远程仓库,发现远程仓库和原来的快照不同时,就会发生冲突。需要我们手动解决该代码冲突。
·在 Git 的世界里,解决冲突本质上是将两个平行发展的版本(你的小圆和同事的小圆)强行合并为一个共识(最终的大圆)的过程: 
(1)冲突的触发:推送失败
当你完成本地开发(本地小圆)并尝试 git push 时,如果远程服务器发现已经有人在你之前提交了代码(远程小圆),Git 会立即拦截你的请求。
报错信息:通常会提示 [rejected] (non-fast-forward)。
现状:你的本地分支、远程跟踪分支和远程分支此时指向了不同的提交点,历史出现了分叉。
(2) 同步情报:执行 git pull
为了解决分叉,你必须先把"对手"的情报拿下来。
动作:执行 git pull(或者先 fetch 再 merge)。
底层变化:Git 会更新你的远程跟踪分支(如 origin/main),让它指向远程那个小圆,并尝试将其合并到你的本地分支中。
(3) 陷入僵局:冲突检测
如果 Git 发现你们两人改动了同一个文件的同一行,它会停止自动合并。
状态:此时你的本地分支处于"Merging"中间态。
文件表现:冲突的文件会被 Git 强行注入"冲突标记":
<<<<<<< HEAD
你的代码(本地小圆的内容)
=======
同事的代码(远程小圆的内容)
>>>>>>> origin/main
(4)人工手动解决
**这是唯一需要你大脑介入的时刻。**你需要打开编辑器,决定这些冲突行的去留:
选择 A:保留你的修改,删除同事的。
选择 B:舍弃你的修改,采用同事的。
选择 C:将两者的逻辑结合,写出一段全新的代码。
清理:删除所有的 <<<<<<<, =======, >>>>>>> 标记。
(5)达成共识,生成"大圆"
解决完代码矛盾后,你需要告诉 Git 这一阶段的战斗结束了。
暂存:执行 git add <文件名>,这代表你已经完成了该文件的"调解"。
提交:执行 git commit。
结果:Git 此时会生成一个合并提交(Merge Commit)。这就是你要求的那个大圆。
大圆的特殊性:普通小圆只有一个"父亲",而大圆有两个"父亲"(它同时指向了之前的本地小圆和远程小圆),象征着两者的融合。
(6)重新推送
现在你的本地分支已经站在了"大圆"的高度,而大圆的历史里已经包含了远程那个小圆。
动作:执行 git push。
结局:远程服务器检查发现你的提交历史已经完整包含了它的历史,于是愉快地接受。此时,远程分支也更新到了那个大圆的位置。
**解决冲突不是"覆盖",而是"整合"。**小圆代表独立性。大圆代表一致性。
整个解决的过程就是:发现分叉 -> 拉取对手 -> 手动调解 -> 铸造共识大圆 -> 同步云端。
多分支
在 Git 的世界里,分支就像是"平行宇宙"。你可以让多个宇宙永远并行运行,也可以在某个时点选择让它们交汇(合并)。
**Git 允许甚至鼓励多个分支长期共存。**以下是几种常见的不合并场景:
**实验性分支 (Experimental Branches):**你有个疯狂的想法,开个分支去试。试完发现行不通,或者代码写得太烂了。你完全可以把这个分支搁置在那里,或者直接删除,永远不合并进主线。
**环境分支 (Environment Branches):**在很多公司里,develop(开发)、test(测试)和 production(生产)是三个独立的分支。它们长期共存,分别对应不同的服务器环境。
版本维护分支 (Maintenance Branches): 如果你在开发软件的 2.0 版本,但还需要为 1.0 版本的用户提供安全补丁。你会保留一个 v1.x 的分支,只在上面修 Bug,而不会把它合并到 2.0 的主线里。
虽然不强制合并,但分支的存在通常遵循以下逻辑:
| 分支类型 | 命运 | 描述 |
|---|---|---|
| 功能分支 (Feature) | 最终合并 | 开发完一个新功能(如:登录页面),测试没问题后必须合并,否则用户用不到。 |
| 发布分支 (Release) | 最终合并 | 准备发布前的最后修整,完成后通常会合并回 main 和 develop。 |
| 环境分支 (Long-lived) | 永久共存 | 只要项目还在运行,main 和 test 分支就会一直存在。 |
| 废弃/归档分支 | 永不合并 | 开发失败或已过时的尝试。 |
当我们push推送时,其实只是推送了当前所在的工作分支。而pull会把远程仓库里所有分支的新动态都下载。需要认识到两者的区别:
(1)推送 (Push):默认只送"当前"
当你执行 git push 而不带任何参数时:
行为:Git 只会将你当前所在的分支推送到它关联的远程分支。
例外:除非你显式运行 git push --all,否则你本地的其他分支(比如你偷偷开的 experiment 分支)是不会被送到服务器上的。
注意:如果当前分支没有设置"上游(upstream)",Git 会报错并提醒你使用 git push --set-upstream origin <branch>。
(2)拉取 (Pull):看似只拉当前,实则"暗度陈仓"
git pull 实际上是两个命令的组合:git fetch + git merge。
第一步 fetch(全量更新):当你输入 pull 时,Git 其实会把远程仓库里所有分支的新动态都下载到本地的"远程跟踪分支"里(比如更新所有的 origin/*)。
第二步 merge(定向合并):Git 只会将你当前分支对应的那个远程分支合并进来。
结论:你的其他本地分支虽然知道了远程有更新(通过 fetch 拿到了数据),但它们的文件内容并不会变,直到你切换过去手动执行 merge。

下面是一个多分支工作的示例:

下载安装
a) 下载本地电脑平台对应版本(需要科学上网):Git - Downloads
Linux使用命令:
apt-get install git
b) 以管理员身份运行 Git 安装程序,除了添加右键菜单要勾选,其他默认即可。
c) 到git官网注册账号
d) 本地电脑任意一个文件夹右键打开git bash,配置用户名、邮箱、密码
配置用户名
git config --global user.name "我的名字"
配置邮箱
git config --global user.email "我的邮箱"
配置密码
git config --global user.password "我的密码"
实战练习
**(1)**从远程仓库拉取代码
如果是第一次下载项目,在任意一个文件夹下,从远程下载项目:
git clone 项目地址
如果是本地已经有项目,在项目文件夹打开git命令行,从远程拉取更新项目:
将远程仓库中的更改合并到当前分支中
git pull
**(2)**本地修改代码后,在项目文件夹打开git命令行,进行本地暂存、提交
先将修改的文件放入暂存区
git add ./
将暂存区的修改记录本地提交
git commit -m "本次提交的注释"
**(3)**将项目推送到远程:
git push
**(4)**如果与绑定的远程跟踪分支进行合并时有冲突,git会提示解决冲突后才可以提交。
**(5)**拉取远程代码
git pull
**(6)**git会把有区别的文件进行合并,同时保留所有冲突的代码,需要我们修改代码。
**(7)**再次add和commit进行本地提交,再次push推送。
git add ./
git commit -m "合并后的注释"
git push
**(8)**完成。
私有仓库
- 创建私密仓库
登录到GitHub账户,在右上角点击加号 (+) 图标,然后选择 "New repository"。
在仓库名称旁边,确保选择了 "Private"(私密)选项。
填写其他必要的详细信息,如描述、是否初始化README文件等。
点击 "Create repository" 完成创建。
- 邀请成员
一旦你创建了私密仓库,你可以邀请其他人成为协作者:
在你的仓库页面,点击 "Settings"(设置)。
在左侧菜单中,选择 "Collaborators"(成员)。
点击 "Add People"(邀请协作者)。
输入你想要邀请的成员的GitHub用户名。
选择成员的权限级别(例如,可以设置为 "Read"、"Write" 或 "Admin")。
点击 "Add to repository"(添加协作者到仓库)按钮。