第一章
版本控制
定义
版本控制(Version Control System)是一种记录一个或多个文件内容变化,以便未来查阅特定版本的修订情况的系统;
VCS可以将文件、项目回溯到之前的状态,并且可以根据比较文件的变化细节(提交、修改记录等),查出问题所在;
本地版本控制系统(RCS)是记录文件前后内容变化,并将其记录为特定的文件补(patch),以便未来进行回退。
集中化版本控制系统(Centralized Version Control Systems,例如SVN)是近年来版本控制系统的标准做法,它通过集中管理的服务器,来保存文件的所有修订版本,供项目人员进行取出更新或下载;
- 集中化版本控制系统的优缺点:
优点:开发者可以在一定程度上知道项目成员的改动;管理员可以控制各个成员的权限;
缺点:当出现中央服务器的单点故障,则项目成员都无法进行提交更新操作。
分布式版本管理系统(Distributed Version Control Systems,例如Git)由个人将代码仓库完整镜像下来,从而当任何一处协同工作的服务器发生故障,都可用任意一个镜像出来的本地仓库恢复,而且每次的提取操作都是对代码仓库的完整备份。
Git
特性
直接记录快照,而非差异比较:Git只关心文件数据的整体是否发生变化,二大多数其他系统只关心文件内容的具体差异(如SVN)。
近乎所有操作都是本地执行:在Git大部分操作都只需要访问本地文件和资源,Git在本地磁盘上保存着所有当前项目的历史更新,因此处理速度较CVCS更快。
保持数据的完整性:在保存至Git时,所有数据均要经过校验和计算,并将结果作为唯一标示和索引;
多数操作只添加数据:Git的常用操作仅仅将数据添加至数据库,因为任何一种不可逆操作(删除)都会使得版本回退困难重重;
文件三种状态:Git工作目录(committed)、暂存区域(staged)、本地仓库(modified);
Git的配置
用户信息配置:便于Git提交后,他人查看提交记录的发起者
$ git config --global user.name John Doe $ git config --global user.email johndoe@example.com
文本编辑器:采用自定义的文本编辑器设置
$ git config --global core.editor notepadqq
查看配置信息
$ git config --list
查看帮助
$ git help config $ git help <verb> $ git <verb> --help $ man git-<verb>
Git基础
获得项目的仓库
- 工作目录中初始化新仓库:要对想现有项目进行Git管理,只需要到此项目所在的目录执行:
$ git init
创建完毕之后,所有Git需要的数据和资源将被保存至该目录下,并生成一个
.git
目录,若当前文件夹下有别的文件需要进行项目的版本控制,需要先用git add
进行追踪,并提交$ git add *.c $ git add README $ git commit -m 'initial project version'
-
从现有仓库中克隆:
$ git clone xxxx
记录更新到仓库
-
检查文件状态
$ git status
-
跟踪新文件
$ git add README
-
暂存已修改的文件(当新添加的文件修改后,要再次进行add,否则提交是之前暂存的版本)
$ git add README_2.0
-
忽略某些文件(通过修改一个名为
.ignore
的文件,列出所需忽略的文件模式)$ cat .gitignore # 此为注释 – 将被 Git 忽略 # 忽略所有 .a 结尾的文件 *.a # 但 lib.a 除外 !lib.a # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO /TODO # 忽略 build/ 目录下的所有文件 build/ # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt doc/*.txt
-
查看尚未暂存的文件更新的部分
$ git diff --staged
-
提交更新
$ git commit
-
跳过使用暂存区域(避免使用git add将最近更新的文件再次暂存)
$ git commit -a
-
移除文件
$ git rm xxx # 强制删除选项适用于删除之前修改过且已经放入暂存区域,以防止误删文件丢失了修改后的内容 $ git rm -f xxxx
-
删除匹配格式的文件
# 删除当前目录下所有以x结尾的文件 $ git rm *x # 递归删除当前目录及子目录下所有以x结尾的文件 $ git rm \*x
-
移除跟踪但不删除文件(从远程仓库中删除,但不删除本地文件)
git rm --cached readme.txt
-
移动文件
# 表示删除一个旧文件,添加一个新文件 $ git mv file_from file_to
查看提交历史
-
回顾提交历史
$ git log # 显示增改行数可加入--stat,代码审查 $ git log --stat
-
限制输出长度
$ git log --since=2.weeks # 选项 说明 -(n) 仅显示最近的 n 条提交 --since, --after 仅显示指定时间之后的提交。 --until, --before 仅显示指定时间之前的提交。 --author 仅显示指定作者相关的提交。 --committer 仅显示指定提交者相关的提交。
-
图形化工具:gitk
撤销操作
-
上次提交忘记跟踪几个文件,或是文件信息未加,可通过修改提交实现
$ git commit --amend
-
退回之前的文件版本,放弃当前修改
$ git checkout -- xxx
-
取消文件的暂存
$ git reset HEAD xxx
远程仓库的使用
-
查看当前的远程库
# 加入--verbose(-v)简写,查看相应的克隆地址 $ git remote -v
-
添加新的远程库
git remote add [shortname] [url]
-
从远程仓库抓取数据
$ git fetch [remote-name]
-
推送数据到远程仓库
$ git push [remote-name] [branch-name]
-
查看远程仓库信息
$ git remote show [remote-name]
-
远程仓库的移除和重命名
$ git remote rename xx xxx $ git remote rm xxx
打标签
-
列出已有标签
$ git tag
-
新建标签
$ git tag -l "vesion"
第二章 Git分支
分支的概念
基本概念
-
分支即为指向commit对象的可变指针,Git使用master作为分支的默认名字;
-
通过
git branch
命令创建分支,可在当前的commit对象上添加一个分支指针,如下图所示; -
HEAD指针指向当前工作中的指针,通过执行
git checkout
命令更换分支
-
分支创建与合并
-
删除分支
$ git branch -d xxx
-
合并分支
$ git merge xxx
-
跟踪远程分支
$ git checkout -b [分支名] [远程名]/[分支名]
-
推送本地分支
$ git push [remote] [local branch]
-
删除远程分支
# 注意空格 $ git push [remote]: [branch name]
-
分支的rebase(衍合):即将原先并行开发的分支,重新移动到原来并行的分支下,使之看起来像是从原来并行分支下顺序开发得到的结果
# 切换至要进行衍合的分支 $ git checkout [branch name] # 将该分支衍合至指定的分支 $ git rebase [destinated branch name]
Git的进阶操作
-
通过log查询commit记录hash的值,进行HEAD移动操作
# 查询相关的commit记录 $ git log # 得到相应的记录 commit 019e8f0e7f317e805c115f8c702770f528d0676f # 直接移动HEAD,使得操作指向制定的commit记录 $ git checkout 019e8f0e7f317e805c115f8c702770f528d0676f
-
简单的移动HEAD方式
# 表示移动到master的上一次提交记录 $ git checkout master^
-
通过相对位置移动分支与HEAD
# 移动HEAD到master的前面第三个提交记录 $ git checkout master~3 # 移动分支master到master的前面第三个提交记录处 $ git chekout -f master HEAD~3
-
取消当前的改动,返回之前提交记录的版本,从返回的版本起后续版本均舍弃,例如从V3回到V1,V2也不要了
# 移动当前分支到前一次改动的记录处 $ git reset HEAD~1 # 移动当前分支到指定记录号处 $ git reset --hard [commit记录] # 采用强制手段提交更改 $ git push -f
-
取消之前的改动,但是在之前改动后的版本仍需要,例如V1有bug需要删掉,但V2又需要留下
$ git revert -n [commit记录] $ git commit -m "revert ... ..."
-
未完待续… …