git 自我学习详解

一 git简介

1 git 是什么?
     git 是现在世界上最先进的分布式版本控制工具。

2 git是怎么诞生的?
     很多人都知道在1991年linus创建了开源的linux,从此linux不断壮大发展已经成为最大的服务器系统软件了。
但Linux的壮大是靠全世界的热心志愿者参与完成的,那么问题就出现了,这么多全球各地的志愿者参与代码的
开发,那linux是如何管理的呢,在2002年之前全球的志愿者还是通过diff的方式将源代码发送给linus本人有他Helvetica Neue
本人手动合并代码,其实在哪个时候是有免费的版本的控制工具的例如CVS和SVN那么为什么linux不使用这些
免费的版本控制工具呢,因为linus坚决的反对cvs和svn这种集中式的版本控制系统不但速度慢,而且必须联网
才能使用,但是当时也是有一些商用的版本控制工具的,但是都是付费的与linux的开源精神不符。但是到了20
02年,linux已经发展了10年,linux的代码库非常之大已经很难再通过手工何并代码了,于是linus选择了一个
商业的控制版本BitKepper,BitKeeper的东家BitMover出于人道主义精神,授权了linux不需要付费可以免费使
用,但是到了2005年安定的局面就被打破了,因为linux的N人太多了,开发samba的andrew试图破解BitKeeper
的协议,但是被Bitmover公司发现了,BitMover公司大怒,要收回linux的免费使用权,这个时候linux就显示出
了他们N人的作风,花了两周的时间用C写了一个分布式版本控制工具就是git,一个月内linux的源码就有git接管
了(牛是怎么定义的。。。。),之后git就成为了非常流行的分布式版本控制工具。尤其到了2008年的github网
站上线了,他为开源项目免费提供git存储,无数开源项目开始迁移github包括jQuery,PHP, Ruby等。

3 集中式版本控制工具和分布式版本控制工具有什么不同呢?
     先说集中版本控制工具,版本库是集中存放在中央服务器的,而干活的时候用的都是自己的电脑,所以先要在
中央服务器获取到最新的代码在进行编程,编程结束后在把自己的代码推送给中央服务器,集中式版本控制工具最
大的毛病就是必须联网才能工作,如果遇到网速慢的情况下,提交一个10M左右的文件就需要几分钟,这还不把人
憋死,我们再来说说分布式版本控制系统,分布式版本控制系统根本就不存在中央服务器每台电脑都有一个完整的
版本库,这样你工作的时候就不需要联网了,既然每个人的电脑都是一个完整的版本库,那么多人之间是怎么协作的
呢,比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改
推送给对方,就可以互相看到对方的修改了。和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,
因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。而集
中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。其实在真实的分布式版本控制系统中,很少有
两人之间的推送,分布式版本控制通常都有一台充当中央服务器的电脑,他的作用只是用来让大家交换修改后的信息
没有他大家一样干活,只是交换修改不方便而已。

二 工作区和暂存区和版本库
工作区(Working Directory)
就是你在电脑里能看到的目录,比如我的gitRep文件夹就是一个工作区:
版本库(Repository)工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。

这里写图片描述

在工作区和暂存区以及版本库之间我们经常用到的命令操作:
git add . 或者git add –files 实际上就是把文件修改添加到暂存区;
git commit -m “”, 实际上就是把暂存区的所有内容提交到当前分支。
git reset files, 将提交到暂存区的文件撤回到工作区, 你也可以用git reset 撤销所有暂存区域文件。 git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。
git checkout files , 将工作区的文件撤回(但是这个时候你在工作区的文件修改也会撤回到你修改前的状态);

这里写图片描述

git add命令实际上就是把要提交的所有修改放到暂存区(Stage), 一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的,然后,执行git commit就可以一次性把暂存区的所有修改提交到分支
现在版本库变成了这样,暂存区就没有任何内容了:

这里写图片描述

回退版本 :
回退版本的时候我们需要知道几个查看的操作
git log 查看出来的是每次提交后的commit版本号,已经提交人和提交的时间等信息。 命令显示从最近到最远的提交日志
如果嫌输出信息太多,看得眼花缭乱的,可以试试加上–pretty=oneline参数:

$ git log
commit 3628164fb26d48395383f8f31179f24e0882e1e0
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Tue Aug 20 15:11:49 2013 +0800

    append GPL

commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Tue Aug 20 14:53:12 2013 +0800

    add distributed

commit cb926e7ea50ad11b8f9e909c05226233bf755030
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Mon Aug 19 17:51:55 2013 +0800

这个时候我们如果想把版本回退到上一个版本:
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交3628164…882e1e0(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100,
但是我们真是的版本回退一般都用commit的版本号回退

git reset --hard 3628164  或者   git reset --hard HEAD^ 这是回退到上一个版本

如果我们回退了一个版本突然发现不应该回退,想要还原我们的版本这个时候我们可以通过git reflog
git reflog用来记录你的每一次命令:例如我想回到3268164这个版本就可以git reset –hard 3628164

这里写图片描述

现在HEAD指向的就是最新版本。

这里写图片描述

git的回退只是将HEAD指针指向不同的版本。 然后顺便把工作区的文件更新了。所以你让HEAD指向哪个版本号,你就把当前版本定位在哪。
一、得到本地仓库

完成了基本的安装和配置之后,下面我们就开始来使用了。

有两种取得 Git 项目仓库的方法:

1、在本地项目工作目录中初始化新仓库

要对现有的某个项目开始用 Git 管理,只需到此项目所在的目录,执行:

git init
1
例如,如果现在有一个TestDemo项目,我们我们需要执行下面命令:

cd TestDemo
git init
1
2
初始化后,在当前目录下会出现一个名为 .git 的目录,所有 Git 需要的数据和资源都存放在这个目录中。这样我们就可以对我们当前的这个TestDemo项目来使用git进行管理了。

2、从已有远程仓库克隆

可以先把远程仓库中的项目的 Git 仓库复制一份到本地,这就需要用到 git clone 命令。服务器上有的数据克隆之后本地也都有了。

克隆仓库的命令格式为 git clone [url]。例如:

git clone git://github.com/schacon/grit.git
1
这会在当前目录下创建一个名为grit的目录,其中包含一个 .git 的目录,用于保存下载下来的所有版本记录。如果进入这个新建的 grit 目录,你会看到项目中的所有文件已经在里边了,准备好后续的开发和使用。如果希望在克隆的时候,自己定义要新建的项目目录名称,可以在上面的命令末尾指定新的名字:

git clone git://github.com/schacon/grit.git mygrit
1
唯一的差别就是,现在新建的目录成了 mygrit,其他的都和上边的一样。得到这个项目之后,接着就是进入这个项目的目录中,我们就可以进一步开发,并且使用git进行管理和操作了。

二、远程仓库

1、添加远程仓库

要添加一个新的远程仓库,可以指定一个简单的名字,以便将来引用,运行 git remote add [shortname] [url]

$ git remote add pb git://github.com/paulboone/ticgit.git
1
这样就现在可以用字符串 pb 指代对应的仓库地址了。

2、查看当前的远程库
要查看当前配置有哪些远程仓库,可以用 git remote 命令,它会列出每个远程库的简短名字。在克隆完某个项目后,至少可以看到一个名为 origin 的远程库,Git 默认使用这个名字来标识你所克隆的原始仓库。

也可以加上 -v 选项(译注:此为 –verbose 的简写,取首字母),显示对应的克隆地址:

$ git remote -v
pb git://github.com/paulboone/ticgit.git
1
2
3、从远程仓库抓取数据

可以用下面的命令从远程仓库抓取数据到本地:

$ git fetch [remote-name]
1
此命令会到远程仓库中拉取所有你本地仓库中还没有的数据。运行完成后,你就可以在本地访问该远程仓库中的所有分支,将其中某个分支合并到本地,或者只是取出某个分支。

如果是克隆了一个仓库,此命令会自动将远程仓库归于 origin 名下。所以,git fetch origin 会抓取从你上次克隆以来别人上传到此远程仓库中的所有更新(或是上次 fetch 以来别人提交的更新)。有一点很重要,需要记住,fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支,只有当你确实准备好了,才能手工合并。

如果设置了某个分支用于跟踪某个远端仓库的分支,可以使用 git pull 命令自动抓取数据下来,然后将远端分支自动合并到本地仓库中当前分支。实际上,默认情况下 git clone命令本质上就是自动创建了本地的 master 分支用于跟踪远程仓库中的 master 分支,所以一般我们运行 git pull,目的都是要从原始克隆的远端仓库中抓取数据后,合并到工作目录中的当前分支。

4、推送数据到远程仓库

如果需要将本地仓库中的数据推送到远程仓库上,可以使用命令git push [remote-name] [branch-name], 例如要把本地的 master 分支推送到 origin 服务器上。

$ git push origin master
1
只有在所克隆的服务器上有写权限,或者同一时刻没有其他人在推数据,这条命令才会如期完成任务。如果在你推数据前,已经有其他人推送了若干更新,那你的推送操作就会被驳回。你必须先把他们的更新抓取到本地,合并到自己的项目中,然后才可以再次推送。

5、查看远程仓库信息

我们可以通过命令 git remote show [remote-name]查看某个远程仓库的详细信息,比如要看所克隆的 origin 仓库,可以运行:

$ git remote show origin
1
6、远程仓库的删除和重命名

可以用 git remote rename 命令修改某个远程仓库在本地的简称,比如想把 pb 改成 paul,可以这么运行:

$ git remote rename pb paul
1
注意,对远程仓库的重命名,也会使对应的分支名称发生变化,原来的 pb/master 分支现在成了 paul/master。

碰到远端仓库服务器迁移,或者原来的克隆镜像不再使用,又或者某个参与者不再贡献代码,那么需要移除对应的远端仓库,可以运行 git remote rm 命令:

$ git remote rm paul
1
掌握了上面的一些东西,下面我们具体来配置一些,前面第一章我们将本地git配置好了,现在我们需要做的是配置远程代码仓库,我们使用的是github,然后就可以在本地使用git管理代码,并且代码提交到github上了。

三 远程仓库
1 了解远程仓库我们就需要了解git的分布式原理。
这里写图片描述

例如现在我和A1,A2,A3,都在开发一个crm的项目。我们每个人的电脑上都有一个版本库,我开发了新的功能可以再自己的电脑上 add . commit 但是我只要没有推送到远程库。
那么A1,A2在远程库更新数据的时候就不会获得到我最新的代码,远程库的作用就可以理解为我们不同开发人员的一个代码交互的中间介。
在这里我们需要了解几个命令:

 git  pull  这是更新。
 git push 这是往远程库推送。
 远程库的名字就是origin,这是Git默认的叫法。
 master 是分之的名称  git默认创建的分支就是master,我们一把也将master当做主分支。用来发布版本。
 git  pull origin master : 从远程的master分支获取最新的数据
 git push origin master : 将本地的最新数据推送到远程的master分之。

四 分之管理
1 创建分支:
每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。
HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。
一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:

这里写图片描述

每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长:

当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:

这里写图片描述

你看,Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!
不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:
假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

这里写图片描述

所以Git合并分支也很快!就改改指针,工作区内容也不变!
合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:

这里写图片描述

在这里我们就涉及到几个命令了:
创建分支并切换到dev分支 : git checkout -b dev
查看当前分支状况 : git branch 命令会显示出你闲杂所有的分之信息带有 * 号表示的是你当前所处的分之。
这个时候我们就可以再分支dev上进行开发了。当我们在dev上进行了修改并提交。表示我们dev上的工作完成了我们就可以切换回master上了。进行master的合并。

这里写图片描述

git merge命令用于合并指定分支到当前分支 : git merge dev
合并后我们的dev分支也就可以删除了。

git checkout -d dev

2 解决冲突
冲突的产生是因为我们不同的人在一个工作文件进行修改。当第一个人将修改后的内容推送到了远程。我们在去推送远程的时候。git会进行自行判断。
判断你的本地仓库和远程时候一致如果不一致的情况下。会要求你git pull也就是将远程的信息更新下来。这个时候我们就会产生冲突文件了。
Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,我们修改后就可以保存了。
这个时候在提交到远程就可以了。

这里写图片描述

五 分支策略
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。
所以,团队合作的分支看起来就像这样:

这里写图片描述

还有一些标签的配置。别名的管理。特殊文件的忽略等信息推荐网站:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值