参考资料
什么是版本控制?
版本控制(Revision control)是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术。
简单说就是用于管理多人协同开发项目的技术。
没有进行版本控制或者版本控制本身缺乏正确的流程管理,在软件开发过程中将会引入很多问题,如软件代码的一致性、软件内容的冗余、软件过程的事物性、软件开发过程中的并发性、软件源代码的安全性,以及软件的整合等问题。
无论是工作还是学习,或者是自己做笔记,都经历过这样一个阶段!我们就迫切需要一个版本控制工具!
主流的版本控制器有如下这些
版本控制产品非常的多(Perforce、Rational ClearCase、RCS(GNU Revision Control System)、Serena Dimention、SVK、BitKeeper、Monotone、Bazaar、Mercurial、SourceGear Vault),现在影响力最大且使用最广泛的是Git与SVN
1、本地版本控制
记录文件每次的更新,可以对每个版本做一个快照,或是记录补丁文件,适合个人用,如RCS。
2、集中版本控制
所有的版本数据都保存在服务器上,协同开发者从服务器上同步更新或上传自己的修改
所有的版本数据都存在服务器上,用户的本地只有自己以前所同步的版本,如果不连网的话,用户就看不到历史版本,也无法切换版本验证问题,或在不同分支工作。而且,所有数据都保存在单一的服务器上,有很大的风险这个服务器会损坏,这样就会丢失所有的数据,当然可以定期备份。代表产品:SVN、CVS、VSS
3、分布式版本控制
每个人都拥有全部的代码!安全隐患!
所有版本信息仓库全部同步到本地的每个用户,这样就可以在本地查看所有版本历史,可以离线在本地提交,只需在连网时push到相应的服务器或其他用户那里。由于每个用户那里保存的都是所有的版本数据,只要有一个用户的设备没有问题就可以恢复所有的数据,但这增加了本地存储空间的占用。
不会因为服务器损坏或者网络问题,造成不能工作的情况!
Git与SVN的主要区别
SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而工作的时候,用的都是自己的电脑,所以首先要从中央服务器得到最新的版本,然后工作,完成工作后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,对网络带宽要求较高。
SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而工作的时候,用的都是自己的电脑,所以首先要从中央服务器得到最新的版本,然后工作,完成工作后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,对网络带宽要求较高。
Git 的介绍
Git是一款免费、开源的分布式版本控制系统
Git可以有效、高速的处理从很小到非常大的项目版本管理。
Git最初由 Linux 之父 Linus Trovalds(林纳斯·托瓦兹) 开发,用作Linux内核代码的管理。
官网:
https://git-scm.com/
图标
Git 的历史
同生活中的许多伟大事物一样,Git 诞生于一个极富纷争大举创新的年代。
Linux 内核开源项目有着为数众广的参与者。绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上(1991-2002年间)。到 2002 年,整个项目组开始启用一个专有的分布式版本控制系统 BitKeeper 来管理和维护代码。
到了 2005 年,开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回了 Linux 内核社区免费使用 BitKeeper 的权力。这就迫使 Linux 开源社区(特别是 Linux 的缔造者 Linus Torvalds)基于使用 BitKeeper 时的经验教训,开发出自己的版本系统(2周左右!)。 也就是后来的 Git!
Git是目前世界上最先进的分布式版本控制系统。
Git是免费、开源的,最初Git是为辅助 Linux 内核开发的,来替代 BitKeeper!
Linux和Git之父李纳斯·托沃兹(Linus Benedic Torvalds)1969、芬兰
GitHub 的介绍
Github是全球最大的社交编程及代码托管网站(https://github.com/)。
Github可以托管各种git库,并提供一个web界面。
Github作为开源代码库以及版本控制系统,Github拥有百万开发者用户。随着越来越多的应用程序转移到了云上,Github已经成为了管理软件开发以及发现已有代码的首选方法。
国内知名互联网公司的开源项目:
全球顶级科技公司纷纷加入 GitHub ,并贡献他们自己的项目代码
仓库(Repository)
仓库的意思,即你的项目,你想在 GitHub 上开源一个项目,那就必须要新建一个 Repository ,如果你开源的项目多了,你就拥有了多个 Repositories 。
收藏(Star)
仓库主页star按钮,意思为收藏项目的人数,在 GitHub 上如果你有一个项目获得100个star都算很不容易了!
复制克隆项目(Fork)
这个不好翻译,如果实在要翻译我把他翻译成分叉,什么意思呢?你开源了一个项目,别人想在你这个项目的基础上做些改进,然后应用到自己的项目中,这个时候他就可以 Fork 你的项目(打开项目主页点击右上角的fork按钮即可),然后他的 GitHub 主页上就多了一个项目,只不过这个项目是基于你的项目基础(本质上是在原有项目的基础上新建了一个分支),他就可以随心所欲的去改进,但是丝毫不会影响原有项目的代码与结构。
注意:该fork的项目时独立存在的,不会影响原项目
发起请求(Pull Request)
发起请求,这个其实是基于 Fork 的,还是上面那个例子,如果别人在你基础上做了改进,后来觉得改进的很不错,应该要把这些改进让更多的人收益,于是就想把自己的改进合并到原有项目里,这个时候他就可以发起一个 Pull Request(简称PR) ,原有项目创建人,也就是你,就可以收到这个请求,这个时候你会仔细review他的代码,并且测试觉得OK了,就会接受他的PR,这个时候他做的改进原有项目就会拥有了。
关注(Watch)
这个也好理解就是观察,如果你 Watch 了某个项目,那么以后只要这个项目有任何更新,你都会第一时间收到关于这个项目的通知提醒。
事务卡片(Issue)
发现代码BUG,但是目前没有成型代码,需要讨论时用;
举个例子,就是你开源了一个项目,别人发现你的项目中有bug,或者哪些地方做的不够好,他就可以给你提个 Issue ,即问题,提的问题多了,也就是 Issues ,然后你看到了这些问题就可以去逐个修复,修复ok了就可以一个个的 Close 掉。
哈哈,我已经注册过了,就拿老师的 PPT 来说事吧~
哈哈,迫不得已,为了演示各种操作,我又注册了一个号
注:我用 Chrome 浏览器出现如下提示,无法注册 GitHub 账号,换成 Edge 就可以了~
注意事项
创建仓库的步骤
1、创建新仓库,一般来说一个git库(仓库)对应一个开源项目
在首页点击【Create repository】按钮
2、设置仓库信息
① Repository name:仓库名称
② Description:仓库(项目)描述
③ Public:公有仓库,任何人都能看到
④ Readme:创建 Readme 文件,用于详细描述项目
⑤ Create repository:点击按钮创建仓库
3、创建成功后跳转到仓库主页
QQ邮箱设置白名单
我注册的时候不需要设置白名单,估计老师这个视频有点年代了吧
1、点击【设置】–>【反垃圾】–>【设置域名白名单】
2、填入 github.com,点击【添加到域名白名单】
在 GitHub 项目仓库中新建文件
点击 Create new file 新建文件
新建一个文件要做的事情
HelloWorld.java
,创建成功后跳转回仓库主页面,点击【提交描述】可以查看文件提交的详细信息
喏,文件提交的详细信息
在 GitHub 项目仓库中编辑文件
在仓库中点击要编辑的文件
点击【Edit this file】
更改文件内容后,点击【Commit changes】即可
提交成功后跳转至文件查看页面
回到仓库主页,提交次数变成了【3 commits】,分别是 Initial commit、创建 HelloWorld.java
文件、编辑 HelloWorld.java
文件
删除 GitHub 仓库中的文件
在仓库中点击要删除的文件
点击【Delete this file】删除文件
填写提交描述和详细描述,点击【Commit changes】删除 HelloWorld.java
文件
删除成功,提交次数变成了【4 commits】
思考:被删除文件如何查看信息
点击 【commits】按钮
点击删除之前的那一次 commit
即可查看到 HelloWorld.java
的内容
向 GitHub 项目仓库中上传文件
点击【Uploa files】上传文件
选择要上传的文件(可直接将文件拖拽至窗体中进行上传)
Unravel.java
上传成功
在 GitHub 项目仓库中搜索仓库文件
点击【Go to file】或者直接敲击【T】键
搜索 Unravel 关键词
下载/检出 GitHub 项目
点击 【Download ZIP】
如何删除一个 repository?
设置默认分支为 master 分支(GitHub 改版了,现在默认分支改为了 main 分支)
在【Settings】–>【Repositories】中,修改默认分支名为 master
单独修改某一个项目的默认分支
如果想单独修改某一个项目的默认分支名,可以在项目的【Settings】面板中设置
在弹出的窗口中设置新分支名即可
GitHub Issues 的作用
当发现代码Bug但目前没有成型代码,或者使用开源项目出现问题时,可以在 Issues 讨论区探讨如何解决项目的 Bug 或者问题
GitHub Issues 的使用方法
如果发现开源项目有问题,可以在 Issues 讨论区提出一个 Issue,首先在【Issues】界面下点击【New issue】
填入 Issue 的标题和详细描述后,点击【Submit new issue】
如果问题已经解决,那么可以告诉别人:别担心,局势在我掌控之中
然后点击【Close issue】关闭此 Issue
Issues 个数减 1
GitHub 主页主要有:仓库、动态、项目推荐
emmm,最右边的项目推荐应该是安装了【Octotree-GitHub code tree】插件的原因
换了 Edge 浏览器就没有了呀~~~
个人主页的两种进入方式
1、在仓库主页点击 【Username(oney1314)】 进入用户主页
2、点击【Your profile】进入
个人主页主要有显示:仓库、关注的项目、关注的用户等信息
如何收藏一个项目?
情景:Heygo 无意访问到 Oneby 的开源项目感觉不错并进行收藏
操作:打开对应项目主页,点击右上角 star 按钮即可收藏
如何查看自己收藏了哪些项目?
点击【Your stars】
在收藏页面,显示 Heygo 收藏了 Oneby 的 test 项目
如何关注一个项目?
情景:张三关注了李四的项目,李四添加项目文件,张三的github主页会有怎样的展示?
操作:打开对应项目主页,点击右上角 watch 按钮即可关注
想要收到关于该项目的所有通知应该要选择【All Activity】
关注项目的作用:会收到更新提醒
Oneby 对 test 仓库做了更改:新建了一个 Oneby.java
文件
观察 Heygo 的 GitHub 主页有什么变换?答:会显示 test 仓库的动态
点进去还能查看到详细的修改信息
如何克隆一个项目?
情景:Heygo fork 了 Oneby 的项目,相当于 Heygo 复制了 Oneby 的项目,所以自己也单独有了一个一样名称的仓库(注:该仓库会声明来自于 Oneby,但是独立存在)
操作:打开对应项目主页,点击右上角 fork 按钮即可克隆
点击项目主页右上角的 【fork】 按钮进行克隆
克隆成功后,Heygo 的 test 项目下面会显示【forked from oneby1314/test】,表示该项目是从 Oneby 的 test 项目克隆过来的
验证:fork后的仓库是否单独存在?
先在 Heygo 的 test 项目(克隆的仓库)新建一个 Heygo.java
文件
呐,在 Heygo 的 test 仓库中已经创建成功啦~
Oneby 的 test 仓库丝毫不受影响
注:要是我随便 fork 一个项目,然后更改里面的内容就能影响别人原油的项目,那原作者不是要疯掉~~~想想就不可能嘛
如何发起请求?
情景:Heygo 修改了fork 的项目中的文件,希望更新到原来的仓库,这时候他要新建一个pull request
操作:打开对应项目主页,点击【Pull request】按钮
在 Heygo 的项目主页,点击【Pull request】按钮
点击【Create pull request】
填写相关说明,点击【Create pull request】发起一个请求
发起请求成功后,自动跳转到【Pull requests】页面
项目的原作者如何操作?
在 Oneby 的仓库首页中打开【Pull requests】页面,点击刚才 Heygo 提交的请求
代码审核确认无误后,可选择【Merge pull request】接收此请求
呐,Heygo.java
就更新到 Oneby 的 test 仓库啦
邀请 CodeHeygo 协作开发 git-test 项目
在【Settings】–>【Manage access】面板中,点击【Invite a collaborator】邀请他人一同协作
输入被邀请人的 GitHub 昵称
Heygo 就能与 Oneby 一起协作开发啦~~
方法一:新建Issue
通过 Issues 提交问题、建议或者想法
方法二:Pull request
通过 Pull request 提交请求
方案一:官网下载
打开git官网,下载最新稳定版本(与你的电脑硬件和操作系统对应的版本)
哈哈,这速度得下载到猴年马月去了。。。
方案二:镜像下载
官网下载太慢,我们可以使用淘宝镜像下载,在官网找到git-for-windows
下载最新稳定版本
安装注意事项
1、选择一个没有空格和中文字符的路径
2、使用默认的 Vim 编辑器(作为一个程序员,不用 Vim 你的良心不会痛吗?)
3、还是使用 master 作为主分支名吧~
4、仅在 Git Bash 中使用 Git 命令(Git 命令仅在 Git Bash 中生效)
5、其他默认吧~~~
三种启动 Git 的方式
基本的 Linux 命令复习
cd
: 改变目录。cd . .
回退到上一个目录,直接cd进入默认目录pwd
: 显示当前所在的目录路径。ls(ll)
: 都是列出当前目录中的所有文件,只不过ll(两个ll)列出的内容更为详细。touch
: 新建一个文件 如 touch index.js 就会在当前目录下新建一个index.js文件。rm
: 删除一个文件,rm index.js 就会把index.js文件删除。mkdir
: 新建一个目录,就是新建一个文件夹。rm -r
: 删除一个文件夹,rm -r src
删除src目录mv
移动文件,mv index.html src
,index.html 是我们要移动的文件,src 是目标文件夹,当然这样写,必须保证文件和目标文件夹在同一目录下。reset
重新初始化终端/清屏。clear
清屏(Windows 下位 cls
)。history
查看命令历史。help
帮助。exit
退出。#
表示注释查看 Git 配置:
git config -l
在 Git Bash 中输入 git config -l
命令
查看不同级别的配置文件:
#查看系统config(位于 Git 安装目录 Git/etc/ 目录中)
git config --system --list
#查看当前用户(global)配置(位于家目录中 ,cd~ 即可回到家目录)
git config --global --list
Git 配置签名(设置用户名与邮箱)
1、项目/仓库级别
首先 Git 本地项目仓库执行如下代码设置,然后去查看 .git 目录下的 config 文件,
git config user.name oneby1314
git config user.email 891734032@qq.com
在 .git 目录下的 .gitconfig 文件中,保存了刚才设置的用户名和用户邮箱
2、系统用户级别
使用
git config --global user.name oneby1314 #设置用户名
git config --global user.email 891734032@qq.com #设置用户邮箱
配置文件位于:C:\Users\Heygo\.gitconfig
,用于配置系统用户级别的签名
系统用户级配置文件中的内容
注意:
就近原则:项目级别优先于系统用户级别,二者都有时采用项目级别的签名。
Git 工作区域的概念
Git本地有三个工作区域:工作目录(Working Directory)、暂存区(Stage/Index)、资源库(Repository或Git Directory)。如果在加上远程的git仓库(Remote Directory)就可以分为四个工作区域。文件在这四个区域之间的转换关系如下:
本地的三个区域确切的说应该是git仓库中HEAD指向的版本:
Git 的工作流程
git的工作流程一般是这样的:
因此,git管理的文件有三种状态:已修改(modified),已暂存(staged),已提交(committed)
文件的四种状态
版本控制就是对文件的版本控制,要对文件进行修改、提交等操作,首先要知道文件当前在什么状态,不然可能会提交了现在还不想提交的文件,或者要提交的文件没提交上。
查看文件状态
上面说文件有4种状态,通过如下命令可以查看到文件的状态:
#查看指定文件状态
git status [filename]
#查看所有文件状态
git status
# git add . 添加所有文件到暂存区
# git commit -m "消息内容" 提交暂存区中的内容到本地仓库 -m 提交信息
参考资料
.gitignore
文件的作用
.gitignore
文件用来忽略被指定的文件或文件夹的改动,被记录在.gitignore
文件里的文件或文件夹,是无法被git跟踪到的,换句话说,被忽略的文件是不会被放入到远程仓库里的
即 .gitignore
文件文件的作用就是告诉Git哪些文件不需要添加到版本管理中。
注意事项
.gitignore
文件来忽略的。.gitignore
文件存放于git仓库的根目录下。
.gitignore
文件的语法
1、注释
#
表示注释,如下:
# Here is Oneby.
2、忽略文件/文件夹
直接写入文件或文件夹名即可,指定文件夹里的所有文件也会一起被忽略,如下:
# ignore target folder
target
# ignore Eclipse files
.settings
build
.classpath
.project
# ignore IDEA files
.idea
.mvn
3、不忽略文件/文件夹
!
表示不忽略指定的文件,如下:
# don't ignore src folder
!src
4、在指定文件夹里不忽略指定的文件
通过!
可以实现更加有意思的用法,如下:
# ignore scaffolds folder, but don't ignore draft.md under scaffolds folder.
scaffolds/*
!scaffolds/draft.md
注意:这里必须在文件夹后面加上/\*
,否则是无法实现想要的效果的。
5、使用通配符及其他符号
可以使用通配符及其他符号来指定复杂条件的文件,如下:
*.log
day_1?.txt
hello[0-9].txt
**/bin/Debug/
*
表示匹配任意字符;?
表示匹配一个字符;[]
表示匹配中括号内的单个字符:
-
来表示连贯的字符,比如0-9
,a-z
,A-Z
等,[0-9]
表示匹配从0到9的单个字符。^
来表示除外,比如[^0-9]
表示除0到9之外的单个字符。**
表示任意多层文件夹创建工作目录与常用指令
工作目录(WorkSpace)一般就是你希望Git帮助你管理的文件夹,可以是你项目的目录,也可以是一个空目录,建议不要有中文。日常使用只要记住下图6个命令:
初始化
git init
:初始化本地 Git 仓库
状态查看
git status
:查看工作区、暂存区状态
添加
git add
:将工作区的“新建/修改”添加到暂存区
提交
git commit -m "commit message" [file name]
:将暂存区的内容提交到本地库
历史记录
git log
:查看 git commit 的历史记录
git log --pretty=oneline
:以行的形式显示 commit 的历史记录
git log --oneline
:git log --pretty=oneline
的简化版本(commit 索引没有这么长)
git reflog
:增加 HEAD 指针所需移动的步数
前进 & 后退
基于索引值操作(推荐):git reset --hard [commit 索引值]
表示移动到指定的 commit 索引处
使用^符号(只能后退):git reset --hard HEAD^
表示后退一步;git reset --hard HEAD^
表示后退两步
使用~符号:只能后退:git reset --hard HEAD~n
表示后退 n 步骤
比较文件差异
将工作区的文件和暂存区的文件进行比较:git diff [文件名]
将工作区的文件和本地库的历史文件进行比较:git diff [本地库中历史版本] [文件名]
比较所有已经修改的文件(工作区和暂存区进行比较):git diff
分支管理
创建分支:git branch [分支名]
查看分支:git branch -v
切换分支:git checkout [分支名]
合并分支:
git checkout [被合并分支名]
git merge [有新内容分支名]
拉取远程仓库
拉取远程仓库至本地并执行合并操作:git pull [远程库地址别名] [远程分支名]
,pull 可以分为两个步骤:
git fetch [远程库地址别名] [远程分支名]
git merge [远程库地址别名/远程分支名]
停止跟踪文件
.gitignore 文件的目的是为了确保不被跟踪的 Git 某些文件仍然未被跟踪,要停止跟踪当前跟踪的文件,请使用 git rm --cached
命令
git ls-files
git rm --cached 文件通配符
初始化一个 Git 仓库:
git init
在桌面新建一个文件夹,右击选择【Git Bash Here】
执行完 git init
命令后,会多出来一个 .git
的隐藏文件夹
注意:.git 目录中存放的是本地库相关的子目录和文件,不要删除,也不要胡乱修改。
向仓库中添加文件:
git status
&git add
&git commit -m "
"
先使用 touch
指令创建一个 GitTest.java
文件
使用 vim 编辑器添加代码
使用 git status
查看文件状态,【untracked files】表示文件在工作区,需要使用 git add
将文件添加到暂存区
使用 git add
将文件添加到暂存区,再次使用 git status
查看文件状态,【changes to be commited】表示文件需要被提交到仓库
使用 git commit -m "
提交文件至仓库,再次使用 git status
查看文件状态,【nothing to commit, working tree clean】表示暂无文件可提交
修改仓库中的文件:
git status
&git add
&git commit -m "
"
使用 vim 编辑器修改 GitTest.java
文件中的内容后,使用 git status
查看文件状态,【changes not staged for commit】表示文件处于工作区,需要先提交到暂存区后才能提交到仓库,【modified】表示文件已经被修改
使用 git add
将文件添加到暂存区,再次使用 git status
查看文件状态,【changes to be commited】表示文件需要被提交到仓库,【modified】表示文件已经被修改
使用 git commit -m "
将修改后的文件提交至仓库,再次使用 git status
查看文件状态,【nothing to commit, working tree clean】表示暂无文件可提交
删除仓库中的文件:
git status
&git rm
&git commit -m "
"
使用 git rm
删除文件,使用 git status
查看文件状态,【deleted】表示删除文件
使用 git commit -m "
将修改内容提交至仓库
查看历史记录:
git log
为了演示 git log
,我新建了一个 Git 仓库,每次 commit 的时候向其中添加一行英文字母
演示 git log
指令:查看 git commit 的历史记录。可以看到本地仓库的 commit 历史记录较多,无法在一页中显示。多屏显示控制方式:空格向下翻页;b 向上翻页;q 退出
演示 git log --pretty=oneline
指令:以行的形式显示 commit 的历史记录。
演示 git log --oneline
指令:commit 的索引变短了,看着更加简洁
演示 git reflog
指令:HEAD 指针后面有一个步数,表示 HEAD指针移动到该 commit 需要多少步
HEAD 指针的实质:在 .git 目录下的 HEAD 文件中,保存了 HEAD 指针的指向的分支
master 分支的索引:上面的 HEAD 文件只说明了当前 HEAD 指针指向了 master 分支,但是并没有告诉我们 master 分支的索引。于是我们需要使用另一个文件来存储 master 分支的索引,该文件在 .git/refs/heads 目录下
版本前进 & 后退的本质
版本前进和后退的本质:移动 HEAD 指针
基于索引值操作(推荐)
演示 git reset --hard [commit 索引值]
指令
使用 git reset --hard 3ace829
指令回到插入 ddd 的那一步,然后使用 cat history.txt
指令查看文件,发现 eee 那一行已经消失不见
再次使用 git reflog
指令查看,发现 HEAD指针已经指向 insert ddd 那一次的提交
使用^符号:只能后退
演示 git reset --hard HEAD^
指令:
经过上面的操作,HEAD 指针已经指向 insert ddd 那一次的提交,执行 git reset --hard HEAD^
指令后,HEAD 指针向后退一步,指向了 insert ccc 那一次的提交
再次使用 git reflog
指令查看,发现 HEAD指针已经指向 insert ccc 那一次的提交
注:有几个 ^ 符号就代表后退几步,比如 git reset --hard HEAD^^^
指令就代表后退三步
使用~符号:只能后退
演示 git reset --hard HEAD~n
指令
经过上面的操作,HEAD 指针已经指向 insert ddd 那一次的提交,执行 git reset --hard HEAD~2
指令后,HEAD 指针向后退两步,指向了 insert aaa 那一次的提交
再次使用 git reflog
指令查看,发现 HEAD指针已经指向 insert aaa 那一次的提交
reset 命令的三个参数对比)
0、查看 reset 命令的参数
使用 git help reset
指令可查看帮助文档,执行指令后会跳出一个本地网页
1、新建 Git 本地仓库
由于之前测试版本的前进和回退,历史记录之中已经夹带了 HEAD指针的移动历史。为了方便进行讲解,每次测试指令时,都使用如下的仓库进行测试
2、–soft 参数:仅仅在本地库移动HEAD 指针
先给张图,不免得一会整懵逼了,–soft 参数保持工作区和暂存区不动的情况下,使得本地仓库的指针发生变换(前后移动)
我们执行 git reset --soft d298c81
将本地仓库撤回到 insert eee 那一次提交,使用 cat history.txt
指令,发现文件里面仍有 fff 这一行。这是因为 --soft 参数只会移动本地仓库指针,不会动暂存区和工作区,因此工作区的 history.txt 文件中不会删除 fff 这一行文本
使用 git status
指令产看文件状态时,为何会显示【Changes to be committed:】和【modified: history.txt(提示颜色为绿色)】?这是因为本地库相对于暂存区后退了一步,这时候判定暂存区中文件的修改并未提交至本地库,因此才会出现如此提示信息
3、–mixed 参数:在本地库移动HEAD 指针;并且重置暂存区
先给张图,不免得一会整懵逼了,–mixed 参数保持工作区不动的情况下,使得本地仓库的指针发生变换(前后移动),并且重置暂存区
我们执行 git reset --mixed d298c81
将本地仓库撤回到 insert eee 那一次提交,使用 cat history.txt
指令,发现文件里面仍有 fff 这一行。这是因为 --mixed 参数不会重置工作区,但是 --mixed 参数会移动本地仓库指针,并且会重置暂存区,因此使用 git status
指令查看文件状态时会显示【Changes not staged for commit:】和【modified: history.txt(提示颜色为红色)】,这是因为本地仓库向后退了一步,并且重置了暂存区,因此就像是我们修改了文件,还没有提交到暂存区一样~~~
4、–hard 参数:在本地库移动HEAD 指针;并且重置暂存区和工作区
我们执行 git reset --mixed d298c81
将本地仓库撤回到 insert eee 那一次提交,使用 cat history.txt
指令,发现文件已经撤回到了 insert eee 那一次提交。这是因为 --hard 参数不但会移动本地仓库指针,还会重置暂存区和工作区,因此使用 git status
指令查看文件状态时会显示【nothing to commit, working tree clean】
如何利用版本回退机制找回删除的文件?
前提:文件删除前,已经将该文件提交到了本地库。
1、删除操作已经提交到本地库
本地 Git 仓库的初始状态如下
在 Git 仓库中删除 delete.txt 文件
回退到之前的版本,可以找回被删除的 delete.txt 文件
2、删除操作尚未提交到本地库
本地 Git 仓库的初始状态如下
删除工作区的 delete.txt 文件,但不将此次修改提交至本地仓库
使用 git reset --hard HEAD
指令重置暂存区和工作区,即可找回被删除的 delete.txt 文件
将工作区的文件和本地库的文件进行比较:
git diff [文件名]
新建 diff1.txt 文件,添加一行 I am Oneby 文本,将其添加至本地仓库中
之后再工作区中,将 I am Oneby 这行文本修改为 I am Heygo
使用 git diff diff1.txt
比较工作区的 diff1.txt 文件与暂存区的 diff1.txt 文件的差异
将工作区的文件和本地库的历史文件进行比较:
git diff [本地库中历史版本] [文件名]
为了接下来的测试,我们将上面的 I am Heygo 这行修改提交至本地仓库中
使用 git reflog
查看可知:现在本地仓库中有两条历史记录
在 diff1.txt 文件中添加新的一行:Here comes NiuNiu
使用 git diff 926bc1a diff1.txt
指令查看当前所做修改与 new diff1.txt 那次提交的差异
比较所有已经修改的文件(工作区和本地仓库进行比较):
git diff
为了测试多个文件的比较。我们新建 diff2.txt 文件,并将修改提交至本地仓库
修改 diff1.txt 和 diff2.txt 文件中的内容
使用 git diff
命令比较所有已经修改过的文件(工作区和暂存区进行比较)
什么是分支管理?
在版本控制过程中,使用多条线同时推进多个任务
分支管理的好处?
演示分支操作
新建 Git 仓库,该仓库中有一个 branch.txt 文件,并且该仓库只包含一个 master 分支(使用 git branch -v
指令查看)
使用 git branch hotfix
指令新建 hotfix 分支,在使用 git checkout hotfix
指令切换到 hotfix 分支上进行开发
在 hotfix 分支中修改 branch.txt 文件的内容,并将修改提交至本地仓库
使用 git checkout master
指令切换回主分支,在主分支下执行 git merge hotfix
合并 hotfix 分支所做的修改,合并之后使用 cat branch.txt
指令查看文件内容发现已经是 hotfix 分支所修改的内容
如何解决合并冲突?
为了造成冲突,先让 master 分支修改 branch.txt 文件的第一行
为了造成冲突,再让 hotfix 分支修改 branch.txt 文件的第一行
现在切换回 master 分支,让 master 分支去合并 hotfix 分支,显示合并时发生冲突(Merge conflict),并且分支名也变为了 master|MERGING,表示 master 分支正在执行合并操作
现在我们打开 branch.txt 文件捞一眼,在 <<<<<<< HEAD
和 =======
之间的是当前分支的内容,在 =======
和 >>>>>>> hotfix
之间的是合并分支的内容
现在我们手动消除冲突,编辑 branch.txx,留下我们认为正确的那一行代码,然后 add
和 commit
操作打一套即可解决冲突
先使用 fetch 将仓库拉取至本地,再使用 merge 合并仓库
先将远程库拉取至本地,然后将远程库往前迭代一个版本
执行 git fetch origin master
命令将远程仓库拉取至本地,此时本地仓库多了一个名为 origin/master
的分支。使用 cat Heygo.java
命令查看 Heygo.java 文件中的内容,发现并没有任何变化(还是本地仓库中的内容)
执行 git checkout origin/master
命令切换至 origin/master
分支,查看 Heygo.java 文件,不出意料,是远程仓库迭代的新版本
切换至本地仓库的 master 分支,执行 git merge origin/master
命令合并远程分支
直接使用 pull 命令
先将远程库拉取至本地,然后将远程库往前迭代一个版本
执行 git pull origin master
命令拉取并合并远程仓库,可以看到 Oneby.java 文件已经是远程仓库迭代的新版本
为什么要停止跟踪文件?
由于之前的 .gitignore 文件配置错了,导致没有忽略 .factorypath 文件
就算是我在 .gitignore 文件中加上 *.factorypath
配置项,三连招再打一套也没有用
演示如何停止跟踪文件
为何之后的配置无法生效呢?我们使用 git ls-files
指令查看被 Git 追踪的文件,发现 Git 仍会追踪 .factorypath
文件
执行 git rm --cached *.factorypath
移除对 .factorypath 文件的追踪
再次三连招打一套就行啦~~~
什么是哈希算法?
哈希是一个系列的加密算法,各个不同的哈希算法虽然加密强度不同,但是有以下几个共同点:
①不管输入数据的数据量有多大,输入同一个哈希算法,得到的加密结果长度固定。
②哈希算法确定,输入数据确定,输出数据能够保证不变
③哈希算法确定,输入数据有变化,输出数据一定有变化,而且通常变化很大
④哈希算法不可逆
Git 底层采用的是SHA-1 算法。Git 就是靠这种机制来从根本上保证数据的完整性。
哈希算法可以被用来验证文件
哈希算法验证文件是否被篡改的原理如下图所示:
哈希算法验证文件的安全性
看看 Tomcat 官网说了啥?You must verify the integrity of the downloaded files. 提示我们必须验证 Tomcat 安装包的安全性,目的是防止被注入病毒或者木马。这里我们使用 SHA512
哈希算法校验文件的安全性
点击【64-bit Windows zip】下载 Tomcat 安装包,点击 【sha512】获取 sha512哈希密文(SHA512 是指生成 512 位的哈希)
将文件经 SHA512 算法进行加密之后,然后与官网给出的 SHA512 哈希密文进行对比,就能知道安装包是否被篡改过啦~
集中式版本控制工具的文件管理机制
集中式版本控制工具以文件变更列表的方式存储信息。这类系统将它们保存的信息看作是一组基本文件和每个文件随时间逐步累积的差异。
说人话就是:每次我们修改文件,就记录文件在上一个版本的基础上修改了哪些部分,根据上一个版本的文件和修改的内容(增量),我们就能得出当前版本的文件内容
Git 的文件管理机制
Git 把数据看作是小型文件系统的一组快照。每次提交更新时Git 都会对当前的全部文件制作一个快照并保存这个快照的索引。为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。所以Git 的工作方式可以称之为快照流。
Git 的提交对象
Git 中每个文件都对应着自己的 Hash 值,Git 将每个文件的 Hash 值组成一个 tree,实现本地文件的管理。这个 tree 也有自己的 Hash 值,执行 git commit
的时候将 tree 放在 commit 对象中,提交给本地仓库
提交对象及其父对象形成的链条
每一次提交都会指向其前一次提交(父节点),形成链表结构
分支的创建
第一次提交称为根提交(root commit),当我们新建 testing 分支时,只需要新建一个指针指向 f30ab 提交即可
分支的切换
切换到 testing 分支:切换分支只需要让 HEAD 指针指向 testing 分支即可
在 testing 分支进行开发(相较于 master 分支前进了一个版本)
切换回 master 分支:切换分支只需要让 HEAD 指针指向 master 分支即可
在 master 分支上进行开发
github设置SSH登陆
在 Git Bash 中执行
ssh-keygen
命令
在任意位置执行 ssh-keygen
命令均可,有几个需要注意的地方
ssh-keygen
指令的完整写法为 ssh-keygen -t rsa -C "Oneby"
,-t rsa
表示使用 rsa 加密算法,-C "Oneby"
用于表征用户的身份SSH 登录的本质
刚才执行 ssh-keygen
命令生成了两个文件,分别为公钥文件(id_ras.pub)和私钥文件
分别用Sublime Text 打开这两个文件
配置 SSH 公钥
打开 Settings 面板
选择【New SSH key】
将刚才生成的公钥粘贴到 key 一栏
输入 GitHub 账号密码后,显示添加成功
配置完成后,你的邮箱将收到一封提醒邮件:[GitHub] A new public key was added to your account
执行
ssh -T [email protected]
指令测试配置是否生效
第一次执行 ssh -T [email protected]
指令时,需要手动输入 yes,如果配置没有问题,则会显示如下信息
第二次执行该命令时就会直接输出验证结果啦,不需要再手动输入 yes
执行
git push
指令测试 SSH 配置是否生效
还记得之前我们测试 GitHub 仓库管理,建立了一个 test 测试项目吗?
我们先把这个项目拉取到本地
在 test 项目中添加 Ssh.java 文件后,提交文件至本地仓库后,推送至远程 GitHub 仓库
呐,已经 push 到远程仓库啦~~~
注意:
第一次使用 SSH 登录需要进行验证,之后就不用啦~~~
验证成功后,你的邮箱将收到一封提醒邮件:[GitHub] A first-party GitHub OAuth application has been added to your account
IDEA 创建 SpringBoot 项目
那就来回顾一下如何使用 IDEA 创建 SpringBoot 项目吧
选择【Spring Initializr】
配置 Group ID 和 Artifact ID
勾选 Spring Web 模块
选择项目的名称和存储位置
工程目录如下,可以看到创建 SpringBoot 项目默认会给我们生成一个 .gitignore 文件
这是创建 SpringBoot 自带的 .ignore 配置
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
在 IDEA 中安装 .gitignore 插件
在 Plugins 界面搜索【ignore】插件,点击【Install】安装
安装完成后重启 IDEA
使用 .gitignore 插件创建 .gitignore 配置
新建 Git 版本的 .gitignore 文件
勾选【Example user template】
勾选【Java】
生成的 .gitignore 配置文件如下,我们手动过滤 .mvn 文件夹
# Created by .ignore support plugin (hsz.mobi)
### Java template
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Example user template template
### Example user template
# IntelliJ project files
.idea
*.iml
out
gen
.mvn
配置完成后,文件或文件夹的颜色会发生变化
IDEA 中配置 Git
在 IDEA 中需要配置 Git 命令行的启动路径,才能启动 Git 呀
在 Git 面板中配置 Git/bin/git.exe 的路径,点击【Test】进行测试,若测试成功,则会出现 Git 的版本信息
注:若不配置 Git,在使用 git init
命令初始化 Git 仓库后,IDEA 会报如下错误
执行
git init
初始化 Git 仓库
在项目主目录下执行 git init
初始化 Git 仓库,如下
初始化之后,IDEA 上方工具栏会多出如下图标
在 IDEA 左下角有个 Git 的图标,可以用于查看 Git 仓库相关的信息,比如可查看未添加至暂存区的文件
注意:或者可以先在 GitHub 上创建 Repository,将该项目 Clone 下来,并在其根目录下面创建我们的 SpringBoot 项目,一样的效果~~~
在 IDEA 进行 commit 操作
点这个,IDEA 中的 commit 操作包含了两个操作:将工作区的内容提交到暂存区(add 操作);将暂存区的内容提交到本地仓库(commit 操作)
添加待提交的文件,填入【Commit Message】,点击【Commit】进行提交
提交完成后,通过 Git 面板查看主分支的修改情况
创建 GitHub 远程仓库
在 GitHub 上创建一个远程仓库
记录该仓库的 URL
提交代码至 GitHub 远程仓库