版本控制系统即VCS(version control system)是一种记录一个或若干文件内容变化以便将来查阅特定版本修订情况的系统。有了版本控制我们就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态,可以比较文件的变化细节,查出最后是谁修改了哪个地方,从而找出导致bug出现的原因。
分布式版本控制系统(Distributed Version Control System 简称DVCS),区别于集中化的版本控制系统(Centralized Version Control Systems 简称 CVCS),客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。
Git是一个免费开源的分布式版本控制系统(DVCS),是基于内容寻址的存储系统。区分于其他基于文件的存储系统。 (基于内容寻址:每次提交更新,或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。 为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个快照流。)在 Git 中的绝大多数操作都只需要访问本地文件和资源,一般不需要来自网络上其它计算机的信息。
Git 用以计算 校验和(checksum or hash sum)的机制叫做 SHA-1 散列(hash,哈希)。这是一个由 40 个十六进制字符(0-9 和 a-f)组成字符串,基于 Git 中文件的内容或目录结构计算出来。 SHA-1 哈希看起来是这样: 24b9da6552252987aa493b52f8696cd6d3b00373 实际上,Git 数据库中保存的信息都是以文件内容的哈希值来索引,而不是文件名。 //这也正是Git分支轻量级的原因所在
Git 有三种状态,你的文件可能处于其中之一:已提交(committed)、已修改(modified)和已暂存(staged)。 已提交表示数据已经安全的保存在本地数据库中。 已修改表示修改了文件,但还没保存到数据库中。 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。由此引入 Git 项目的三个工作区域的概念:Git 仓库(Repository)、工作目录(Working Directory)以及暂存区域(Staging Area)。
Git仓库 是 Git 用来保存项目的元数据和对象数据库的地方。 这是 Git 中最重要的部分,从其它计算机克隆仓库时,拷贝的就是这里的数据。
工作目录 是对项目的某个版本独立提取出来的内容。 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。
暂存区域 是一个文件,保存了下次将提交的文件列表信息,一般在 Git 仓库目录中。
基本的 Git 工作流程如下:
在工作目录中修改文件。
暂存文件,将文件的快照放入暂存区域。
提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。
Git安装参照http://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git
//Git Windows版 https://git-for-windows.github.io/
Git初始配置
获取帮助:在命令行输入 git help <command> 以调用相关命令文档 e.g.要想获得 config 命令的手册 只需执行 $
git help
config
git config有三种配置级别:
1. --local 即本地配置【默认 高优先级】:只影响本仓库
2. --global 【中优先级】:影响到所有当前用户的git仓库
3. --system【低优先级】:影响到全系统的git仓库
获取 Git 仓库:
有两种取得 Git 项目仓库的方法。 第一种是在现有项目或目录下导入所有文件到 Git 中; 第二种是从一个服务器克隆一个现有的 Git 仓库。
1.) 在现有目录中初始化仓库:git init 命令
2.) 克隆现有的仓库:使用git clone
命令 获得一份已经存在了的 Git仓库的拷贝。这是 Git 区别于其它版本控制系统的一个重要特性,Git 克隆的是该 Git 仓库服务器上的几乎所有数据,而不是仅仅复制完成你的工作所需要文件。 当你执行 git clone
命令的时候,默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来。(事实上如果你的服务器的磁盘坏掉了,你通常可以使用任何一个克隆下来的用户端来重建服务器上的仓库。)克隆仓库的命令格式是 git clone [url]
。
Git中 git status 是对两种状态的跟踪:
工作目录下的每一个文件都不外乎这两种状态:已跟踪或未跟踪。 已跟踪的文件是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后,它们的状态可能处于未修改,已修改或已放入暂存区。 工作目录中除已跟踪文件以外的所有其它文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有放入暂存区。 初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态。编辑过某些文件之后,由于自上次提交后你对它们做了修改,Git 将它们标记为已修改文件。 我们逐步将这些修改过的文件放入暂存区,然后提交所有暂存了的修改,如此反复。所以使用 Git 时文件的生命周期如下:
Git 命令:
假设创建一个README新文件,可以使用 echo
'My Project'
> README (创建了一个内容是My Project名字为README的文件)
也可以使用 touch README (创建了一个名子为README的空文件)
git add //添加文件内容到暂存区(同时文件被跟踪)
git add . //用于添加所有当前目录下的文件
如果跟踪了意料之外的文件,我们就需要配置忽略文件 .gitignore(在添加时忽略匹配的文件,仅作用于未追踪的文件)。//只是忽略文件而不是真正的删除文件。
删除文件使用 git rm:
git rm --cached:仅从暂存区删除
git rm :从暂存区与工作目录删除
git rm $(git ls-files --deleted) :删除所有被跟踪,但是在工作目录被删除的文件 //tip
git commit 使用该命令提交更新 //根据暂存区内容创建提交记录。该命令将暂存区内容被提交到提交区,形成一个提交历史。
git commit -m 'initial commit' 这里的 -m 参数为这条命令进行一个注释
我们可以使用 git commit -a 命令 直接从工作目录提交到提交区
使用 git log 命令 查看 提交历史记录
使用 git config alias.shortname <full command> 来配置命令行的快捷路径 //git 别名设置 //设置成global级别以便将来使用
git diff 显示不同版本的差异:
git diff 直接输入的话显示的是工作目录与暂存区的差异。 //注意的是 git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。
git diff -cached [<reference>] //暂存区与某次提交差异,默认为HEAD(HEAD指向当前的提交); Git 1.6.1及以上版本还允许使用 git diff --staged
效果相同
git diff <reference> //工作目录与某次提交的差异
撤销本地修改
git checkout --<file> //将文件从暂存区复制到工作目录 //因为git基于内容寻址,此时两者内容一样了,也就表示该文件未改动。//To discard changes
(工作目录有改动,但是尚未提交到暂存区。git status会提示我们 :use "git checkout --<file>..." to discard changes in working directory)
撤销暂存区内容 git reset HEAD --<file> //to unstage 将文件内容从上次提交复制到暂存区 //git基于内容寻址,暂存区与上次提交区内容一样了也就相当于暂存区未被修改
撤销全部改动 git checkout HEAD --<file> //将内容从上次提交复制到工作目录
Git 分支操作 git branch //分支的增删查改
git branch <branchName> //创建分支
git branch -d <branchName> //删除指定的分支
git branch -v //显示当前所存在的分支信息
git checkout //通过移动HEAD检出版本,可用于分支切换 //git checkout 在本质上只是用来移动HEAD
git checkout <branchName> //将指针直接指向该目标分支
git checkout -b <branchName> //加入b参数后 相当于直接创建一个分支并切换到该分支 //相当于git branch <branchName> 后紧接 git checkout <branchName>
git checkout <reference>
git checkout - //恢复到上一个分支,HEAD回到上一个分支
git reset 将当前分支回退到历史某个版本
reset vs checkout
git stach //保存当前的工作目录和暂存区状态,并返回到干净的工作空间 working directory clean//相当于一个 栈
git stach save //保存至 stach区
git stach list //查看收藏记录
git stach apply //将保存在stage区的内容恢复到工作目录上面
git stach drop //将stage区对应的记录删除
// git stach pop 相当于 git stach apply + git stach drop
git merch //合并分支 合并的结果会被复制到工作目录和暂存区,然后完成一次提交
git rebase //合并分支 修剪提交历史的基线,俗称“变基” //使得提交历史变得线性 //不要在公有分支(master分支)使用rebase
git tag //对某个提交设置一个不变的别名 //类似一个commit对象,指向一个commit对象 //作用是我们可以直接使用我们自定义的标签名来进行git checkout等操作
而不需要使用冗长且不直观的hash。(该命令接受两个参数: 自定义的标签名 需要打标签的对象)
远程操作
将本地记录同步到中央服务器
Git 支持多种数据传输协议,除了http
协议,ssh传输协议, Git还支持本地
协议,所以我们可以初始化一个本地的远程服务器。
git init ~/git-server --bare //初始化一个裸仓库 木有工作目录
git push //提交本地历史到远程
git remote //远程仓库相关配置
git fetch //获取远程仓库的提交历史
git pull = git fetch + git merge
git clone //克隆一个远程仓库作为本地仓库 前面已经提到 // 作用相当于 git init + git remote + git pull
参考:
Git Pro http://git-scm.com/book/zh/v2
网易云课堂 版本管理 课程