《版本控制之道——使用Git》
更新日期:
版本控制之道——使用Git
- 2014/05/02 阅读时记录,手工敲入T_T
- [美] Travis Swicegood
- 程序员修炼三部曲 - 第一部
- Broadview 通熟易懂,精炼实用
- The Pragmatic Programmers系列 - Pragmatic Version Control Using Git
Git优势
- Git轻而易举地支持多站点开发和离线工作;使得Git适用于更多应用场景
- Git的性能优于传统版本控制工具若干数量级。使得Git使用于更大的研发项目
序言
版本控制系统
版本控制系统就好比银行保险箱,保管有价值的资产,保证它们的安全。
对程序员来说,源代码就是这样的资产,由版本控制系统来保管。
版本控制系统将程序员所完成并提交的任何修改都记录下来,供日后查询检索。
这个功能就好像银行提供的对账单一样。
- 既可以完全断开和别人的连接以独立工作,也可以在适当的时候与大家沟通分享工作成果。
- Git也具有记录和跟踪源代码修改历史这样的基本功能。
Git具有如下优势
- 分布式体系结构:完全可以断网工作,不受网络连接的限制。
- 分支与合并操作很容易:创建分支简单、经济、快速,这与其他版本控制系统不一样。Git把分支上的所有修改合并回父分支,即使多次,也只是一眨眼的功夫。
- 跟Subversion进行交互:Git可以从Subversion中导入所有的历史,并把你在Git中的改动发送回Subversion的版本库。
第1篇 欢迎来到分布式世界
第1章 Git的版本控制之道
版本控制系统(Version Control System ,VCS)可以帮助我们记录和跟踪项目中各文件内容的修改变化。
- 自动地备份和跟踪项目中所做的修改。
- 它与传统版本控制系统的区别在于:开发人员互相同步修改内容的方式不同。
版本库
Repository存储各个文件的当前状态、历史修改时间、谁做的修改,以及修改的原因。
集中式版本库
- CVS
- Subversion
这种模式下,所有程序员会把他们的改动提交到服务器上的一个公共版本库中。
集中式版本库缺点 - 在本地工作目录树中,只能看到代码的最新版本。如果想查询历史修改记录就必须与服务器上的版本库打交道,而这就要使用网络。
分布式版本控制系统
克服遇到不能上网所带来的问题。
使用分布式版本控制系统,每个人都会在本地有自己的版本库,而不是连接到服务器上的一个公共的版本库。所有的记录都存储在本地的版本库中。向版本库提交代码无需连接远程的版本库,而是记录在本地的版本库中。
版本库中存储什么
- 所有内容
- 存储项目开发所必须的所有内容。
- 构建文件:Makefile,Rakefile 及 Ant 的build.xml等
- 配置文件样例,各类文档,程序使用的图片
- 单元测试脚本
工作目录树
Working tree:程序员进行程序开发的地方
- Git中的版本库是存储在本地工作目录树中的“.git”目录中。要想知道历史信息,之和本地版本库打交道即可。
如何创建工作目录树两种方法:
- Git命令行初始化版本库:git init
- Clone一个已有的版本库
跟踪变更是版本控制系统(VCS)的核心功能。
代码修改与文件同步
修改了文件内容之后需要进行单元测试以保证这次修改不会有任何负面影响。
把远程版本库里的改动拿到本地版本库中,需要两步操作:
- 第一步把改动取来Fetch,把远程版本库中的版本和分支复制到本地版本库中。有点像推入操作的反操作。
- 第二步在本地版本库中,把从远程版本库里取来的改动与自己本地的改动合并Merge。
也可以用一个命令完成上述操作,拖入pull。拖入操作有点像是Subversion中的更新Update操作。但Git是完全分布式的。
跟踪项目、目录和文件
使用标签跟踪里程碑
使用分支来跟踪并行演进
相当于把所有代码拷贝到一个新的目录下,然后开始修改。
主分支(master branch or trunk)
- 也许试验结束后分支就删除了。
- 分支也可以在本地创建。
合并
冲突conflict
知晓解决冲突的方法原理,是精通Git的重要的一步。
合并跟踪:自动记录和跟踪合并的功能。
不用人工记录哪些提交合并到哪儿了。
锁机制
严格锁
乐观锁:允许多个程序员同时修改同一文件。这种锁基于一种假定:大多数时候,这种并发修改不会引起冲突。
第2章:Git 安装与设置
安装Git
Linux环境中安装Git
首先需要安装build-essential安装包。此外,Git还依赖少量其他安装包。
可以使用下述apt-get命令列出所有依赖关系:
sudo apt-get build-dep git-core git-doc
下载源代码并解压到适当路径。然后在该路径下:
make prefix=/usr/local all doc
为所有用户安装Git
运行下述命令安装Git:
sudo make install install-doc
git --version
Window环境中安装Git
- Cygwin:Linux仿真器
- MSys版的Git
设置Git
需要设定一些全局变量的值。全局是指本电脑中任何Git版本库。1
git config --global user.name "lisuxuan1993"
git config --global user.email "lisuxuan1993@gmail.com"
下列命令可以检查上述设置是否成功1
git config --global --list
设置使用不同颜色显示不同类型的内容1
git config --global color.ui "always"
启动Git图形用户界面1
git gui
第3章:创建第一个项目
- 创建版本库
- 添加,修改文件
- 创建新分支
- 打标签并整理版本库
- 克隆版本库
动手执行命令,在反复实践中学习Git,无论多么简单
创建版本库
版本库(.git目录)是与工作目录树并排放在同一个目录中。
存放版本库的所有元数据1
mkdir mysite
cd mysite
git init
代码修改
提交到本地代码版本库1
git add index.html
git add .
git commit -m "add a file"
git commit命令创建一个提交记录。提交记录是存储在版本中的历史记录。每次提交一次创建一个记录,并标记出代码的演进。
提交记录包含:提交者姓名,邮件地址,提交留言等。
命令中的参数 -m 的作用是,告诉Git本次提交的提交留言是什么。
适当书写提交留言极其重要
运行命令git log可以看到这个提交的相关信息。
显示完整的40位哈希码,唯一标识每个提交。
Git使用:SHA-1哈希码。 安全哈希算法。
在项目中工作
显示工作目录树的状态,即当前的视图状态1
git status
跨行提交留言1
git commit =m "add head and title to index" \
-m "This allows for a more document"
理解并使用分支
有两种分支比较有用:
- 用来支持项目的不同发布版本的分支
- 用来支持一个特定功能的开发的分支(常被称为Topic Branch)
先介绍第一种分支
分支可以为要发布的代码保留一份拷贝,所以无须停止正在开发的工作。
创建分支的命令是git branch
该命令需要两个参数:新分支名称和父分支名称。1
git branch RB_1.0 master
master 对应于CVS或者Subversion中的主干(trunk)
RB代表发布分支。release branch。
提交全部修改过的文件1
git commit -a
主分支有最新的修改,发布分支上还是原来的代码。
切换到发布分支:1
git checkout RB_1.0
处理发布
现在准备发布1.0版本了,要给它打个标签。
给Git中代码打标签意味着在版本库的历史中标记处特定的点,这样将来就容易找到相应版本的代码。1
git tag 1.0 RB_1.0
不带参数的git tag可以查看版本库中的标签列表。
带代码打过标签之后需要做一些整理工作。现在两条分支上有不同的提交。要把RB_1.0分支上所做的修改合并到主分支上来。
变基命令git rebase可以完成这项工作。
变基是把一条分支上的修改在另一条分支的末梢重现。1
git checkout master
git rebase RB_1.0
删除发布分支RB_1.0,打过标签后删除只是删除分支的名字,并不会删除分支上的任何实际内容。1
git branch -d RB_1.0
以后若要给1.0.x分支打补丁的话,只需从打标签的地方再创建一条分支即可。1
git branch RB_1.0.1 1.0
git checkout RB_1.0.1
使用Git做的最后一件事是,为代码发布创建归档文件。
创建项目源代码的发布包
下面为mysite创建一个gzip文件:1
git archive --format=tar \
--prefix=mysite-1.0/ 1.0 \
| gzip > mysite-1.0.tar.gz
- –format指明要产生tar格式的输出
- –prefix指明包中所有东西都放到mysite-1.0/ 目录下。
- 最后的1.0指明要归档的标签的名称。
1 | git archive --format=zip \ --prefix=mysite-1.0/ 1.0 \ > mysite-1.0.zip |
克隆远程版本库
1 | git clone git://github.com/tswicegood/mystie.git mysite-remote |
阅读于:2014-05-04
第2篇 Git日常用法
第4章 添加与提交:Git基础
深入学习Git,并练习Git常用命令
添加文件到暂存区
暂存的变更 : 提供精心选择提交内容的机会。
给git add命令添加-i选项会启动交互命令提示符。
暂存文件前显示’*’号。
直接进入补丁模式:选择y使该文件处于暂存状态并准备提交。1
git add -p
提交修改 Committing changes
提交到本地版本库。可以给git commit 命令传递多个-m。
第一种方法:先添加到暂存区,再commit提交1
git add some-file
git commit -m "changes to some-file"
或者 直接提交工作目录中所有修改:1
git commit -m "changes to some-file" -a
或者 指定直接提交文件的方法1
git commit -m "changes to some-file" some-file
给命令起别名
下列命令使得 git ci代替git commit.1
git config --global alias.ci "commit"
查看修改内容
查看当前状态
使用git status查看工作目录树中的所有变动。1
git status
输出:暂存区内要提交的内容+工作目录中未加入暂存区的改动,以及尚未纳入Git版本控制的新文件。
Changes to be committed
Change but not updated
查看文件改动
不添加任何参数而运行,比较工作目录树和暂存区之间区别。1
git diff
比较暂存区和版本库中的区别:
这个比较命令不会1
git diff --cached
一下命令可以比较工作目录树(包括暂存的和为暂存的修改)与版本库的差别:1
git diff HEAD
管理文件
版本库中文件的整理
文件重命名与文件移动1
git mv index.html hello.html
git status
git commit -m "rename to more appropriate name"
复制文件——真的要复制它么
Git提供了创建分支和标签的命令。Git也能记录和跟踪复制的代码。
Git并不跟踪管理文件,而是跟踪文件内容。
Git真正关心的是文件本身的内容
实际上无须额外告诉Git存在文件复制,Git自己就可以检测到它。
忽略文件
把不应该加入版本库的文件加入版本库的.gitignore文件中。
Git支持通配符。
如果把要忽略的文件改添到.git/info/exclude文件中,则本地的版本库会忽略这类文件,同时又不会把此设置传播出去。
确定设置忽略的方式
如果每个人的版本库中都需要这类忽略:就在.gitignore中添加规则来忽略该类文件。
如果仅仅是本人需要忽略:添到.git/info/exclude文件。(.*.swp)
第5章 理解和使用分支
1 | git clone git://github.com/tswicegood/mysite-chp4.git |
分支移动操作(重命名)1
git branch -m master mymaster
git branch
何时创建分支,是一门艺术。
- 试验性更改:测试新算法
- 增加新功能
- Bug修复
创建新分支1
git branch new
git branch 查看创建的情况。
检出分支:1
git checkout new
一下是快捷方式创建新分支并立即检出:1
git checkout -b alternate master
合并分支间的修改
分支合并(共享修改)
主要有三种合并:
直接合并
把一条分支的全部历史提交合并到另一条分支上。1
git checkout master //切换到合并操作的目标分支
git merge alternate //alternate分支上的修改就合并到主分支上
压合合并
功能分支:新功能开发或者Bug修复
压合是指将一条分支上的所有历史提交压合成一个提交,提交到另一条分支上。
只有所有提交都密切相关时候,才适合用压合合并。1
git checkout -b contact master //在主分支上创建一条名为contact的分支并检出
git add contact.html
git commit -m "add contact file with email"
//再添加第二条电子邮件地址,然后再提交修改
git commit -m "add secondary email" -a
git checkout master //切换到主分支
git merge --squash contact
git status
//提交到版本库中
git commit -m "add contact page" \
-m "has primary and secondary email"
拣选提交
仅仅合并一个提交1
git checkout contact
git commit -m "add link to twitter" -a
//create commite 321f:......
git checkout master
git cherry-pick 321d76f
可以告诉Git在创建提交前先进行合并操作:1
git cherry-pick -n 321d76f
git status
//继续拣选
git commit //不要使用-m参数
冲突处理
启动一个合并工具1
git mergetool
删除分支1
git branch -d about2
注意:只有当要删除的分支已经成功合并到当前分支时,分支删除操作才会成功。
强制删除:1
git branch -D about2
分支重命名1
git branch -m contact contacts
//强制覆盖
git branch -M contact contacts
第6章 查询Git历史记录
1 | git log git log 7b1558c //查看一个指定版本 |
指定查找范围1
git log --since="5 hours"
git log --before="5 hours" //5小时之前的最后一个提交
git log 18f822e..0bb3dfb //指定两个版本作为查找范围,不包括起点只包括终点
git log 18f822e..HEAD //末梢
git log 18f822e.. //默认为HEAD