一、 对git的介绍
Git 与常用的版本控制工具 CVS、Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持,使源代码的发布和交流极其方便。
1.1、git是分布式而非集中式版本控制
一个集中式的版本控制系统如上图所示。其特点就是有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。这种做法的好处是:每个人都可以在一定程度上看到项目中的其他人正在做些什么。而管理员也可以轻松掌控每个开发者的权限,并且管理一个 CVCS 要远比在各个客户端上维护本地数据库来得轻松容易。这种做法最显著的缺点是:对于中央服务器的过度依赖,如果服务器宕机,那么大家将无法协同工作。甚至,如果中央服务器的磁盘发生故障,那还会有丢失数据的风险,最坏的情况可能会丢失整个项目所有的历史更改记录,而被客户端提取出来的某些快照数据除外。
一个分布式的版本控制系统如上图所示。其特点是客户端并不是只提取最近版本的文件快照,而是把原始的代码仓库完整地镜像下来。这样就算任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库来恢复。每次提取操作实际上都是一次对代码仓库的完整备份。甚至,许多这类系统可以指定和若干不同的远端代码仓库进行交互。这样,你就可以在同一个项目中分别和不同的工作小组的人协作,你可以设定分层式的工作流,这在集中式的版本控制系统中是无法做到的。
1.2、git保存更新时的文件快照而非差异
git是一个分布式版本控制系统。保存更新时的文件快照而非差异。Git 与其他的版本控制系统的主要差别还在于:Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。
Git 采用这样的设计带来了这些好处:
- 近乎所有的操作都是本地执行。
- 时刻保持数据的完整性。在保存到 Git 之前,所有数据都要进行内容的校验和(checksum)计算,并将此结果作为数据的唯一标识和索引。如果文件在传输时变得不完整,或磁盘损坏导致文件数据缺失,Git 能立刻察觉。
大多数 Git 操作都只是添加数据。我们都知道数据删除了,那么想回退或重现就变得非常困难。在 Git 中大多数操作只是添加数据,回退和重现变得容易而有保障,所以提交快照后就完全不用担心丢失数据。
1.3、Git管理下文件的状态
git管理下文件有三种状态:
- 已修改(modified),表示该文件当前被修改过了,但是还没提交保存,当前的状态也没有做快照暂存。
- 已暂存(staged),表示对这个被修改的文件做了快照,并把快照放在下次提交时要保存的清单中了。
- 已提交(commited),表示该文件已经被安全地保存在本地数据库中了。
所以基本的git工作流程一般是这样的:
git管理下的文件在这三种状态下切换情况以及对应的git命令:
当我们从某个地方clone一分代码后,通常这是的工作仓库是clean的。所有的代码都是commited状态。下面我们解释一下个各状态之间的转换方式:
- commit-1—>Modified,当我们对commit-1状态的代码进行修改后,文件状态发生变化,右commited-1变为Modified。
- Modified—>commit-1,发现文件修改的不对,一处处恢复比较麻烦,此时用 git checkout #filePath命令便可以把对文件的修改恢复到原commit-1状态。
- Modified—>Staged,如果你修改的文件不再暂存区内时,你是无法用 git commit 提交的。因为 git commit 是对文件暂存区域的文件快照进行提交。所以你需要把文件快照放到暂存区域。用 git stage #filePath 命令。也可以用 git add #filePath 命令。
- Staged—>Modified,绕线目前不想把下次commit时提交文件暂存区的某个文件,还想再改改或再缓缓,这是你需要把它的快照撤回来,用 git reset #filePath 命令。
- Staged—>commit-2,使用 git commit 命令就可以把暂存区域的文件快照提交到git版本库永久存储了,这时文件状态变为commit-2。
- Modified—>commit-2,看了上面的流程,有人会问了,我每次改了都要先stage才能提交太麻烦了。我们可以用 git commit -a 就可以把git管理下的文件修改都提交了。这里需要注意的是,新增文件是不再git管理下的,需要 git add #filePath 把文件添加到staged中才行。
撤回提交。如果我已经commit后发现我提交错了,这是我要撤回。这里有两种选择,但是需要搞清楚他们的区别。
1)、用 reset 撤销提交。用reset撤销就是真的删除了提交信息,回退到之前的状态了。不过有下面几种情况:
commit-2—>Staged,从这次提交回到上次提交后的Staged状态用 git reset HEAD^ –soft 命令。
commit-2—>Modified,从这次提交回到上次提交后的Modified状态用 git reset HEAD^ –mix 命令。上次提交后的修改都还在。–mix是默认选项。
commit-2—>commit-1,从这次提交回到上次提交后的commit-1状态用 git reset HEAD^ –hard命令。此时上次提交后的修改都没有了。
2)、用revert反向提交。用revert也可以撤销此次提交,但是它跟reset是不一样的,revert本质上也是一次提交,只不过它是一次与上次提交相逆的提交。
commit-2—>commit-1,我们在commit-2这个状态使用 git revert HEAD 命令,就可以直接回到commit-1状态了。
commit-1—>commit-2,有意思的是,接着上次的revet我们在commit-1这个状态再使用一次 git revert HEAD 命令,会发现我们又回到commit-2状态了。这是合理的,逆提交的逆提交就变成正提交了。1.4、对HEAD的解释
HEAD文件是一个指向你当前所在分支的引用标识符。这样的引用标识符看起来并不像一个普通的引用,其实并不包含SHA-1值,而是一个指向另一个引用的指针。下面我们来看一下这个问价的内容:
当你执行 git branch <分支名称> 这条命令的时候,git怎么知道最后一次提交的SHA-1值呢?这就是HEAD在搞鬼。
此时我切换分支到 anywhere上,那么我们再次查看一下HEAD文件的内容:
二、常用git命令
本地(Local)
配置一些用户名和邮箱等设置,在此忽略。
2.1、设置忽略文件
1)设置项目的忽略文件:
被忽略的文件发生任何变化,都不会再git中显示出来。也就是git不管这些文件的内容变化。
- 1.在根目录下创建一个 .gitignore 文件,在里面添加要忽略的文件或文件夹,一个一行;
2.将 .gitignore 文件加入版本库并且提交。
2)设置只要自己需要忽略的文件:
1.修改 .git/info/exclude 文件,可用正则表达式
2.2、添加新文件到版本库
基本的操作忽略。
2.3、提交
2.4、撤销修改
撤销尚未提交的修改:
撤销提交
2.5、分支
2.6、解决冲突
冲突很少时,直接编辑冲突的文件然后提交即可。
冲突比较复杂时,用 git mergetool 调用之前设定的merge工具来处理。
1、自动生成 BACKUP,BASE,LOCAL和REMOTE四个文件
2、调用设定好的merge工具
3、解决之后,关闭工具,BACKUP,BASE,LOCAL和REMOTE四个辅助文件会自动删除,但会同时生成一个 .orig 的文件来保存冲突前的现场。需手动删除这个文件
4、提交
2.7、标签
2.8、查看状态
2.9、其它
远端(Remote)
1.1、初始化
1.1.1、克隆版本库和添加远程版本库
1)当已经有一个远程版本库,只需要在本地克隆一份:
2)当在本地创建一个工作目录,想把这个目录用Git管理,并初始化到远程版本库,可以在远程服务器上创建一个目录,并把URL记录下来。在本地进入工作目录,然后 执行:
1.2、分支
1.3、从远程仓库获取
推荐用下列方式从远程获取: