用Git进行版本控制
1. 什么是版本控制?
1.1 版本控制的定义
版本控制:是指对软件开发过程中各种程序代码、配置文件及说明文档等文件变更的管理。
三大最热门的版本控制系统:Git,Subversion,Mercurial
版本控制系统模型:
- 集中式模型-所有用户都连接到一个中央的主仓库(master repository)
- 分布式模型-每个用户都在自己的计算机上拥有完整的仓库
小结:版本控制系统的主要目的是帮助保留项目的详细历史记录,并且能够在不同的版本上进行工作。
1.2 Git和版本控制术语
版本控制系统/源代码管理器
版本控制系统(简称VCS)是一个管理源代码不同的工具。源代码管理器(简称SCM)是版本控制系统的别称。
提交(Commit)
Git将数据看做微型文件系统的一组快照。每次commit(在Git中保持项目状态),它都会对文件当时的状况拍照,并存储对该快照的引用。
仓库(Repository/repo)
仓库是一个包含项目内容以及几个文件的目录,用来与Git进行通信。仓库可以存储在本地,或作为远程副本存储在其他计算机上。仓库是由commit构成的。
工作目录/工作区(Working Directory)
工作目录是在计算机的文件系统中看到的文件。与这些文件形成对比的是保持在仓库中(在commit中!)的文件。
在使用Git时,工作目录与命令行工具的current working directory(当前工作目录)不一样,后者是shell当前正在查看的目录。
检出(Check out)
检出是指将仓库中的内容复制到工作目录下。
暂存区/暂存索引/索引(Staging Area/Staging Index/Index)
Git目录下的一个文件,存储的是即将进入下个commit内容的信息。可以将暂存区看做准备工作台,Git将在此区域获取下个commit。暂存索引中的文件是准备添加到仓库中的文件。
SHA
SHA的全称是“Secure Hash Algorithm”(安全哈希算法),它是一个长40个字符的字符串(由0-9和a-f组成),并根据Git中的文件或目录结构的内容计算得出。
分支(Branch)
分支是从主开发流程中分支出来的新的开发流程。这种分支开发流程可以在不更改主流程的情况下继续延伸下去。
1.3 Git设置步骤
初次配置Git
#设置你的Git用户名
git config --global user.name "<Your-Full-Name>"
#设置你的Git邮箱
git config --global user.email "<your-email-address>"
#确保Git输出内容带有颜色标记
git cinfig --global color.ui auto
#对比显示原始状态
git config --global merge.conflictstyle diff3
git config --list
Git与代码编辑器
Atom Editor设置
git config --global core.editor "atom --wait"
Sublime Text设置
git config --global core.editor "'C:/Program Files/Sublime Text 2/sublime_text.exe' -n -w"
VSCode设置
git config --global core.editor "code --wait"
2.创建Git仓库
在对Git仓库进行commit或执行任何其他操作之前,需要一个实际存在的仓库。要使用Git新建一个仓库,这将使用git init
命令。
init
子命令是“initialize”(初始化)的简称,它将进行所以仓库初始化设置。
注(需要使用的终端命令):
ls
-列出文件和目录mkdir
-新建目录cd
-更改目录rm
-删除文件和目录
2.1 从头创建仓库
2.1.1 创建课程目录
git init
开始使用git init命令,该命令会在当前目录下初始化生成一个空的Git仓库。
git init命令的作用
运行git init命令会初始化Git跟踪所有内容会用到的所有必要文件和目录。所以这些文件都存储在叫做 .git 的目录下。.git目录是一个库 ,Git会将所有commit记录在这里,并跟踪所有内容!.git目录是仓库的核心/存储中心。
.git 目录内容
- config 文件-存储累所有与项目有关的配置设置。
- description 文件-此文件仅用于GitWeb程序,因此可以忽略
- hooks 目录-在此放置客户端或服务器端脚本,以便用来连接到Git的不同生命周期事件
- info 目录-包含全局排除文件
- objects 目录-此目录将存储提交的所有commit
- refs 目录-此目录存储累指向commit的指针(通常是“分支”和“标签”)
2.2 克隆现有仓库
在Git上进行克隆的方法是在终端上运行git clone
命令,然后传入要克隆的Git仓库的路径(通常是URL)。
验证终端位置:在克隆任何内容之前,需确保命令行工具已定位于正确的目录下,并确保终端的当前工作目录没有位于Git仓库中。输入pwd
输出工作目录。
在使用git clone
命令克隆仓库时,会为仓库新建一个目录,但不会改变shell的工作目录。它会在当前工作目录下创建新的仓库,要确保使用 cd
命令切换到新的仓库中。
git clone
命令:
- 获取现有仓库的路径
- 默认地将创建一个与被克隆的仓库名称相同的目录
- 可以提供第二个参数,作为该目录的名称
- 将在现有工作目录下创建一个新的仓库
2.3 判断仓库的状态
git status
是了解Git的核心所在。它将告诉我们Git正在考虑什么,以及Git所看到的我们仓库的状态。
git status
命令:
- 告诉我们已在工作目录中被创建但Git尚未开始跟踪的新文件
- Git正在跟踪的已修改文件
3.查看仓库的历史记录
3.1 显示仓库的commit
git log
命令用于显示仓库中所有commit的信息。
默认情况下,该命令会显示仓库中每个commit的:
- SHA
- 作者
- 日期
- 消息
3.2 更改git log显示信息的方式
git log --oneline
可以用来更改仓库信息的显示方式。
要回到普通的命令提示符应该按下键盘上的q键。
git log --oneline
命令:
- 每行显示一个commit
- 显示commit的SHA的前7个字符
- 显示commit的消息
3.3 查看修改后的文件
git log --stat
可以用来显示commit中更改的文件以及添加或删除的行数。
git log --stat
命令:
- 显示被修改的文件
- 显示添加/删除的行数
- 显示一个摘要,其中包含修改/删除的总文件数和总行数
3.4 查看文件更改
git log -p
可以来显示对文件作出实际更改的选项。
git log -p --stat
同时显示两种信息,并且统计信息显示在补丁信息上方。
git log -p -w
将显示补丁信息,但是不会突出显示仅更改了空格的行。
git log -p
命令会向默认输出中添加以下信息:
- 显示被修改的文件
- 显示添加/删除的行所在的位置
- 显示做出的实际更改
3.5 查看特定的commit
git show
显示特定commit的命令。git show
和git log -p
命令完全一样。默认情况下,git show
会显示:
- commit
- 作者
- 日期
- commit消息
- 补丁信息
4.向仓库中添加commit
4.1 git add
git add
命令用于将文件从工作目录移到暂存区。
git add
命令:
- 可接受多个文件名(用空格分隔)
- 此外,可以使用句点“.”来代替文件列表,告诉git添加当前目录至暂存区(以及所有嵌套文件)
4.2 git commit
要在git中提交commit,需要使用git commit
命令。
使用-m
选项绕过编辑器
若编写的提交说明很简短,不想等打开代码编辑器后再输入信息,可以直接在命令行中使用-m
选项传入信息
git commit
命令会取出暂存区的文件并保存到仓库中。
git commit
命令:将打开配置中指定的代码编辑器。
在代码编辑器中:
- 必须提供提交说明
- 以 # 开头的行是注释,将不会被记录
- 添加提交说明后保存文件
- 关闭编辑器以进行提交
4.3 git diff
git diff
命令可以用来查看已被加入但是尚未提交的更改。
git duff
命令会显示:
- 已经修改的文件
- 添加/删除的行所在的位置
- 执行的实际更改
gitignore
若想将某个文件保留在项目的目录结构中,但是确保它不会意外地提交到项目中,可以使用名称特殊的文件.gitignore
。
通配符
通配符允许使用特殊的字符来表示某些格式/字符。在.gitignore
文件中,可以使用:
- 空白行作为空格
- #-将行标记为注释
- *-与0或多个字符匹配
- ?-与1个字符匹配
- [abc] -与a、b或c匹配
- ** -与嵌套目录匹配
5.标签、分支和合并
5.1 标签
git tag 命令
使用git tag
命令与仓库的标签进行交互
在git tag -a v1.0
中,使用-a
选项,该选项告诉git创建一个带注释的标签,若没有提供该选项(即git tag v1.0
),那么它将创建一个轻量级标签。
建议使用带注释的标签,因为标注可包含大量额外信息:
- 标签创建者
- 标签创建日期
- 标签信息
git log的–decorate选项
--decorate
选项将显示默认视图隐藏起来的一些详情。
删除标签
通过输入-d
选项加上标签名称来删除git标签
向以前的commit添加标签
若需要向仓库中很久之前的Commit添加标签,只需要提供要添加标签的commit的SHA即可
5.2 分支
git branch命令
git branch
命令用来与git的分支进行交互,它可以用来:
- 列出仓库中的所有分支名称
- 创建新的分支
- 删除分支
创建分支
要创建分支,只需使用git branch
并提供要创建的分支对于的名称
git checkout命令
在分支之间进行切换,需要使用git的checkout命令。
git checkout
工作方式:
- 从工作目录中删除git跟踪的所有文件和目录(git跟踪的文件存储在仓库中,因此什么也不会丢失)
- 转到仓库,并提取分支指向的commit所对应的所有文件和目录
此命令将删除master分支中的commit引用的所有文件。它会将这些文件替换为sidebar分支中的commit引用的文件
活跃分支
提示符将显示活跃分支。活跃分支名称旁边会显示一个星号。
删除分支
使用-d
选项,但无法删除当前所在的分支。
如果某个分支上有任何其他分支上都没有包含的commit(也就是这个commit是要被删除的分支独有的),git不会删除该分支。
5.3 合并
合并指令
git merge
指令用来合并git分支,发生合并是,git将:
- 查看将合并的分支
- 查看分支的历史记录并寻找两个分支的commit历史记录中都有的单个commit
- 将单个分支上更改的代码行合并到一起
- 提交一个commit来记录合并操作
5.4 合并冲突
合并冲突
当相同的行在要合并的不同分支上做出了更改时,就会出现合并冲突。git将在合并途中暂停,并显示存在冲突,以及哪些文件存在冲突。要解决文件中的冲突:
- 找到并删掉存在合并冲突指示符的所有行
- 决定保留哪些行
- 保存文件
- 暂存文件
- 提交commit
7 撤销更改
7.1 更改最后一个commit
git commit --amend
重新提供commit消息,更新最近的commit,而不是创建新的commit。
7.2 还原commit
git revert
命令用于还原之前创建的commit。
git revert
命令:
- 将撤销目标commit所做出的更改
- 创建一个新的commit来记录这一更改
7.3 重置commit
git reset
命令用来重置(清除)commit:
- 将HEAD和当前分支指针移到目标commit
- 使用
--hard
选项清除commit - 使用
--soft
选项将commit的更改移到暂存区 - 使用
--mixed
选项取消暂存commit的更改
通常会用到祖先引用来指代之前的commit。祖先引用包含: - ^-表示父commit
- ~-表示第一个父commit