http://blog.csdn.net/risky78125/article/details/50850545
版权声明:本文为博主原创文章,未经博主允许不得转载。
Git介绍
Git—>分布式版本控制系统;
这么一说是不是就蒙圈了,咱们来举个例子.文档大家都写过,那是不是会遇到这样的问题:第一天,例如写了Hello Lanou3g,觉得自己非常有才华,可以出篇散文了;第二天,觉得前一天写的不怎么好,需要改一下,改成了Hello Android;第三天,反反复复想了想,还是第一天写的内容比较霸气,可是第一天写啥了???找不回来了咋办!
那有一个比较好的办法,保证每天写的都能记录下来,那就是——每次写完都另存为一下;
终于有一天,你会修道七环(啊啊呸),你的电脑里面有成百上千的文件版本,想找哪个,该咋办.如果没感觉的话把上面说的文档换成代码.
这个时候,厉害的东西来了,就是我们的分布式版本控制系统git,它就可以非常简单的完成上面所说的所有工作.还有功能就是小组共同开发时用它来进行代码的合并.
原始的git,操作起来比较麻烦,因为都是命令行操作.所以结合SourceTree来进行使用,可以做到事半功倍的效果.那么下面就来演示一下git该怎么玩.
Git演示
安装git环境
既然想用git,那么首先咱们的电脑里面得有这个环境.Mac和Linux系统安装非常简单,只要在终端里面打上三个字母:git,那么终端就会提示你进行安装,安装的命令也会提示给你.至于Windows,可能就麻烦一些了,可以去找一下SourceTree的下载,然后git环境会集成在SourceTree里面.
好了,我就当大家都下载完了.完成之后,需要在终端里面进行一下配置,配置你个人的名字和邮箱,命令如下:
<code class="hljs python has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">git config --<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">global</span> user.name <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Your Name"</span> git config --<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">global</span> user.email email<span class="hljs-decorator" style="color: rgb(0, 102, 102); box-sizing: border-box;">@example.com</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
注意这个配置的是全局的名字和邮箱,代表的是所有使用这台电脑的人都会以这个身份进行操作.
初始化git仓库
命令行模式
(以下操作均在mac系统下面进行)
第一步:使用终端,进入到你需要进行版本控制的目录下面,例如我想对桌面上的gitdemo文件夹(当然桌面上面必须得有这个文件夹才行)进行版本控制:
<code class="hljs bash has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">cd</span> desktop/gitdemo</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
第二步:在该文件夹下面使用命令git init
,对该文件夹进行初始化,成功之后会提示一个空的版本库已经创建好:
<code class="hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">git init</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
说的应该够明确的了吧.
SourceTree模式
命令模式都已经会了,那用软件来控制还不是小菜一碟.
软件打开之后选择:
<code class="hljs brainfuck has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">+</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">新仓库</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">-</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">-</span>><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">创建本地仓库</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">-</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">-</span>><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">选择一个路径</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">-</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">-</span>><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">创建</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
这属于最简单的初始化仓库的方法了.对于我的习惯来说,我都是通过Studio创建一个工程,然后在Studio的终端里面直接进行仓库的初始化,非常方便.(顺便一提,Studio的终端输入汉字怎么就一半一半的显示啊!!)
仓库初始化好了之后,会在文件夹里面生成一个名叫.git的隐藏文件夹,可以通过终端命令 ls -a
进行查看.这个隐藏文件夹里面会保存接下来的所有操作.所以千万不要删除了,否则会出人命的.
版本控制
仓库初始化完毕之后,只要是在这个文件夹下面的操作,都会被git进行管理.例如,新建一个文件/修改文件的内容/删除文件等等,所有的操作都可以被记录,并可以随时找到.
下面说一下如何通过git来保存我们的操作.
命令行模式
首先介绍几个命令:
命令 | 功能 |
---|---|
git status | 查看仓库当前的状态 |
git add 文件路径加文件名 | 将该文件添加到暂存区 |
git add . | 将该文件夹下所有有变动的文件都加到暂存区 |
git add -A | 同上 |
git commit -m “备注” | 将暂存区的文件提交到仓库 |
下面我会通过命令演示一下:
我会创建一个文件,例如README.md,里面写一些内容.然后通过git status
查看一下当前的状态,如下:
可以看到新建的文件是红色的.代表的意义就是该文件还未添加到暂存区,也就是还没有执行git add 这个命令.
接下来可以通过git add README.md
或者git add .
或者git add -A
来将此文件添加到暂存区.然后再查看一下状态:
可以看到,竟然变绿了.而且前面提示了,这是一个新的文件.变绿色了之后,就可以通过git commit -m "备注"
来将此文件添加到仓库了,然后再查看一下状态,如下:
可以看到,文件成功提交.提交之后再查看状态,会提示工作区clean,也就是没有什么文件有变动.
这样一来,写代码的时候可以随时提交一下,并写好备注,世界竟然入刺的井猜.
SourceTree模式
同样的,命令行都会了,用软件真是太简单了.
第一步找到刚刚新建的仓库:
第二步双击打开,然后跟着感觉走:
版本回退
强悍的git可以保存你每次commit的记录,并可以在每次的记录间进行切换.下面我为了演示,自己先多commit几次.
命令行模式
首先,通过命令git log
可以看到每次提交的历史记录
可以通过commit标识,来进行相应的版本回退.git log
显示的历史记录比较详细.大家也可以通过git reflog
命令来获取简版的历史记录,如下:
版本回退的命令,请看下表:
命令 | 功能 |
---|---|
git reset –hard HEAD^ | 回退到上一个版本 |
git reset –hard HEAD^^ | 回退两个版本 |
git reset –hard HEAD~100 | 回退100个版本 |
git reset –hard xxxxx(commit的id) | 回退到对应的版本 |
实际上一般最后一个命令是比较常用的,例如我现在需要回退到一开始的版本,那么我只需要在终端中输入git reset --hard 350e137
即可
现在如果再打开README.md文件,会发现后来提交的内容已经不见了.
可以试一下现在使用git log
命令会怎么样.可以发现,提交的历史记录只剩一个了!我还想回退该怎么办??不要心慌不要着急,请使用git reflog
命令来查看记录,找到对应的commit id.
SourceTree模式
看图就能明白了,so easy啊.可以看到,每次提交都有记录的.如果想回到哪个版本,直接双击.
远程仓库
如果只能在当前电脑上面进行版本控制那就也太没意思了,git重要功能之一即为可以创建远程仓库.也就是我们所有的提交修改等等记录都会保存到远程,也就是保存到网站上面.远程仓库常用的有两种认证模式,一种是SSH,一种是HTTPS.下面的例子都是用HTTPS,如果想了解SSH,请查看我的另一篇博客:
http://blog.csdn.net/risky78125/article/details/50117701
既然要添加远程仓库,首先得有一个远程仓库.到全球最大的程序员同性交友网站github注册个账号,并创建个仓库.
登陆成功后,点击屏幕右上角头像附近的+,选择new repository.然后如下:
创建的这个README文件里面的内容,会在创建好的仓库网页上面显示,内容的格式同样是markdown.
.gitignore文件后面咱们再说.
仓库创建完成之后看到一个网址,例如:
https://github.com/risky78125/gitdemo.git
这个就是远程仓库的地址,咱们接下来需要做的,就是将这个网址和本地仓库进行绑定.
命令行模式
绑定远程仓库的命令:
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">git remote <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">add</span> origin https://github<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.com</span>/risky78125/gitdemo<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.git</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
其中origin为远程仓库的名字,一般都这么起.
使用命令git push -u origin master
将本地的提交记录上传到远程仓库.当然,如果创建远程仓库时直接创建了README和.gitignore文件的话,则需要先把远程的文件拉取到本地,然后才能推送.也就是先执行命令git pull origin master
,然后才能push.
之前说了,origin是远程仓库的名字,那么master呢,实际上是分支名字.分支的概念接下来会介绍.
SourceTree模式
<code class="hljs brainfuck has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">设置</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">-</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">-</span>><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">远程仓库</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">-</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">-</span>><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">添加</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">-</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">-</span>><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">输入名称origin</span><span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">,</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">URL/路径</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">-</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">-</span>><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">确定</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
这样就设置好了远程仓库.可以点击推送,将本地的所有提交都发送到远程.
远程仓库的克隆
代码推送到远程之后,可以通过克隆,将所有的提交等历史操作都拉取到任意一台有git环境的电脑上,而不是简简单单的将代码下载下来.
命令行模式
非常简单,git clone 仓库地址
,例如刚才的仓库:
<code class="hljs php has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">git <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">clone</span> https:<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//github.com/risky78125/gitdemo.git</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
SourceTree
也非常简单,点击+新仓库-->从URL克隆
.
.gitignore文件
通过名字可以看出一些端倪,忽略.大家可以想象,提交修改时,有很多无意义的文件我们没有必要去提交,没有必要去关注它们是否有修改.例如Android编译之后的.class文件,生成的.apk文件等等等等,这些文件都是随时在各种变化,如果git追踪他们的话,会占用大量的时间和空间.所以,把这些文件名或文件夹写入到.gitignore文件中,就会自动忽略它们的修改.
团队协作
分支
现在想象一下下面描述的情况.一个团队有两个人A和B.
A完成他自己的功能需要两天,那A该怎么提交修改?随时提交的话,因为功能还未完成,很可能就导致B无法工作.那两天后再提交呢,很可能两天之内出现什么事儿,导致A的代码丢了.
分支的出现即可以解决上面所说的问题,A和B每个人都新建属于自己的分支,提交修改都是在自己的分支上面进行,互不干扰.功能都完成之后,两个分支合并到一起,OK了,非常完美.
前面提到了一下,master其实就是个分支,但是它是主分支.主分支一定要是最稳定的分支,意思就是别有事儿没事儿就往master分支上面合并代码,一定要完全测试没有问题了,马上要发布了,再合并到master分支上面.
一个团队,理想情况下的分支是这样的.
一个master分支,一个develop分支,团队里的每个人都有一个分支,每个人的每个功能都有一个分支.
当然,项目过程中可以缩减一层,也就是每个人都在develop分支上面直接根据功能创建分支,功能完成之后直接合并到develop分支上面.
命令行模式
命令 | 功能 |
---|---|
git checkout -b develop | 创建一个名为develop的分支,并切换到该分支 |
git branch develop | 创建一个名为develop的分支 |
git checkout develop | 切换到develop分支 |
git branch | 查看所有分支和当前分支 |
git merge develop | 将develop分支合并到当前分支 |
SourceTree
点击分支
,可以创建新的分支.点击合并
,可以选择将哪个分支合并到当前分支.双击分支,即可切换到对应的分支.
冲突解决
在团队合作中,无法避免的两个人会同时修改同一个文件,这时候合并就会产生冲突.下面我用两个分支来模拟一下.我在develop分支上面,修改一下文件,并提交修改.然后切换到master分支上面再次修改该文件.之后进行代码合并.合并之后,内容如下:
<code class="hljs asciidoc has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">1.创建了一个文件,叫做README.md 2.为了演示,第二次commit; 3.第三次commit; 4.创建了develop分支,并写下该内容 <<<<<<< HEAD <span class="hljs-header" style="box-sizing: border-box;">5.本条信息是在master分支上写下的 =======</span> 6.本条信息是在develop分支上写下的. >>>>>>> develop</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right- 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>
可以看到,合并之后的代码会多出来一些符号,这即是冲突.那么解决起来也很方便,判断一下冲突的位置,应该怎么保留,然后把多余的信息和符号删除,再提交一下修改即可.
SourceTree软件的使用
当然了,SourceTree能实现的功能,使用命令行肯定都可以实现.工具的出现就是为了方便大家.
现在有个新的仓库,只要点击git工作流
,会自动创建分支:
就问你牛(diao)不牛(diao)!!!
初始化之后,再次点击git工作流
,会出现选项,点击任何一个,都会根据之前创建的规则创建分支!
例如点击建立新的功能
,会自动在develop分支上面再创建一个分支,功能的名字需要自定义一下.之后即可对这个功能写代码了.功能完成之后再次点击git工作流
,会有完成当前版本,即把当前的功能分支合并到develop分支上面.非常简单.完成之后是这样的:
这个功能完成之后,就可以把develop分支推送到远程仓库.点击推送-->选择develop-->确定
.这样一来,其他人就可以通过远程仓库,把develop分支拉取下来,与自己的功能进行合并.如果有冲突,则需要在本地进行冲突解决,并且解决完之后一定要再次推送到远程.这样与你有冲突的人拉取完之后即是解决冲突完毕后的版本