Git | Git基本操作
文章目录
- [Git | Git基本操作](#Git | Git基本操作)
一、创建Git本地仓库
仓库本质上是对版本控制的一个文件目录,想对文件进行版本控制,所以需要先创建一个仓库出来。
而拿到一个Git本地仓库,我们必须要对它进行配置,才方便之后与远程仓库链接
那我们创建的这个Git本地仓库里边有哪些区域,每个区域又起着什么样的作用呢?
这便是我们接下来要解决的三个小问题
1、创建Git仓库
-
准备工作:先创建一个文件夹,在这个路径下创建仓库。这里我选择在root目录下创建一个
gitcode
文件夹,专门用于存放git相关的练习代码mkdir gitcode
-
切换到gitcode目录下
cd gitcode/
-
创建git本地仓库
git init
-
检查gitcode目录下是否多了.git文件夹
ll -a
当目录下多了.git的隐藏文件,就算创建成功了
特别注意:.git目录及文件不要手动修改!!!因为这个文件是用来跟踪管理仓库的,一旦改乱,整个Git仓库可能就报废掉,甚至远程的仓库也会乱掉。
2、配置Git
这里的配置主要是配置我们的用户名和邮箱,方便之后和远程仓库链接的。
-
首先确定自己gitee/github上边的用户名和邮箱,这里以git为例:
-
配置:进入gitcode目录下,输入下边两条命令[以张三为例,具体配置时需要设置成自己的信息]:
git config --global user.name "zhangsan"
git config --global user.email "123@example.com"
其中,这里的--global是可选的参数。因为一个主机上其实可以有多个本地仓库,每个仓库可以配置不同,这里我没有配置不同信息的需求,所以这里全部设置成了同一个用户的信息。初学时或者没有特别需求,建议先用上
如果不要这个选项,也可以,那时执行命令时必须在对应的仓库内。
-
检查是否配置成功
git config -l
补充如配置失误,需要删除重新配置,删除命令:
git config --global --unset user.name
git config --global --unset user.email
与配置相对应的,这里的--global也是可选参数,当配置时使用此参数,若想要删除,也必须带上这个参数。
这里我们演示完,还重新配置上,进行后边的操作
3、理解工作区、暂存区、版本库关系
对于Git仓库,一般划分为几个区域理解,一是远程仓库,而是本地仓库。其中本地仓库又有工作区、暂存区和版本库的概念。
- 工作区:即我们编写代码/文件的目录,对应这里gitcode就是我们的工作区。
- 暂存区 /索引:stage或index。在.git目录下的index文件中[
.git/index
]。 - 版本库:repository。本地仓库中的.git文件其实不算工作区而是版本库,这个版本库中所有文件可以被Git管理和追踪,在某个时刻进行还原。
在版本库中,每从工作区中add一次,就会生成一个git对象,并写入到对象库中,在暂存区中存的是git对象的索引,Git通过对git对象的维护来维护文件的版本。
版本库中的HEAD指针存的也是对象索引,它指向master分支。
工作区中的内容只有经过add和commit两步操作之后才算真正意义上写入了版本库中
二、添加、修改与查看
创建好了本地仓库,接下来尝试向版本库中添加内容。[0-->1]
之后,在工作区修改内容再提交修改[1-->2]
最后,基于上述操作,查看.git文件并尝试解释重要文件的含义。
添加文件
-
准备工作:首先创建文件ReadMe,并使用vim命令进行编写
创建文件:
touch ReadMe
编辑文件:
vim ReadMe
按下
I
键[切换成插入模式],输入hello,git
,点击esc
,输入:wq[保存并退出], -
通过add操作加入暂存区:
git add .
或者git add 文件名1 ... 文件名n
其中.是添加所有修改到暂存区,后者则是只添加指定的文件。
这里我用的是
git add ReadMe
-
通过commit操作将文件提交到版本库:
commit操作这里也有两种:
- 提交暂存区所有内容:git commit -m "提交细节"
- 提交暂存区指定内容:git commit [file1] ...[file2] -m "message"
这里我采用的是第一种
git commit -m "add first file"
查看历史提交记录
命令:git log
以一行的形式进行打印:git log --pretty=oneline
一般来说,会用第二个。
修改文件
假设我们需要在ReadMe中追加一行内容:hello,world【增删改都是修改操作】
清屏操作:ctrl+L或者直接输入clear
修改成功后,我们添加并提交
我们也可以再查看日志进行检验
查看.git文件
在gitcode文件夹下,输入tree .git/
命令:
目前来说,我们只关注HEAD、index、objects、refs、master几个部分即可,下边逐一解释。
-
HEAD
是一个指向当前分支的指针
对于它,我们可以通过cat .git/HEAD查看
在这里我们会发现,它指向master分支,与我们之前说的一致。
那么master下又是什么
-
master分支 && refs/heads/master
refs/heads/master中保存了当前master分支的最新commit id
同样通过cat命令查看
cat .git/refs/heads/master
这里我们会发现它存了一个字符串,这里其实就是我们每次提交的commit id也就是版本号。
它不是递增的数字,而是通过安全哈希(SHA1)算出来的一个16进制数字。
仔细看上边的图,会发现,这里查出来的内容,与objects中第三个分支相同,我们再去看看objects
-
objects
我们之前已经说过,objects中存放的是git对象的索引,是具体每次修改的信息。它维护了所有修改
这个字符串是由两部分组成,前边两位和后边的部分。
根据刚刚查出来的commit id,我们可以查看对应的修改:命令为
git cat-file -p commitid
会发现这里与我们之前打印的日志是一样的
-
index
这里我们发现index中没有东西,也就是暂存库中没有,我们试着向暂存库中添加:
touch file1 file2
git add .
并再次查看git目录
暂存区,git add后会更新内容
事实上,我们可以创建除master之外的分支,如果切换到对应的分支上,那么HEAD指针就会指向对应的分支,但默认情况下HEAD还是指向master的
三、版本回退
版本回退
git reset [--soft | --mixed --hard] [HEAD]
参数说明:soft、mixed、hard是回退的模式,HEAD是回退的版本
- --soft:将版本库回退到特定版本,修改内容存在于工作区和暂存区
- --mixed:默认模式,将暂存区和版本库回退到指定版本,修改内容只在工作区中存在
- --hard:将本地、暂存库和版本库中所有内容都回退到指定版本
- HEAD:HEAD/HEAD~0是当前版本,HEAD^/HEAD~1是上个版本,HEAD^^/HEAD~2是上上个版本,这里也可以直接写commitid,其中commit id支持部分检索,可以只要前边的
下边针对hard模式进行测试:
- 准备工作:准备三个版本的ReadMe------修改三次:
-
工作区从v3回退到v2:希望从v2开始编写
git reset --hard v2的commitid
补充:从v3回退到v2时,可能有这种情况------我又想回退到v3
对于这种情况,我们有下边的解决方案
git reflog
:记录本地每一次命令,此时如果找到v3的版本号,用hard模式回退就好。
通过这次操作,我们也可以发现,git进行版本回退的时候,可以使用部分commitid进行
- 需要说明的是,因为实际开发中版本提交可能过多,找不到,所以即使有上边的方法也存在一定的风险
撤销修改
注意:撤销修改的前提是还没有将版本库中的代码push到远程仓库上!
撤销操作存在三种情况:只在工作区的、已在暂存区但没在版本库、已在版本库了
尚未add
比如,对于工作区中ReadMe文件,我们进行了修改并保存了,还未进行add,commit操作,但是发现有错误,需要删除当前版本的更改重新修改,对应的解决办法就有下边三种:
- 直接删掉
- 通过
git diff ReadMe
查看差异,进行对应修改 - 通过
git checkout -- ReadMe
让文件回到最近一次add/commit状态。注意中间的--不能省略,不然就是其他含义,分支管理那里我们再谈。
已add但还未commit
这里我们可以通过:git reset HEAD ReadMe
已add并commit
git reset --hard HEAD^
删除文件
说明:这里的删除文件是指删除版本库中的内容
例如这里我们想要删除file2,那么有
rm file2
git status
查看工作区中文件的修改git add file2
:将file2的修改情况加入暂存区git commit -m "delete file2"
:提交file2的删除信息