开发工具之Git工具--版本控制神器

LidaJ45 7年前
   <p><strong>写在前面</strong></p>    <p>Git版本控制工具是由Linux之父 <strong>Linus Torvalds</strong> 开发的,Git工具的出现降低了软件版本维护的成本,极大的提高了工作效率。熟练的使用Git工具是一个合格的开发者的基本技能。而关于Git我们学习的重点和难点有两部分, <strong>第一就是Git复杂的指令</strong> ,这些指令我希望你不要去背它,那将会是一件非常痛苦的事情。所谓熟能生巧,你只需要多多使用它即可,实在想不起某个指令查就是了。 <strong>第二就是Git的思想</strong> ,想学好Git,就必须得对Git的思想有很好的理解,否则你始终有一种很不爽的感觉,总想抓住点什么却总又抓不住....= =</p>    <h3><strong>一、版本控制工具的分类</strong></h3>    <p>目前市面上的版本控制工具主要分为 <strong>集中式版本控制工具</strong> 和 <strong>分布式版本控制工具</strong> 两种。</p>    <ul>     <li>集中式版本控制工具<br> 带头大哥——SVN。它有一个中央服务器控制着所有的版本管理,所有的终端都可以对这个中央库进行操作,中央库保证版本的唯一性。<br> 缺点:<br> <strong>1.安全性差</strong> 如果中央服务器出现故障,那么整个项目的版本控制将要付出沉重的代价。<br> <strong>2.通信频繁</strong> 终端无论是提交修改还是获取更新都需要不断与服务器进行通信,一旦网络出现故障,就很难再继续操作下去。</li>     <li>分布式版本控制工具<br> 分布式版本控制工具终端可以获取到中央服务器的完整信息,就好像做了一个完整的镜像。这样我们就可以在终端获取各种信息,提交管理我们的代码而不需要与服务器频繁通信,即使中央服务器出故障,各个终端仍有完整的备份。但实际上分布式版本控制工具也有一个“中央服务器”,它的作用主要是用来最后提交代码和方便拉取备份的,并不会像集中式版本控制工具那样严重依赖网络。</li>    </ul>    <h3><strong>二、Git的安装与配置</strong></h3>    <p>关于Git的 <strong>安装</strong> 没什么值得说的,直接下一步即可。安装完Git后,在控制台输入 <strong>git</strong> 只要出现一屏你看不懂的东西就表示你成功了!</p>    <p>对Git Global参数进行配置:</p>    <p>打开Git cmd 输入如下内容可以增添一个配置</p>    <p>git config --global --add user.name xxx user.email xxx@xx.com</p>    <p>删除一个配置:</p>    <p>git config --global --unset user.name xxx</p>    <h3><strong>三、Git指令</strong></h3>    <p>接下来我们学习Git指令,这些指令你将会反复查阅实践,只有这样你才能做到知行合一,大师可成也。</p>    <p>接下来的指令,你可以跟我一步一步的来,我们共同学习。你可以随便在某处建一个文件夹,比如桌面,然后进入这个文件夹-右键- <strong>Git Bash Here</strong></p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/c97dc8063438c026ba10a6bb3b0fcdb0.png"></p>    <p>多说一句,Git GUI Here是指在当前目录打开Git图形化工具,Git Bash Here 是在当前目录打开命令行工具。而我们要学的 就是Git Bash Here,因为Git GUI Here已经不用我教你。</p>    <ul>     <li> <p><strong>创建Git仓库</strong></p> </li>    </ul>    <p>为了管理代码,代码要关在仓库里面。仓库是 <strong>自己创建</strong> 或者 <strong>clone</strong> 的。<br> 1. <strong>Git init——将一个目录快速设置为Git代码仓库</strong></p>    <p style="text-align: center;"><br> <img src="https://simg.open-open.com/show/566cc94712ccfa0fa42044adf3d99b0d.png"></p>    <p>仓库创建成功后,会在当前目录中生成一个.git目录,这是一个隐藏文件夹,包含所有的版本和配置信息。关于这个文件夹的目录结构,这里先不说,等你对Git思想掌握后,再去研究也不迟。</p>    <p>2. <strong>Git clone——clone一个仓库</strong></p>    <p>我们可以在github上clone一个远程仓库到本地。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/206325ddb5b7f7db0c0edd01f841e869.png"></p>    <p>在clone的时候,可以选择HTTPS或者SSH,一般我们都会使用SSH,因为HTTPS要求帐户密码验证。</p>    <p>得到地址后,使用 <strong>git clone 某仓库地址</strong> 命令如下:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/f375ce059ac8930e6e4add20c35197bd.png"></p>    <p style="text-align: center;"> </p>    <p>可以看到,远程仓库已经clone下来了。</p>    <ul>     <li> <p><strong>提交修改</strong></p> <p>为了演示方便,可以先在文件夹中创建一个文本文件test.txt,然后随便写点什么,使用 <strong>git status</strong> 查看当前仓库状态:</p> </li>    </ul>    <p style="text-align: center;"><br> <img src="https://simg.open-open.com/show/2a7a8cc7fa841f32fb9acb5812906b0f.png"></p>    <p>可以看到 Git追踪到了新的文件,并提示我们使用 <strong>git add <file></strong> 添加版本控制。最后使用 <strong>git commit <file> --m "提交描述"</strong> 将add后的文件提交到代码仓库:</p>    <p> </p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/9105a94ddcb3c6dc76dce1e6f6dbbf8f.png"></p>    <p>你可以使用 <strong>git log</strong> 或者 <strong>git shortlog</strong> 查看提交记录,其中 <strong>git shortlog</strong> 是按照提交者分类的一个简短log日志。</p>    <ul>     <li> <p><strong>追加修改</strong></p> <p>当想要修改 <strong>上次提交描述信息(即:--m后面的描述)</strong> 的时候,可以使用 <strong>git commit --amend -m ''提交描述信息"</strong> :</p> </li>    </ul>    <p style="text-align: center;"><br> <img src="https://simg.open-open.com/show/9913d430e9faa7ddb35b82c0421e0077.png"></p>    <ul>     <li> <p><strong>查看仓库状态</strong></p> 通过查看仓库状态,我们能够了解当前文件状态以及版本之间的差异。除了使用前面提到的 <strong>git status</strong> 指令,我们还可以使用 <strong>git diff <file></strong> 指令查看某文件的具体变化内容,使用 <strong>git diff "节点名称"</strong> 比较与指定节点之间的差异:</li>    </ul>    <p style="text-align: center;"><br> <img src="https://simg.open-open.com/show/a14fff99608aa8e175960f3170e25d43.png"></p>    <p>节点名称可以指定为HEAD、HEAD^、HEAD^^、HEAD^^^...分别代表当前版本,上一版本,上上版本,以此类推。</p>    <ul>     <li> <p><strong>版本历史</strong></p> 一个仓库中通常会有非常多次的add和commit,这些过程都会被git记录下来,使用 <strong>git log</strong> 指令,会列出所有的提交记录。使用 <strong>gitk</strong> 指令查看图形化的log记录:</li>    </ul>    <p style="text-align: center;"><br> <img src="https://simg.open-open.com/show/1cb73f5d2f4ea6284bd55653547d82e7.png"></p>    <p>commit id 是一个40位16进制的SHA-1 hash code用来唯一标记一个commit。</p>    <p>gitk图形化工具比命令行展示的信息更加条理丰富,Git会将commit串成一条时间线,每个点就代表一个commit。</p>    <p>除此之外,还可以使用 <strong>git blame</strong> 指令追溯一个指定文件的历史修改记录:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/c04231a5f313385958254fcc4d19fc03.png"></p>    <p>注意信息中列出了不同的id 修改者 时间 和 内容</p>    <ul>     <li> <p><strong>Git的操作区域</strong></p> <p>Git通常是工作在三个区域上的,即工作区,暂存区和历史区。其中,工作区就是开发者平时工作,修改代码的区域;历史区是用来保存各个版本的区域;暂存区则是Git的核心所在,它被保存在 <strong>.git/index</strong> 文件中。</p> <p>git管理修改的是内容而不是文件,每个SHA-1的值也是根据内容计算出来的。</p> <p>我们执行add操作实际上是将修改的记录保存到暂存区,执行commit操作就是就是将暂存区的内容全部提交到历史区。</p> </li>     <li> <p><strong>Git回退</strong></p> 回退主要包括add操作之前,add操作之后但还没有执行commit操作,commit操作之后这样三种情景。</li>    </ul>    <p><strong>1. git checkout <file></strong> 指令:主要用在add操作之前和add操作之后commit操作之前,如果你在这两种情境下,修改了文件内容,想要回到修改文件内容之前,就可以使用这个指令,如图:</p>    <p style="text-align: center;"><br> <img src="https://simg.open-open.com/show/16044c565065835c341e8af231b4bc09.png"></p>    <p>git checkout操作实际上是用版本库里的版本(包括历史区和暂存区)替换工作区中的版本!<br> 你一定会有一个疑问,前面我们的回退操作并没有跨越工作区,那么我们怎么从暂存区甚至是历史区(也可以理解为撤销add以及commit)指令呢?别急,马上讲解!</p>    <p><strong>2. git reset HEAD <file></strong> 指令和 <strong>git reset <last commit id> <file></strong> 指令:<br> 前一个指令 <strong>用于commit之前</strong> ,撤销add指令,即退出暂存区到工作区。<br> 后一个指令用于commit之后,撤销commit指令,使用这个指令可以实现任意版本之间的跳转,当然"last commit id"不能是当前版本id。</p>    <p style="text-align: center;"><br> <img src="https://simg.open-open.com/show/fe125b2b5d0e890ce5c14be090167584.png"></p>    <p>3. <strong>git reset --hard HEAD^</strong> 指令:这个指令也是用于回退版本的。回退到上一个版本写作HEAD^,上一百个版本写作HEAD~100。这个指令和上一个指令 <strong>git reset</strong> 的区别就是,上一个指令可以在任意版本之间 <strong>"跳转"</strong> ,而本指令回退到某一个版本后,会把之后的版本全部删除。<br> <strong>note:</strong> 使用git reset指令进行版本回退后,使用git log指令你会发现之后的版本commit id都消失了,怎么办呢?其实,我们可以使用git log指令的pro版——git reflog指令解决这个问题,此处不再演示。</p>    <ul>     <li> <p><strong>Git文件操作</strong></p> Git提供了类似Linux的文件管理基本指令,下面介绍一下删除和暂存文件指令。<br> <strong>1. shell的rm命令</strong><br> 执行shell的rm命令,可以将某一文件删除,Git不仅可以监听到增加、修改文件,还可以监听到删除文件,同样需要通过git add/commit操作来完成一次新的提交。</li>    </ul>    <p style="text-align: center;"><br> <img src="https://simg.open-open.com/show/958d603c30d16f16b350bba4975d6c4f.png"></p>    <p><strong>2. git rm 命令</strong><br> git rm命令和shell rm命令的区别在于git rm命令省去了git add操作。</p>    <p style="text-align: center;"><br> <img src="https://simg.open-open.com/show/9f01897037ab0445d039d92226843bde.png"></p>    <p><strong>3. 文件暂存</strong><br> 这里的文件暂存,是指一次备份与恢复操作。<br> 怎么理解这个概念呢?你可以想象一种这样的开发情景:你在某一git 分支开发新功能,这时上司交给你一个新的任务,修复上一版本的bug。你是不能直接在当前分支拉取分支修复bug的,因为当前分支的代码并不完善,可能会出现各种各样的问题,甚至编译都不能通过。这时候,我们可以使用git stash命令将当前修改暂存起来,从其修改之前的分支拉取分支,进行bug的修复。bug修复完成后,可使用git stash list 指令查看之前储存的内容,使用 git stash apply指令或者git stash pop指令进行内容恢复(区别:前者不会删除记录,后者会)。</p>    <h3><strong>结语</strong></h3>    <p>考虑到篇幅问题,本文就先写到这里。但你要知道Git工具的使用远远不止这些,后续文章中 我将会继续介绍Git的远程仓库,分支管理,Tag等知识点,这些知识也都是非常重要的 。 <strong>学习Git,你最好亲自去敲敲命令,光看是远远不够的。</strong></p>    <p>写这一系列的关于Git工具的使用的博客,一是为了分享知识,一是为了整理一下知识点,方便复习查阅。文中有错误,或者是概念理解不一致的地方欢迎大家留言讨论。</p>    <p> </p>    <p> </p>    <p>来自:http://www.jianshu.com/p/4f823ee912a6</p>    <p> </p>