版本控制
你可以把一个版本控制系统(缩写VCS)理解为一个“数据库”,在需要的时候,它可以帮你完整地保存一个项目的快照。当你需要查看一个之前的快照(称之为“版本”)时,版本控制系统可以显示出当前版本与上一个版本之间的所有改动的细节。
版本控制工具功能
- 协同修改
- 多人并行不冲突的修改服务器端的同一个文件
- 数据备份
- 不仅保存目录和文档的当前状态,还能够保存每一个提交过的历史状态。
- 版本管理
- 在保存每一个版本的文件信息的时候要做到不保存重复数据,以节约存储空间,提高运行效率。这方面SVN采用的是增量式管理的方式,而Git采取了文件系统快照的方式。
- 权限控制
- 对团队中参与开发的人员进行权限控制。
- 对团队外开发者贡献的的代码进行审核——Git独有。
- 历史记录
- 查看修改人、修改时间、修改内容、日志信息。
- 将本地文件恢复到某一个历史状态。
- 分支管理
- 允许开发团队在工作过程中多条生产线同时推进任务,进一步提高效率。。
本地库与远程库交互
1.团队内部协作
流程:
- User1新建了一个远程库,将本地库的文件目录推送(push)到远程库中。
- User2若想修改远程库中的文件,就需要克隆(clone)下来到自己的本地库中。
克隆(clone)不光是下载远程库里的东西,还会把本地库初始化好。 - User2在本地库的基础上修改,改完之后推送(push)到远程库中。
这里要注意,因为远程库是由User1创建的,User2不能直接往里面写东西,需要加入团队才有权限。 - User1从远程库中进行拉取(pull)到本地库中,获得远程库最新版本的文件。
2.跨团队合作
User1和User2是一个团队的,User3是另外一个团队的。
流程:
- User3对User1所创建的远程库1做一个fork的操作,复制出一份新的属于User3的远程库2。
- User3克隆(clone)下到本地库进行修改,之后推送(push)到自己的远程库2中。
- User3发起一个拉取请求(pull request)
- User1进行审核
- 审核后没问题,就进行合并(merge)到远程库1中。
- User1,User2拉取(pull)到自己的本地库中。
Git简介
Git是一个版本控制工具,与Svn相似。他们两个主要区别在于,Git是分布式,Svn是集中式。话说回来Git跟Svn一样有自己的集中式版本库和Server端,但Git更倾向于分布式开发,因为每一个开发人员的电脑上都有一个Local Repository,所以即使没有网络也一样可以Commit,查看历史版本记录,创建项 目分支等操作,等网络再次连接上Push到Server端。
Git简史
有兴趣的可以看一看,或者跳过这一part直接看接下来的部分。
Git结构和概念介绍
你的本地仓库由 git 维护的三棵“树”组成。
- 工作目录(Working Directory),它持有实际文件。
- 暂存区(Stage/Index),它像个缓存区域,临时保存你的改动。
- HEAD,它指向你最后一次提交的结果。
概念介绍
1.工作区\工作目录(Working Directory)
在电脑上,所能看到的一个目录(不包括显示后的隐藏目录.git)就是一个工作区,比如我的git_exec。
2. 暂存区(Stage/Index)
Git和其他版本控制系统如SVN的一个不同之处还在于,它有暂存区。
git add <filenames>
把当前工作目录中的文件放入暂存区域
这其实做了两件事:
- 将本地文件的时间戳、长度,当前文档对象的id等信息保存到一个树形目录中去(index,即平时说的暂存区)
- 将本地文件的内容做快照并保存到Git 的对象库(.git/objects) 。
综上两点来说,暂存区实际上就是一个包含文件索引的目录树,像是一个虚拟的工作区。在这个虚拟工作区的目录树中,记录了文件名、文件的状态信息(时间戳、文件长度等),文件的内容并不存储其中,而是保存在 Git 对象库中,文件索引建立了文件和对象库中对象实体之间的对应。
图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下:
- 当对工作区修改(或新增)的文件执行
git add
命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID 被记录在暂存区的文件索引中 - 当执行提交操作
git commit
时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树 。
3. 仓库/版本库(Repository)
可以理解为,一个记录所有文件或目录状态的地方,存储着内容修改的历史记录。Git能跟踪每个文件的修改、删除,以便将来某个时刻可以对文件进行还原。
Git有两种仓库:
- 远程仓库: 配有专用的服务器,为了多人共享而建立的数据库。(需联网)
- 本地仓库: 为了方便用户个人使用,在自己的机器上配置的仓库。(无需联网)
创建本地仓库两种方法:
- 创建全新的仓库
- 复制远程数据库
4.快照(Snapshot)
使用过git的人应该都会发现在使用git管理自己的代码仓库时,随着代码更改次数的增加,代码仓库的实际大小并不会有太大变化,这的确是很神奇。而魔法师git所用的“道具”就是快照(snapshot),不过这一名词过于抽象,真的很让人费解!
我在网上看过很多人的解释,有些人虽然解释得很通俗,不过还是让人摸不着头脑:
想象一下,给一张桌子拍一张照片,纪录了桌子上所有物品的位置、状态,这样就可以称之为快照了。
我们不必存储所有的物品,只需存储这个照片就可以了,下一次想恢复以前的状态的时候,只需要翻出当时的那张照片,再把物品按照那张照片里的位置摆放一下就OK了。
当然,还有一些错误的认识。有不少人认为git存储的是每次文件相对于基本文件的差异,其实这是很多人的误区。的确有不少版本控制软件就是这样做的,如CVS、Subversion等等,但git不是,它记录的是快照。但重点是这快照究竟是什么呢?
在Progit的第一章中,对记录差异和记录快照进行了对比,下图是记录差异的原理图:
这类版本控制软件记录的是一组基本文件和每个文件随时间逐步积累的差异,这个看起来非常好理解。但是git记录快照就稍微有点儿抽象了:
在英文版中这样描述:
Every time you commit, or save the state of your project in Git, it basically takes a picture of what all your files look like at that moment and stores a reference to that snapshot.
通俗的翻译就是:每次你提交或者要在git中保存项目的状态时,git仅仅是制作快照(像拍照一样记录所有文件在那个时刻的样子),并保存指向这个快照的引用。之所以把英文引用过来,是想让大家注意一下里面的这个描述:
takes a picture of what all your files look like at that moment
这一句的意味在中文版Progit中是感受不出来的。
虽然上面的解释让我有了大致的理解,但是还是很有些似懂非懂,模棱两可。
另外,在书中的这样一句话好像点醒了我,虽然并没有直接解释快照(snapshot),但是为我指明了方向:
Git更像是把数据看作是对小型文件系统的一组快照
也许快照是文件系统中的概念或者技术,而git只是利用这一技术,所以Progit中才没有详细介绍这一技术,虽然其中频繁提到快照(snapshot)这个词。我在提问之前,我在维基百科上看过这一概念,但所能知道也就是:来自照相领域的概念,是指特定时间点的一个状态。
开始上路
1.安装Git
//Ubuntu安装Git
$ sudo apt-get install git-all
2.设置签名
- 形式
用户名:ckck
Email地址:emailname@email.com - 作用:区分不同开发人员的身份
- 辨析:这里设置的签名和登录远程库(代码托管中心)的账号,密码没人任何关系。
- 命令:
- 项目级别/仓库级别:
git config
仅在当前本地库范围内有效 - 系统用户级别:
git config --global
登录当前操作系统的用户范围 - 就近原则: 项目级别优先于用户级别,二者都有时Git将采用项目级别的签名。
- 项目级别/仓库级别:
设置项目级别
$ git config user.name tom_pro
$ git config user.email gitgit@suibian.com
查看签名
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[user]
name = tom_pro
email = gitgit@suibian.com
设置系统级别
$ git config --global user.name tom_sys
$ git config --global user.email gitgitsys@suibian.com
查看签名
$ cd ~
$ cat .gitconfig
[user]
name = tom_sys
email = gitgitsys@suibian.com
实际开发为了省事,一般都设置系统级别的签名。
3.初始化仓库
//新建Repository
cd Desktop/learngit
git init
如果在当前目录下看到.git的话,可以用ls -ah
命令或者快捷键ctrl+h
查看隐藏文件。
4.添加与提交
//添加到暂存区
git add readme.txt
//改动提交到了HEAD
git commit -m "wrote a readme file"
简单解释一下git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。