前言
本文的git运行环境为 win11 操作系统
在日常工作中,尤其是软件工程师,会不可避免的使用到git工具,下面我将从历史发展到git命令详细的介绍git
历史发展
Git 是由 Linus Torvalds 创建的分布式版本控制系统,2025 年 4 月 7 日,Git 迎来了 20 岁生日。其发展历史如下:
- 诞生背景:在 2002 年以前,Linux 内核开发主要靠世界各地的志愿者把源代码文件通过 diff 的方式发给 Linus Torvalds,再由他手工合并代码。随着 Linux 代码库逐渐庞大,这种方式难以为继。2002 年,Linux 社区开始使用商业版本控制系统 BitKeeper,BitMover 公司出于人道主义精神授权社区免费使用。但 2005 年,因开发 Samba 的 Andrew 试图破解 BitKeeper 协议,BitMover 公司收回了免费使用权。
- 诞生初期:为了解决上述问题,Linux 之父 Linus Torvalds 决定自己开发版本控制系统,他仅用 10 天时间就写出了 Git 的第一个版本。2005 年 4 月 7 日,Linus Torvalds 提交了 Git 的首个版本,并在几天内就完成了 Linux 内核的版本控制迁移。2005 年 7 月,Git 实现自托管,即用 Git 来管理 Git 开发。
- 发展与普及:2008 年,GitHub 成立,它为开源项目免费提供 Git 存储,极大推动了 Git 的普及,无数开源项目迁移至此,如 jQuery、PHP、Ruby 等。2010 年,Google 宣布 Android 项目迁移到 Git,同年 Git 被评为最受欢迎的版本控制系统。2014 年,微软宣布将 Windows 源代码迁移到 Git,进一步扩大了 Git 在企业级开发中的影响力。
- 后续发展:2015 年,Git 2.0 版本发布,引入了默认推送行为、配置系统、分支模型等重要变化和改进。此后,Git 持续发展,不断提高易用性和友好性,通过图形界面、命令行提示等方式降低学习曲线和使用难度,同时通过优化算法等方式提升性能和稳定性,以适应更多的需求和挑战。如今,Git 已成为全球软件开发领域不可或缺的工具,是 "开源的默认语言",几乎所有知名的 AI 库和模型都在 GitHub 上维护。
除Git外,还有svn,cvs等版本控制器,但它们在架构设计、功能特性和适用场景上有显著区别,以下是具体对比:
- Git :分布式版本控制
每个开发者的本地设备都包含完整的代码仓库(包括所有历史版本和分支信息),不依赖中央服务器即可完成提交、分支、合并等核心操作。中央服务器仅用于同步代码(如push
/pull
),断网时仍可正常工作。 - SVN :集中式版本控制
依赖单一的中央服务器存储所有版本历史,开发者本地仅保留当前工作副本(无完整历史)。所有操作(提交、更新等)必须联网与中央服务器交互,断网时无法提交或查看历史。 - CVS :早期集中式版本控制
同样基于中央服务器架构,是更早出现的版本控制工具,设计更简单,功能有限,现已基本被淘汰。
那分布式和集中式有什么区别呢
- 选集中式(如 SVN) :若团队固定办公、网络稳定,且需严格管控文件权限,或项目以大二进制文件为主(如设计、影视)。
- 选分布式(如 Git) :若团队跨地域、需远程办公,或项目迭代快(需频繁分支)、重视代码安全性,尤其适合开源项目或互联网团队。
安装Git
安装git这里就不再介绍,大家可以去 git-scm.com/自行安装
配环境 config命令
配置用户名
git config --global user.name "用户名"
配置邮箱
git config --global user.email "邮箱"
邮箱和用户名也可以不需要配置,在使用远程仓库时,系统会提示需要输入用户名和密码
在输入密码时,需要注意一点,输入密码过程中没有*字符,光标也不会有任何变化,用户只需要正常输入即可
初始化 init命令
初始化当前目录为仓库,初始化后会自动将当前仓库设置为master
下面是一个目录
我们在终端里面执行init后
然后回到文件夹,选择查看-显示-隐藏的项目,就会有一个隐藏的文件夹
这个就是本地仓库
Git图解
图片来源 Git入门图文教程(1.5W字40图)🔥🔥--深入浅出、图文并茂 - 安木夕 - 博客园
提交本地仓库 add命令 commit命令
add命令是将数据暂存到缓存区
commit命令是将缓存区的数据提交到本地仓库
在下面这个目录中
如果我们只修改了test.ts文件,我们就可以通过 git add test.ts 来把数据提交到缓存区
如果我们修改了三个文件,并且需要一次性放入到缓存区,就需要通过 git add . 命令
当我们把数据放入到缓存区后,还需要通过commit命令将缓存区的数据提交到本地仓库,原因下面有写
git commit -m "第一次提交" 描述信息必须要写,但不宜过长
工作区就是我们能够直观看到的文件夹,文件,代码
那我们重点看一下缓冲区和本地仓库
1. 缓存区(Index/Stage):临时的 "待提交区域"
-
定义:缓存区是一个临时存储区域,位于工作目录(Working Directory)和本地仓库之间,用于暂存即将提交的文件修改。
-
作用:
- 筛选需要提交的内容:允许开发者从工作目录的所有修改中,选择部分文件或部分变更(而非全部)进行提交,实现 "精细化提交"。
- 预检查提交内容:在提交到本地仓库前,可通过
git diff --cached
查看缓存区与仓库的差异,确认无误后再提交。
-
操作相关命令:
git add <文件>
:将工作目录的修改添加到缓存区。git reset <文件>
:将缓存区的修改撤回(放回工作目录)。git status
:查看工作目录和缓存区的状态(哪些文件已修改、已暂存)。
-
特点:
- 是一个 "临时中转站",不永久保存版本历史。
- 内容会在执行
git commit
后被清空(提交到仓库),或被git reset
撤销。
2. 本地仓库(Local Repository):永久的 "版本数据库"
-
定义 :本地仓库是存储所有版本历史的数据库(位于工作目录下的
.git
隐藏文件夹中),包含所有提交记录、分支、标签等元数据。 -
作用:
- 永久保存代码的完整历史:每一次
git commit
都会在本地仓库创建一个新的版本快照,包含当时的代码状态和提交信息(作者、时间、备注等)。 - 支持版本回溯和分支管理:可通过
git log
查看历史,通过git checkout <版本号>
回滚到过去的状态,或基于仓库历史创建新分支。
- 永久保存代码的完整历史:每一次
-
操作相关命令:
git commit
:将缓存区的内容提交到本地仓库,生成新的版本记录。git log
:查看本地仓库的提交历史。git reset --hard <版本号>
:将本地仓库回滚到指定版本(谨慎使用,会覆盖工作目录和缓存区)。
-
特点:
- 是 Git 最核心的存储区域,所有版本历史以哈希值(SHA-1)唯一标识,确保数据不可篡改。
- 本地仓库的内容不会因工作目录或缓存区的修改而变化,除非执行
commit
、reset
等仓库级操作。
3. 直观对比:工作流程中的角色
- 工作目录:开发者实际修改文件的地方(如用编辑器修改代码)。
- 缓存区 :执行
git add
后,修改从工作目录进入缓存区(此时可继续修改其他文件,再选择性add
)。 - 本地仓库 :执行
git commit
后,缓存区的所有暂存内容被打包成一个版本,永久存入本地仓库。
假如说我们把数据提交到本地仓库后,发现 git commit -m 'message' 里面的message写错了,这时我们就需要用到--amend参数
git commit --amend 重写上次提交信息
我们在终端输入这条指令后,会进入Vim编辑器,Vim简单的操作流程如下
Vim编辑器操作流程
如果你觉得 Vim 太难用,可以更改 Git 的默认编辑器为你熟悉的工具,比如 VS Code 或 记事本。
Git编辑器设置为VS Code
git config --global core.editor "code --git config --global core.editor "code --wait"wait"
Git编辑器设置为记事本
git config --global core.editor "notepad"
Git 日志 log命令
git log
我们可以看到有四行信息,分别表示的意思如下
1. commit:<哈希值>
- 含义:提交的唯一标识(SHA-1 哈希值,共 40 位)。head->master代表这次提交到master主仓库。
- 作用:通过哈希值可以精确指代某次提交(如
git checkout <哈希值>
回滚到该版本)。 - 简化:实际使用时可只写前 7 位(如
a1b2c3d
),Git 会自动匹配完整哈希。
2. Author: <姓名> <邮箱>
- 含义:提交者的姓名和邮箱(由
git config user.name
和git config user.email
配置)。 - 注意:与
Committer
不同(部分场景会显示),Author
是代码的实际编写者,Committer
是执行提交操作的人(通常两者相同,协作时可能不同)。
3. Date: <时间>
- 含义:提交操作发生的时间(格式为「星期 月 日 时:分: 秒 年份 时区」)。
- 示例中
Fri Aug 29 10:00:00 2025 +0800
表示「2025 年 8 月 29 日周五上午 10 点,东八区时区」。
4. 提交说明(空行后的内容)
- 含义:开发者提交时填写的备注信息(通过
git commit -m "说明内容"
指定)。 - 作用:描述本次提交的目的(如 "修复 XX bug""新增 XX 功能"),便于后续追溯修改原因。
回滚代码仓库 reset命令
git reset 是 Git 中用于版本回退和修改提交历史的核心命令,主要作用是调整当前分支的「指针位置」,并可同步修改缓存区和工作目录的状态。它的行为灵活且具有一定危险性,需要理解清楚不同参数的作用。
reset命令有三种模式
git reset --soft <目标版本号>
- 作用 :仅移动
HEAD
指针到目标版本,不改变缓存区和工作目录。 - 场景:用于 "撤销最近的几次提交",但保留这些提交的修改内容(存于缓存区),便于重新组织提交。
git reset --mixed <目标版本>
- 作用 :移动
HEAD
指针到目标版本,重置缓存区 (与目标版本一致),但 不改变工作目录。 - 场景 :用于 "撤销
git add
操作" 或 "取消最近的提交并将修改放回工作目录"。
git reset --hard <目标版本>
- 作用 :移动
HEAD
指针到目标版本,同时重置缓存区和工作目录(完全与目标版本一致)。 - 风险 :会彻底丢弃目标版本之后的所有修改(包括工作目录的未提交内容),且无法恢复,谨慎使用!
- 场景:当需要彻底放弃最近的修改,回到某个稳定版本时使用。
一般我们在进行版本回退时,需要先看一下log日志,获取到每个版本的版本号
编辑
到这里我们需要引入一个新的概念,更改和暂存的更改
在 Git 中, "暂存的更改" (Staged Changes)和 "更改"(Changes/Unstaged Changes)是工作区中两种不同状态的修改,它们的核心区别在于是否被标记为 "准备提交到本地仓库",具体差异如下:
更改
指在工作目录(你实际编辑文件的地方)中已经修改,但尚未通过
git add
命令添加到缓存区(Stage/Index)的内容。这些修改仅存在于你的本地工作文件中,Git 知道它们被修改了,但不会将其纳入下一次提交的范围。
暂存的更改
指已经通过
git add
命令添加到缓存区的修改。这些修改被 Git 标记为 "准备好提交",会被包含在下次
git commit
操作中,成为新的版本记录。
reset演示
下面先看提交的日志
先使用**git reset --soft <目标版本号>
** 命令从第三次提交回到第二次提交
然后我们看vscode的git管理,以及工作区内容
可以看到工作区内容没变,但是修改的内容放入了缓存区
然后我们再回到第三次提交版本,再次使用**git reset --mixed
** 命令回到第二次提交版本
这是修改的内容就不再是暂存的更改,如果我们需要提交数据,还需要将这部分数据通过 git add命令提交到缓存区,对于工作区内容,和soft一样,没有修改
然后我们再回到第三次提交版本,再次使用**git reset --hard
** 命令回到第二次提交版本
这是工作区的内容就变成了第二次提交的内容
对于soft和mixed参数,他们从第三次提交回退到第二次提交后,都会保留第三次提交的数据
区别只是在于回滚的数据一个是放在了更改区,一个是放在了暂存的更改区
hard参数回滚后,是不可逆的,也就是说从第三次提交回滚到第二次提交后,第三次提交的数据就不见了
回滚重新提交 revert命令
git revert
和git reset
都用于撤销更改,但它们的工作方式、安全性和对项目历史的影响有本质区别。
git reset
: "回到过去" - 它通过移动分支指针来删除提交记录,从而"改写历史"。git revert
: "负负得正" - 它通过创建一个新的提交来抵消之前的提交内容,从而"增加历史"来撤销更改。
特性 | git reset |
git revert |
---|---|---|
操作对象 | 分支指针 (如 main , dev ) |
具体的提交 |
工作原理 | 将当前分支指针移动到指定的提交,丢弃之后的提交 | 创建一个新的提交 ,该提交的内容是指定提交的反向操作 |
历史记录 | 删除/改写历史。之前的提交会从分支历史中消失 | 添加新的历史。原有的提交记录保持不变,新增一个撤销记录 |
安全性 | 危险,特别是对已推送到远程仓库的提交 | 安全,适用于任何情况,尤其是公共分支 |
适用场景 | 本地分支上撤销未推送的提交 | 撤销已推送到公共分支的提交 |
恢复难度 | 如果操作了已推送的记录,恢复起来很麻烦,需要强制推送 | 易于恢复,只需再次 revert 那个"撤销提交"即可 |
展示
还是先使用git log命令
使用revert命令,并解决冲突
再次查看log日志
revert的回滚并没有改变历史
比如在第三次提交回滚到第二次,只是把第二次提交的数据拿出来,和现有的数据进行融合,若有冲突则解决冲突,然后形成一个新的提交
查看提交之后文件是否做了改动 status命令
git status 用于查看当前工作区、缓存区与本地仓库之间的状态差异,帮助开发者了解哪些文件被修改、哪些已暂存、哪些未跟踪等信息。它是日常开发中掌握 "当前项目状态" 的核心工具。
- 显示工作目录 (本地编辑的文件)中哪些文件被修改但未暂存(
Changes not staged for commit
)。 - 显示缓存区 中哪些文件已暂存,等待提交到本地仓库(
Changes to be committed
)。 - 显示哪些文件是未跟踪文件(新创建的文件,Git 尚未开始追踪)。
- 提示下一步操作建议(如 "用
git add
暂存""用git commit
提交" 等)。
下面我展示一下怎么使用
如下图所示
这是我们使用status命令
提示我们工作区干净(无任何修改)
经过更改数据后
然后使用git status命令
提示我们存在未暂存的修改(工作目录有变更)
-
Changes not staged for commit
:列出已修改但未暂存的文件(如 test.ts)。 -
提示操作:
- 用
git add
test.ts 将修改暂存到缓存区。 - 用
git restore
test.ts 丢弃工作目录的修改(恢复到缓存区状态)。
- 用
然后我们把更改内容通过add命令提交到缓存区
再次使用status命令
提示我们存在暂存的修改(缓存区有内容等待提交)
-
Changes to be committed
:列出已暂存(通过git add
)的文件,将被包含在下次git commit
中。modified
:文件被修改后暂存。new file
:新文件被暂存(首次git add
后)。
-
提示操作:用
git restore --staged <file>
取消暂存(将文件从缓存区放回工作目录)。
如果我们增加一个新文件
使用status命令
提示我们存在未跟踪文件(新文件未被 Git 追踪)
Untracked files
:列出 Git 从未追踪过的新文件(如tests/new.test.js
)。- 提示操作:用
git add tests/new.test.js
开始追踪该文件(同时暂存)。
文件撤销最近更改 checkout -- 命令
如下图所示
git checkout 命令可以将最近一次提交的数据返回到缓存区,也可以返回到工作区
本地仓库--> 缓存区/工作区
我们使用 git checkout <当前分支名称> -- . 命令,后面的点也可以改成具体的文件名称
缓存区 --> 工作区
修改一下数据,提交到缓存区
然后再修改一些数据,但是修改的数据不要提交到缓存区
此时执行 git checkout -- .命令
查看提交历史 reflog 命令
git reflog
接下来我们将git分支操作
创建分支 checkout -b 命令
css
git checkout -b <分支名称>
查看当前所处分支 branch 命令
git branch
切换分支 checkout 命令
xml
git checkout <目标分支名称>
合并分支 merge 命令
例子
假如说我们在开发某个功能时,比如我在开发校园图书管理系统,然后我现在需要开发"个人信息" 页面
那么我就需要在master主分支上分出一个PersonalInformation分支
然后当我们在PersonalInformation分支上把功能开发完毕后,就需要合并两个分支
此时我们需要在PersonalInformation分支上把master分支的代码拉过来进行合并,这一步是解决冲突
回到master分支上,再次合并PersonalInformation分支
演示
比如现在有两个分支,master和test分支,我需要在master分支上合并test分支
bash
git merge test
如果我们在test分支下,创建了文件,但是并没有提交到仓库,然后我又回到了master分支下,那么这个文件依旧是存在的,因为创建的文件在工作目录中,切换仓库时git只会更新跟仓库有关的文件,无关的文件依然存放在工作区。
删除分支 branch -D 命令
xml
git branch -D <分支名>
修改分支名称 branch -m
xml
git branch -m <分支名> <新的分支名>
保存当前工作切换分支 stash 命令
假如我们现在有这样一种情况
我们在开发某个功能A时,代码还没有写完,还不能提交
此时产品经理来了一个紧急需求,要求我们开发功能B,此时功能A相关代码不能提交,代码不提交无法创建新分支
此时我们就需要利用stash命令
演示
假如我们进行更改,但是代码没有提及到本地仓库
我们进行 git stash 命令
然后使用git stash list 查看我们查看当前存储了多少工作状态
然后我们就可以去其他分支开发新功能
当新功能开发完毕后,我们再切回到此分支,然后再将刚才的数据进行恢复
perl
git stash pop
git stash pop会将list保存的列表也给删除掉
stash其他参数命令
git stash pop //会将list保存的列表也给删除掉
git stash apply //不会删除列表里的内容会默认恢复第一个,如果想恢复指定内容可以使用git stash apply <list名称>
git stash drop //名称可以移除指定list
git stash clear //移除所有lsit
git stash show //查看栈中最新保存的stash和当前目录的差异。
注意stash是以栈的方式保存的,先进后出。
准确来说,这个命令的作用就是为了解决git不提交代码不能切换分支的问题。
查看当前仓库信息 remote 命令
git remote
2.23版本 Git 新增分支命令 switch/restore
这两个命令是git 2.23以后引入的命令,目的是为了提供对新手更友好的分支操作,最早我们使用的是git checkout命令来对分支进行操作,这个命令相对于复杂了许多,使用很多子参数来进行操作,为此git新增了两个命令:switch、restore,switch是用来切换分支与新增分支的,而restore用来撤销文件的修改
创建分支
r
git switch -c test
切换分支
arduino
git switch test
若test分支不存在,则不会创建test分支
切换到指定id并创建一个分支
arduino
git switch -d e7488524a5f606600fcf1fe89b66a50ebac5d116
合并分支
arduino
git switch -b test
恢复工作区文件
将工作区中修改的文件恢复到与暂存区(或指定提交)一致的状态,丢弃本地修改。
xml
git restore <file>
恢复暂存区文件
使用 --staged
选项,可以将暂存区的文件恢复到与上一次提交(HEAD)一致的状态(即取消 git add
的效果)。
css
git restore --staged <file>
本地的git命令讲解到这里,我们在项目中使用时,上面的这些命令足够满足我们百分之九十的需求,接下来讲一下远程指令
远程仓库获取 fetch 命令
git fetch
是 Git 中用于从远程仓库获取最新代码但不自动合并到本地分支的命令
基本语法
css
git fetch [远程仓库名] [远程分支名]
查看远程分支的更新
执行 git fetch
后,可以通过以下命令查看远程分支与本地分支的差异
css
# 查看远程main分支与本地main分支的差异
git diff main origin/main
多分支合并到当前分支 merge 命令
git merge
是 Git 中用于将一个或多个分支的修改合并到当前分支的命令,是团队协作中整合代码的核心操作之一。
基本语法
sql
git merge <目标分支名>
合并特性分支到主分支
bash
# 切换到主分支
git checkout main
# 将 feature 分支的修改合并到 main 分支
git merge feature/login
快速合并(Fast-forward)
bash
git merge --ff-only feature/simple # 仅允许快速合并,否则失败
强制创建合并提交
sql
git merge --no-ff feature/important
中止合并
sql
git merge --abort
查看合并历史
css
git log --graph --oneline --all # 简洁展示所有分支的合并历史
远程仓库获取 pull命令
git pull
是 Git 中用于从远程仓库获取代码并合并到本地分支的常用命令,它本质上是 git fetch
和 git merge
两个操作的组合。
它与 git fetch
的区别在于:git fetch
只获取数据,不修改本地工作区和当前分支,而 git pull
会自动合并。
基本语法
css
git pull [远程仓库名] [远程分支名]
拉取并合并默认远程分支
当本地分支与远程分支存在跟踪关系时,可直接使用
git pull
指定远程仓库和分支
css
git pull origin main
表示从 origin
远程仓库的 main
分支拉取代码,并合并到当前本地分支。
推送到远程仓库 push命令
git push
是 Git 中用于将本地仓库的提交推送到远程仓库的命令,是团队协作中分享本地代码的关键操作。通过 git push
,可以将本地分支的修改同步到远程仓库,让其他开发者能够获取到你的更新
基本语法
xml
git push <远程仓库名> <本地分支名>:<远程分支名>
当本地分支与远程分支存在跟踪关系时,可直接简化命令
这会将当前分支的提交推送到其跟踪的远程分支(通常是 origin/分支名
)
perl
git push
指定远程仓库和分支推送
css
git push origin main
表示将本地 main
分支的提交推送到 origin
远程仓库的 main
分支。
推送本地分支到远程新分支
arduino
git push origin feature/new:feature/new
注意事项
- 推送前通常需要先通过
git pull
同步远程最新代码,避免推送冲突 - 只有拥有对应远程仓库权限的用户才能成功推送
- 对于受保护的分支(如
main
或master
),远程仓库可能设置了推送限制,需要通过 Pull Request 等流程合并代码 - 推送成功后,其他开发者可以通过
git pull
获取你推送的更新
总结
以上介绍的这些 Git 命令,是日常开发中高频使用的核心工具,它们共同构成了代码版本管理的基础流程:
从 git clone
获取远程项目开始,通过 git add
、git commit
记录本地修改;用 git branch
管理分支,git checkout
或 git switch
切换上下文;通过 git pull
同步远程更新,git push
分享本地成果;遇到问题时,git status
查看状态,git diff
比对差异,git log
追溯历史;需要撤销操作时,git restore
恢复文件,git reset
调整提交;多人协作中,git fetch
先看更新,git merge
整合代码。
这些命令的灵活组合,能帮你高效管理代码版本、顺畅进行团队协作。但 Git 的功能远不止于此,随着使用深入,你还可以探索 git rebase
优化历史、git stash
暂存工作区、git cherry-pick
精选提交等进阶操作。记住,熟练掌握基础命令是用好 Git 的关键,遇到疑问时,git help <命令>
随时能为你提供详细文档。