一、前言
在上一篇文章中已经对Git进行了基本的介绍和下载安装的讲解,下面正式进入到Git相关命令的介绍与使用的讲解。
二、理解Git的工作区、暂存区、本地仓库和远程仓库
![](https://img-blog.csdnimg.cn/20191202160904103.png)
Workspace
:工作区,在新建的文件夹内,使用命令git init
初始化一个Git仓库之后,那么当前文件夹就可以称为是工作区,同时对项目代码的相关操作都发生在工作区里面,工作区内的文件是可以看见的,当然这个工作区不包括初始仓库生成的.git文件夹
。
Index / Stage
:暂存区,用于存储工作区中添加上来的变更(新增、修改、删除)的文件的地方,操作时,在项目目录下使用命令git add fileName
就可以把文件存入到暂存区,这里的fileName
是指要往暂存区添加的文件名,当然也可以使用.
代表当前的整个目录,即:git add .
会将工作区中所有新增、变更、删除过的文件的情况存入暂存区中。git status
命令可以查看缓存区有什么文件。
Repository
:本地仓库又称版本库(即:.git文件夹
),用于存储本地工作区和暂存区提交上来的变更(新增、修改、删除)过的文件的地方。操作时,使用命令git commit –m “本次操作的相关描述”
就可以将添加到暂存区的变更文件提交到本地仓库中,其中Git本地仓库
里存在很多东西,其中最为重要的是stage(或者叫index)的暂存区
。还有Git为我们自动创建的第一个分支master
,以及指向master的第一个指针HEAD
。
![](https://img-blog.csdnimg.cn/20191202163648501.png)
Remote
:远程仓库,简单来说,就是我们工作过程中,当某一个人的开发工作完毕时,需要将自己开发的功能合并到主项目中去,但因为功能是多人开发,如果不能妥善保管好主项目中存储的代码及文件的话,将会存在丢失等情况出现,所以不能将主项目放到某一个人的本地电脑上,这时就需要有一个地方存储主项目,这个地方就是我们搭建在服务器上的git远程仓库,也就是在功能开始开发前,每个人要下载项目到本地的地方。操作时,使用命令git push origin 分支名称
,将本次仓库存储的当前分支的修改推送至远程仓库中的对应分支中。
三、Git相关命令的介绍与使用
1、初始化Git仓库
git init
如果需要使用Git
对文件夹内的文本文档进行版本管理,那么就必须进行Git仓库初始化。新建一个文件夹,进入到文件夹内,鼠标右键,选择Git Bash Here
,进入到Git命令终端,使用git init
命令初始化Git仓库
![](https://img-blog.csdnimg.cn/20191202165311619.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
当出现Initialized empty Git repository in G:/depot/.git/
信息时,则表示Git仓库初始化成功,同时会在当前文件夹下生成一个.git
的隐藏文件夹,这个.git
文件夹里存储着管理当前目录内容所需的仓库数据。由于windows下默认是不显示隐藏的文件夹,需要我们在查看选项中,点击勾选隐藏的项目,才能看到.git
文件夹。
注意
:.git
文件夹里存储着管理当前目录内容所需的仓库数据,不要删除,也不要胡乱修改
![](https://img-blog.csdnimg.cn/20191202171625836.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
2、设置签名
设置签名,用于区分不同开发人员的身份,签名级别 分为仓库/项目级别 和 系统用户级别两种,其作用范围如下所示:
- 仓库/项目级别:仅在当前本地库范围内有效
- 系统用户级别:当前操作系统的用户范围内有效
设置为仓库/项目级别,我们需要在每个新建的Git仓库下都设置一遍,但是如果只是你自己用,设置为系统用户级别就可以了,如果两者都设置了,则优先使用仓库/项目级别。
2.1、设置仓库/项目级别的签名
//1、设置用户名
git config user.name 你的用户名
//2、设置邮箱
git config user.email 你的邮箱
//3、查看配置信息
cat .git/config
注意:修改用户名和邮箱命令 和 设置用户名和邮箱命令一样,即:没有设置用户名和邮箱,则设置用户名和邮箱,有用户名和邮箱则修改用户名和邮箱
![](https://img-blog.csdnimg.cn/20191202173958318.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
2.2、设置系统用户级别的签名
//1、设置用户名
git config --global user.name 你的用户名
//2、设置邮箱
git config --global user.email 你的邮箱
//3、查看配置信息
cat ~/.gitconfig
注意:修改用户名和邮箱命令 和 设置用户名和邮箱命令一样,即:没有设置用户名和邮箱,则设置用户名和邮箱,有用户名和邮箱则修改用户名和邮箱
![](https://img-blog.csdnimg.cn/20191202200441415.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
3、查看Git仓库的状态
//查看当前工作区 和 暂存区某个文件的状态
git status filename
//查看当前工作区 和 暂存区所有文件的状态
git status
//查看当前工作区 和 暂存区所有文件的详细状态列表
git status -s
![](https://img-blog.csdnimg.cn/20191202204525424.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
-
On branch master
:由于我们刚初始化仓库,没有进行相关分支切换操作,所以默认正处在master分支
下,即:主分支下。
-
No commits yet
:表示本地仓库没有提交的内容
-
nothing to commit (create/copy files and use "git add" to track)
:表示暂存区没有可以提交的东西
现在我们在当前工作区中,新建一个名为lemon.txt
的文件,并添加一些内容,作为被管理的对象,当然任何文本文件都是可以被管理的,然后尝试使用命令git status filename
来观察某个文件的状态
![](https://img-blog.csdnimg.cn/20191202213206251.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
添加完新文件之后,仓库的状态变了,显示的是Untracked files
,表示当前有未被追踪的文件lemon.txt
(这里有一个小细节,那就是新添加的lemon.txt
还未被Git管理的时候,显示的是红色
,后面使用到IntelliJ IDEA
的时候,新创建的*.java
未被管理之前,文件显示也将是红色
,所以根据颜色也可以判断当前文件的状态)。类似地,只要对Git的工作区或者暂存区进行相关操作,git status
命令的显示结果都会发生变化。
文件的四种状态,如下图所示:
![](https://img-blog.csdnimg.cn/20191202221143319.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
-
Untracked
:未跟踪,表示此文件在工作区
中,但是并没有添加到暂存区
中,通过git add fileName
命令,把文件添加到暂存区,这里的fileName
是指要往暂存区添加的文件名,使文件状态由Untracked
(未暂存) → Staged
(已暂存)
-
Unmodified
:未修改,即:本地仓库与工作区的内容一致,如果文件被修改,则文件状态由Unmodified
(未修改) → Modified
(已修改)
-
Modified
:已修改, 仅仅只是修改, 并没有进行其他的操作,这时文件的状态可以有两种变化,一是通过使用命令git add fileName
,文件状态由Modified
(已修改) → Staged
(已暂存),二是通过使用命令git checkout -- fiilename
丢弃修改内容,即:从本地仓库取出最新内容,覆盖当前修改,文件状态由Modified
(已修改) → Unmodified
(未修改)
-
Staged
:已暂存,这时文件的状态可以有两种变化,一是执行git commit
命令则可以将修改的文件同步到本地仓库中,这时本地仓库与工作区的内容一致,文件状态由Staged
(已暂存) → Unmodified
(未修改),二是执行git reset HEAD filename
命令取消暂存,文件状态由Staged
(已暂存) → Untracked
(未暂存)
4、向暂存区添加文件
如果我们只是在工作区中添加或者修改了文件,那么这个文件将不会被Git
管理,换句话说就是无法进行版本管理,那么添加、修改完文件,需要将其用Git
管理起来,就需要使用到git add
命令。git add
后面的参数可以是一个文件夹,可以是一个文件,或者是某一类文件(*.java
)等。
//1、将工作区的某个文件添加到暂存区,filename是指要往暂存区添加的文件名
git add filename
//2、将工作区中所有新增、变更、删除过的文件添加到暂存区中
git add .
![](https://img-blog.csdnimg.cn/20191202213948172.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
添加完之后,再次查看仓库状态,又发生了变化,显示的是Changes to be committed
,表示未提交的修改(这里有一个小细节,未提交修改的文件显示的是绿色
,后期在IntelliJ IDEA
中显示绿色的文件*.java
表示修改后添加了索引但还未提交
)。这里还显示了可以使用命令git rm --cached filename
来撤销已添加到暂存区
的文件。
5、撤销操作
5.1、撤销工作区中的改动的文件内容
前提
:在撤销工作区中的新增内容的文件之前,该文件必须进行过添加索引操作,即:添加到暂存区,否则就没有所谓的恢复,因为暂存区中没有内容,也就没有所谓的恢复
//拉取暂存区的文件,并将其替换成工作区的文件
git checkout -- filename
由于上一步,我们已经将lemon.txt
文件添加到暂存区,这时我们再来修改lemon.txt
文件,往其中加入一些内容,来进行撤销测试
![](https://img-blog.csdnimg.cn/20191203215503954.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
可以看到,我们往lemon.txt
文件中新增了一行bbbbb
内容,通过git checkout -- lemon.txt
把lemon.txt
文件又撤回到了原先提交到暂存区
只有一行aaaaa
内容的文件状态。
5.2、撤销已添加到暂存区的文件
git rm --cached filename
![](https://img-blog.csdnimg.cn/20191202215151313.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
可以看到lemon.txt
文件的状态和之前新建lemon.txt
文件到工作区的状态一摸一样。注意
:这里只会移除添加到暂存区
的文件,不会影响到工作区
中的文件。
6、提交文件到本地仓库
6.1、记录一行提交信息
git commit
命令是提交命令,是将已经添加到暂存区的文件提交到本地仓库的历史记录中,通过这些记录,就可以在日后的某一天将此时的文件状态进行恢复。
注意
:由于上一步操作,把lemon.txt
文件移除了暂存区
,需要先使用git add lemon.txt
命令将其添加到暂存区,然后在使用git commit -m "提交信息" lemon.txt
命令提交。
//参数-m之后是提交的信息,一般都是记录当前修改的内容等。
git commit -m "提交信息" filename
![](https://img-blog.csdnimg.cn/20191203093412659.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
这时,我们就将lemon.txt
文件提交到了本地仓库中,同时记录了一条日志,1 file changed, 1 insertion(+)
表示一个文件被更改,添加了一行内容。同时查看Git仓库状态,显示的是nothing to commit, working tree clean
,表示此时工作区 和 本地仓库的内容是一致的,暂存区也没有什么要提交的内容。
6.2、记录 多条/详细 提交信息
有时候,我们提交的代码仅仅一行提交信息是难以描述清楚本次修改的具体内容,所以需要写多行描述信息,那么我们可以直接使用git commit filename
命令来完成多行提交信息的记录。在此之前,我们在刚才测试的lemon.txt
文件中添加一些内容,然后重新提交,测试多行描述信息编写的功能,最后测试git commit filename
命令。
注意
:对lemon.txt
文件添加了一些内容之后,必须先使用git add lemon.txt
命令将其添加到暂存区,才可以进行提交。
//启动Vim文本编辑器写提交信息,可以记录 多条/详细 提交信息
git commit filename
![](https://img-blog.csdnimg.cn/20191203095915913.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
使用git commit filename
命令提交多条信息时,会自动启用Vim
文本编辑器进行多条信息的提交,其信息提交情况如下图所示:
![](https://img-blog.csdnimg.cn/2019120310032822.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
7、查看当前本地仓库提交的日志信息记录
7.1、查看文件提交的日志信息记录
git log
是一个很重要的命令,使用它可以查看当前本地仓库
提交的日志信息,通过日志信息可以很方便查看何人在何时对代码进行了提交和合并,以及提交前后的区别。
//查看当前本地仓库所有文件的提交日志信息
git log
//查看当前本地仓库指定文件的提交日志信息
git log filename
使用git log lemon.txt
查看刚才lemon.txt
文件被提交的两次日志信息,如下图所示:
![](https://img-blog.csdnimg.cn/20191203103024472.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
上图中显示了两次提交的详细日志,包括 HEAD
(指向当前最新提交的内容)和 commit
(黄色内容部分,即:指向相应提交的hash
值),这个hash
值是唯一代表本次提交,使用这个hash
值可以轻松回退到指定的版本。上图上还显示了本次提交的作者和日期时间以及提交时编辑的具体提交说明内容。
当日志记录超过一页时,这是我们可以通过如下操作进行日志的查看:
-
空格
:查看下一页日志信息
-
b
:查看上一页日志信息
-
q
:退出查看日志信息操作
7.2、以图表方式查看文件提交的日志信息记录
//以图表的方式查看当前本地仓库所有文件的提交日志信息
git log --graph
//以图表的方式查看当前本地仓库指定文件的提交日志信息
git log --graph filename
![](https://img-blog.csdnimg.cn/20191203221903701.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
7.3、以简短方式查看文件提交的日志信息记录
//查看当前本地仓库所有文件的提交日志信息,以简短方式显示日志
git log --pretty=oneline/--oneline
//查看当前本地仓库指定文件的提交日志信息,以简短方式显示日志
git log --pretty=oneline/--oneline filename
上图中以简短的方式显示了两次提交的详细日志,其中包括 commit id
(黄色内容部分,即:指向相应提交的hash
值)、HEAD
(指向当前最新提交的内容)和 提交时编辑的具体提交说明内容。
7.4、查看文件所有操作的提交日志信息记录
//查看当前本地仓库所有文件操作的提交日志信息,
git reflog
//查看当前本地仓库指定文件操作的提交日志信息,
git reflog filename
![](https://img-blog.csdnimg.cn/20191203110214834.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
上图中同样以简短的方式显示了两次提交的详细日志,其中包括 commit id
(黄色内容部分,即:指向相应提交的hash
值的前7位数)、HEAD
(指向当前最新提交的内容)、HEAD@{HEAD
指针指向相关提交版本需要移动的步数} 和 提交时编辑的具体提交说明内容。
git log 与 git reflog的区别:
8、修改提交的日志信息
当我们第一次提交代码的时候,提交的日志信息可能是完全根据我们自己的意愿来写的,但是呢,公司往往对代码提交的日志信息格式有要求,比如需要加上一些特殊符号等,所以我们偶尔会需要修改提交的日志信息,那么使用命令git commit --amend
就可以进行修改了。
git commit --amend
使用该命令之后,就可以对上一次提交的日志信息
进行修改了,进入Vim
编辑器之后就可以修改其中的日志信息了。
![](https://img-blog.csdnimg.cn/20191203222558590.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20191203222624865.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
可以看到我们上一次提交的日志信息由第二次提交lemon.txt文件; 新增一行内容bbbbb到lemon.txt文件中。
修改成 第二次提交lemon.txt文件; 修改日志信息,新增一行内容bbbbb到lemon.txt文件中。
9、压缩提交的日志信息
当提交完代码之后,发现代码的部分注释或者其他不太紧要的内容有些错误,大多数人的做法是撤销本次提交,再次修改后重新提交,其实还有一种比较常见的操作,那就是修改部分错误,重新提交,然后将这次提交包含到前一个提交之中,压缩成一个提交记录,这样的效果就是没有多余的提交记录,看起来就是这个小错误从来没发生过一样。这个小技巧也是很常用的小技巧,我们来测试一下。
//压缩最近的n次提交的日志信息
git rebase -i HEAD~n
![](https://img-blog.csdnimg.cn/20191204093705219.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
上图中lemon.txt
文件的最后一行,我们错把read
单词拼写成了raed
单词,并对文件进行了添加索引和提交操作。对应上面制造出来的问题,我们对其进行修改并再次提交。
![](https://img-blog.csdnimg.cn/20191204094322836.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
由于对lemon.txt
文件进行了两次提交,所以在历史记录中就有两次提交的记录,但是对于第二次提交,健全的历史记录并不需要它们,所以我们希望将这两次提交记录合并成为一条记录,那么使用Git
的相关命令轻松可以做到。首先我们查看两次提交的日志记录:
![](https://img-blog.csdnimg.cn/20191204100326115.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
我们使用命令git rebase -i HEAD~2
来将两次提交合并,输入命令之后,会打开编辑器,我们将第二次提交的记录前面的pick
改成fixup
即可,就完成了两次提交记录的合并,后面可以通过查看日志来确认一下。
![](https://img-blog.csdnimg.cn/20191204094923933.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
修改完成之后,就会出现一行Successfully rebased and updated refs/heads/master.
的温馨提示,同时lemon.txt
文件中最后一行的单词拼写错误也被改过来了。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191204100558333.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
我们再次查看日志,可以发现两次提交成功合并成为一次提交了,且这次提交的commit id
(即:hash
值) 也和之前的都不一样了。
![](https://img-blog.csdnimg.cn/20191204095549388.png)
10、版本的前进与回退
在日常的工作中,我们对某些文件进行了git commit
操作,但是提交之后发现某些文件内容有误,这时我们就可以已经提交到本地仓库的文件使用git reset
命令进行撤销或回退,即:撤销当前提交操作 或 回退到上一次文件提交的状态,其操作有如下三种方式:
10.1、基于hash值进行操作 (推荐)
git reset --hard 局部hash值(即:hash值的前7位数)
由于之前添加的两条日志记录,不够我们来测试版本的前进与回退,所以我又多添加了几条日志记录来进行相关测试
![](https://img-blog.csdnimg.cn/20191203145113618.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
上图中可以看到,我们使用局部hash
值由insert kkkkk into lemon.txt
版本回退到了insert hhhhh into lemon.txt
版本。
10.2、使用^符号进行操作
//一个^表示回退一步,n个^表示回退n步
git reset --hard HEAD^
![](https://img-blog.csdnimg.cn/20191203145713939.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
上图中可以看到,我们使用了HEAD^^
两个^
符号,回退了两步,由insert hhhhh into lemon.txt
版本回退到了insert fffff into lemon.txt
版本,注意
:该方式只能回退
,不能前进
。
10.3、使用~符号进行操作
//n表示回退的步数
git reset --hard HEAD~n
![](https://img-blog.csdnimg.cn/20191203150334888.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
上图中可以看到,我们使用了HEAD~2
,回退了两步,由insert fffff into lemon.txt
版本回退到了insert ddddd into lemon.txt
版本,注意
:该方式只能回退
,不能前进
。
10.4、git reset命令的三个参数的对比
-
git reset --soft [commit id或者HEAD]
:仅仅只会回退本地仓库
中的内容(即:git commit
提交的内容),不会影响到暂存区
和 工作区
中的内容。如果回退之后还要提交,可以直接使用git commit
命令提交到本地仓库
即可。
-
git reset --mixed [commit id或者HEAD]
:此为默认方式
,不带任何参数的git reset
,默认就是这种方式,它会回退本地仓库
中的内容(即:git commit
提交的内容) 和 暂存区
中的内容(即:git add
提交的内容),不会影响到工作区
中的内容。
-
git reset --hard [commit id或者HEAD]
:本地仓库
、暂存区
和 工作区
全部回退到指定版本的内容。
11、删除文件并找回
前提
:文件删除前,其文件存在时的状态
已经提交到了本地仓库
11.1、找回删除文件操作已经提交到本地仓库的文件
git reset --hard 文件存在时版本的局部hash值(即:hash值的前7位数)
1、首先,我们新建一个data.txt
文件,并添加到本地仓库中
![](https://img-blog.csdnimg.cn/20191203154046923.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
2、删除新建一个data.txt
文件,并添加到本地仓库中
![](https://img-blog.csdnimg.cn/20191203154821328.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
3、回退到data.txt
文件存在的版本历史记录,找回删除的data.txt
文件
![](https://img-blog.csdnimg.cn/2019120315512591.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
11.2、找回删除文件操作已添加到暂存区但尚未提交到本地仓库的文件
git reset --hard HEAD/文件存在时版本的局部hash值(即:hash值的前7位数)
1、还是以data.txt
文件为例,删除data.txt
文件并添加到暂存区中
![](https://img-blog.csdnimg.cn/20191203155517689.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
2、回退到data.txt
文件存在的版本历史记录,找回删除的data.txt
文件
![](https://img-blog.csdnimg.cn/20191203155742719.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
12、查看文件更改前后的差别
git diff
可以查看工作区、暂存区(index
)和 本地仓库(HEAD
)之间的差别,可以使用该命令查看自己在代码中修改了一些什么内容,接下来就让我们来看一下如何使用它吧。
12.1、查看工作区与暂存区文件的差别
git diff filename
我们在data.txt
文件中添加一行内容,并使用git diff data.txt
查看查看工作区与暂存区文件的差别。
![](https://img-blog.csdnimg.cn/20191203161934908.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
从上图可以看出,工作区中的data.txt
文件的内容相较于暂存区增加了一行。我们再次将data.txt
文件添加到暂存区时,然后使用git diff data.txt
命令进行比较,结果没有任何显示,说明工作区和暂存区中的文data.txt
件没有任何差别。
12.2、查看工作区与本地仓库文件的差别
git diff HEAD filename
接着上面的操作,我们使用git diff HEAD data.txt
命令查看工作区与本地仓库文件的差别
![](https://img-blog.csdnimg.cn/20191203162605327.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
可以看到与data.txt
未提交到暂存区显示的结果是一样的,很容易理解,这是因为我们并没有把data.txt
文件使用git commit data.txt
命令提交到本地仓库,所以显示的结果与data.txt
未提交到暂存区是一样的。
13、分支操作
使用Git
来进行代码托管,主要是为了方便团队的合作开发与并行开发。在并行开发过程中,往往存在多个分支,且各个分支的代码进度都不一样,开发的内容也不一样,比如develop
分支是开发分支,feature
是新功能开发分支,master
是主分支。对于分支的操作,大多都是新建分支、切换分支、合并分支等操作。同时各个分支完全可以独立开发,等分支作业完成之后,再与主分支mater
合并,共同推进项目前进。
![](https://img-blog.csdnimg.cn/20191203165810632.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
13.1、分支的查看
git branch -v
![](https://img-blog.csdnimg.cn/20191203172032194.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
可以看到,当前本地只有一个master
主分支,前面的*
号表示我们当前正处在master
主分支下。
13.2、分支的创建
git branch 新分支名 [master]
后面中括号的内容可以省略,即:默认是以当前分支为基础,创建新的分支,其中新分支
的内容 与 当前分支
的内容是一致的
,其中master
可以换成远程分支,这样就可以在本地以远程分支为基础创建一个新的分支。
![](https://img-blog.csdnimg.cn/20191203172400335.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
可以看到我们以当前分支master
创建了一个名叫feature
的新分支,同时新分支
中的内容与当前分支master
的内容是一致的
。
13.3、分支的切换
git checkout 新分支名
//创建并切换分支
git checkout -b 新分支名 [master]
相当于
git branch 新分支名
git checkout 新分支名
![](https://img-blog.csdnimg.cn/20191203172728320.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
可以看到我们已经由主分支master
切换到新分支feature
了
13.4、分支的删除
//删除分支
git branch –d 分支名
//强制删除本地分支
git branch –D 分支名
//删除服务器远端的分支
git push origin --delete 分支名
![](https://img-blog.csdnimg.cn/2019120317363669.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
由于我们当前处在feature
分支上,所以需要先切换到master
分支下,再去删除新分支feature
分支。
13.5、分支的合并
在实际的项目开发中,往往需要对项目增加一些新的功能,但是在master
主干分支下进行新功能开发的话,又怕新增加的功能对master
主干分支原有的功能产生影响,所以这时我们需要创建一个特性分支
,特性分支
一般都是为了完成某项特殊功能的分支,特性分支
大多都是从主分支
上新建而来,然后待特性分支
开发完成之后再合并到主分支
上。
git merge 合并的分支名
//该命令可以将分支与合并的操作的日志给记录下来,方便后续使用给git log --graph命令进行查看 (推荐)
git merge --no-ff 合并的分支名
1、由于上一步操作,我们把新创建的分支feature
给删除了,这时我们重新创建feature
分支,并在feature
分支中对data.txt
文件添加新内容 (添加的内容不影响其他分支),然后把它添加到暂存区,再提交到本地仓库中
![](https://img-blog.csdnimg.cn/20191203205343255.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
2、把feature
分支并到master
主分支上
注意
:需要合并到哪个分支上,就需要先切换到哪个分支上,例如我们需要把feature
分支合并到master
主分支上,我们就需要先切换到master
主分支上,然后在进行合并操作。
![](https://img-blog.csdnimg.cn/20191203210601809.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
可以看到,master
主分支下的data.txt
文件也新增了一行bbbbb from feature
的内容,同时使用git log --graph
命令,可以查看到分支与合并的操作的日志记录,这就是在合并时参数--no-ff
的作用,--no-ff
指的是强行关闭fast-forward
方式,fast-forward
方式就是当条件允许的时候,git
直接把HEAD
指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息,因为在这个过程中没有进行git commit
操作。
![](https://img-blog.csdnimg.cn/20191203211432169.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
14、冲突的解决
14.1、冲突的产生
由于多个分支对同一个文件的内容进行了修改,并都做了相应的提交操作,此时在进行分支的合并操作时,每个分支的同一个文件的内容都是不一样的,这就导致在合并时Git拿不定主意,即:不知道该用哪个分支的文件内容,这就导致了冲突的产生。
14.2、解决分支合并时产生的冲突
1、首先,我们切换到feature
分支下,对feature
分支下的lemon.txt
文件进行相应的修改并提交到本地仓库
![](https://img-blog.csdnimg.cn/20191204112215617.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
可以看到,我们将feature
分支下的lemon.txt
文件中的bbbbb
修改为 bbbbb from feature
,并提交到了本地仓库中。
2、我们切换到master
分支下,对master
分支下的lemon.txt
文件的同一处地方进行相应的修改并提交到本地仓库
![](https://img-blog.csdnimg.cn/20191204112910473.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
可以看到,我们对master
分支下的lemon.txt
文件中的同一处地方进行了修改,由bbbbb
修改为 bbbbb from master
,并提交到了本地仓库中。
3、将feature
分支合并到master
分支中,由于我们已经处于master
分支下,所以不需要再切换到master
分支
![](https://img-blog.csdnimg.cn/20191204113359919.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
从上图可以看到一条提示信息Automatic merge failed; fix conflicts and then commit the result.
,系统告诉我们分支合并失败了,原因是产生了冲突,需要我们手动解决冲突,然后提交结果。我们使用Vim
编辑器打开产生冲突的lemon.txt
文件,显示的内容如下所示:
![](https://img-blog.csdnimg.cn/20191204113933642.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
<<<<<<< HEAD
与=======
之间的内容是我们当前被合并的分支内容,即:master
分支的内容,而=======
与>>>>>>> feature
之间的内容是合并分支的内容,即:feature
分支的内容,我们将lemon.txt
文件的内容修改成我们想要的内容,删除<<<<<<< HEAD
、=======
和 >>>>>>> feature
,修改完成之后的内容为:
![](https://img-blog.csdnimg.cn/20191204114557108.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
4、重新将lemon.txt
文件提交到暂存区,然后提交到本地仓库中
![](https://img-blog.csdnimg.cn/20191204114957962.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MTM1Mjg3,size_16,color_FFFFFF,t_70)
这样,冲突就被我们给解决了,不过需要注意的是,以往我们在进行提交操作时,都习惯在提交命令后带上文件名,即:git commit -m "提交信息" filename
,但是在进行冲突的提交时,是不能够带上文件名的,即:git commit -m "提交信息"
,不然会提示:fatal:cannot do a partial commit during a merge.
的错误信息,这点需要特别注意。
Git入门与使用系列文章列表:
Git入门与使用 (一) Git介绍与安装
Git入门与使用 (二) Git相关命令的介绍与使用
Git入门与使用 (三) 使用GitHub进行代码托管的相关操作
Git入门与使用 (四) IDEA集成Git,并通过图形化界面进行Git相关操作
Git入门与使用 (五) GitLab介绍与安装