介绍
VCS(Version Control Systems)
版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。运用版本控制的好处:可以随意回退到某一时间点的状态,比较文件的变化细节,查出修改人及其修改内容等。
CVCS(Centralized...)
集中化版本控制系统都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。
- 例子:CVS、Subversion(SVN)以及Perforce等。
- 缺点:如果宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。如果中心数据库所在的磁盘发生损坏,又没有做恰当备份,毫无疑问你将丢失所有数据——包括项目的整个变更历史,只剩下人们在各自机器上保留的单独快照。本地版本控制系统也存在类似问题,
只要整个项目的历史记录被保存在单一位置,就有丢失所有历史更新记录的风险。
DVCS(Distributed)
客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。
- 例子:Git、Mercurial、Bazaar以及Darcs等。
概念
- 直接记录快照,而非差异比较
其他VCS记录的是一组基本文件以及每个文件随时间积累的差异,而Git则是对当时的全部文件制作快照并保存该快照索引。
- 近乎所有操作都是本地执行
- 保证数据完整性
Git中所有数据在存储前基于文件的内容或目录结构采用SHA-1散列计算校验和,然后以校验和来作为索引。这意味着不可能在Git不知情时更改任何文件内容或目录内容。 - 文件的3种状态
- Committed:已提交表示数据已经安全地保存在本地数据库中。
- Staged:已暂存表示文件已经提交到暂存区,使得文件被包含在下一次的commit中。
- Modified:已修改表示文件已被修改但既未暂存也未提交。
- 3个区域
- 工作目录:从某个版本提取出来的内容,增删改都在其上操作。
- 暂存区:保存了下次将要提交的文件列表信息,也被称为“索引”。
- Git仓库目录:Git保存项目元数据及对象数据库的地方。
- 工作目录下文件的4种状态
请记住,你工作目录下的每一个文件都不外乎这两种状态:已跟踪或未跟踪。已跟踪的文件是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后,它们的状态可能处于未修改,已修改或已放入暂存区。工作目录中除已跟踪文件以外的所有其它文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有放入暂存区。初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态。
- 标签
commit的别名。 - HEAD
特殊的引用,总是指向当前所在的commit。后缀^
表示上一个,^^
表示上上一个,^n
表示上N个(commit)。^
和~
等价。 - 分支
指向某一commit的引用。 - 合并
前进(快速)合并:被合并的分支位于当前分支的分支流的前端。则直接将当前分支前移指向被合并分支即可。
- 变基
变基操作命令流程:rebase
后需再merge
。
Git常用命令
git config
配置有3种级别,分别对应3个前缀:系统(system)、用户(global)、仓库(local)。默认级别是仓库,后者的设置会优先于前者的设置。
git help
查看帮助手册。
git init
将一个项目(文件夹)初始化为一个Git仓库。将在文件夹内创建名为.git
的子目录,该子目录标记其为一个Git仓库并存有Git仓库的骨干内容。该命令通常应用于已有项目。
git clone
克隆远程Git仓库到本地。远程仓库的所有历史记录也会被拉取到本地,本地所拥有的是一个完整的镜像版本。
git status
显示当前仓库内各文件的状态,以及当前处于哪个分支等信息。
git add
将文件或目录下的所有文件标记为跟踪状态,即纳入VCS管理。文件会处于已暂存状态。
.gitignore
- 所有空行或者以
#
开头的行都会被Git忽略。 - 可以使用标注你的glob模式匹配。glob模式是指shell所使用的简化了的正则表达式。
- 匹配模式可以以
/
开头防止递归。 - 匹配模式可以以
/
结尾指定目录。 - 要忽略指定模式以外的文件或目录,可以在模式前加上
!
取反。
git diff
比较尚未暂存的改动。--cached
或--staged
选项则比较暂存后但未提交的改动。
git commit
-
-m
选项可提交信息与命令放在同一行。 -
-a
选项会自动将已跟踪的文件暂存起来一并提交,从而跳过git add
步骤。 -
--amend
选项会修订上一次提交。若自上一次提交后暂存区无变化,那么修改的只有提交信息,否则会修订上一次提交的结果。
git rm
- 从已跟踪文件清单中移除(从暂存区域移除),该命令会连带从工作目录删除指定文件。
- 简单地从工作目录对文件执行删除操作,则会记录为一次删除变动(仍纳入版本管理中)。可在这之后再运行
git rm
从版本管理中移除。 - 若git rm前距离上一次提交对文件已暂存过,则需要加
-f(force)
选项。(文件的暂存理论上意味着文件计划被纳入下一次提交。) - 若仅想将文件设为未跟踪状态(从暂存区移除),但仍希望文件保留在工作目录中,添加
--cached
选项。当你忘记在.gitignore添加文件,或后悔了文件的暂存操作时,这一做法尤其有效。
例子:git rm log/\*.log。注意到星号*
之前的反斜杠\
,因为Git有它自己的文件模式扩展匹配方式,所以我们不用shell来帮忙展开。此命令删除log/
目录下扩展名为.log
的所有文件。
git mv
移动或者重命名文件,与直接mv
的区别类似于直接rm
与git rm
的区别。
git log
查看提交历史。
与
git status
的区别是:git status
观察范围是一个commit周期内,而git log
观察的对象是所有commit。
git remote
查看已配置的远程仓库信息。origin
是Git对远程仓库设置的默认名字。
-
-v
选项还会显示对应URL。 -
add <shortname> <url>
添加远程仓库。仅仅是配置而并未进行拉取或者克隆操作。 -
show [remote-name]
列出指定远程仓库的URL与跟踪分支等信息。 -
prune
移除已经不在服务器的远程仓库中的本地远程分支。 -
rename
修改远程仓库在本地的简写名。如origin
改为foo
。 -
rm
移除本地的远程仓库引用。
git clone <url>
将其配置为远程仓库并默认以origin
命名,自动设置本地master
分支跟踪远程仓库的默认分支(master
)。
git fetch <remote-name>
拉取服务器上的远程仓库数据到本地,含当前分支信息。该命令会抓取克隆或上一次抓取后新推送的所有工作,而并不会自动尝试合并到本地当前分支。合并对象:本地当前分支——本地当前分支跟踪的远程分支。
-
--all
选项拉取服务器上远程仓库的所有分支信息。
git pull
git fetch
且自动尝试合并分支。
-
--rebase
选项不合并而是变基。
git push <remote-name> <branch-name/tag-name>
将指定分支推送到远程仓库,也可推送标签到远程仓库。
-
--tags
选项会在推送分支到远程仓库时附带tag推送。默认时并不会推送tag。
git show <tag/commitid>
展示commit信息。
git tag
-
-l
选项,如git tag -l 'v1.8.5*'
。 -
-a
选项,打附注标签。-m
选项标签信息。
git reset [commitid/tagname] [file]
-
--mixed
选项将HEAD指向指定commit,回滚索引区。默认选项。 -
--soft
选项仅将HEAD指向指定commit。 -
--hard
选项将HEAD指向指定commit,回滚索引区,用指定commit的数据内容覆盖工作区的内容(丢弃工作区的修改)。
git reset [commitid/tagname] -- [file]
仅仅将暂存区的文件内容设置到指定commit节点。
git branch
- 不加参数显示分支列表。
-
<branch-name>
参数创建分支,但并不切换至该分支。 -
-d
选项删除指定分支。 -
-v
选项附带显示每个分支的最后一次提交。 -
--merged
或--no-merged
选项过滤分支显示列表。
git checkout
切换至分支。
-
-b
选项创建分支并切换到该新分支。
git checkout -- <file>
用暂存区覆盖工作区。
git merge
将当前分支与指定分支合并。
git rebase [basebranch] [topicbranch]
变基。
git stash
储藏工作区及暂存区的变动。储藏后工作目录是干净的。
-
list
查看储藏的列表。 -
apply
应用储藏的内容。如git stash apply stash@{2}
。如果还想要应用暂存区的变动,需要加--index
选项。
-
drop
删除指定储藏内容。 -
pop
应用栈顶储藏内容并删除之。 -
--keep-index
储藏时忽略暂存区的内容。 -
branch
应用储藏内容在新分支。避免冲突。
git clean
移除未被跟踪的文件。慎用。
git reflog
引用日志记录了最近几个月你的HEAD和分支引用所指向的历史。
附注
checkout VS reset --hard
checkout branch
跟reset --hard <commitid>
有点类似,均会更新3个区域使其看起来像branch
,但有2点主要不同。
- 对工作目录安全。它会在工作目录中尝试简单合并一下,使得工作区未修改的文件都会被更新,即有可能产生冲突。而
reset --hard
则不作检查。 - 分支的指向。假设有
develop
、master
两个分支切处在develop
中。
参考
- 《Pro Git 2nd Edition》
网友评论