cater

IT、爱情、运动、音乐、生活。。

Git基础

Git是当今最为先进的分布式版本控制系统之一,当前国内大部分互联网都在使用。一直以来,我都是皮毛式地使用Git,到实习了才发现这Git,只要你身处互联网,是不得不熟悉啊!难得抽出点时间,好好总结一下Git常用的命令的用法。

一、Git基础

三个工作区域

Git中有三个工作区域:工作区(Working directory)、暂存区(staging directory)和仓库(Git directory)。一般工作流程:

  • 在工作区添加或修改文件,状态:已修改(modified)
  • 使用git add命令添加到暂存去,状态:已暂存(staged)
  • 使用git commit命令添加到仓库,状态:已提交(commited)

工作区就是我们平时写代码的目录,当我们修改文件后通过git add以快照的形式暂存在暂存区中,暂存区域只不过是个简单的文件,一般都放在 git 目录中。仓库则是Git最重要的部分,以数据链的形式不同的commit对象。并且只有一个HEAD指针指向正在工作的分支。

Git 仓库

文件保存

Git区别于其他版本控制系统,Git只关心数据的整体是否变化,而大多数其他系统则关心文件内容的具体差异。这类系统(CVS)等每次纪录有哪些文件做了更新,以及都更新了哪些行的内容。而Git并不保存这些前后变化的差异数据,只对变化的文件作快照后,记录在一个微型的文件系统中,若文件没有变化,则对上次保存的快照作一链接。


Git 文件保存


二、基本用法

文件在工作区间的转换

Git 工作区间的转换

以上的四条命令在工作区、暂存区(也叫索引)和仓库间转换(文件快照)。

  • git add files: 把当前修改的文件加入到暂存区
  • git commit -m “描述内容”: 把暂存区的内容提交到仓库
  • git reset -- files: 撤销暂存区文件,用来撤销git add操作
  • git checkout -- files: 把文件从暂存区府复制到工作区,用来丢弃本地修改(没有add到暂存区)

也可以跳过暂存区直接从工作区提交文件到仓库或反之。

Git 工作区间的转换

  • git commit -a -m “描述内容”: 相当于git add + git commit -m
  • git checkout HEAD – files: 把仓库HEAD指向的快照复制到暂存区和工作区


三、命令详解

基础状态

Git 文件目录
下面命令以上图为基础,绿色的5位字符表示提交的ID,分别指向父节点。分支用橘色显示,分别指向特定的提交。当前分支由附在其上的HEAD标识。 这张图片里显示最后5次提交,ed489是最新提交。 master分支指向此次提交,另一个maint分支指向祖父提交节点。

diff

Git diff
使用git diff 可以查看工作区与暂存区,暂存区与仓库,两次提交间的不同,加文件名可以指定文件的不同。

commit

提交时,git用暂存区域的文件创建一个新的提交,并把此时的节点设为父节点。然后把当前分支指向新的提交节点。下图中,当前分支是master。 在运行命令之前,master指向ed489,提交后,master指向新的节点f0cec并以ed489作为父节点。 Git commit

如果想更改一次提交,使用 git commit –amend。git会使用与当前提交相同的父节点进行一次新提交,旧的提交会被取消。 Git commit

Checkout

‘git checkout’ 命令多用于切换分支或者从历史提交(或者暂存区域)中拷贝文件到工作区(或者也拷贝到暂存区) 当给定某个文件名(或者打开-p选项,或者文件名和-p选项同时打开)时,git会从指定的提交中拷贝文件到暂存区域和工作目录。比如,git checkout HEAD~ foo.c会将提交节点HEAD~(即当前提交节点的父节点)中的foo.c复制到工作目录并且加到暂存区域中。(如果命令中没有指定提交节点,则会从暂存区域中拷贝内容。)注意当前分支不会发生变化。 Git checkout拷贝文件

当不指定文件名,而是给出一个(本地)分支时,那么HEAD标识会移动到那个分支(也就是说,我们“切换”到那个分支了),然后暂存区域和工作目录中的内容会和HEAD对应的提交节点一致。新提交节点(下图中的a47c3)中的所有文件都会被复制(到暂存区域和工作目录中);只存在于老的提交节点(ed489)中的文件会被删除;不属于上述两者的文件会被忽略,不受影响。 Git checkout切换分支

如果既没有指定文件名,也没有指定分支名,而是一个标签、远程分支、SHA-1值或者是像master~3类似的东西,就得到一个匿名分支,称作detached HEAD(被分离的HEAD标识)。这样可以很方便地在历史版本之间互相切换。比如说你想要编译1.6.6.1版本的git,你可以运行git checkout v1.6.6.1(这是一个标签,而非分支名),编译,安装,然后切换回另一个分支,比如说git checkout master。然而,当提交操作涉及到“分离的HEAD”时,其行为会略有不同,详情见在下面。 Git checkout匿名分支

reset

reset命令把当前分支指向另一个位置,并且有选择的变动工作目录和索引。也用来在从历史仓库中复制文件到索引(暂存区),而不动工作目录。 如果不给选项,那么当前分支指向到那个提交。如果用--hard选项,那么工作目录也更新,如果用–soft选项,那么都不变。 Git reset改变HEAD指向和暂存区

如果没有给出提交点的版本号,那么默认用HEAD。这样,分支指向不变,但是索引会回滚到最后一次提交,如果用–hard选项,工作目录也同样。 Git reset改变HEAD指向和暂存区

如果给了文件名(或者 -p选项), 那么工作效果和带文件名的checkout差不多,除了索引被更新。 Git reset改变HEAD指向和暂存区

merge

merge 命令把不同分支合并起来。合并前,索引必须和当前提交相同。如果另一个分支是当前提交的祖父节点,那么合并命令将什么也不做。 另一种情况是如果当前提交是另一个分支的祖父节点,就导致fast-forward合并。指向只是简单的移动,并生成一个新的提交。 Git merge

否则就是一次真正的合并。默认把当前提交(ed489 如下所示)和另一个提交(33104)以及他们的共同祖父节点(b325c)进行一次三方合并。结果是先保存当前目录和索引,然后和父节点33104一起做一次新提交。 Git merge

cherry Pick

cherry-pick命令复制一个提交节点并在当前分支做一次完全一样的新提交。 Git cherry-pick

rebase

衍合是合并命令的另一种选择。合并把两个父分支合并进行一次提交,提交历史不是线性的。衍合在当前分支上重演另一个分支的历史,提交历史是线性的。 本质上,这是线性化的自动的 cherry-pick Git cherry-pick

上面的命令都在topic分支中进行,而不是master分支,在master分支上重演,并且把分支指向新的节点。注意旧提交没有被引用,将被回收。 要限制回滚范围,使用–onto选项。下面的命令在master分支上重演当前分支从169a6以来的最近几个提交,即2c33a。 Git cherry-pick

引自-图解Git

标签 : technology
南山南-cater
00:00