Git-分布式版本管理系统

Git-分布式版本管理系统

1、Git简介

Git是什么

Git是目前世界上最先进的分布式版本控制系统(没有之一)

Git有什么特点?简单来说就是高端大气上档次!

2、Git的诞生

image-20210907111058254

3、集中式vs分布式

linus一直痛恨的cvs和svn都是集中式版本控制系统,而git是分布式的版本控制系统,集中式和分布式版本控制系统有什么区别呢?

先说集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活再把自己的活推送给中央服务器。中央服务器就好比一个图书馆,你要改一本书,必须先得从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。

image-20210907111121284

集中式版本控制系统最大的毛病是必须联网才能工作。如果在局域网还好,带宽勾搭,速度够快,可是如果在互联网上,遇到网速慢的话,可能提交一个10M的文件就需要5分钟那种,这不得把人憋死啊。

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

和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人的电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。而集中式版本控制系统的中央服务器要是出了问题,所有人就没法干活了。

在实际使用分布式版本控制系统的时候,其实很少人在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑相互访问不了,也可能今天你的同时病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家一样干活,只是交换修改不方便而已。

image-20210907111141421

image-20210907111157955

4、git安装(centos-stream)和基础使用

1
[root@shanghai ~]# yum install -y git

4.1git的简单配置

1
2
3
4
5
6
7
8
[root@shanghai ~]# git config --global user.name "zy"
[root@shanghai ~]# git config --global user.email "[email protected]"
[root@shanghai ~]# cat .gitconfig
[user]
name = zy
email = [email protected]


4.2创建版本库

1
2
3
4
5
6
7
8
9
10
11
[root@shanghai ~]# mkdir ansible-first-project
[root@shanghai ~]# cd ansible-first-project/
[root@shanghai ansible-first-project]# ls
[root@shanghai ansible-first-project]#

#上面的ansible-first-project是一个普通的目录,并不是一个git的仓库,你给它打一个标记,那么它就成了git仓库

[root@shanghai ansible-first-project]# git init
Initialized empty Git repository in /root/ansible-first-project/.git/
[root@shanghai ansible-first-project]# du -sh .git/
72K .git/

4.3 git基础操作和它的状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#在git的仓库中创建一个文件
[root@shanghai ansible-first-project]# echo "this is my first file on git repository" > first_file.test

#如果你就这样创建了一个文件,git是不知道这个文件已经创建了,但是你可以问一下git,让git检查一下是否有异常(对于git来说,所谓的异常就是有一些文件没有记录在git的仓库中)

[root@shanghai ansible-first-project]# git status
On branch master

No commits yet

Untracked files:
(use "git add <file>..." to include in what will be committed)
first_file.test

nothing added to commit but untracked files present (use "git add" to track)

#当使用git status 之后,我们发现我们创建的first-file.test文件属于未被追踪的文件,一定要让这个文件被追踪

[root@shanghai ansible-first-project]# git add first_file.test
[root@shanghai ansible-first-project]# git status
On branch master

No commits yet

Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: first_file.test

#当我们使用git add添加了first-file.test文件,那么就意味着这个文件已经被git追踪了,但是这个文件并没有被提交。此时文件的状态是tracked files和uncommited file

#如果你想提交这个文件这个文件到版本库里面,那么你必须使用git commit命令,但是git commit命令有一个强制的要求,就是你需要在提交文件的时候带上信息,就是要加上 -m 参数(message),-m参数后面指定的是你的提交说明。必须要带上提交说明才能提交文件,否则文件就无法提交。


[root@shanghai ansible-first-project]# git commit -m "my first commit"
[master (root-commit) f252b36] my first commit
1 file changed, 1 insertion(+)
create mode 100644 first_file.test
[root@shanghai ansible-first-project]# git status
On branch master
nothing to commit, working tree clean

#所以说当我们提交之后带上说明,那么文件才会被提交到git仓库,然后我们再使用git status 我们就可以看到nothing to commit,working tree clean,就表示没有内容需要提交,工作树是干净的。那么我们反推就会知道working tree 其实就是/root/ansible-first-project

#你使用git log就能看到你的提交
[root@shanghai ansible-first-project]# git log
commit f252b369f0faeaae38e0c82b8143f507fddfa260 (HEAD -> master)
Author: zy <[email protected]>
Date: Sat May 22 21:25:53 2021 +0800

my first commit

#再来一次提交
[root@shanghai ansible-first-project]# echo "this is my first modification on my first-file" >> first_file.test
[root@shanghai ansible-first-project]# cat first_file.test
this is my first file on git repository
this is my first modification on my first-file
[root@shanghai ansible-first-project]# git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: first_file.test

no changes added to commit (use "git add" and/or "git commit -a")

#使用git restore 丢弃本次的修改
[root@shanghai ansible-first-project]# git restore first_file.test
[root@shanghai ansible-first-project]# git status
On branch master
nothing to commit, working tree clean
[root@shanghai ansible-first-project]# cat first_file.test
this is my first file on git repository

#换一条路走,直接git commit 提交之后
[root@shanghai ansible-first-project]# git commit -a -m 'first modification'
[master 07052a3] first modification
1 file changed, 1 insertion(+)
[root@shanghai ansible-first-project]# git status
On branch master
nothing to commit, working tree clean

#正常来说如果修改了git所在的track文件,那么就需要先git add,再git commit 提交。你也可以git commit -a 相当于自动的使用git add
[root@shanghai ansible-first-project]# git log
commit 07052a38b84932283b98f3e14dab19ec49ac5585 (HEAD -> master)
Author: zy <[email protected]>
Date: Sat May 22 21:37:50 2021 +0800

first modification

commit f252b369f0faeaae38e0c82b8143f507fddfa260
Author: zy <[email protected]>
Date: Sat May 22 21:25:53 2021 +0800

my first commit

#把文件从被git托管的状态中释放出来
[shanghai ansible-first-project(master)] $ git restore --staged test2

5、更加舒服的使用git

1
2
3
4
5
#建议在设备上都这样设置git
source /usr/share/git-core/contrib/completion/git-prompt.sh
export GIT_PS1_SHOWDIRTYSTATE=true #会显示出来*和+的,*意味着已跟踪的文件被修改,+表示已追踪文件被修改和被添加
export GIT_PS1_SHOWUNTRACKEDFILES=true #会显示出来%,意味着有未被追踪的文件
export PS1='\[\033[01;35m\][\[\033[01;32m\]\h\[\033[01;34m\] \W\[\033[31m\]$(__git_ps1 "(%s)")\[\033[01;35m\]] \[\033[01;34m\]$\[\033[00m\] '

6、时光穿梭机(git版本管理)

6.1、版本回退

1
2
3
4
5
6
7
8
9
10
11
12
13
[shanghai ansible-first-project(master)] $ git log --pretty=oneline 
07052a38b84932283b98f3e14dab19ec49ac5585 (HEAD -> master) first modification
f252b369f0faeaae38e0c82b8143f507fddfa260 my first commit

#git log 查看到的内容可以使用git reset来进行回滚,还可以通过git reflog查看你的操作行为,显示的HEAD的值来前进或者回滚你想到的任何版本

#回滚到上一个版本
[shanghai ansible-first-project(master)] $ git reset --hard HEAD^
HEAD is now at f252b36 my first commit

#通过git reflog查看HEAD值利用git reset可以回退到指定的版本
[shanghai ansible-first-project(master)] $ git reset --hard HEAD@{6}
HEAD is now at 07052a3 first modification

6.2、git工作区和暂存区

image-20210907111218693

image-20210907111230182

7、使用远程仓库

7.1 github的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
https://github.com/

#git remote add 表示添加远程仓库,origin表示你把远程仓库的名称当作什么
git remote add origin https://github.com/vorabend/do447.git

#修改分支的名字为main,—M表示重新设置分支的名字
git branch -M main

[shanghai ansible-first-project(master)] $ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = https://github.com/vorabend/do447.git
fetch = +refs/heads/*:refs/remotes/origin/*

#将本地的git仓库推送到远程的github仓库中,git push表示推送仓库,-u origin表示推送到远端的origin仓库,main表示推送的分支是谁
git push -u origin main
[HG git(master)] $ git push -u origin master
Username for 'https://github.com': vorabend
Password for 'https://[email protected]':
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (6/6), 382 bytes | 382.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/vorabend/do447.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

#此时再刷新网页就会看到上传到github上的文件

image-20210907111243636

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#把仓库从github上克隆下来
[HG git-ano] $ git clone https://github.com/vorabend/do447.git
Cloning into 'do447'...
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 6 (delta 0), reused 6 (delta 0), pack-reused 0
Unpacking objects: 100% (6/6), 362 bytes | 362.00 KiB/s, done.
[HG git-ano] $ pwd
/root/git-ano
[HG git-ano] $ cd do447/
[HG do447(master)] $ pwd
/root/git-ano/do447

[HG do447(master %)] $ touch file{5..8}
[HG do447(master %)] $ git add -A #—A表示把所有的文件都添加进去(暂存区)
[HG do447(master +)] $ git commit -m 'touch file5-file8'
[master e216a90] touch file5-file8
4 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file5
create mode 100644 file6
create mode 100644 file7
create mode 100644 file8
[HG do447(master)] $ git push
Username for 'https://github.com': vorabend
Password for 'https://[email protected]':
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 270 bytes | 270.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/vorabend/do447.git
ffccdd4..e216a90 master -> master

7.2码云的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[HG git(master)] $ git remote add mayun https://gitee.com/vorabend/do447.git
[HG git(master)] $ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = https://github.com/vorabend/do447.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[remote "mayun"]
url = https://gitee.com/vorabend/do447.git
fetch = +refs/heads/*:refs/remotes/mayun/*

#由于有两个仓库,必须指定一个仓库进行push,-u mayun 表示使用mayun这个仓库
[HG git(master)] $ git push -u mayun
Username for 'https://gitee.com': vorabend
Password for 'https://[email protected]':
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (10/10), 772 bytes | 772.00 KiB/s, done.
Total 10 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-5.0]
To https://gitee.com/vorabend/do447.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'mayun'.

8、git的分支管理

8.1 git分支的介绍

分支是为了将修改记录的整理流程分叉保存。分叉后的分支不受其他分支的影响,所以在一个数据库里可以同时进行多个修改。

image-20210907111258402

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#查看现在有一个叫master分支
[HG git(master)] $ git branch
* master

#创建一个zy的分支
[HG git(master)] $ git branch
* master
zy

#切换到zy分支(文件并没有什么变化,主分支文件是什么,这个分支文件也就是什么样的)
[HG git(master)] $ git switch zy
Switched to branch 'zy'
[HG git(zy)] $ git branch
master
* zy

[HG git(zy)] $ touch file11
[HG git(zy +)] $ git commit -m 'create file11'
[zy d075784] create file11
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file11

[HG git(master)] $ git log --pretty=oneline
aac4aac9325089ff210349a021f5fdb6049703c4 (HEAD -> master, origin/master, mayun/master) create file9
e216a9016ed9ed2e961e5836ca42d8d3bcba4a71 touch file5-file8
ffccdd46631283dcde06750223f34fe05ab13947 test1-1
849840a7a65605bff48b61f50c2ec2ed0385960a test1
[HG git(master)] $ git switch zy
Switched to branch 'zy'
[HG git(zy)] $ git log --pretty=oneline
d0757841169ff1ef69101ff834c74cb4d3cabf51 (HEAD -> zy) create file11
aac4aac9325089ff210349a021f5fdb6049703c4 (origin/master, mayun/master, master) create file9
e216a9016ed9ed2e961e5836ca42d8d3bcba4a71 touch file5-file8
ffccdd46631283dcde06750223f34fe05ab13947 test1-1
849840a7a65605bff48b61f50c2ec2ed0385960a test1

[HG git(zy)] $ git switch master
Switched to branch 'master'
Your branch is up to date with 'mayun/master'.
[HG git(master)] $ git merge zy #合并zy
Updating aac4aac..d075784
Fast-forward
file11 | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file11
[HG git(master)] $ ls
file11 file5 file6 file7 file8 file9 test1

[HG git(master)] $ git branch -d zy #删除zy这个分支
Deleted branch zy (was d075784).
[HG git(master)] $ git branch
* master