王先森写最简单Git入门教程

Git是什么

Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。

Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。

Git是目前世界上最先进的分布式版本控制系统。

工作原理 / 流程:

Workspace:工作区
Index / Stage:暂存区
Repository:仓库区(或本地仓库)
Remote:远程仓库

SVN与Git的最主要的区别

SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,如果在局域网还可以,带宽够大,速度够快,如果在互联网下,如果网速慢的话,就纳闷了。

Git是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们两之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。

Git与软件开发生命周期

开发流程

项目立项–>需求调研–>需求拆解–>交给不同的开发进行开发–>测试环境测试–>部署生产环境。

img

环境解释

开发环境:一般开发环境是指开发人员自己的电脑环境,不同语言不通的环境,比如python,go,php,java等。
测试环境:开发好的代码先要在测试环境跑通,测试环境的软件版本和生产环境一致,但是数据一般为测试数据,作用主要是测试开发好的代码各个组件之间是否能跑通。
预发布环境:比测试环境更贴近生产环境,数据更接近真实环境,与生产环境的域名不同,主要用于质量检测。
生产环境:真正面向用户的线上环境,一般只有运维有权限进行代码的部署和维护,其他人员一般没有权限。

手动部署的问题

  1. 上传方式不方便,scp rsync rz ftp等
  2. 手动部署效率低下,占用大量时间
  3. 如果服务器多,上线速度慢
  4. 手动部署容易误操作,不能保证准确率
  5. 出问题不好回滚,手忙脚乱

自动部署的优势

持续集成

  1. 开发的代码持续的集成到代码仓库里就是持续集成,不用等所有人都开发完毕在合并,可以多个开发人员同时工作。
  2. 开发将代码提交到代码仓库,由ci服务器自动将代码拉下来进行编译,测试,然后将结果返回给开发人员。
  3. 持续集成的目的是可以频繁的将开发的功能进行合并,提高工作效率。

持续交付

  1. 持续交付就是将编译开发好的代码持续的交付到测试环境进行测试。
  2. 在预发布环境我们可以对代码进行质量扫描和漏洞扫描,并且将测试结果返回给测试人员。
  3. 如果测试的代码有问题,测试人员就通知开发人员进行修复,如果没有问题则进入下一个部署环节。

git基本操作

安装配置

1
2
3
4
5
6
7
8
9
10
yum install git -y

[root@boysec.cn ~]# git config
用法:git config [选项]

配置文件位置
--global 使用全局配置文件
--system 使用系统级配置文件
--local 使用版本库级配置文件
-f, --file <文件> 使用指定的配置文件

配置使用git的用户、邮箱

1
2
3
4
5
git config --global user.name "wangxiansen"
git config --global user.email "1767361332@qq.com"

# 设置语法高亮(可选)
git config --global color.ui true

因为Git是分布式版本控制系统,所以需要填写用户名和邮箱作为一个标识。

注意:git config –global 参数,有了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然你也可以对某个仓库指定的不同的用户名和邮箱。

查看配置

1
2
3
4
5
6
7
8
9
10
11
[root@boysec.cn ~]# git config --list
user.name=wangxiansen
user.email=1767361332@qq.com
color.ui=true

[root@boysec.cn ~]# cat .gitconfig
[user]
name = wangxiansen
email = 1767361332@qq.com
[color]
ui = true

创建版本库

1
2
3
4
5
6
7
8
mkdir /git_data

# 初始化
cd /git_data
git init

# 查看状态
git status

隐藏文件介绍

1
2
3
4
5
6
7
8
9
10
[root@boysec.cn /git_data]# ls .git|xargs -n 1
branches #分支目录
config #定义项目的特有配置
description #描述
HEAD #当前分支
hooks #git钩子文件
info #包含一个全局排除文件
objects #存放所有数据,包含info和pack两个子文件夹
refs #存放指向数据(分支)的提交对象的指针
index #保存暂存区信息,在执行git init的时候,这个文件还没有

基本命令

在工作目录创建测试文件

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@boysec.cn /git_data]# touch a b c 
[root@boysec.cn /git_data]# git status
# 位于分支 master
#
# 初始提交
#
# 未跟踪的文件:
# (使用 "git add <file>..." 以包含要提交的内容)
#
# a
# b
# c
提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)

提交文件到暂存区

提交a文件到暂存区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@boysec.cn /git_data]# git add a
[root@boysec.cn /git_data]# git status
# 位于分支 master
#
# 初始提交
#
# 要提交的变更:
# (使用 "git rm --cached <file>..." 撤出暂存区)
#
# 新文件: a
#
# 未跟踪的文件:
# (使用 "git add <file>..." 以包含要提交的内容)
#
# b
# c

查看隐藏目录

1
2
3
4
5
6
7
8
9
10
11
[root@boysec.cn /git_data]# ll .git/
总用量 20
drwxr-xr-x 2 root root 6 5月 11 12:32 branches
-rw-r--r-- 1 root root 92 5月 11 12:32 config
-rw-r--r-- 1 root root 73 5月 11 12:32 description
-rw-r--r-- 1 root root 23 5月 11 12:32 HEAD
drwxr-xr-x 2 root root 4096 5月 11 12:32 hooks
-rw-r--r-- 1 root root 96 5月 11 13:01 index # git add a 把文件提交到了暂存区
drwxr-xr-x 2 root root 20 5月 11 12:32 info
drwxr-xr-x 5 root root 37 5月 11 13:01 objects
drwxr-xr-x 4 root root 29 5月 11 12:32 refs

提交所有文件

1
2
3
4
5
6
7
8
9
10
11
12
[root@boysec.cn /git_data]# git add .
[root@boysec.cn /git_data]# git status
# 位于分支 master
#
# 初始提交
#
# 要提交的变更:
# (使用 "git rm --cached <file>..." 撤出暂存区)
#
# 新文件: a
# 新文件: b
# 新文件: c

撤回提交到暂存区的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@boysec.cn /git_data]# git rm --cached c
rm 'c'

[root@boysec.cn /git_data]# git status
# 位于分支 master
#
# 初始提交
#
# 要提交的变更:
# (使用 "git rm --cached <file>..." 撤出暂存区)
#
# 新文件: a
# 新文件: b
#
# 未跟踪的文件:
# (使用 "git add <file>..." 以包含要提交的内容)
#
# c

删除提交到暂存区的文件

方法1: 先从暂存区撤回到工作区,然后直接删除文件

1
2
3
4
5
6
7
8
9
10
11
[root@boysec.cn /git_data]# rm -f c
[root@boysec.cn /git_data]# git status
# 位于分支 master
#
# 初始提交
#
# 要提交的变更:
# (使用 "git rm --cached <file>..." 撤出暂存区)
#
# 新文件: a
# 新文件: b

方法2:直接同时删除工作目录和暂存区的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@boysec.cn /git_data]# ll
总用量 0
-rw-r--r-- 1 root root 0 5月 11 13:00 a
-rw-r--r-- 1 root root 0 5月 11 13:00 b

[root@boysec.cn /git_data]# git rm -f b
rm 'b'

[root@boysec.cn /git_data]# git status
# 位于分支 master
#
# 初始提交
#
# 要提交的变更:
# (使用 "git rm --cached <file>..." 撤出暂存区)
#
# 新文件: a
#

[root@boysec.cn /git_data]# ll
总用量 0
-rw-r--r-- 1 root root 0 11月 11 13:32 a

提交当前暂存区的所有文件到本地仓库

1
2
3
4
5
6
7
8
[root@boysec.cn /git_data]# git commit -m "commit a"
[master(根提交) 1153f56] commit a
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 a

[root@boysec.cn /git_data]# git status
# 位于分支 master
无文件要提交,干净的工作区

对比工作目录的文件和暂存区文件的差异

提交新内容wangxiansen到文件a

1
2
3
4
5
6
7
8
[root@boysec.cn ~/git_data]$echo wangxiansen>a
[root@boysec.cn ~/git_data]$git diff
diff --git a/a b/a
index e69de29..3423b2b 100644
--- a/a
+++ b/a
@@ -0,0 +1 @@
+wangxiansen

对比暂存区和本地仓库的文件内容的差异

提交a到本地暂存区,此时用git diff查看是相同的

1
2
[root@gitlab /git_data]# git add a
[root@gitlab /git_data]# git diff

对比暂存区和本地仓库文件的不同

1
2
3
4
5
6
7
[root@boysec.cn ~/git_data]$git diff --cached a
diff --git a/a b/a
index e69de29..3423b2b 100644
--- a/a
+++ b/a
@@ -0,0 +1 @@
+wangxiansen

将暂存区文件提交到本地仓库后再对比

1
2
3
4
[root@boysec.cn ~/git_data]$git commit -m "modified a"
[master a6576d2] modified a
1 file changed, 1 insertion(+)
[root@gitlab /git_data]# git diff --cached a

查看历史的提交记录

查看详细信息

1
2
3
4
5
6
7
8
9
10
11
12
[root@boysec.cn ~/git_data]$git log
commit a6576d2734f2be278bea30b8e7e85c8e7881162a
Author: wangxiansen <1767361332@qq.com>
Date: Mon Dec 6 22:41:05 2021 +0800

modified a

commit d3dfcbbe5249d44f193894a407a6712a8aa5557b
Author: wangxiansen <1767361332@qq.com>
Date: Mon Dec 6 22:34:36 2021 +0800

commit a

查看简单的信息一行现实

1
2
3
4
5
6
7
8
[root@boysec.cn ~/git_data]$git log --pretty=oneline
a6576d2734f2be278bea30b8e7e85c8e7881162a modified a
d3dfcbbe5249d44f193894a407a6712a8aa5557b commit a

# 更精简
[root@boysec.cn ~/git_data]$git log --oneline
a6576d2 modified a
d3dfcbb commit a

显示当前的指针指向

1
2
3
[root@boysec.cn ~/git_data]$ git log --oneline --decorate
a6576d2 (HEAD, master) modified a
d3dfcbb commit a

显示具体内容的变化

1
[root@gitlab /git_data]# git log -p

只显示最新的内容

1
2
3
4
5
6
[root@boysec.cn ~/git_data]$ git log -1
commit a6576d2734f2be278bea30b8e7e85c8e7881162a
Author: wangxiansen <1767361332@qq.com>
Date: Mon Dec 6 22:41:05 2021 +0800

modified a

回滚到指定版本

提交新内容boysec到文件a

1
2
3
4
5
[root@boysec.cn ~/git_data]$echo boysec > a
[root@boysec.cn ~/git_data]$git add a
[root@boysec.cn ~/git_data]$git commit -m "add boysec"
[master 562b1b9] add boysec
1 file changed, 1 insertion(+), 1 deletion(-)

再次提交新内容ceshi到文件a

1
2
3
4
[root@boysec.cn ~/git_data]$echo ceshi > a
[root@boysec.cn ~/git_data]$git commit -m "add ceshi" a
[master d3bf633] add ceshi
1 file changed, 1 insertion(+), 1 deletion(-)

查看版本号

1
2
3
4
5
[root@boysec.cn ~/git_data]$git log --oneline 
d3bf633 add ceshi
562b1b9 add boysec
a6576d2 modified a
d3dfcbb commit a

回滚到指定版本 modified a

1
2
3
4
[root@boysec.cn ~/git_data]$git reset --hard a6576d2
HEAD is now at a6576d2 modified a
[root@boysec.cn ~/git_data]$cat a
wangxiansen

此时发现回滚错了,应该回退到boysec

此时查看历史会发现并没有bbb,因为回到了过去,那时候提交bbb还没发生,所有看不到记录

1
2
3
[root@boysec.cn ~/git_data]$git log --oneline
a6576d2 modified a
d3dfcbb commit a

我们可以使用reflog来查看总的历史记录

1
2
3
4
5
6
[root@boysec.cn ~/git_data]$git reflog 
a6576d2 HEAD@{0}: reset: moving to a6576d2
d3bf633 HEAD@{1}: commit: add ceshi
562b1b9 HEAD@{2}: commit: add boysec
a6576d2 HEAD@{3}: commit: modified a
d3dfcbb HEAD@{4}: commit (initial): commit a

然后再指定回退到boysec版本

1
2
3
4
[root@boysec.cn ~/git_data]$git reset --hard 562b1b9
HEAD is now at 562b1b9 add boysec
[root@boysec.cn ~/git_data]$cat a
boysec

总结

命令总结

1
2
3
4
5
6
7
8
git init              #初始化一个目录为git版本库
git add . #将没有被管理的文件,加入git管理,添加到暂存区
git commit -m "描述" #将暂存区的文件提交到版本库中,进行版本的管理
git log #查看提交的历史记录
git reflog #查看git提交的所有历史记录
git show #查看最新的提交记录
git status #查看当前的文件管理状态(已提交|未提交)
git reset --hard commitID #回退到指定的提交版本记录

图解

img