1.Git安装
Linux-centos
如果你的的平台是centos,安装git相当简单,以我的centos7.6为例:
⾸先,你可以试着输⼊Git,看看系统有没有安装Git:
$ git-bash: git: command not found
出现像上⾯的结果,Linux会友好地告诉你Git没有安装。
安装 Git:
sudo yum -y install git
查看 Git 安装的版本:
git --version
Linux-ubuntu
如果你的的平台是ubuntu,安装git相当简单,以我的ubuntu20.04为例:
⾸先,你可以试着输⼊git,看看系统有没有安装Git:
$ gitCommand 'git' not found, but can be installed with:sudo apt install git
出现像上⾯的结果,Linux会友好地告诉你Git没有安装,还会告诉你如何安装Git。
安装 Git:
$ sudo apt-get install git -y
查看 git 安装的版本:
$ git --version
Windows
参考链接:
https://www.bilibili.com/video/BV1hf4y1W7yT?
p=3&vd_source=b57c3f3e8a7507d4af7322c28f05fdbc
2.Git基本操作
创建Git本地仓库
要提前说的是,仓库是进⾏版本控制的⼀个⽂件⽬录。我们要想对⽂件进⾏版本控制,就必须先创建⼀个仓库出来。
创建⼀个 Git 本地仓库对应的命令为
git init
,注意命令要在⽂件⽬录下执⾏,例如:
![](https://i-blog.csdnimg.cn/blog_migrate/0c4506805dd2c7cabae4584064f39d5c.png)
我们发现,当前⽬录下多了⼀个
.git
的隐藏⽂件,
.git
⽬录是 Git 来跟踪管理仓库的,不要⼿动
修改这个⽬录⾥⾯的⽂件,不然改乱了,就把 Git 仓库给破坏了.
其中包含 Git 仓库的诸多细节,有兴趣的可以进⼊看看.
![](https://i-blog.csdnimg.cn/blog_migrate/d071583509d29e16a47a2927ec4db9cb.png)
配置Git
当安装 Git 后⾸先要做的事情是设置你的 ⽤⼾名称 和 e-mail 地址,这是⾮常重要的。配置命令为:
git config [ --global ] user.name "Your Name"git config [ --global ] user.email "email@example.com"# 把 Your Name 改成你的昵称# 把 email@example.com 改成邮箱的格式,只要格式正确即可
其中
--global
是⼀个可选项。如果使⽤了该选项,表⽰这台机器上所有的 Git 仓库都会使⽤这个
配置。如果你希望在不同仓库中使⽤不同的
name
或
e-mail
,可以不要
--global
选项,但要
注意的是,执⾏命令时必须要在仓库⾥。
查看配置命令为:
git config -l
删除对应的配置命令为:
git config [ --global ] --unset user.namegit config [ --global ] --unset user.email
认识工作区,暂存区,版本库
⼯作区:是在电脑上你要写代码或⽂件的⽬录。
•
暂存区:英⽂叫 stage 或 index。⼀般存放在
.git
⽬录下的 index ⽂件(.git/index)中,我们
把暂存区有时也叫作索引(index)。
•
版本库:⼜名仓库,英⽂名
repository
。⼯作区有⼀个隐藏⽬录
.git
,它不算⼯作区,⽽
是 Git 的版本库。这个版本库⾥⾯的所有⽂件都可以被 Git 管理起来,每个⽂件的修改、删除,Git
都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
下⾯这个图展⽰了⼯作区、暂存区和版本库之间的关系:
![](https://i-blog.csdnimg.cn/blog_migrate/9fcfcb7b4de7b88c4059658aade4deda.png)
图中左侧为⼯作区,右侧为版本库。Git 的版本库⾥存了很多东西,其中最重要的就是暂存区。
•
在创建 Git 版本库时,Git 会为我们⾃动创建⼀个唯⼀的 master 分⽀,以及指向 master 的⼀个指针叫 HEAD。
•
当对⼯作区修改(或新增)的⽂件执⾏
git add
命令时,暂存区⽬录树的⽂件索引会被更新。
•
当执⾏提交操作
git commit
时,master 分⽀会做相应的更新,可以简单理解为暂存区的⽬录
树才会被真正写到版本库中。
由上述描述我们便能得知:通过新建或粘贴进⽬录的⽂件,并不能称之为向仓库中新增⽂件,⽽只是在⼯作区新增了⽂件。必须要通过使⽤
git add
和
git commit
命令才能将⽂件添加到仓库中进⾏管理!!!
添加文件
在包含 .git 的⽬录下新建⼀个 ReadMe ⽂件,我们可以使⽤
git add
命令可以将⽂件添加到暂存
区:
•
添加⼀个或多个⽂件到暂存区:
git add
[
file1
] [
file2
] ...
•
添加指定⽬录到暂存区,包括⼦⽬录:
git add
[
dir
]
•
添加当前⽬录下的所有⽂件改动到暂存区:
git add
.
再使⽤
git commit
命令将暂存区内容添加到本地仓库中:
•
提交暂存区全部内容到本地仓库中:
git commit
-
m "message"
•
提交暂存区的指定⽂件到仓库区:
git commit
[
file1
] [
file2
] ... -
m "message"
注意
git commit
后⾯的
-m
选项,要跟上描述本次提交的 message,由⽤⼾⾃⼰完成,这部分内
容绝对不能省略,并要好好描述,是⽤来记录你的提交细节,是给我们⼈看的。
例如:
![](https://i-blog.csdnimg.cn/blog_migrate/6de90b054e4fa0d9e4f0c86e9de80e2a.png)
我们还可以多次 add 不同的⽂件,⽽只 commit ⼀次便可以提交所有⽂件,是因为需要提交的⽂件是通通被 add 到暂存区中,然后⼀次性 commit 暂存区的所有修改.如:
![](https://i-blog.csdnimg.cn/blog_migrate/b7b12c8c68178efa0226916db254f150.png)
截⾄⽬前为⽌,我们已经更够将代码直接提交⾄本地仓库了。我们可以使⽤
git log
命令,来查看
下历史提交记录:
![](https://i-blog.csdnimg.cn/blog_migrate/b14e2fcd9b56eea4e680ae731b63c31e.png)
该命令显⽰从最近到最远的提交⽇志,并且可以看到我们 commit 时的⽇志消息。
如果嫌输出信息太多,看得眼花缭乱的,可以试试加上
--pretty=oneline
参数:
![](https://i-blog.csdnimg.cn/blog_migrate/e261e5dc0a647691b6aaa5b0e444e35e.png)
需要说明的是,我们看到的⼀⼤串类似 5a250e
...2111e0
的是每次提交的
commit id
(版本
号),Git 的
commit id
不是1,2,3……递增的数字,⽽是⼀个 SHA1 计算出来的⼀个⾮常⼤的数字,⽤⼗六进制表示.
查看.git 文件
先来看看我们的
.git
的⽬录结构:
![](https://i-blog.csdnimg.cn/blog_migrate/d071583509d29e16a47a2927ec4db9cb.png)
1.index
就是我们的暂存区,add 后的内容都是添加到这⾥的。
2.
HEAD
就是我们的默认指向 master 分⽀的指针。
![](https://i-blog.csdnimg.cn/blog_migrate/c77097b4b33e117190a4d08526b367f5.png)
⽽默认的 master 分⽀,其实就是:
打印的 5a250e9e1895753939dfcf9cba0719ee6d2111e0
是什么东西呢?保存的就是当前最新
的
commit id
。
3.
objects
为 Git 的对象库,⾥⾯包含了创建的各种版本库对象及内容。当执⾏
git add
命令
时,暂存区的⽬录树被更新,同时⼯作区修改(或新增)的⽂件内容被写⼊到对象库中的⼀个新的
对象中,就位于 ".git/objects" ⽬录下,让我们来看看这些对象有何⽤处:
![](https://i-blog.csdnimg.cn/blog_migrate/1ddd085d2007b1a7c9845e6c63617320.png)
查找 object 时要将
commit id
分成2部分,其前2位是⽂件夹名称,后38位是⽂件名称。
找到这个⽂件之后,⼀般不能直接看到⾥⾯是什么,该类⽂件是经过
sha
(安全哈希算法)加密过的⽂件,好在我们可以使⽤ git cat-file
命令来查看版本库对象的内容:
![](https://i-blog.csdnimg.cn/blog_migrate/770cb3a38abfe5a93fa72be04f5d0e02.png)
其中,还有⼀⾏ tree c9b796e175c00c170f3e2b54ce4e2dd73cf43af9 ,我们使⽤同样的⽅
法,看看结果:
再看 ReadMe 对应的 a0423896973644771497bdc03eb99d5281615b51 :
总结⼀下,在本地的 git 仓库中,有⼏个⽂件或者⽬录很特殊
• index: 暂存区, git add 后会更新该内容。• HEAD: 默认指向 master 分⽀的⼀个指针。• refs/heads/master: ⽂件⾥保存当前 master 分⽀的最新 commit id 。• objects: 包含了创建的各种版本库对象及内容,可以简单理解为放了 git 维护的所有修改。
修改文件
Git ⽐其他版本控制系统设计得优秀,因为 Git 跟踪并管理的是修改,⽽⾮⽂件。
什么是修改?⽐如你新增了⼀⾏,这就是⼀个修改,删除了⼀⾏,也是⼀个修改,更改了某些字符,也是⼀个修改,删了⼀些⼜加了⼀些,也是⼀个修改,甚⾄创建⼀个新⽂件,也算⼀个修改。
让我们将 ReadMe ⽂件进⾏⼀次修改:
![](https://i-blog.csdnimg.cn/blog_migrate/624dc1fc03f0366396bee2251daec012.png)
此时,仓库中的 ReadMe 和我们⼯作区的 ReadMe 是不同的,如何查看当前仓库的状态呢?
git
status
命令⽤于查看在你上次提交之后是否有对⽂件进⾏再次修改。
![](https://i-blog.csdnimg.cn/blog_migrate/63e5aa2b944eac294b3af60c346da349.png)
上⾯的结果告诉我们,ReadMe 被修改过了,但还没有完成添加与提交。
⽬前,我们只知道⽂件被修改了,如果能知道具体哪些地⽅被修改了,就更好了。有人会说,我刚改的我知道呀!可是,你还记得你三天前写了什么代码吗?或者没写?
git diff [file]
命令⽤来显⽰暂存区和⼯作区⽂件的差异,显⽰的格式正是Unix通⽤的diff格
式。也可以使⽤
git diff HEAD -- [file]
命令来查看版本库和⼯作区⽂件的区别。
知道了对 ReadMe 做了什么修改后,再把它提交到本地仓库就放⼼多了。
![](https://i-blog.csdnimg.cn/blog_migrate/5b1c4721983b4c6c4a6e7070e7e3f2cb.png)
![](https://i-blog.csdnimg.cn/blog_migrate/523197fe2972c53ca329f8c4ce433121.png)
git add 之后,就没有看到上⾯ no changes added to commit (use "git add" and/or "git commit -a") 的消息了。接下来让我们继续 git commit 即可:
版本回退
执⾏
git reset
命令⽤于回退版本,可以指定退回某⼀次提交的版本。要解释⼀下“回退”本质是
要将版本库中的内容进⾏回退,⼯作区或暂存区是否回退由命令参数决定:
git reset 命令语法格式为: git reset [-- soft | -- mixed | -- hard ] [ HEAD ]• --mixed 为默认选项,使⽤时可以不⽤带该参数。该参数将暂存区的内容退回为指定提交版本内容,⼯作区⽂件保持不变。• --soft 参数对于⼯作区和暂存区的内容都不变,只是将版本库回退到某个指定版本。• --hard 参数将暂存区与⼯作区都退回到指定版本。切记⼯作区有未提交的代码时不要⽤这个命令,因为⼯作区会回滚,你没有提交的代码就再也找不回了,所以使⽤该参数前⼀定要慎重。• HEAD 说明:◦ 可直接写成 commit id,表⽰指定退回的版本◦ HEAD 表⽰当前版本◦ HEAD^ 上⼀个版本◦ HEAD^^ 上上⼀个版本◦ 以此类推...• 可以使⽤ 〜数字表⽰:◦ HEAD~0 表⽰当前版本◦ HEAD~1 上⼀个版本◦ HEAD^2 上上⼀个版本◦ 以此类推...
值得说的是,Git 的版本回退速度⾮常快,因为 Git 在内部有个指向当前分⽀(此处是master)的
HEAD 指针,
refs/heads/master
⽂件⾥保存当前
master
分⽀的最新
commit id
。当我们
在回退版本的时候,Git 仅仅是给
refs/heads/master
中存储⼀个特定的version,可以简单理解
成如下⽰意图:
![](https://i-blog.csdnimg.cn/blog_migrate/244c7d5cc8971ca3b63c7673a7188b51.png)
撤销修改
情况⼀:对于⼯作区的代码,还没有
add
我们可以使⽤ git checkout -- [file] 命令让⼯作区的⽂件回到最近⼀次 add 或 commit 时的状态。 要注意 git checkout -- [file] 命令中的-- 很重要,切记不要省略,⼀旦省略,该命令就变为其他意思了
情况⼆:已经
add
,但没有
commit
add 后还是保存到了暂存区呢?怎么撤销呢?
让我们来回忆⼀下学过的 git reset 回退命令,该命令如果使⽤ --mixed 参数,可以将暂存区的内容退回为指定的版本内容,但⼯作区⽂件保持不变。那我们就可以回退下暂存区的内容了!!!
示例如下:
# --mixed 是默认参数,使⽤时可以省略[wmh@hcss-ecs-1036 gitcode]$ git reset HEAD ReadMeUnstaged changes after reset:M ReadMe
情况三:已经
add
,并且也
commit
了
不要担⼼,我们可以
git reset --hard HEAD^
回退到上⼀个版本!不过,这是有条件的,就是
你还没有把⾃⼰的本地版本库推送到远程。还记得Git是分布式版本控制系统吗?我们后⾯会讲到远程版本库,⼀旦你推送到远程版本库,你就真的惨了……
删除文件
在 Git 中,删除也是⼀个修改操作,我们实战⼀下, 如果要删除
file3
⽂件,怎么搞呢?如果你这样
做了:
![](https://i-blog.csdnimg.cn/blog_migrate/25fd2400fac405c8ae90f15f001d56f1.png)
但这样直接删除是没有⽤的,反⽽徒增烦恼, git status 命令会⽴刻告诉你哪些⽂件被删除了:
[wmh@hcss-ecs-1036 gitcode]$ git statusOn branch masterChanges not staged for commit:(use "git add/rm <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)deleted: file3no changes added to commit (use "git add" and/or "git commit -a")
此时,⼯作区和版本库就不⼀致了,要删⽂件,⽬前除了要删⼯作区的⽂件,还要清除版本库的⽂
件。
⼀般⾛到这⾥,有两种可能:
•
确实要从版本库中删除该⽂件
•
不⼩⼼删错了
对第⼆种情况,很明显误删,需要使⽤
git
来进⾏恢复,很简单,我们刚学过(删除也是修改):
[wmh@hcss-ecs-1036 gitcode]$ git checkout -- file3[wmh@hcss-ecs-1036 gitcode]$ lsfile1 file2 file3 ReadMe
对于第⼀种情况,很明显是没有删完,我们只删除了⼯作区的⽂件。这时就需要使⽤
git rm
将⽂
件从暂存区和⼯作区中删除,并且
commit
:
[wmh@hcss-ecs-1036 gitcode]$ git rm file3rm 'file3'[wmh@hcss-ecs-1036 gitcode]$ git statusOn branch masterChanges to be committed:(use "git restore --staged <file>..." to unstage)deleted: file3[wmh@hcss-ecs-1036 gitcode]$ git commit -m"deleted file3"[master 5476bde] deleted file31 file changed, 0 insertions(+), 0 deletions(-)delete mode 100644 file3[wmh@hcss-ecs-1036 gitcode]$ git statusOn branch masternothing to commit, working tree clean
现在,⽂件就从版本库中被删除了。