第1章 版本控制软件介绍
1.1 版本控制软件的作用
- 对程序代码或文件自动生成备份
- 可以知道每个版本对源文件的改动
- 可以随时回滚会历史版本
1.2 常见版本管理工具
1.2.1 SVN
SVN是集中式的版本控制系统,只有一个中央数据仓库,如果中央数据仓库挂了或者不可访问,所有的使用者无法使用SVN,无法进行提交或备份文件。
1.2.2 Git
Git是分布式的版本控制系统,在每个使用者电脑上就有一个完整的数据仓库,没有网络依然可以使用Git。当然为了习惯及团队协作,会将本地数据同步到Git服务器或者GitHub等代码仓库。
第2章 GIT安装配置
2.1 系统环境准备
[root@centos7 ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) [root@centos7 ~]# uname -r 3.10.0-327.el7.x86_64 [root@centos7 ~]# getenforce Disabled [root@centos7 ~]# systemctl status firewalld ● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled) Active: inactive (dead) [root@centos7 ~]# hostname -I 10.0.0.211 172.16.1.211
2.2 安装Git
[root@centos7 ~]# yum install -y git [root@centos7 ~]# rpm -qa git git-1.8.3.1-12.el7_4.x86_64
2.3 Git全局配置
[root@centos7 ~]# git config --global user.name "ly" # 配置git使用用户 [root@centos7 ~]# git config --global user.email [email protected] # 配置git使用邮箱 [root@centos7 ~]# git config --global color.ui true # 设置语法高亮 [root@centos7 ~]# git config --list # 查看全局配置 user.name=ly [email protected] color.ui=true # git配置后会在用户家目录下生成.gitconfig隐藏文件 [root@centos7 ~]# cat .gitconfig [user] name = ly email = [email protected] [color] ui = true
2.4 初始化Git工作目录
[root@centos7 ~]# mkdir -p git_data [root@centos7 ~]# cd git_data/ [root@centos7 git_data]# git init # 初始化Git Initialized empty Git repository in /root/git_data/.git/ [root@centos7 git_data]# git status # 查看工作区状态 # On branch master # # Initial commit # nothing to commit (create/copy files and use "git add" to track)
第3章 Git的常规使用
3.1 Git使用的步骤
- Git的常规使用主要分为三步(对于开发来说):
- 创建文件
- 将文件添加到暂存区域
- 将暂存区域的文件提交到本地仓库
3.1.1 代码实现
[root@centos7 git_data]# touch README # 创建文件 [root@centos7 git_data]# git status # On branch master # # Initial commit # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # README nothing added to commit but untracked files present (use "git add" to track) [root@centos7 git_data]# git add README # 将文件添加到暂存区域(或git add *增加所有文件) [root@centos7 git_data]# git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: README # [root@centos7 git_data]# git commit -m "this is first commit" # 将暂存区域的文件提交到本地仓库 [master (root-commit) 29d3077] this is first commit 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 README [root@centos7 git_data]# git status # On branch master nothing to commit, working directory clean
3.2 添加新文件
3.2.1 常规方法
git add * # 添加到暂存区域 git commit # 提交git仓库 -m 后面接上注释信息,内容关于本次提交的说明,方便自己或他人查看
3.2.2 简便方法
git commit -a -m "注释信息"
-
commit创建新文件示例
# 初始创建时需要先使用add命令才可以提交文件,不可直接使用-a进行提交 [root@centos7 git_data]# touch shadow [root@centos7 git_data]# git commit -a -m 'first' # 位于分支 master # 未跟踪的文件: # (使用 "git add <file>..." 以包含要提交的内容) # # shadow 提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪) [root@centos7 git_data]# git add shadow [root@centos7 git_data]# git commit -m 'first' [master cda13ff] first 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 shadow
-
commit修改新文件示例
# 修改或删除文件时可以直接使用-a参数代替add命令 [root@centos7 git_data]# echo "first" > shadow [root@centos7 git_data]# git commit -a -m 'second' [master deeae25] second 1 file changed, 1 insertion(+)
3.3 删除暂存区数据
- 没有添加到暂存区的数据直接rm删除即可。
- 已经添加到暂存区数据使用如下命令进行删除:
git rm --cached <file>...# 将文件从git暂存区域的追踪列表移除(并不会删除当前工作目录内的数据文件) git rm -f <file>... # 将文件数据从git暂存区和工作目录一起删除
-
删除文件错误做法
# 如果直接删除文件,在暂存区的文件会报错 [root@centos7 git_data]# touch leon [root@centos7 git_data]# git add leon [root@centos7 git_data]# git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: leon # [root@centos7 git_data]# rm -f leon [root@centos7 git_data]# git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: leon # # Changes not staged for commit: # (use "git add/rm <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # deleted: leon #
-
删除文件正确做法
# 需要使用git命令先从暂存区将文件删除再删除本地的文件 [root@centos7 git_data]# touch leon [root@centos7 git_data]# git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: leon # [root@centos7 git_data]# git reset HEAD leon # 或git rm --cached <file>... [root@centos7 git_data]# git status # On branch master # Untracked files: # (use "git add <file>..." to include in what will be committed) # # leon nothing added to commit but untracked files present (use "git add" to track) [root@centos7 git_data]# rm -f leon [root@centos7 git_data]# git status # On branch master nothing to commit, working directory clean
3.4 重命名暂存区数据
- 没有添加到暂存区的数据直接mv/rename改名即可。
- 已经添加到暂存区数据使用如下命令进行重命名:
git mv README NOTICE
3.5 查看历史记录
-
查看历史记录
# 查看1条历史记录 [root@centos7 git_data]# git log -1 commit b6fc7ba233269376072a785954985997e0dd0f9c Author: ly <[email protected]> Date: Wed Nov 8 10:47:27 2017 +0800 test # 查看所有历史记录 [root@centos7 git_data]# git log commit b6fc7ba233269376072a785954985997e0dd0f9c Author: ly <[email protected]> Date: Wed Nov 8 10:47:27 2017 +0800 test commit 29d3077cf9d3b4f6b2884af140d52a369b0aa5fb Author: ly <[email protected]> Date: Wed Nov 8 09:48:43 2017 +0800 this is first commit ...省略部分内容...
-
显示最近提交记录的差异
[root@centos7 git_data]# echo "test" > README [root@centos7 git_data]# git commit -a -m 'second' [master ba93b47] second 1 file changed, 1 insertion(+) [root@centos7 git_data]# git log -p -1 commit ba93b4726665af8bfdfe921cf497e2c4658970f9 Author: ly <[email protected]> Date: Wed Nov 8 10:53:54 2017 +0800 second diff --git a/README b/README index e69de29..9daeafb 100644 --- a/README +++ b/README @@ -0,0 +1 @@ +test index 0000000..e69de29
-
简要显示数据整改行数
[root@centos7 git_data]# git log --stat -1 commit ba93b4726665af8bfdfe921cf497e2c4658970f9 Author: ly <[email protected]> Date: Wed Nov 8 10:53:54 2017 +0800 second README | 1 + 1 file changed, 1 insertion(+)
-
按照指定的格式进行记录显示
[root@centos7 git_data]# git log --pretty=fomat:"%h %cn" fomat:ba93b47 ly fomat:b6fc7ba ly fomat:29d3077 ly
3.6 还原历史数据
Git服务程序中有一个叫做HEAD的版本指针,当用户申请还原数据时,其实就是将HEAD指针指向到某个特定的提交版本,但是因为Git是分布式版本控制系统,为了避免历史记录冲突,故使用了SHA-1计算出十六进制的哈希字串来区分每个提交版本,另外默认的HEAD版本指针会指向到最近的一次提交版本记录,而上一个提交版本会叫HEAD^,上上一个版本则会叫做HEAD^^,当然一般会用HEAD~5来表示往上数第五个提交版本。
-
文件回滚示例
# 创建多版本文件 [root@centos7 git_data]# echo "test3" > README [root@centos7 git_data]# git commit -a -m 'third' [master 1919114] third 1 file changed, 1 insertion(+), 1 deletion(-) [root@centos7 git_data]# echo "test4" > README [root@centos7 git_data]# git commit -a -m 'four' [master 0d7a244] four 1 file changed, 1 insertion(+), 1 deletion(-) [root@centos7 git_data]# echo "test5" > README [root@centos7 git_data]# git commit -a -m 'five' [master 39b5106] five 1 file changed, 1 insertion(+), 1 deletion(-) # 查看记录 [root@centos7 git_data]# git log commit 39b51068ec7acbe70636224ea0ddf62ee95d6038 Author: ly <[email protected]> Date: Wed Nov 8 11:04:30 2017 +0800 five commit 0d7a2446d0d07768ce65a508b67189d3162afc85 Author: ly <[email protected]> Date: Wed Nov 8 11:04:22 2017 +0800 four commit 1919114b1d96938ac5143f32c087d86b86776f70 Author: ly <[email protected]> Date: Wed Nov 8 11:04:11 2017 +0800 third commit ba93b4726665af8bfdfe921cf497e2c4658970f9 Author: ly <[email protected]> Date: Wed Nov 8 10:53:54 2017 +0800 second commit b6fc7ba233269376072a785954985997e0dd0f9c Author: ly <[email protected]> Date: Wed Nov 8 10:47:27 2017 +0800 test commit 29d3077cf9d3b4f6b2884af140d52a369b0aa5fb Author: ly <[email protected]> Date: Wed Nov 8 09:48:43 2017 +0800 this is first commit # 回滚历史版本 [root@centos7 git_data]# cat README test5 [root@centos7 git_data]# git reset --hard HEAD^ HEAD 现在位于 0d7a244 four [root@centos7 git_data]# cat README test4 [root@centos7 git_data]# git reset --hard HEAD~2 HEAD 现在位于 ba93b47 second [root@centos7 git_data]# cat README test [root@centos7 git_data]# git log --pretty=fomat:"%h %cn" fomat:ba93b47 ly fomat:b6fc7ba ly fomat:29d3077 ly [root@centos7 git_data]# git reset --hard b6fc7ba HEAD 现在位于 b6fc7ba test [root@centos7 git_data]# cat README [root@centos7 git_data]# git log commit b6fc7ba233269376072a785954985997e0dd0f9c Author: ly <[email protected]> Date: Wed Nov 8 10:47:27 2017 +0800 test commit 29d3077cf9d3b4f6b2884af140d52a369b0aa5fb Author: ly <[email protected]> Date: Wed Nov 8 09:48:43 2017 +0800 this is first commit
3.7 还原未来数据
未来数据就是当我们还原到历史数据,想撤销更改时,使用git log命令已经找不到这个版本的文件,这个找不到的文件就是未来数据。
-
还原未来数据
# 查看所有版本数据 [root@centos7 git_data]# git reflog b6fc7ba HEAD@{0}: reset: moving to b6fc7ba ba93b47 HEAD@{1}: reset: moving to HEAD~2 0d7a244 HEAD@{2}: reset: moving to HEAD^ 39b5106 HEAD@{3}: commit: five 0d7a244 HEAD@{4}: commit: four 1919114 HEAD@{5}: commit: third ba93b47 HEAD@{6}: commit: second b6fc7ba HEAD@{7}: commit: test 29d3077 HEAD@{8}: commit (initial): this is first # 还原未来数据 [root@centos7 git_data]# git reset --hard 39b5106 HEAD 现在位于 39b5106 five [root@centos7 git_data]# cat README test5
3.8 标签使用
前面回滚使用的是一串字符串,又长又难记,标签相当于一个别名,可以让我们不用查找commit编码,直接快速地还原到我们想要的版本。
-
打标签示例
[root@centos7 git_data]# git tag v20171108 [root@centos7 git_data]# git reset --hard ba93 HEAD 现在位于 ba93b47 second [root@centos7 git_data]# cat README test [root@centos7 git_data]# git reset --hard v20171108 HEAD 现在位于 39b5106 five [root@centos7 git_data]# cat README test5
-
给所有版本的文件打标签
[root@centos7 git_data]# git reset --hard 0d7a HEAD 现在位于 0d7a244 four [root@centos7 git_data]# git tag v4.0-20171107 [root@centos7 git_data]# git reset --hard v20171108 HEAD 现在位于 39b5106 five [root@centos7 git_data]# cat README test5 [root@centos7 git_data]# git reset --hard v4.0-20171107 HEAD 现在位于 0d7a244 four [root@centos7 git_data]# cat README test4 [root@centos7 git_data]# git tag v20171108 v4.0-20171107
3.9 对比数据
git diff可以对比当前文件与仓库已保存文件的区别,知道了对README作了什么修改后,再把它提交到仓库就放 多了。
-
对比数据
[root@centos7 git_data]# git diff ba93b47 1919114 diff --git a/README b/README index 9daeafb..df6b0d2 100644 --- a/README +++ b/README @@ -1 +1 @@ -test +test3
第4章 分支结构
在实际的项目开发中,尽量保证master分支稳定,仅用于发布新版本,平时不要随便直接修改里面的数据文件。
修改都在dev分支上。每个人从dev分支创建自己个人分支,开发完合并到dev分支,最后dev分支合并到master分支。
如下图所示:
4.1 创建/切换分支
[root@centos7 git_data]# git branch linux # 创建分支 [root@centos7 git_data]# git branch linux * master [root@centos7 git_data]# git checkout linux # 切换分支 切换到分支 'linux' [root@centos7 git_data]# git branch # 查看当前分支情况,当前分支前有*号 * linux master # 在新的分支操作不会影响其他分支的数据 [root@centos7 git_data]# ls leon README [root@centos7 git_data]# cat README test4 [root@centos7 git_data]# echo linux >> README [root@centos7 git_data]# git commit -a -m 'linux branch' [linux 57c8155] linux branch 1 file changed, 1 insertion(+) [root@centos7 git_data]# cat README test4 linux [root@centos7 git_data]# git log -1 commit 57c8155aeb87afbb74ec7c8e257c74654878246d Author: ly <[email protected]> Date: Wed Nov 8 11:59:45 2017 +0800 linux branch [root@centos7 git_data]# git checkout master 切换到分支 'master' [root@centos7 git_data]# cat README test4
4.2 合并分支
[root@centos7 git_data]# git branch linux * master [root@centos7 git_data]# git merge linux 更新 0d7a244..57c8155 Fast-forward README | 1 + 1 file changed, 1 insertion(+) [root@centos7 git_data]# git log -1 commit 57c8155aeb87afbb74ec7c8e257c74654878246d Author: ly <[email protected]> Date: Wed Nov 8 11:59:45 2017 +0800 linux branch [root@centos7 git_data]# cat README test4 liux
4.2.1 制造冲突
多个分支中有两个或两个以上的人对文件的同一行进行修改后,合并文件就会产生冲突:
[root@centos7 git_data]# cat README test4 linux [root@centos7 git_data]# echo "master branch" >> R EADME [root@centos7 git_data]# git commit -a -m 'master branch' [master 6267612] master branch 1 file changed, 1 insertion(+) [root@centos7 git_data]# git checkout linux 切换到分支 'linux' [root@centos7 git_data]# cat README test4 linux [root@centos7 git_data]# echo "linux branch" >> README [root@centos7 git_data]# git commit -a -m 'linux branch' [linux 3004c98] linux branch 1 file changed, 1 insertion(+) [root@centos7 git_data]# git checkout master 切换到分支 'master' [root@centos7 git_data]# git merge linux 自动合并 README 冲突(内容):合并冲突于 README 自动合并失败,修正冲突然后提交修正的结果。
4.3 解决冲突
手动编辑合并后的文件,将要保留的代码保留,其他的删除掉即可:
[root@centos7 git_data]# cat README test4 linux <<<<<<< HEAD # master分支的代码 master branch ======= linux branch >>>>>>> linux # linux(分支名)分支的代码 [root@centos7 git_data]# vim README test4 linux master branch [root@centos7 git_data]# git commit -a -m 'master branch' [master a7d87e5] master branch
第5章 附录
5.1 Git命令解析
5.1.1 常用命令
[root@centos7 git_data]# git --help 用法:git [--version] [--help] [-c name=value] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path] [-p|--paginate|--no-pager] [--no-replace-objects] [--bare] [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>] <command> [<args>]
最常用的 git 命令有: add 添加文件内容至索引 bisect 通过二分查找定位引入 bug 的变更 branch 列出、创建或删除分支 checkout 检出一个分支或路径到工作区 clone 克隆一个版本库到一个新目录 commit 记录变更到版本库 diff 显示提交之间、提交和工作区之间等的差异 fetch 从另外一个版本库下载对象和引用 grep 输出和模式匹配的行 init 创建一个空的 Git 版本库或重新初始化一个已存在的版本库 log 显示提交日志 merge 合并两个或更多开发历史 mv 移动或重命名一个文件、目录或符号链接 pull 获取并合并另外的版本库或一个本地分支 push 更新远程引用和相关的对象 rebase 本地提交转移至更新后的上游分支中 reset 重置当前HEAD到指定状态 rm 从工作区和索引中删除文件 show 显示各种类型的对象 status 显示工作区状态 tag 创建、列出、删除或校验一个GPG签名的 tag 对象 命令 'git help -a' 和 'git help -g' 显示可用的子命令和一些指南。参见 'git help <命令>' 或 'git help <指南>' 来查看给定的子命令帮助或指南。
5.1.2 commit命令常用参数
SYNOPSIS git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend] [--dry-run] [(-c | -C | --fixup | --squash) <commit>] [-F <file> | -m <msg>] [--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [-S[<keyid>]] [--] [<file>...]
- -a:表示直接提交,在修改或删除已经提交过的文件时使用此参数可以省略add命令,但是在新创建文件时不可直接使用此参数进行提交,依然需要使用add命令先放入暂存区后再提交。
- -m:设置此版本的备注信息,方便后期查看。
5.1.3 rm命令常用参数
SYNOPSIS git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>...
- -f:将文件数据从git暂存区和工作目录一起删除
- --cached:将文件从git暂存区域的追踪列表移除(并不会删除当前工作目录内的数据文件)
5.1.4 mv命令常用参数
SYNOPSIS git mv <options>... <args>...
5.1.5 log命令常用参数
SYNOPSIS git log [<options>] [<revision range>] [[--] <path>...]
- 参数解析:
git log # 查看提交历史记录,只显示当前版本之前版本的信息 git log -2 # 查看最近几条记录 git log -p -1 # -p显示每次提交的内容差异,例如仅查看最近一次差异 git log --stat -2 # --stat简要显示数据增改行数,这样能够看到提交中修改过的内容,对文件添加或移动的行数,并在最后列出所有增减行的概要信息 git log --pretty=oneline # --pretty根据不同的格式展示提交的历史信息 git log --pretty=fuller -2 # 以更详细的模式输出提交的历史记录 git log --pretty=fomat:"%h %cn" # 查看当前所有提交记录的简短SHA-1哈希字串与提交着的姓名,其他格式见备注。 # 还可以使用format参数来指定具体的输出格式,这样非常便于后期编程的提取分析哦,常用的格式有: %s 提交说明。 %cd 提交日期。 %an 作者的名字。 %cn 提交者的姓名。 %ce 提交者的电子邮件。 %H 提交对象的完整SHA-1哈希字串。 %h 提交对象的简短SHA-1哈希字串。 %T 树对象的完整SHA-1哈希字串。 %t 树对象的简短SHA-1哈希字串。 %P 父对象的完整SHA-1哈希字串。 %p 父对象的简短SHA-1哈希字串。 %ad 作者的修订时间。
5.1.6 reset命令常用参数
SYNOPSIS git reset [-q] [<tree-ish>] [--] <paths>... git reset (--patch | -p) [<tree-sh>] [--] [<paths>...] git reset [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]
- 参数解析:
git reset --hard HEAD^ # 还原历史提交版本上一次 git reset --hard 3de15d4 # 找到历史还原点的SHA-1值后,就可以还原(值不写全,系统会自动匹配)
5.1.7 reflog命令常用参数
SYNOPSIS git reflog <subcommand> <options>
5.1.8 tag命令常用参数
SYNOPSIS git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] <tagname> [<commit> | <object>] git tag -d <tagname>... git tag [-n[<num>]] -l [--contains <commit>] [--points-at <object>] [--column[=<options>] | --no-column] [<pattern>...] [<pattern>...] git tag -v <tagname>...
- 参数解析:
git tag v1.0 # 当前提交内容打一个标签(方便快速回滚),每次提交都可以打个tag。 git tag # 查看当前所有的标签 git show v1.0 # 查看当前1.0版本的详细信息 git tag v1.2 -m "version 1.2 release is test" # 创建带有说明的标签,-a指定标签名字,-m指定说明文字 git tag -d v1.0 # 我们为同一个提交版本设置了两次标签,删除之前的v1.0
5.1.9 diff命令常用参数
SYNOPSIS git diff [options] [<commit>] [--] [<path>...] git diff [options] --cached [<commit>] [--] [<path>...] git diff [options] <commit> <commit> [--] [<path>...] git diff [options] <blob> <blob> git diff [options] [--no-index] [--] <path> <path>
5.1.10 branch命令常用参数
SYNOPSIS git branch [--color[=<when>] | --no-color] [-r | -a] [--list] [-v [--abbrev=<length> | --no-abbrev]] [--column[=<options>] | --no-column] [(--merged | --no-merged | --contains) [<commit>]] [<pattern>...] git branch [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>] git branch (--set-upstream-to=<upstream> | -u <upstream>) [<branchname>] git branch --unset-upstream [<branchname>] git branch (-m | -M) [<oldbranch>] <newbranch> git branch (-d | -D) [-r] <branchname>... git branch --edit-description [<branchname>]
- 参数解析:
git branch linux # 创建分支 git checkout linux # 切换分支 git branch # 查看当前分支情况,当前分支前有*号 git branch -d linux # 确认合并完成后,可以放心地删除Linux分支。
5.1.11 merge命令常用参数
SYNOPSIS git merge [-n] [--stat] [--no-commit] [--squash] [--[no-]edit] [-s <strategy>] [-X <strategy-option>] [--[no-]rerere-autoupdate] [-m <msg>] [<commit>...] git merge <msg> HEAD <commit>... git merge --abort
- 参数解析:
git merge linux # 合并Linux分支至master
