Git 版本控制工具的使用
前言
在现代化程序项目开发中版本控制成了工作中不可缺少的一部分,无论使用哪种语言、框架,以及无论开发什么项目,都需要版本控制。
版本控制(Version Control System)主要有以下几个作用:
名称 |
模型 |
并发模式 |
历史模式 |
变更范围 |
网络协议 |
原子提交性 |
---|---|---|---|---|---|---|
CVS | Client-server | Merge | Changeset | File | Pserver,ssh | No |
SVN | Client-server | 3-way merge,recursive merge,octopus merge | Changset and Snapshot | Tree | custion(svn),custom(svn) over ssh,HTTP and SSL (usingWebDAV) | Yes |
Git | Distributed | Merge or lock | Snapshot | Tree | custion,custom over ssh,rsync,HTTP/HTTPS,email,bundles | Yes |
- 版本库模型(Repository model)
描述了多个源码版本库副本间的关系,有客户端/服务器和分布式两种模式。在客户端/服务器模式下,每一用户通过客户端访问位于服务器的主版本库,每一客户机只需保存它所关注的文件副本,对当前工作副本(working copy)的更改只有在提交到服务器之后,其它用户才能看到对应文件的修改。而在分布式模式下,这些源码版本库副本间是对等的实体,用户的机器出了保存他们的工作副本外,还拥有本地版本库的历史信息。
- 并发模式(Concurrency model)
描述了当同时对同一工作副本/文件进行更改或编辑时,如何管理这种冲突以避免产生无意义的数据,有排它锁和合并模式。在排它锁模式下,只有发出请求并获得当前文件排它锁的用户才能对对该文件进行更改。而在合并模式下,用户可以随意编辑或更改文件,但可能随时会被通知存在冲突(两个或多个用户同时编辑同一文件),于是版本控制工具或用户需要合并更改以解决这种冲突。因此,几乎所有的分布式版本控制软件采用合并方式解决并发冲突。
- 历史模式(History model)
描述了如何在版本库中存贮文件的更改信息,有快照和改变集两种模式。在快照模式下,版本库会分别存储更改发生前后的工作副本;而在改变集模式下,版本库除了保存更改发生前的工作副本外,只保存更改发生后的改变信息。
- 变更范围(Scope of change)
描述了版本编号是针对单个文件还是整个目录树。
- 网络协议(Network protocols)
描述了多个版本库间进行同步时采用的网络协议。
- 原子提交性(Atomic commit)
描述了在提交更改时,能否保证所有更改要么全部提交或合并,要么不会发生任何改变。
SVN
SVN 是 Subversion 的简称,目前是 Apache 项目底下的一个开放源代码的版本控制系统,它的设计目标就是取代 CVS。
优点:
- 集中式管理,管理方式在服务端配置好,客户端只需要同步提交即可,使用方便,操作简单,很容易就可以上手。
- 在服务端统一控制好访问权限,利用代码的安全管理。
- 所有的代码已服务端为准,代码一致性高。
缺点:
- 所有操作都需要通过服务端进行同步,这会导致服务器性能要求比较高。如果服务器宕机了就无法提交代码了。
- 分支管理不灵活,SVN 分支是一个完整的目录,且这个目录拥有完整的实际文件,这些操作都是在服务端进行同步的,不是本地化操作,如果要删除分之,也是需要将远程的分支进行删除,这会导致大家都得同步。
- 需要联网。如果无法连接到 SVN 服务器,就无法提交自己的代码,更别说还原、对比等操作了。如果在内网还好,网速比较稳定,同步相对比较快,如果是通过外网同步,有可能就需要同步很久。
GIT
GIT 是 Linus Trovalds 的作品,是一个开放源码的版本控制软件。与SVN最大的区别,就是分布式的管理。
优点:
- 分布式开发时,可以 Git clone 克隆一个本地版本,然后在本地进行操作提交,本地可以完成一个完整的版本控制。在发布的时候,使用Git push来推送到远程即可。
Git 分支的本质是一个指向提交快照的指针,速度快、灵活,分支之间可以任意切换。都可以在本地进行操作可以不同步到远程。
冲突解决,多人开发很容易就会出现冲突,可以先 Pull 远程到本地,然后在本地合并一下分支,解决好冲突,在 Push 到远程即可。
离线工作,如果 Git 服务器出现问题,也可以在本地进行切换分支的操作,等联网后再提交、合并等操作。
缺点:
- Git 没有严格的权限控制,一般是通过系统设置文件的读写权限来做权限控制。
- 工作目录只能是整个目录,而 Svn 可以单独 Checkout 某个有权限的目录。
GIT vs SVN
git:
- 要配合 Hub,可以避免分布式损坏。
- 适合纯代码。
svn
- 有权限控制,避免全被 Clone 走。
- 综合性文档管理,结合起来就完美。显然最大的不同在于 Git 是分布式的。
建议
- 如果对访问控制、权限分配和代码安全性等要求比较高的,建议使用 Svn。
- 如果是分布式,多人开发,版本迭代比较快的项目,建议使用 Git。
Git 组成结构
- 工作区:用来保存项目的元数据和对象数据库的地方。这是 Git 中最重要的部分,从其它计算机克隆仓库是,拷贝的就是这里的数据。
- 暂存区:保存了下次将提交的文件列表信息,一般在 Git 仓库目录中。有时候也被称作“索引”,不过一般说法还是叫暂存区域。
- 版本库:也叫本地版本库,之所以说 Git 快,大部分提交都是对本地仓库而言的,不依赖网络,最后一次会推送到远程仓库。
- 远程仓库:可以看作是 GitHub,它是一个远程仓库。
文件的状态
新建文件状态为 *Untracked*,`add` 命令执行后状态变为 *staged*,已存在的文件状态为 *Unmodified*,修改文件内容,文件状态变为 *modified*,`commit` 提交,文件状态变成 *Unmodified*。
Git 常用命令
创建版本库
$ git clone <url> # 克隆远程版本库
$ git init # 初始化本地版本库
修改 & 提交
$ git status # 查看状态
$ git diff # 查看变更内容
$ git add . # 跟踪所有改动过的文件
$ git add <file> # 跟踪指定的文件
$ git mv <old> <new> # 文件改名
$ git rm <file> # 删除文件
$ git rm --cached <file> # 停止跟踪文件但不删除
$ git commit -m "commit message" # 提交所有更新过的文件
$ git commit --amend # 修改最后一次提交
查看提交历史
$ git log # 查看提交历史
$ git log -p <file> # 查看指定文件的提交历史
$ git blame <file> # 以列表方式查看指定文件的提交历史
撤销
$ git reset --hard HEAD # 撤销工作目录中所有未提交文件的修改内容
$ git checkout HEAD <file> # 撤销指定的未提交文件的修改内容
$ git revert <commit> # 撤销指定的提交
分支与标签
$ git branch # 显示所有本地分支
$ git check out <branch/tag> # 切换到指定分支或标签
$ git branch <new-branch> # 创建新分支
$ git branch -d <branch> # 删除本地分支
$ git tag # 列出所有本地标签
$ git tag <tagname> # 基于最新提交创建标签
$ git tag -d <tagname> # 删除标签
合并 & 衍合
$ git merge <branch> # 合并指定分支到当前分支
$ git rebase <branch> # 衍合指定分支到当前分支
远程操作
$ git remote -v # 查看远程版本库信息
$ git remote show <remote> # 查看指定远程版本库信息
$ git remote add <remote> <url> # 添加远程版本库
$ git fetch <remote> # 从远程库获取代码
$ git pull <remote> <branch> # 下载代码及快速合并
$ git push <remote> <branch> # 上传代码及快速合并
$ git push <remote> :<branch/tag-name> #删除远程分支或标签
$ git push --tags # 上传所有标签
配置身份信息
首先得有个 GitHub 账号,然后配置:
$ git config --global user.name "Galois"
$ git config --global user.name "Galois.Alex@Gmaill.com"
提交文件时,就知道这个文件是谁提交的,出了问题,就知道是谁干的!
查看配置信息
$ git config --list
创建本地仓库
$ cd ~/Code/ && mkdir myProject
进入仓库后初始化仓库
$ cd ./myProject
$ git init
初始化仓库后,此仓库目录下多了一个 .git 的目录,这个目录是 Git 来跟踪管理版本库的,如果对这个目录做一些操作意味着把 Git 仓库给破坏了。在 Mac 环境下,在 Finder 目录环境界面里可以使用快捷键
commond
+shift
+.
来显示或者隐藏文件名和文件夹名为 “.” 开头的文件和文件夹。(文件名或文件夹名以“.”开头的都为隐藏文件或隐藏文件夹)
Git 本地工作流
- 克隆仓库
- 在工作目录中新增、修改、删除文件
- 暂存文件,将文件的快照放入暂存区
- 提交更新,把暂存区的内容提交到 Git 仓库中
$ touch file.txt
$ git add file.txt # 暂存单个文件
$ git add ./* # 批量暂存当前目录下所有内容
$ git status # 查看文件状态
$ git commit -m "test" # 提交
$ git status
$ git log # 查看提交记录
$ vim file.txt # 随便编辑点文件内容
$ git diff file.txt # 和仓库中已经提交的 file.txt 比较
Add 和 Commit 的区别
本作品采用《CC 协议》,转载必须注明作者和本文链接