如何优雅地使用git(二)

来源:互联网 发布:杭州网络策划公司 编辑:程序博客网 时间:2024/04/28 18:02

  • 远程仓库
    • 配置基础设置
    • 添加远程仓库
    • 从远程仓库克隆
  • 分支管理
    • 什么是Git分支
    • 分支管理基本策略
    • 分支的操作
  • 剩下的过两天再写
    • Bug分支应用
    • Feature分支应用
    • 多人协作

远程仓库

配置基础设置

Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。实际情况往往是这样,找一台电脑充当服务器的角色,每天24小时开机,其他每个人都从这个“服务器”仓库克隆一份到自己的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交。
若是在公司中完全可以自己搭建一台运行Git的服务器,不过现阶段,为了学Git先搭个服务器绝对是小题大作。好在这个世界上有个叫GitHub的神奇的网站,从名字就可以看出,这个网站就是提供Git仓库托管服务的,所以,只要注册一个GitHub账号,就可以免费获得Git远程仓库。
由于本地的Git仓库与GitHub仓库之间的传输通过SSH加密,所以需要一点设置:
首先创建SSH Key,打开shell:

firgavin@firgavin-virtual-machine:~$ ssh-keygen -t rsa -C "247652784@qq.com"Generating public/private rsa key pair.Enter file in which to save the key (/home/firgavin/.ssh/id_rsa): Created directory '/home/firgavin/.ssh'.Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/firgavin/.ssh/id_rsa.Your public key has been saved in /home/firgavin/.ssh/id_rsa.pub.The key fingerprint is:91:29:84:a2:37:d8:77:7e:c7:a6:4e:16:d6:7a:59:27 247652784@qq.comThe key's randomart image is:+--[ RSA 2048]----+|     ..          ||  . ..   o       || + .  . +        ||o + . .. o       || . o o  S.. E .  ||      ...o+o o   ||       .++o      ||       o..       ||       ..        |+-----------------+

忽略这次奇怪的框框我也不知道它是什么意思好像是RSA的key的映射图什么鬼的。。切换目录:

firgavin@firgavin-virtual-machine:~$ cd ./.ssh/firgavin@firgavin-virtual-machine:~/.ssh$ lsid_rsa  id_rsa.pub

以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
登陆GitHub,打开“Account settings”,“SSH Keys”页面,然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容。为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。

这里写图片描述
OK,配置成功。

添加远程仓库

目前以经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,从而达到我们的目的。
首先登陆GitHub创建一个新的仓库,点右上角的那个加号,选择New Repository,然后在Repository name中填入与本地仓库相同的名称learngit,然后Great即可。
这里写图片描述

根据GitHub的提示啊,我们可以命令行下新建一个仓库,也可以通过命令行导入一个库或者从GitHub中导入第三方的仓库。接下来根据提示继续即可(注意,要切换到本地仓库目录下才行):

firgavin@firgavin-virtual-machine:~$ cd learngit/firgavin@firgavin-virtual-machine:~/learngit$ git remote add origin https://github.com/firgavin/learngit.gitfirgavin@firgavin-virtual-machine:~/learngit$ git push -u origin master Username for 'https://github.com': firgavinPassword for 'https://firgavin@github.com': Counting objects: 15, done.Delta compression using up to 4 threads.Compressing objects: 100% (10/10), done.Writing objects: 100% (15/15), 1.22 KiB | 0 bytes/s, done.Total 15 (delta 3), reused 0 (delta 0)remote: Resolving deltas: 100% (3/3), done.To https://github.com/firgavin/learngit.git * [new branch]      master -> master分支 master 设置为跟踪来自 origin 的远程分支 master。

把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。推送成功后,可以立刻在GitHub页面中看到远程库的内容已经和本地一模一样。
这里写图片描述
那么以后工作呢,只要本地做了提交就可以通过命令:

git push origin master

把本地master分支的最新修改推送至GitHub,这样你就拥有了真正的分布式版本库。

从远程仓库克隆

假设我们从零开发,那么最好的方式是先创建远程库,然后,从远程库克隆。
首先呢,登陆GitHub,创建一个新的仓库,名字叫gitskills,勾选Initialize this repository with a README,这样GitHub会自动为我们创建一个README.md文件。创建完毕后,可以看到README.md文件。点击那个绿色的Clone,GitHub给出的地址不止一个。实际上,Git支持多种协议,默认的git://使用ssh,但也可以使用https等其他协议。
这里写图片描述
下面回到自己的主目录下克隆远程仓库:

firgavin@firgavin-virtual-machine:~/learngit$ git clone git@github.com:firgavin/gitskills.git正克隆到 'gitskills'...The authenticity of host 'github.com (192.30.253.113)' can't be established.RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.Are you sure you want to continue connecting (yes/no)? yPlease type 'yes' or 'no': yesWarning: Permanently added 'github.com,192.30.253.113' (RSA) to the list of known hosts.remote: Counting objects: 3, done.remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0接收对象中: 100% (3/3), done.检查连接... 完成。firgavin@firgavin-virtual-machine:~/learngit$ cd gitskills/firgavin@firgavin-virtual-machine:~/learngit/gitskills$ lsREADME.md

这样,gitskills被我们从GitHub上克隆到本地仓库了。

分支管理

什么是Git分支

顾名思义,分支就是从主线上分离出来进行另外的操作,而又不影响主线,主线又可以继续干它的事,是不是有点像线程,最后分支做完事后合并到主线上而分支的任务完成可以删掉了。这样是不是很方便,主线继续做它的事,分支用来解决临时需求,二者互不相干。
git的分支功能特别的强大,它不需要将所有数据进行复制,只要重新创建一个分支的指针指向你需要从哪里开始创建分支的提交对象(commit),然后进行修改再提交,那么新分支的指针就会指向你最新提交的这个commit对象,而原来分支的指针则指向你原来开发的位置,当你在哪个分支开发,HEAD就指向那个分支的最新提交对象commit。
下面用图解释下:
这里写图片描述
事实上,我们的HEAD指向的是当前分支,分支指向的才是当前地版本。当我们创建一个新的分支时,新的分支会从当前版本衍生,从而HEAD指向新分支,并且随着我们提交新文件而不断地更新。当我们要合并时,系统也是操控着HEAD和分支来进行的。将HEAD和分支理解成两个指针,各个版本及分支上的版本理解成链表节点就好。

分支管理基本策略

这里写图片描述
在实际开发中,我们应该按照几个基本原则进行分支管理:

master分支应该是非常稳定的,也就是仅用来发布新版本;

干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;

你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

分支的操作

理解了Git分支的结构和原理那么操作就十分简单了.
下面直接列出分支的基本操作:

//查看分支git branch//创建分支git branch <BranchName>//切换分支git checkout <BranchName>//创建并切换分支git checkout -b <BranchName>//合并某个分支到当前分支git merge <BranchName>//删除分支git branch -d <BranchName>

当然分支操作不止这么多,而且分支的合并存在着冲突的可能,何为冲突?
这里写图片描述

如图,假如我创建了一个新的分支叫feature1,并且对工作进行了修改提交了,那么在这条分支上版本高于master主线,然后我又切换回了主线master后,在主线上又提交了新的版本,然后将feature1分支合并于主线master,由于两条线上我均做了修改那么合并就不是简单的移动指针覆盖文件了。这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突。

firgavin@firgavin-virtual-machine:~/learngit$ git checkout -b feature1切换到一个新分支 'feature1'firgavin@firgavin-virtual-machine:~/learngit$ vi readme.txt firgavin@firgavin-virtual-machine:~/learngit$ cat readme.txt Git is a distributed version control system.Git is free software distributed under the GPL.Git has a mutable index called stage.Git tracks changes of files.Greating a new branch is quick AND simple.firgavin@firgavin-virtual-machine:~/learngit$ git add readme.txt firgavin@firgavin-virtual-machine:~/learngit$ git commit -m "AND simple"[feature1 b8c03f1] AND simple 1 file changed, 2 insertions(+)

我们先创建一个新的分支切换进去修改工作并提交。

firgavin@firgavin-virtual-machine:~/learngit$ git checkout master切换到分支 'master'您的分支与上游分支 'origin/master' 一致。firgavin@firgavin-virtual-machine:~/learngit$ vi readme.txt firgavin@firgavin-virtual-machine:~/learngit$ cat readme.txt Git is a distributed version control system.Git is free software distributed under the GPL.Git has a mutable index called stage.Git tracks changes of files.Greating a new branch is quick & simple.firgavin@firgavin-virtual-machine:~/learngit$ git add readme.txt firgavin@firgavin-virtual-machine:~/learngit$ git commit -m "& simple"[master c0a530f] & simple 1 file changed, 2 insertions(+)

然后我们回到master主线下修改并提交,同时合并分支:

firgavin@firgavin-virtual-machine:~/learngit$ git merge feature1 自动合并 readme.txt冲突(内容):合并冲突于 readme.txt自动合并失败,修正冲突然后提交修正的结果。firgavin@firgavin-virtual-machine:~/learngit$ git status位于分支 master您的分支领先 'origin/master'1 个提交。  (使用 "git push" 来发布您的本地提交)您有尚未合并的路径。  (解决冲突并运行 "git commit")未合并的路径:  (使用 "git add <文件>..." 标记解决方案)    双方修改:     readme.txt修改尚未加入提交(使用 "git add" 和/或 "git commit -a")firgavin@firgavin-virtual-machine:~/learngit$ cat readme.txt Git is a distributed version control system.Git is free software distributed under the GPL.Git has a mutable index called stage.Git tracks changes of files.<<<<<<< HEADGreating a new branch is quick & simple.=======Greating a new branch is quick AND simple.>>>>>>> feature1

我们尝试合并后报错,因为Git不知道到底如何合并。这时查看文件,Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,所以我们要作出修改告诉Git合并结果。修改保存如下

firgavin@firgavin-virtual-machine:~/learngit$ vi readme.txt firgavin@firgavin-virtual-machine:~/learngit$ cat readme.txt Git is a distributed version control system.Git is free software distributed under the GPL.Git has a mutable index called stage.Git tracks changes of files.Greating a new branch is quick and simple.firgavin@firgavin-virtual-machine:~/learngit$ git add readme.txt firgavin@firgavin-virtual-machine:~/learngit$ git commit -m "conflict fixed"[master bd34884] conflict fixed

更正完毕并且提交。此时分支情况如下:
这里写图片描述
也可以在shell中查看具体结构图:

firgavin@firgavin-virtual-machine:~/learngit$ git log --graph *   commit bd348847fb89c58be90b060da7b8231cafddcfb2|\  Merge: c0a530f b8c03f1| | Author: firGavin <247652784@qq.com>| | Date:   Fri Aug 19 13:31:12 2016 +0800| | | |     conflict fixed| |   | * commit b8c03f1a41f685bb2756435b0054e965b2e67656| | Author: firGavin <247652784@qq.com>| | Date:   Fri Aug 19 12:40:52 2016 +0800| | | |     AND simple| |   * | commit c0a530f5b7a63ed19a354e5ae7e6bca24b456f0e|/  Author: firGavin <247652784@qq.com>|   Date:   Fri Aug 19 13:04:26 2016 +0800|   |       & simple|  * commit 76ff34922089a97c19a33491c4c87b37fa7ab12b| Author: firGavin <247652784@qq.com>| Date:   Tue Aug 16 19:56:41 2016 +0800| 

通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

$ git merge --no-ff -m "merge with no-ff" dev

剩下的过两天再写

Bug分支应用

~

Feature分支应用

~

多人协作

~

0 0