背景:
由于公司内部目前采用git来进行代码管理,因此近期会逐步更新部分关于git的介绍。一来是为了给大家提供一个集中学习和参考的地方;二来是希望通过具体的示例来给出git的操作指南。虽然之前介绍过很多关于git的使用但不够系统,不够集中。这次希望通过几篇连续的博文给出一个简单的git实用指南。
既然提到了开发代码的版本管理,那么首要的就是从目标仓库中获取开发代码,即SVN中常用的检出(checkout)。本系列就从git的代码检出(git checkout?)开始!
git的几个关键概念
相较于SVN等其他版本管理系统,GIT的组织结构略显复杂,但正是因为这样,才使得GIT这一分布式的版本管理系统更能适应多变的开发环境和协同需求。在SVN中只有本地副本(working copy)和版本库(repository)两大部分,在GIT中结构复杂一些,包括:
working tree:也叫working directory.与SVN的本地副本有些类似,但也有不同。官方手册对working tree的介绍为:
The working directory is a single checkout of one version of the project. These files are pulled out of the compressed database in the Git directory and placed on disk for you to use or modify.
index:也叫staging area.可以简单的理解为缓冲区。官方手册对index的介绍为:
The staging area is a file, generally contained in your Git directory, that stores information about what will go into your next commit. It’s sometimes referred to as the “index”, but it’s also common to refer to it as the staging area.
repository分为local repository(本地的版本库)和remote repository(远程仓库)。由于git采用无中心分布式设计,因此本质上来说local repository与remote repository的地位是相同的,内容也几乎相同(远程仓库可能为了协同开发会绑定相关集成脚本),唯一的不同就是remote repository可以被更多的开发者访问,而local repository仅仅是个人工作环境的维护。官方手册对于repository(即.git目录)的介绍为:
The Git directory is where Git stores the metadata and object database for your project. This is the most important part of Git, and it is what is copied when you clone a repository from another computer.
为了说清楚上述几个概念,这里节选了几幅比较形象的示意图:
如上述图片所示,正式因为在本地存在着完完整整的仓库目录(.git目录),在工作副本和仓库之间添加了Staging Area缓冲区,才使得git能够实现本地和远程双重管理。
git的日常操作流workflow
官方文档给出了git版本管理系统下的文件的各种状态,包括untracked、unmodified、modified、staged。如下图所示:
git不单单是一个版本管理系统,其实可以看成是一个mini的文件系统,用于管理文件和日常的所有操作。git中的所有操作会使得git文件系统内部的各文件状态在上述四种之间来回切换。如下面两张截图所给出的git的各种日常操作指令。
【备注】:这里要注意,不要将git所管理的文件的状态(untracked、unmodified、modified、staged)与git自身的阶段(working tree、index、local repository、remote repository)相混淆。
(1)working tree中的文件可以包含多种状态,例如从版本库上一次提交snapshot检出的文件处于tracked和unmodified状态、本地对tracked文件的任何修改会使文件处于modified和staged(git add操作即可)状态,本地新增文件或其他操作会使得文件处于untracked状态;
(2)index中的文件只能处于modified和staged状态(同时处于);
(3)repository(local or remote)中文件的状态只能处于unmodified的跟踪状态。——当然这句话还有待考究,这里严格意义来说是从repository中检出的文件只能处于unmodified的tracked状态,因为你只能从别的仓库中将unmodified的tracked状态的文件拉倒本地。但原始的仓库中其实有可能存在着其他状态的文件,但是对外来讲是隐藏的、透明的。
git的代码“检出”
其他版本库管理系统(例如SVN)一般都会使用checkout来直接检出服务端的版本库(即开发代码)到本地工作目录,而git checkout却不能实现这一功能,原因是:
If you’re familiar with other VCS systems such as Subversion, you’ll notice that the command is “clone” and not “checkout”. This is an important distinction – instead of getting just a working copy, Git receives a full copy of nearly(服务器会存在部分hooks或者其他文件,详情参考Git Internals) all data that the server has. Every version of every file for the history of the project is pulled down by default when you run git clone.
上文提到了git采用分布式无中心化设计,因此检出代码的同时需要将完整的仓库下载到本地。所以简单的checkout是不能完成这项任务的,在git中应该使用git clone将远程仓库检出到本地。