首先必须说明,本文不是讲解GIT原理和深入的文章。只是对日常开发中比较常用的需求的总结,以及对这些GIT命令的一般原理的解释。所以掌握这个只能说是能够满足一定的开发需求。但如果你是一个追求极致价值和完美的人。你应该多了解一下GIT的具体模型和实现细节。需要注意的是,对于技术性的东西,先入门再深入理论是非常重要的。入门让你不断实践,加深理解,而不是纸上谈兵,看着理论无从下手。GIT的应用我们主要掌握GIT中团队开发辅助的常用命令和场景。在此之前,我们需要介绍一些必要的概念。A.基本概念1.Repositoryrepository,用过SVN的人应该都知道这就是repository。什么是版本库,简单理解就是用来存储和检索数据的仓库,但我们用它来存储代码,实现团队开发中的代码共享,实现协同工作。一个简单的地方用于确保软件项目中的代码是同步的。GIT中一般有两种版本库,一种是本地版本库,一种是服务器版本库(共享版本库)。这是因为GIT本身被设计成一个非中心化(分布式)的版本控制器。好处是在没有网络的时候,不用依赖服务器版本库(共享版本库)。想一想,你用SVN的时候,能不上网吗?如果你想让一个项目用GIT来管理,那么在项目所在的同级目录下应该有一个.GIT文件夹,本地仓库就存放在这个文件夹中。这时候在没有网络的情况下,可以在本地进行版本管理。当再次有网络连接时,本地版本库会与共享版本库同步。在GIT中,我们使用gitinit命令来创建和初始化存储库。它会自动生成.git文件夹和对应的文件,然后你就可以使用git进行版本管理了。使用了gitinit--bare(在共享版本库中),因为在共享版本库中,我们不需要项目文件夹(也就是工作区),因为共享版本库相当于一个服务器,存放着代码,不需要工作空间。总而言之,gitinit用于需要在我们本地工作空间管理的项目。gitinit--bare用于创建共享版本库,用于与本地版本库同步,实现多人开发的版本库。2.工作区所谓工作区就是你的项目所在的文件夹,可以统称为工作区。3、暂存区(stage、index)该区用于保存所有要提交到本地版本库的文件,称为stage或index。当执行gitcommit命令时,区域类的文件会被一次性提交到本地仓库。可以理解为相当于一个缓存区,用于缓存本地仓库要管理的文件。将文件添加到暂存区,需要使用gitadd命令添加。也就是说提交到本地仓库需要两步:gitadd+gitcommit。执行这两项后,只提交到本地版本库,只能自己使用。如果是团队开发,需要执行gitpush提交到共享版本库。4.HEAD指针简而言之,这里的HEAD指针是一个用来标识当前版本的。也就是我们通过HEAD指向的版本来判断当前版本,所以当我们切换版本的时候,我们所做的就是改变HEAD指针的指向。B.基本操作1.添加我们从GIT模型中知道,首先要提交到stage,然后再交给本地仓库管理。然后把stage提交到本地版本库,我把这一步总结为增加。这样就增加了数据库中的概念类比,方便学习。所以我们这里所说的添加又细分为添加到stage和添加到本地版本库。需要明确的是,本地版本库的添加是根据stage来的。具体实例说明。由于我们要模拟多人开发,所以首先要完成以下准备工作。准备工作1.创建一个SWPTest文件夹,我们将在其中为用户A创建一个工作区和一个共享代码库。执行以下操作:mkdirSWPTestcdSWPTest/mkdirAWorkersharedRep2。创建共享仓库(模拟远程仓库)cdsharedRepgitinit--bare3。用户A在服务器上下载存储库并准备工作。并添加.gitigonre忽略文件(用于过滤掉项目中未提交到仓库管理的文件)。(记得在SWPTest的根目录下执行命令)cdAWordordergitclone../sharedRep/touch.gitignore//在工作区创建了一个.gitignore文件open.gitignoregitadd.gitignore//执行完这一步后,将.gitignore文件提交到theworkspacetoTemporarystoragearea(cachearea)gitstatus-s//查询的是工作区和暂存区的文件状态(了解文件状态是重点)gitcommit-m"addgitignorefile"//执行后,将临时存储区的内容提交到本地仓库。此时暂存区被清空。然后将object-cignore信息粘贴到.gitignore文件中。(在Github上搜索gitignore)总结:以上三个小步骤分别是创建服务端版本库(1,2),以及客户端(3,)clone到本地(如果项目没有gitignore文件,最好自己添加,并添加到本地仓库和服务器端仓库(共享仓库)。补充总结(三种不同的补充)1.添加(提交)到stage:gitadd//的值是git要管理的文件。上面第三步的最后一个小步骤是Addstage2.添加(提交)到本地版本库:gitcommit//基于stagecache3.添加(提交)到共享版本库:gitpushoriginmaster//提交所有的当前暂存区的数据到共享版本库(远程Repository)执行以上3个小步骤后,还可以立即将文件同步到共享代码库,方便其他同事使用。gitpushoriginmaster//提交到主分支2.删除在执行删除模拟之前,我们首先做以下准备工作,创建三个源文件a.m、b.m、c.m。并准备交给本地仓库管理。所以在舞台上添加操作。具体如下suweipeng:sharedRepsixleaves$toucha.mb.mc.msuweipeng:sharedRepsixleaves$gitadd*.msuweipeng:sharedRepsixleaves$gitstatus-sAa.mAb.mAc.msuweipeng:sharedRepsixleaves$在查询当前暂存区的文件状态时,你会发现,已经变成了A(第一列表示暂存区,第二列表示工作区),说明已经添加到暂存区,状态为A(添加)。然后我们开始研究删除。通过模型我们可以知道git中存放文件的地方有3个,分别是工作区、暂存区(stage)和分支。所以,我们在学习之前应该问自己一个问题,如果有删除操作,是针对哪个区域的。我们通过具体操作来理解,如下(目标缓存区和工作区一起删除)mrm'a.m'suweipeng:sharedRepsixleaves$ls-altotal8drwxr-xr-x6sixleavesstaff20472116:43.drwxr-xr-x3sixleavesstaff10272111:34..drwxr-xr-x13sixleavesstaff44272116:43.git-rw-r9@--r--1sixleavegitignore-rw-r--r--1sixleavesstaff072116:27b.m-rw-r--r--1sixleavesstaff072116:27c.msuweipeng:sharedRepsixleaves$第一行的意思是从工作区中删除文件a.m并暂存Mark区域响应的文件中的删除操作。但是提示是错误的。根据提示,我们可以使用-f来强制执行。Git2.0中已经支持了一种更易于理解的文件删除方式。新方法:现在我们直接使用系统自带的rm程序来删除,而不是gitrm。步骤如下使用rm删除工作区中的文件。使用gitadd将工作区的移除添加到暂存区。(删除工作区和暂存区指定的文件)使用gitcommit-m"deletefileb"。从本地存储库中删除该文件。(删除工作区、暂存区、本地仓库指定的文件)使用gitpushoriginmaster。这时不仅可以删除本地仓库中的文件,还可以删除共享仓库中的文件。((删除工作区、暂存区、本地版本库、共享版本库中指定的文件)。也许你会想问,如果是已经提交到本地版本库的文件呢?只想removeitfromthelocal这种新方法不能用来删除版本库中的文件,因为这种方法的前提是你需要删除工作区中的文件,同时删除版本库中的文件。那么如何处理这个需求,请看下面gitrm分析:这时候我们来验证一下gitrm的范围,验证的时候我这边只剩下一个e.m文件,已经交给git管理了,在这次重新创建b.m和c.m,交给git管理。具体分析:首先,如何验证gitrm-fa.m删除了这两个区域?此时操作会影响版本库吗?答案是负的,只影响暂存区和工作区,即只删除这两个区的元素。验证思路很简单,我们创建一个文件z.m,然后提交到本地仓库进行管理。之后,暂存区被清空,所以此时只剩下版本库和工作区文件。这个时候我们执行gitrm,然后同步到共享版本库,然后共享到另一个员工工作目录Repository下的clone下,查看z.m是否存在。如果z.m存在,那么gitrm将不会影响存储库中的现有文件。在AWorker的工作区中,此时AWork的暂存区有两个文件。提交到本地版本库进行管理。并同步到共享版本库中。然后我们删除gitrm删除b.m文件。由于此时暂存区不存在该文件,所以gitrm不会提示Error。这个时候假设gitrm对本地版本库有影响,那么我们再将本地版本库同步到共享版本库中。如果有影响,此时共享版本库中将不存在该文件。于是我们在BWorker中执行gitpull命令进行验证。AWorkerssuweipeng:sharedRepsixleaves$gitstatus-sAb.mAc.msuweipeng:sharedRepsixleaves$gitcommit-m"addb,cfiles"[masterb8e8cc9]添加b,c文件2fileschanged,0insertions(+),0deletions(-)createmode100644b.mcreatemode100644c.msuweipengaves:sharedReps$gitpushoriginmasterCountingobjects:2,done.Deltacompressionusingupto4threads.Compressingobjects:100%(2/2),done.Writingobjects:100%(2/2),288bytes|0bytes/s,done.Total2(delta0),reused0(delta0)到/用户/sixleaves/SWPTest/AWorker/../sharedRep/97b6aa0..b8e8cc9master->mastersuweipeng:sharedRepsixleaves$gitrmb.mrm'b.m'suweipeng:sharedRepsixleaves$ls-ltotal0-rw-r--r--1sixleavesstaff072117:27c.m-rw-r--r--1sixleavesstaff072117:16e.msuweipeng:sharedRepsixleaves$gitpushoriginmasterEverythingup-to-datesuweipeng:sharedRepsixleaves$在BWorker中执行gitpull命令,具体如下,可以看到BWorker工作pullb.mc.me.m后存在区域所以我们可以得出结论,gitrm只是针对工作空间和临时sto狂暴区。当文件同时存在于两个区域时,删除文件会出错。我们需要指定是否将文件保存在工作区中。BWorkersuweipeng:sharedRepsixleaves$pwd/Users/sixleaves/SWPTest/BWorker/sharedRepsuweipeng:sharedRepsixleaves$gitpullremote:Countingobjects:2,done.remote:Compressingobjects:100%(2/2),done.remote:Total2(delta0),重用0(delta0))Unpackingobjects:100%(2/2),done.From/Users/sixleaves/SWPTest/BWorker/../sharedRep97b6aa0..b8e8cc9master->origin/masterUpdating97b6aa0..b8e8cc9Fast-forwardb.m|0c.m|02fileschanged,0insertions(+),0deletions(-)createmode100644b.mcreatemode100644c.msuweipeng:sharedRepsixleaves$ls-altotal8drwxr-xr-x7sixleavesstaff23872119:00.drwxr-xr-x3sixleavesstaff10272117:18..drwxr-xr-x15sixleavesstaff51072119:00.git-rw-r--r--1sixleavesstaff83672117:18.gitignore-rw-r--r--1sixleavesstaff072119:00b.m-rw-r--r--1sixleavesstaff072119:00c.m-rw-r--r--1sixleavesstaff072117:18e.msuweipeng:sharedRepsixleaves$最后分别总结这三个区域,删除工作区如下:(如果文件已经交给git管理)这种情况下,版本库必须也是同步的,所以实际上是新方法的完整过程。如果还没有提交给git管理,可以直接使用rm删除。暂存区的删除(不删除工作区):gitrm<文件名>--cached分支(仓库)的删除:所谓的删除分支其实是没有必要的,因为每次commit都会有新的版本被生成。如果出现问题,我们可以直接使用gitreset来回滚版本。所以如果要实现版本库的删除效果,只能使用版本回滚。其他:同时删除工作区和暂存区:gitrm-f3.修改有一点需要明确的是,当你把文件交给git管理的时候,一旦你修改了一个文件(不管是换行还是空格都算在内),此时git会跟踪文件发生了变化。也就是说,这时候,每次修改后,都必须添加到暂存区,然后commit。三篇文章,应有尽有!!!每次修改都要添加到暂存区,保持暂存区文件的最新状态,这样commit后,版本库才会保存修改后的文件!!!.我觉得改的就是这个注意点,比较简单,所以具体操作可以参考官方文档。所以我把变化分为两种,一种是为我自己的编程任务编码的“变化”。一个是你需要从共享版本库更新最新代码的“变化”。前者不再赘述,后者简单说明。在git中,我们可以使用gitpull来更新一个已经关联了共享版本库的本地版本库,以及对应的工作空间。严格来说,gitpull=gitfetch+merge。即一步是取数据,一步是合并数据,所以gitpull在合并的时候可能会造成数据冲突,冲突的解决方法后面会详细介绍。到这里我们就可以暂时掌握简单的更新操作了。4、检查所谓检查有两种,一种是检查版本记录。一是检查暂存区和工作区文件的区别,从而判断何时更新暂存区文件。查看版本记录:就是查看版本(gitlog,gitreflog)。前者是当前存在的可追溯版本,后者是历史记载中存在的版本。一般我们如果要回滚版本,使用gitreflog会比较方便,应该可以查看所有版本的历史记录。suweipeng:sharedRepsixleaves$gitlogcommit7f0486eda9bfcaaae56ec8382be580d446d854d3Author:sixleaves<18649772243@163.com>Date:TueJul2120:09:532015+0800添加了main.mcommit97b6aa090388d0fc1b73eaeb615d86faf83807f7Author:sixleaves<18649772243@163.com>Date:TueJul2117:20:052015+0800删除文件bcommitef1169ef156294cfd68ac10b568781ca9ab4a15cAuthor:sixleaves<18649772243@163.com>Date:TueJul2117:16:462015+0800添加了e文件commit4eb100209198d1f5c7bf914bdf9776795f7753f1Author:sixleaves<18649772243@163.com>Date:2015年7月21日星期二17:15:00+0800添加了b文件suweipeng:sharedRepsixleaves$gitreflog7f0486eHEAD@{0}:提交:添加了main.m97b6aa0HEAD@{1}:重置:移动到97b6aa0b8e8cc9HEAD@{2}:commit:添加b和c文件97b6aa0HEAD@{3}:commit:删除文件bef1169eHEAD@{4}:commit:添加e文件4eb1002HEAD@{5}:commit:添加b文件a18151cHEAD@{6}:commit(initial):addgitignorefilessuweipeng:sharedRepsixleaves$检查工作区的文件状态:gitstatus命令会去如果暂存区不存在,则到暂存区与工作区进行比较,并且如果工作区存在,两个?,说明还没有提交给git管理。这时候可以执行gitadd命令提交到暂停区。此时暂停区的文件状态变为A,表示已加入暂停区。如果提交到本地版本库,那么git可以管理文件,所以此时使用gitstatus查询是没有结果的,因为暂停区已经清空(执行gitcommit后清空),而在工作区已经交给git管理,没有发送任何改动。suweipeng:sharedRepsixleaves$gitstatus-s??1.msuweipeng:sharedRepsixleaves$git添加1.msuweipeng:sharedRepsixleaves$gitstatus-sA1.msuweipeng:sharedRepsixleaves$vim1.msuweipeng:sharedRepsixleaves$gitstatus-sA1.msuweipeng:sharedRepsixleaves$vim1.msuweipeng:sharedRepsixleaves$gitstatus-sAM1.msuweipeng:sharedRepsixleaves$gitadd1.msuweipeng:sharedRepsixleaves$gitstatus-sA1.msuweipeng:sharedRepsixleaves$-mgitcommit"Add1.m"[masterf6378aa]添加1.m1个文件改变,1个插入(+)createmode1006441.msuweipeng:sharedRepsixleaves$gitstatus-ssuweipeng:sharedRepsixleaves$如果修改了main.m文件,那么此时第二列变成红色M,说明工作区中的文件被修改了,此时git中版本库中的文件和这个文件不一样,所以我们要先同步一下。gitadd,此时文件的状态由工作区的M变为临时区的M,并且变为绿色,而工作区的M消失。这时候可以使用gitdiff查看工作区和挂起区的具体变化。suweipeng:sharedRepsixleaves$触摸2.msuweipeng:sharedRepsixleaves$gitadd2.msuweipeng:sharedRepsixleaves$vim2.msuweipeng:sharedRepsixleaves$gitstatus-sAM2.msuweipeng:sharedRepsixleaves$gitdiffdiff--gita/2.mb/2.mindexe69de29..abe4786100644---a/2.m+++b/2.m@@-0,0+1@@+dddddsuweipeng:sharedRepsixleaves$上图表示修改后的文件类型,添加一个newlineddddchecksummary1.使用gitlog或gitreflog查询版本记录。前者记录的是当前版本号的迭代顺序(回滚可能会被覆盖)。后者记录了所有的历史版本记录。(后者包含前者)。2、使用gitstatus-s可以知道暂存区的数据是否是最新的,是否有没有被添加到暂存区的文件。3.如果暂存区的数据不是最新的,可以使用gitdiff查看变化的数据。gitdiff中的格式说明---:表示变化前的文件(工作区文件)。+++:表示改变的文件(暂存区文件)。没有减号或加号的行表示未更改的行。带-号的行表示在第一个文件中删除的行,+号表示在第二个文件中添加的行。@@-1,7+1,7@@这句话中的减号和加号分别代表第一个文件和第二个文件。文件状态汇总:补充:暂存区D和工作区D的区别:1、第一列绿色D,即暂存区,表示文件已从工作区删除workspace,以及删除标记提交到暂存区,如果此时再次执行gitcommit,就会从版本库中删除。2、第二列红色的D,表示工作区上的文件已经被删除,但是删除操作还没有提交到暂存区。只有提交到暂存区,才有机会在git中删除。红色和绿色只是为了让你快速区分暂存区和工作区文件状态的修改状态。这是第一篇简单介绍GIT的文章。有什么疑问可以给我留言,我们可以互相交流。后面的文章会介绍git中的冲突解决等问题。重剑无锋,巧得工夫。