1、版本控制
1.1、概述
版本控制是一种记录文件内容变化,以便将来查阅特定版本修订情况的系统。版本控制其实最重要的是可以记录文件修改历史记录,从而让每个用户能够查看历史版本,方便版本切换。 下图是一个本地最简单的版本控制机制的体现
1.2、为什么需要版本控制
个人开发过渡到团队协作
- 小红将服务器上的代码拉下来到自己本地修改一部分并提交了上去
- 小蓝也将服务器上的代码拉下来到自己修改一部分并提交了上去
- 必须保证两者之间修改的代码不能冲突,即小蓝修改的代码不能覆盖小红修改的,必须起到统一
1.3、版本控制工具
1.3.1、集中式版本控制工具
如何让不同的用户系统上的开发者协同工作的问题?于是系统集中化的版本控制(Centralized Version Control Systems,简称CV)应运而生,以及 Perforce 等。集中化的版本控制系统诸如 CVS、SVN 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。多年以来,这已成为版本控制系统的标准做法。
这种做法带来了许多好处,每个人都可以在一定程度上看到项目中的其他人正在做些什么。而管理员也可以轻松掌控每个开发者的权限,并且管理一个集中化的版本控制系统,要远比在各个客户端上维护本地数据库来得轻松容易。事分两面,有好有坏。这么做显而易见的缺点是中央服务器的单点故障。如果服务器宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。
1.3.2、分布式版本控制工具
像 Git、Mercurial、Bazaar、Darcs…… 这种分布式版本控制工具,客户端提取的不是最新版本的文件快照,而是把代码仓库完整地镜像下来(本地库),是一次对代码仓库的完整备份,这样任何一处协同工作用的文件发生故障,事后都可以用其他客户端的本地仓库进行恢复。因为每个客户端的每一次文件提取操作,实际上都是一次对整个文件仓库的完整备份。分布式的版本控制系统出现之后,解决了集中式版本控制系统的缺陷:
- 服务器断网的情况下也可以进行开发(因为版本控制是在本地进行的)
- 每个客户端保存的也都是整个完整的项目(包含历史记录,更加安全)
版本保持统一的实现:用远程库github、gitee等实现
2、Git介绍
Git是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目。Git 易于学习,占地面积小,性能极快。 它具有廉价的本地库,方便的暂存区域和多个工作流分支等特性。其性能优于 Subversion、CVS、Perforce 和 ClearCase 等版本控制工具。
- Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
- Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
- Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。
官网地址:git-scm.com/
3、Git简史
同生活中的许多伟大事物一样,Git 诞生于一个极富纷争大举创新的年代。
Linux 内核开源项目有着为数众多的参与者。 绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上(1991-2002年间)。 到 2002 年,整个项目组开始启用一个专有的分布式版本控制系统 BitKeeper 来管理和维护代码。
到了 2005 年,开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回了 Linux 内核社区免费使用 BitKeeper 的权力。 这就迫使 Linux 开源社区(特别是 Linux 的缔造者 Linus Torvalds)基于使用 BitKeeper 时的经验教训,开发出自己的版本系统。 他们对新的系统制订了若干目标:
- 速度
- 简单的设计
- 对非线性开发模式的强力支持(允许成千上万个并行开发的分支)
- 完全分布式
- 有能力高效管理类似 Linux 内核一样的超大规模项目(速度和数据量)
自诞生于 2005 年以来,Git 日臻成熟完善,在高度易用的同时,仍然保留着初期设定的目标。 它的速度飞快,极其适合管理大项目,有着令人难以置信的非线性分支管理系统
4、Git工作机制
Git 有三种状态,你的文件可能处于其中之一: 已提交(committed)、已修改(modified) 和 已暂存(staged)。
- 已修改表示修改了文件,但还没保存到数据库中。
- 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
- 已提交表示数据已经安全地保存在本地数据库中。
这会让我们的 Git 项目拥有三个阶段:工作区、暂存区以及 Git 目录。
4.1、Git的三个基本区域
本地库:保存各种文件版本的数据库,可以向这个数据库中拉取各个文件版本或把更新后的文件推入数据库进行记录。这是 Git 用来保存项目的元数据和对象数据库的地方,是 Git 最重要的部分,也叫做Git 仓库目录。从其他计算机克隆仓库时,拷贝的就是这里的数据。已经推入到这个数据库中的文件对应的状态是 已提交 (commited) 。
暂存区:用来临时存储对当前已修改过并且作了版本标记的文件,在同一段时间内位于暂存区尚未提交的所有文件都属于同一个当前的版本,这些标记使得对应文件被包含在下次提交的快照中。这个区域是一个文件,保存了下次将提交的文件列表信息,一般位于 Git 仓库目录中。在这个区域的文件状态是 已暂存 (staged) 。暂存区提交到本地库的命令为git commit
工作区:开发人员写代码的地方,对于已经修改并保存的文件,都会存储在这个区域,等待转移到暂存区并提交。它是对项目的某个版本独立提取出来的内容。那些从 Git 仓库的压缩数据库中提取出来的文件,就是放在这个区域所在的磁盘上供你使用或修改。在这个区域的文件状态是已修改 (modified) 。工作目录提交到暂存区的命令为git add
基本的 Git 工作流程如下:
- 在工作区中修改文件。
- 将你想要下次提交的更改选择性地暂存,这样只会将更改的部分添加到暂存区。
- 提交更新,找到暂存区的文件,将快照永久性存储到 Git 目录(本地库)。
如果 Git 目录中保存着特定版本的文件,就属于 已提交 状态。 如果文件已修改并放入暂存区,就属于 已暂存 状态。 如果自上次检出后,作了修改但还没有放到暂存区域,就是 已修改 状态。
4.2、Git和代码托管中心
版本保持统一的实现:用远程库github、gitee等实现
代码托管中心是基于网络服务器的远程代码仓库,一般我们简单称为远程库。
- 局域网
GitLab
- 互联网
GitHub(外网)
Gitee 码云(国内网站)
因此:加上远程仓库,我们的git
就可以分为4个基本工作区域:
在git中分为四个基本工作区域:
- Workspace: 工作区,就是你平时存放项目代码的地方
- Index / Stage: 暂存区,用于临时存放你的改动
- Repository: 仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本
- Remote: 远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换
5、Git 安装配置
安装官网地址:git-scm.com/downloads
在 Git Bash 终端里输入 git --version
查看 git 版本,如图所示,说明 Git 安装成功。
注意:
- git终端里面写命令可以当做Linux去操作【兼容】
- git bash执行
ll
,ls
,等命令后怎么退出,此命令主要用来浏览文件内容,如果想退出这些命令只需按下键盘q
键 就可以了
6、Git常用命令
6.1、设置用户签名
形式:
用户名:tom
Email地址:12334567@qq.com
复制代码
基本语法:全局范围的签名设置
git config --global user.name 用户名
git config --global user.email 邮箱
复制代码
实例
lemon@LAPTOP-DU0LC6FO MINGW64 ~/Desktop
$ git config --global user.name lemon
lemon@LAPTOP-DU0LC6FO MINGW64 ~/Desktop
$ git config --global user.email lemon@qq.com
复制代码
这些签名信息都保存家目录在家目录~
的.gitconfig
文件夹下,如下用命令进行查看
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ cd ~
lemon@LAPTOP-DU0LC6FO MINGW64 ~
$ pwd
/c/Users/lemon
lemon@LAPTOP-DU0LC6FO MINGW64 ~
$ cat .gitconfig
[user]
name = lemon
email = lemon@qq.com
复制代码
说明:
签名的作用是区分不同操作者身份。用户的签名信息在每一个版本的提交信息中能够看到,以此确认本次提交是谁做的。Git
首次安装必须设置一下用户签名,否则无法提交代码。
注意:这里设置用户签名和将来登录 GitHub(或其他代码托管中心)的账号没有任何关系。
6.2、初始化本地库
基本语法
git init
复制代码
实例
1、创建文件夹—-我在E盘下创建了一个文件夹,当做本次项目的本地仓库,牛逼的人都通过mkdir 文件夹名字
这样创建,哈哈哈
2、进入此文件夹中,空白处右键Git bash here
打开Git
终端【当然我们也可以随便比如桌面直接git bash,然后通过cd命令进入该文件夹
】,进行初始化
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace
$ git init
Initialized empty Git repository in E:/git-workspace/.git/
复制代码
3、初始化操作【初始化一遍就好】
git init
复制代码
4、在文件夹下可以查看到创建了一个.git
的文件,需要设置勾选隐藏的项目,才能进行查看
5、当然也可以通过命令查看
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ ls -lA //查看隐藏文件
total 4
drwxr-xr-x 1 lemon 197121 0 Mar 5 16:05 .git/ #这是我们的git文件
复制代码
6、通过命令查看.git
文件夹里面的内容
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ ll .git/
total 7
-rw-r--r-- 1 lemon 197121 23 Mar 5 16:05 HEAD
-rw-r--r-- 1 lemon 197121 130 Mar 5 16:05 config
-rw-r--r-- 1 lemon 197121 73 Mar 5 16:05 description
drwxr-xr-x 1 lemon 197121 0 Mar 5 16:05 hooks/
drwxr-xr-x 1 lemon 197121 0 Mar 5 16:05 info/
drwxr-xr-x 1 lemon 197121 0 Mar 5 16:05 objects/
drwxr-xr-x 1 lemon 197121 0 Mar 5 16:05 refs/
复制代码
注意:.git 目录中存放的是本地库相关的子目录和文件,不要删除,也不要胡乱修改。
6.3、查看本地库状态
用来查看工作区和暂存区的状态,执行命令如下:git status
基本语法
git status
复制代码
案例实操
1、首次查看(工作区无任何文件),如果没有文件在暂存区,会显示如下信息:这就表示没有文件在暂存区
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git status
On branch master #在主干分支上
No commits yet #没有什么可以提交的
nothing to commit (create/copy files and use "git add" to track)
复制代码
其实仓库里面文件为空和提交完了以后都是这样
2、如果有文件没被git
管理,会显示如下信息:(演示:直接在该文件夹下再创建一个新的a.txt
文件,直接执行git status
),你可以通过vim
命令添加
执行命令后,(检测到未被追踪到的文件)
红色代表这个文件只是存在于工作区,并未追踪过这个文件,需要执行git add
命令添加到暂存区
6.4、添加暂存区
基本语法
git add 文件名
复制代码
案例实操
当文件只进行git add
操作时,比如我们对a.txt
文件只进行add操作,状态如下:
解释:
- 查看状态,检测到暂存区有新文件,绿色,存在于暂存区,暂存区的文件,只是临时存储,是可以删除的
- 第4行提示的就是撤销删除命令
git rm --a.txt
,只是删除的是暂存区,工作区还是有的
6.5、提交到本地库
基本语法
git commit -m "日志信息" 文件名
复制代码
案例实操
- 将
a.txt
文件提交到暂存区执行命令为:git add a.txt
- 将文件提交到本地库执行命令为:
git commit -m "(描述提交文件的信息)" a.txt
,也可以不写描述信息 - 提交到本地库以后查看状态,没有文件需要提交,就说明暂存区的文件已经提交到本地库了,工作区没有什么文件可以提交了
注意:
- 不放在本地仓库中的文件,
git
是不进行管理,即使放在本地库的文件,如果不进行add,commit
命令,git
也不进行管理,这时候,提交本地库成功了
补充
查看版本信息,查看引用日志信息:git reflog
主分支指向第一次提交的版本
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reflog
bc34445 (HEAD -> master) HEAD@{0}: commit (initial): 第一次提交
#bc34445是执行的版本号COMMIT_ID
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
复制代码
git log
:查看更加详细的
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git log
commit bc34445f66f7c77d9375e3e45beb248773348765 (HEAD -> master)
Author: lemon <lemon@qq.com>
Date: Sat Mar 5 16:35:37 2022 +0800
第一次提交
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$
复制代码
6.6、修改文件
1、如果对a.txt
文件进行修改【也可以通过vim进入编辑模式进行修改】,并查看status
状态,就会检测到工作区有文件被修改
这个红色的就代表,这次的修改并没有添加到暂存区,没有追踪
2、将修改的文件重新提交到暂存区,add命令 ,并查看状态
修改的文件变绿了,成功
3、再提交到本地仓库,commit命令
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git commit -m "第二次提交的版本" a.txt
[master 6882e70] 第二次提交的版本
1 file changed, 5 insertions(+), 1 deletion(-) //1个文件被修改,5行新增,1行删除
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$
复制代码
4、查看状态:在主干分支上,没有什么可以提交的,其实仓库里面文件为空和提交完了以后都是这样
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git status
On branch master
nothing to commit, working tree clean
复制代码
5、查看日志信息
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reflog
6882e70 (HEAD -> master) HEAD@{0}: commit: 第二次提交的版本
bc34445 HEAD@{1}: commit (initial): 第一次提交
复制代码
指针指向第二个版本了,这时候查看a.txt
就是修改后的内容,如下,这就是我们当前指针指向的版本代表的文件的内容,并且在工作区里面就只有一个文件。
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ cat a.txt
hello
hello
hello
hello
hello
yes
yes
复制代码
7、其它命令
7.1、reflog和log命令
基本语法
git reflog 查看版本信息
git log 查看详细版本信息
复制代码
案例实操
git reflog
在显示的结果中,包含信息:HEAD@{数字}
,此数字的含义是:指针【head】表示回到当前历史版本需要走多少步
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reflog
6882e70 (HEAD -> master) HEAD@{0}: commit: 第二次提交的版本
bc34445 HEAD@{1}: commit (initial): 第一次提交
复制代码
git log
:用于显示详细的日志、历史记录、版本信息
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git log
commit 6882e709e61d5e8d10a5af43a49def72227f95e8 (HEAD -> master)
Author: lemon <lemon@qq.com>
Date: Sat Mar 5 16:44:36 2022 +0800
第二次提交的版本
commit bc34445f66f7c77d9375e3e45beb248773348765
Author: lemon <lemon@qq.com>
Date: Sat Mar 5 16:35:37 2022 +0800
第一次提交
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$
复制代码
解释:
- 里面的长串数字是哈希值,即版本号,后面信息是以键值对形式存在
- 注意:显示日志的时候,记录过多终端会自动进行分页操作
- 下一页:空格
- 上一页:键盘b
- 按钮退出:键盘q
- 按钮到了尾页:会显示END
**拓展:**展示日志的不同方式:
优美型 git log --pretty=oneline
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git log --pretty=oneline
6882e709e61d5e8d10a5af43a49def72227f95e8 (HEAD -> master) 第二次提交的版本
bc34445f66f7c77d9375e3e45beb248773348765 第一次提交
复制代码
简洁型git log --oneline
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git log --oneline
6882e70 (HEAD -> master) 第二次提交的版本
bc34445 第一次提交
复制代码
7.2、reset命令:版本重置
当开发者不想要之前提交的修改时,就会用到这个命令,重置又分为软重置和硬重置。
软重置:
-
软重置会将
HEAD
移至指定的提交(或与 HEAD 相比的提交的索引),而不会移除该提交之后加入的修改!git reset --soft HEAD~2 #还原到两个版本前 git reset --soft $COMMIT_ID #还原到指定版本 复制代码
另:由于软重置会保留修改的内容,故也可用于合并多个提交为一个提交。具体操作为将git reset
重置为自己的首次提交,然后重新使用git commit
进行提交。该命令在本地提交历史极为复杂(产生了各种merge的结)时,依然十分有效。
硬重置:
-
该命令不会保存你提交过的修改,强制使代码回退到之前的某个版本
git reset --hard $COMMIT_ID 复制代码
实操
该命令的作用:
- 用于前进或者后退历史版本 版本穿梭
- 只对本地库发生改变,使用
--soft
参数 - 使
git
的暂存区和本地库同时发生改变,工作区不变,使用--mixed
参数 - 使
git
的三个区都同时发生改变,使用--hard
参数
git reset --hard (索引值/版本号) #基于索引值进行前进后退的操作
复制代码
演示:
1、再次对a.txt
进行修改,并提交,比如插入一句古诗
2、进行add,commit
操作
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git add a.txt
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git commit -m "第三次修改的版本" a.txt
[master a4c2e81] 第三次修改的版本
1 file changed, 2 insertions(+), 1 deletion(-)
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$
复制代码
3、查看历史版本:此时指向第三次修改的版本
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reflog
a4c2e81 (HEAD -> master) HEAD@{0}: commit: 第三次修改的版本
6882e70 HEAD@{1}: commit: 第二次提交的版本
bc34445 HEAD@{2}: commit (initial): 第一次提交
复制代码
4、演示回退到最初时候的版本,命令为:git reset --hard bc34445
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reset --hard bc34445
HEAD is now at bc34445 第一次提交 //现在头指针在这里
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$
复制代码
5、查看a.txt
,发现内容已经更改 ,回到原来最初的样子
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ cat a.txt
hello
hello
hello
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$
复制代码
6、查看日志,发现指向第一次提交的版本
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reflog
bc34445 (HEAD -> master) HEAD@{0}: reset: moving to bc34445
a4c2e81 HEAD@{1}: commit: 第三次修改的版本
6882e70 HEAD@{2}: commit: 第二次提交的版本
bc34445 (HEAD -> master) HEAD@{3}: commit (initial): 第一次提交
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$
复制代码
7、演示前进到第二个版本,命令为:git reset --hard 6882e70
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reset --hard 6882e70
HEAD is now at 6882e70 第二次提交的版本
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reflog
6882e70 (HEAD -> master) HEAD@{0}: reset: moving to 6882e70
bc34445 HEAD@{1}: reset: moving to bc34445
a4c2e81 HEAD@{2}: commit: 第三次修改的版本
6882e70 (HEAD -> master) HEAD@{3}: commit: 第二次提交的版本
bc34445 HEAD@{4}: commit (initial): 第一次提交
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ cat a.txt
hello
hello
hello
hello
hello
yes
yes
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$
复制代码
【补充】:软重置与硬重置
使用^符号,只能后退
- 输入命令:
git reset --hard HEAD^
- 一个
^
表示一步
使用~
符号,也是只能后退
- 输入命令:
git reset --hard HEAD~n
n
表示后退了几部,相比起来,这种方法比较任性化。
reset命令的三个参数对比:
––soft
- 仅仅在本地库移动 HEAD 指针,不重置暂存区,不重置工作区
- 暂存区和工作区在同一水平版本,由于本地版本后退了,而工作区提交到暂存区有东西,
git status
就会变成绿色,表示在暂存区中的东西可以提交到本地)
注意:如果采用这种方式向后回退了版本,那么就会显得暂存区中的新内容没有被提交.
––mixed
- 在本地库移动 HEAD 指针
- 重置暂存区
- 不重置工作区
- 暂存区重置了,而工作区没有重置,工作区有东西可以提交到暂存区,因此git status显示红色)
注意:如果采用这种方式向后退回版本,那么就会显得工作区中的新内容没有被添加到暂存区
在上面的基础上,回退到了第一个版本,
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reflog
bc34445 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
6882e70 HEAD@{1}: reset: moving to 6882e70
bc34445 (HEAD -> master) HEAD@{2}: reset: moving to bc34445
a4c2e81 HEAD@{3}: commit: 第三次修改的版本
6882e70 HEAD@{4}: commit: 第二次提交的版本
bc34445 (HEAD -> master) HEAD@{5}: commit (initial): 第一次提交
复制代码
重新进入第二个版本
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reset --hard 6882e70
HEAD is now at 6882e70 第二次提交的版本
复制代码
开始实验:回退到第一个版本
指向第一次提交的版本了
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reflog
bc34445 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
6882e70 HEAD@{1}: reset: moving to 6882e70
bc34445 (HEAD -> master) HEAD@{2}: reset: moving to HEAD^
6882e70 HEAD@{3}: reset: moving to 6882e70
bc34445 (HEAD -> master) HEAD@{4}: reset: moving to bc34445
a4c2e81 HEAD@{5}: commit: 第三次修改的版本
6882e70 HEAD@{6}: commit: 第二次提交的版本
bc34445 (HEAD -> master) HEAD@{7}: commit (initial): 第一次提交
复制代码
**––hard **
- 在本地库移动 HEAD 指针
- 重置暂存区
- 重置工作区
- 暂存区和工作区都重置,git status 就会先没有东西可以提交,工作区也没有发生变化
- 就是我们演示的方式
8、练习
1、初始状态:
当前本地库里面的文件目录和内容如下:
指向第一次的版本,且a.txt
文件内容如下
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reflog
bc34445 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
6882e70 HEAD@{1}: reset: moving to 6882e70
bc34445 (HEAD -> master) HEAD@{2}: reset: moving to HEAD^
6882e70 HEAD@{3}: reset: moving to 6882e70
bc34445 (HEAD -> master) HEAD@{4}: reset: moving to bc34445
a4c2e81 HEAD@{5}: commit: 第三次修改的版本
6882e70 HEAD@{6}: commit: 第二次提交的版本
bc34445 (HEAD -> master) HEAD@{7}: commit (initial): 第一次提交
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ cat a.txt
hello
hello
hello
hello
hello
yes
yes
复制代码
2、将文件提交到暂存区和本地库执行命令为:
git add a.txt
git commit -m "(描述提交文件的信息)" a.txt
复制代码
实例
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git add a.txt
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git commit -m "(练习的第一次提交)" a.txt
[master db30392] (练习的第一次提交)
1 file changed, 5 insertions(+), 1 deletion(-)
复制代码
3、查看工作区和暂存区的状态,执行命令如下:git status
,如果没有文件在暂存区,会显示如下信息:这就表示没有文件在暂存区
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git status
On branch master
nothing to commit, working tree clean
复制代码
4、另外直接在该文件夹下再创建一个新的b.txt
文件,直接执行git status
,如果有文件没被git
追踪管理,会显示如下信息:
5、提交b.txt
文件到暂存区和本地库
6、查看历史版本
可以发现现在主分支头指针指向我们现在最新的的版本:新创建的一个文件这一刻的版本
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reflog
ff39c2b (HEAD -> master) HEAD@{0}: commit: 新创建的一个文件
db30392 HEAD@{1}: commit: (练习的第一次提交)
bc34445 HEAD@{2}: reset: moving to HEAD^
6882e70 HEAD@{3}: reset: moving to 6882e70
bc34445 HEAD@{4}: reset: moving to HEAD^
6882e70 HEAD@{5}: reset: moving to 6882e70
bc34445 HEAD@{6}: reset: moving to bc34445
a4c2e81 HEAD@{7}: commit: 第三次修改的版本
6882e70 HEAD@{8}: commit: 第二次提交的版本
bc34445 HEAD@{9}: commit (initial): 第一次提交
复制代码
5、演示回退到最初时候的版本,命令为:git reset --hard bc34445
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reset --hard bc34445
HEAD is now at bc34445 第一次提交
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reflog
bc34445 (HEAD -> master) HEAD@{0}: reset: moving to bc34445
ff39c2b HEAD@{1}: commit: 新创建的一个文件
db30392 HEAD@{2}: commit: (练习的第一次提交)
bc34445 (HEAD -> master) HEAD@{3}: reset: moving to HEAD^
6882e70 HEAD@{4}: reset: moving to 6882e70
bc34445 (HEAD -> master) HEAD@{5}: reset: moving to HEAD^
6882e70 HEAD@{6}: reset: moving to 6882e70
bc34445 (HEAD -> master) HEAD@{7}: reset: moving to bc34445
a4c2e81 HEAD@{8}: commit: 第三次修改的版本
6882e70 HEAD@{9}: commit: 第二次提交的版本
bc34445 (HEAD -> master) HEAD@{10}: commit (initial): 第一次提交
复制代码
此时我们打开本地仓库文件夹,发现文件只剩下a.txt
,并且里面是最开始的内容。因为我们最开始的时候就是只有一个文件在里面,并且里面就是没有内容。
6、演示前进到创建b.txt
文件后的版本,命令为:git reset --hard ff39c2b
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reset --hard ff39c2b
HEAD is now at ff39c2b 新创建的一个文件
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reflog
ff39c2b (HEAD -> master) HEAD@{0}: reset: moving to ff39c2b
bc34445 HEAD@{1}: reset: moving to bc34445
ff39c2b (HEAD -> master) HEAD@{2}: commit: 新创建的一个文件
db30392 HEAD@{3}: commit: (练习的第一次提交)
bc34445 HEAD@{4}: reset: moving to HEAD^
6882e70 HEAD@{5}: reset: moving to 6882e70
bc34445 HEAD@{6}: reset: moving to HEAD^
6882e70 HEAD@{7}: reset: moving to 6882e70
bc34445 HEAD@{8}: reset: moving to bc34445
a4c2e81 HEAD@{9}: commit: 第三次修改的版本
6882e70 HEAD@{10}: commit: 第二次提交的版本
bc34445 HEAD@{11}: commit (initial): 第一次提交
复制代码
此时我们打开本地仓库文件夹,发现文件都回来了【处在这两个版本的中间版本的新建的b.txt文件也有】 ,并且里面有相应的内容。
9、删除操作
现在的文件目录如下:
使用命令rm 文件名
删除工作区中的文件b.txt
,可以看见文件b.txt
不见了。也可以通过ll
命令显示
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ rm b.txt
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ ll
total 1
-rw-r--r-- 1 lemon 197121 43 Mar 5 19:20 a.txt
复制代码
将删除操作同步到暂存区: 显示delete
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git add b.txt
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: b.txt
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$
复制代码
将删除操作同步到本地库:
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git commit -m "删除了文件b.txt" b.txt
[master b5be15c] 删除了文件b.txt
1 file changed, 1 deletion(-)
delete mode 100644 b.txt
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git status
On branch master
nothing to commit, working tree clean
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$
复制代码
查看日志 :这些记录删不掉的。
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reflog
b5be15c (HEAD -> master) HEAD@{0}: commit: 删除了文件b.txt
ff39c2b HEAD@{1}: reset: moving to ff39c2b
bc34445 HEAD@{2}: reset: moving to bc34445
ff39c2b HEAD@{3}: commit: 新创建的一个文件
db30392 HEAD@{4}: commit: (练习的第一次提交)
bc34445 HEAD@{5}: reset: moving to HEAD^
6882e70 HEAD@{6}: reset: moving to 6882e70
bc34445 HEAD@{7}: reset: moving to HEAD^
6882e70 HEAD@{8}: reset: moving to 6882e70
bc34445 HEAD@{9}: reset: moving to bc34445
a4c2e81 HEAD@{10}: commit: 第三次修改的版本
6882e70 HEAD@{11}: commit: 第二次提交的版本
bc34445 HEAD@{12}: commit (initial): 第一次提交
复制代码
删除了的文件恢复[回退原来的历史记录]:前提:删除前,文件存在时的状态提交到了本地库。
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ git reset --hard ff39c2b
HEAD is now at ff39c2b 新创建的一个文件
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
$ ll
total 2
-rw-r--r-- 1 lemon 197121 43 Mar 5 19:20 a.txt
-rw-r--r-- 1 lemon 197121 9 Mar 5 19:25 b.txt
lemon@LAPTOP-DU0LC6FO MINGW64 /e/git-workspace (master)
复制代码
10、diff命令
比对工作区与暂存区的不同,命令如下:git diff (文件名)
- 注意:如果不加文件名,会对所有文件进行比较
- 在
b.txt
中插入一行数据[修改],并保存
再进行对比,绿色的表示新添加的。
然后将修改后的文件再次提交暂存区,在进行比较,什么都不显示就是没有什么区别
- 上面的diff命令没有什么参数。表示是和暂存区进行比较。
- 有参数的话。如与本地库最新版本的历史记录进行比较:命令如下:
git diff HEAD 文件名
- 注意:如果不想与最新版本比较可以把HEAD改为对应的索引号 事例:
- 比如和最新版本的上一个历史记录进行比较:
git diff a12c36b c.txt
或git diff HEAD^ c.txt
11、不同工作区在实际开发中的应用场景
在实际的开发过程中,具体的流转流程如下所示:
- 使用
git clone
命令拉取远程仓库到本地 - 使用
git checkout
命令,切换到你要开发的分支。一般不在原分支中作修改,而在稳定的分支上新建分支进行操作 - 修
bug
,就在稳定的分支上新建fix
分支 - 新功能,就在稳定的分支上新建
feature
分支。在新分支上进行编码和测试操作 - 使用
git add
和git commit
命令来将所作的更改提交到本地仓库,每一次使用commit
命令都会产生一条提交日志。 - 使用
git push
命令将分支推送到远程分支之上 - 待同事
Review
之后,将分支合并到稳定分支上