Jusene's Blog

Git 分布式版本控制

字数统计: 2.5k阅读时长: 11 min
2017/08/06 Share

Git

Git算是出身名门,它是一款免费、开源的分布式版本控制系统,用于敏捷高效地处理任何大小的项目管理,最初是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开源的版本控制软件,如今因为Git造就了世界上最大的代码托管网站Github,更有社区的GitLab使用。

版本控制工具

  • 本地版本控制系统:git
  • 集中化版本控制系统:svn
  • 分布式版本控制系统:git

git与svn的相比,区别很明显,git是分布式的,而svn是集中式的,git的分布式设计使每个人本地都存在一个本地仓库,所以即使没有网络我们一样可以commit,等有网络的时候我们再push上服务端,而svn则必须有网络,svn版本库只能有一个指定版本库,当这个版本库有问题的时候,所以工作都将瘫痪,而git却有无数个版本库,每一个git用户都有一个完整的版本库,很容易就可以恢复git版本库,总体来说svn比git容易,但是git可以不依赖网络做任何事情,对分支和合并有更好的支持(当然这是开发者最关心的地方)。

git配置

git的配置命令: git config

  • 仓库特有:REPO/.git/config git config
  • 全局:~/.gitconfig git config --global
  • 系统:/etc/git/gitconfig git config --system

可以通过git config -l查看当前的配置
必要的配置:

1
git config --global user.email "you@example.com"
2
git config --global user.name "Your Name"

git仓库

git可以分为三个区域:工作区,暂存区(索引),版本库(对象库)

  • 工作区: 编写代码的区域,可以使用git init创建一个空仓库
  • 暂存区: 将代码文件设置为追踪文件,可以使用git add来添加追踪文件,可以使用git status来查看文件追踪状态
  • 版本库: 将索引与文件版本快照对应关系,并形成树对象结构,可以使用git commit提交

git的对象类型:

  • 块(blob)对象:文件的每个版本表现为一个块(blob)
  • 树(tree)对象:一个目录树代表一层目录信息
  • 提交(commit)对象:用于保存版本库一次变化的元数据,包括作者、邮箱、提交日期、日志;每个提交对象都指定一个目录树对象
  • 标签(tag)对象:用于给一个特定对象一个易读的名称

查看索引中文件:

1
~]# git ls-files
2
install
3
readme
4
~]# git ls-files -s
5
100644 f8d728c11926d350cbe480b05a4f835f6bad03d5 0       install
6
100644 528a57553a7329f504c3fc7fcfb16aeb58bdd7ca 0       readme
7
~]# git cat-file -p f8d728c11926d350cbe480b05a4f835f6bad03d5
8
www
9
~]# git cat-file -t f8d728c11926d350cbe480b05a4f835f6bad03d5
10
blob

git的文件分类:

  • 已追踪的(tracked):已经在版本库中,或者已经使用git add命令添加至索引中的文件

  • 被忽略的(ignore):在版本库中通过“忽略文件列表”明确声明为被忽略的文件

  • 未追踪的(untracked):上述两类之外的其他文件

  • git add:暂存文件:
    可以使用git ls-files查看:默认显示索引或工作目录中的文件列表,而且为原始文件

  • s:显示暂存的文件信息:权限、对象名、暂存号及原始文件名

  • o:显示未被追踪的文件
    如果想要忽略文件,需要创建.gitignore,里面支持忽略列表,支持*通配,!反选,/目录

  • git rm:删除文件与暂处区的文件,版本库中的无法删除

  • f: 未提交,强行删除

  • -cached:只删除暂存区的文件

  • git mv:改变工作目录及索引中的映射

  • git提交:
    git commit -m “COMMIT_NAME”
    git log:查看提交日志

提交标识:
引用:ID,reference,SHA1,绝对提交名
符号引用:symbolic reference,symref
本地特性分支名称、远程跟踪分支名称、标签名;
名称:

  • refs/heads/REF:本地特性分支名称
  • refs/remote/REF:远程跟踪分支名称
  • refs/tags/REF:标签名

git会自动维护几个特定的特殊符号引用:

  • HEAD:始终指向当前分支的最近提交;或检出到其他分支时,目标分支的最近提交
  • ORGIN_HEAD:合并操作时,新生成的提交之前的提交保存于此引用中
  • FETCHED_HEAD:
  • MERGE_HEAD:合并操作时,其他分支的一次提交

相对提交名:
^:C6^(C5),C6^2(C5-DEV)
:C6(C5),C6~2(C4)

  • git diff:
    git diff:比较索引于工作目录的不同
    git diff –cached:比较索引与最近提交的不同
    git diff commit1 commit2:比较最精两次提交的不同
    git diff HEAD:比较工作目录与最近一次提交的不同

  • git reset

  • -soft:将HEAD引用指向给定的提交,但不影响索引和工作目录

  • -mixed:将HEAD应用指向给定的提交,并将索引内容改变为提交的快照;但不影响工作目录

  • -hard:将HEAD应用指向给定的提交,并将索引内容改变为提交的快照;并改变工作目录中的内容反映指定提交的内容

git 分支

分支是每个版本控制软件必须要实现的功能,它有利于灰度开发,在master开发线出现bug时,创建出一个新的分支,而不影响master上的功能,能分支修复bug时,合并分支与master的代码,提交成一个新的稳定版本。

git 分支命名格式:

  • 可以使用/,但不能以/结尾
  • 不能以-开头
  • 以位于/后面的组件,不能以.开头
  • 不能使用连续的…
  • 不能使用空白字符
  • 不能使用^,-,?,*,[等
  • 必须唯一;分支名字始终指向目标分支的最近一次提交

git branch:

1
~]# git branch
2
* master
3
~]# git log
4
commit af6354c62cf3223a3722e60d0a48f28dd1a7e22d
5
Author: zgx <zgx@123.com>
6
Date:   Tue Jul 25 18:40:32 2017 +0800
7
8
    v3
9
10
commit 805934e19a9ef565ad73654f9c43ba66c66cbf61
11
Author: zgx <zgx@123.com>
12
Date:   Tue Jul 25 18:38:26 2017 +0800
13
14
    v2
15
16
commit 285a1d4ca7b5eebeed490bbd10dc2e3c16268019
17
Author: zgx <zgx@123.com>
18
Date:   Tue Jul 25 13:54:46 2017 +0800
19
20
    v2
21
22
commit d5824058338089b5f5300f5a121e49fcf07b357f
23
Author: zgx <zgx@123.com>
24
Date:   Tue Jul 25 13:42:35 2017 +0800
25
26
    v1
27
28
~]# git branch dev     默认基于最后一次提交创建分支
29
~]# git branch dev2 d5824058338089b5f5300f5a121e49fcf07b357f   基于v1版本创建分支
30
~]# git show-branch
31
! [dev] v3
32
 ! [dev2] v1
33
  * [master] v3
34
---
35
+ * [dev] v3
36
+ * [dev^] v2
37
+ * [dev~2] v2
38
++* [dev2] v1
39
40
~]# git branch -d dev2   删除分支
41
Deleted branch dev2 (was d582405).
42
43
44
~]# git branch
45
  dev
46
* master
47
~]# git checkout dev
48
Switched to branch 'dev'
49
~# git branch      
50
* dev
51
  master
52
53
~]# touch 2.txt
54
~]# git add .
55
~]# git commit -m "v4"
56
[dev 2926720] v4
57
 1 file changed, 1 insertion(+)
58
 create mode 100644 2.txt
59
~]# git log
60
commit 292672053981716efadbb0981d75e9613100ea98
61
Author: zgx <zgx@123.com>
62
Date:   Tue Jul 25 18:47:39 2017 +0800
63
64
    v4
65
66
commit af6354c62cf3223a3722e60d0a48f28dd1a7e22d
67
Author: zgx <zgx@123.com>
68
Date:   Tue Jul 25 18:40:32 2017 +0800
69
70
    v3
71
72
commit 805934e19a9ef565ad73654f9c43ba66c66cbf61
73
Author: zgx <zgx@123.com>
74
Date:   Tue Jul 25 18:38:26 2017 +0800
75
76
    v2
77
78
commit 285a1d4ca7b5eebeed490bbd10dc2e3c16268019
79
Author: zgx <zgx@123.com>
80
Date:   Tue Jul 25 13:54:46 2017 +0800
81
82
    v2
83
84
commit d5824058338089b5f5300f5a121e49fcf07b357f
85
Author: zgx <zgx@123.com>
86
Date:   Tue Jul 25 13:42:35 2017 +0800
87
88
    v1
89
~]# git checkout master
90
~]# ls
91
1.txt  install  readme
92
~]# git log
93
commit af6354c62cf3223a3722e60d0a48f28dd1a7e22d
94
Author: zgx <zgx@123.com>
95
Date:   Tue Jul 25 18:40:32 2017 +0800
96
97
    v3
98
99
commit 805934e19a9ef565ad73654f9c43ba66c66cbf61
100
Author: zgx <zgx@123.com>
101
Date:   Tue Jul 25 18:38:26 2017 +0800
102
103
    v2
104
105
commit 285a1d4ca7b5eebeed490bbd10dc2e3c16268019
106
Author: zgx <zgx@123.com>
107
Date:   Tue Jul 25 13:54:46 2017 +0800
108
109
    v2
110
111
commit d5824058338089b5f5300f5a121e49fcf07b357f
112
Author: zgx <zgx@123.com>
113
Date:   Tue Jul 25 13:42:35 2017 +0800
114
115
    v1
116
117
dev分支中提交的文件在master互不影响
118
当时如果在分支中创建的文件未添加微追踪文件并提交,这样如果在切换回master,该文件在master中也是可见的,并且如果文件名重名的话会报错。

git 分支合并

git merge

  • 合并基础:要合并的分支最近的一次共同提交
  • 我们的版本:当前分支的最近一次提交
  • 它们的版本:要合并进来的分支的最近一次提交
  1. 无冲突合并

    1
    ~]# git checkout master
    2
    ~]# git status  检查是否有未提交的暂存文件
    3
    ~]# git merge dev
    4
    Updating af6354c..2926720
    5
    Fast-forward
    6
     2.txt | 1 +
    7
     1 file changed, 1 insertion(+)
    8
     create mode 100644 2.txt
    9
    ~]# ls
    10
    1.txt  2.txt  install  readme
    11
    12
    该基础是机遇两个分支无修改相同的文件,可以正常的无冲突合并。
  2. 冲突合并

    1
    我们两个分支先修改1.txt的内容,并且追踪提交
    2
    ~]# git checkout master
    3
    ~]#  git merge dev
    4
    Auto-merging 1.txt
    5
    CONFLICT (content): Merge conflict in 1.txt
    6
    Automatic merge failed; fix conflicts and then commit the result.
    7
    8
    9
    这里我们需要手动解决冲突,解决后再提交一次即可。
    10
    ~]# cat 1.txt
    11
    <<<<<<< HEAD
    12
    sssssss
    13
    =======
    14
    xxxxxxx
    15
    >>>>>>> dev
    16
    ~]# cat 1.txt
    17
    xxxxxxx
    18
    ~]# git add .
    19
    ~]# git commit -m 'v6'
    20
    ~]# [master 346d87e] v6
    21
     git log --graph --pretty=oneline --abbrev-commit
    22
    *   346d87e v6
    23
    |\  
    24
    | * 9e3a894 v5
    25
    * | a3ae690 v5
    26
    |/  
    27
    * 2926720 v4
    28
    * af6354c v3
    29
    * 805934e v2
    30
    * 285a1d4 v2
    31
    * d582405 v1
  3. 撤销合并

    1
    ~]# git reset --hard ORGIN_HEAD

git 远程代码库

远程代码库:

1
~]# yum install -y git httpd
2
~]# mkdir /var/www/git
3
~]# cd /var/www/git
4
~]# git init --bare myproject.git
5
~]# chown -R apache.apache /var/www/git
6
~]# git config http.receivepack true
7
~]# httpd -M | grep -Ei "^[[:space:]](alias|env|cgi)"
8
 alias_module (shared)
9
 env_module (shared)
10
 cgi_module (shared)
11
~]# vim /etc/httpd/conf.d/git.conf
12
<VirtualHost *:80>
13
        ServerName git.jusene.me
14
        SetEnv GIT_PROJECT_ROOT /var/www/git
15
        SetEnv GIT_HTTP_EXPORT_ALL
16
        ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
17
        <Directory "/usr/libexec/git-core">
18
                Options ExecCGI Indexes
19
                Require all granted
20
        </Directory>
21
        <LocationMatch "^/git/.*/git-receive-pack$">
22
                AuthType Basic
23
                AuthName "Private Git Repo"
24
                AuthUserFile /etc/httpd/conf/.httpd
25
                Require valid-user
26
        </LocationMatch>
27
</VirtualHost>
28
~]# systemctl start httpd
29
~]# htpasswd -c -m /etc/httpd/conf/.httpd zgx

克隆到本地版本库:

1
~]# git clone http://git.jusene.me/git/myproject.git
2
Cloning into 'myproject'...
3
remote: Counting objects: 21, done.
4
remote: Compressing objects: 100% (13/13), done.
5
remote: Total 21 (delta 2), reused 0 (delta 0)
6
Unpacking objects: 100% (21/21), done.
7
~]# cd myproject
8
~]# touch mytest
9
~]# git add .
10
~]# git commit -m "v1"
11
~]# git push origin master
12
Counting objects: 17, done.
13
Delta compression using up to 2 threads.
14
Compressing objects: 100% (11/11), done.
15
Writing objects: 100% (16/16), 1.33 KiB | 0 bytes/s, done.
16
Total 16 (delta 2), reused 0 (delta 0)
17
Username for 'http://10.211.55.39': zgx
18
Password for 'http://zgx@10.211.55.39': 
19
To http://10.211.55.39/git/test.git
20
   285a1d4..346d87e  master -> master
CATALOG
  1. 1. Git
  2. 2. 版本控制工具
  3. 3. git配置
  4. 4. git仓库
  5. 5. git 分支
  6. 6. git 分支合并
  7. 7. git 远程代码库