GIT详解

一、GIT由来

     Git是目前世界上最先进的分布式版本控制系统。

     Linus创建了Linux,Linux的壮大是靠全世界热心的志愿者参与的。世界各地的志愿者把源代码文件通过diff的方式发给Linus,然后由Linus本人通过手工方式合并代码! 时间到了2002年,Linux系统已经发展了十年,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是Linus选择了一个商业的版本控制系统BitKeeper(专有的分布式版本BitKeeper 的权BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。 
       安定团结的大好局面在2005年就被打破了,原因是Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发Samba的 Andrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错),于是BitMover公司怒了,要收回Linux社区的免费使用权,开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回了 Linux 内核社区免费使用 。

    Linux 开源社区(特别是 Linux 的缔造者 Linus Torvalds)基于使用 BitKeeper 时的经验教训,开发出自己的版本系统。 他们对新的系统制订了若干目标:

  • 速度很快
  • 设计简单
  • 对非线性开发模式的强力支持(允许成千上万个并行开发的分支)
  • 完全分布式
  • 有能力高效管理类似 Linux 内核一样的超大规模项目(速度和数据量)

     Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git诞生!一个月之内,Linux系统的源码已经由Git管理了!
     Git迅速成为最流行的分布式版本控制系统。尤其是2008年,GitHub网站上线。它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。同生活中的许多伟大事物一样,Git 诞生于一个极富纷争大举创新的年代。  自诞生于 2005 年以来,Git 日臻成熟完善,在高度易用的同时,仍然保留着初期设定的目标。 它的速度飞快,极其适合管理大项目,有着令人难以置信的非线性分支管理系统

二、GIT与SVN

 GITSVN
概念Git是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们两之间只需把各自的修改推送给对方,就可以互相看到对方的修改了SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,如果在局域网还可以,带宽够大,速度够快,如果在互联网下,如果网速慢的话,就纳闷了。
差异

1. SVN是集中式版本控制系统,Git是分布式版本控制系统;

2. SVN记录差异比较,Git是对新版本直接做快照;

3. SVN的提交会出现冲突的概率随着同一时间工作人数的增加而增加,Git鼓励多建分支使得冲突几率减小,且冲突解决机制更好

4. SVN可以通过权限控制使得部分代码的安全性,Git 则是完全clone整个仓库到本地,任何人均可以访问任何部分的代码

优点1、适合分布式开发,强调个体。 
2、公共服务器压力和数据量都不会太大。 
3、速度快、灵活。 
4、任意两个开发者之间可以很容易的解决冲突。 
5、离线工作
1、 管理方便,逻辑明确,符合一般人思维习惯。 
2、 易于管理,集中式服务器更能保证安全性。 
3、 代码一致性非常高。 
4、 适合开发人数不多的项目开发
缺点1、学习周期相对而言比较长。 
2、不符合常规思维。 
3、代码保密性差,一旦开发者把整个库克隆下来就可以完全公开所有代码和版本信息
1、 服务器压力太大,数据库容量暴增。 
2、 如果不能连接到服务器上,基本上不可以工作,看上面第二步,如果服务器不能连接上,就不能提交,还原,对比等等。 
3、 不适合开源开发(开发人数非常非常多,但是Google app engine就是用svn的)。但是一般集中式管理的有非常明确的权限管理机制(例如分支访问限制),可以实现分层管理,从而很好的解决开发人数众多的问题

     三、git原理

     Git 把数据看作是对小型文件系统的一组快照。 每次你提交更新,或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。 为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。

     Git 有三种状态,你的文件可能处于其中之一:

       已提交(committed):表示数据已经安全的保存在本地数据库中。

       已修改(modified):   表示修改了文件,但还没保存到数据库中。

       已暂存(staged):      表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。

   由此引入 Git 项目的三个工作区域的概念             

       Repository:仓库区(或本地仓库),Git 仓库目录是 Git 用来保存项目的元数据和对象数据库的地方。 这是 Git 中最重要的部                                     分,从其它计算机克隆仓库时,拷贝的就是这里的数据。

      Workspace:工作区工作目录是对项目的某个版本独立提取出来的内容。 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁                              盘上供你使用或修改。

      Index / Stage:暂存区域是一个文件,保存了下次将提交的文件列表信息,一般在 Git 仓库目录中。 有时候也被称作‘索引’,不过一                                 般说法还是叫暂存区域。

   基本的 Git 工作流程如下:

  1. 在工作目录中修改文件。
  2. 暂存文件,将文件的快照放入暂存区域。
  3. 提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。

      如果 Git 目录中保存着的特定版本文件,就属于已提交状态。 如果作了修改并已放入暂存区域,就属于已暂存状态。 如果自上次取出后,作了修改但还没有放到暂存区域,就是已修改状态。

      Repository(仓库)包含的内容 - Git的目标是管理一个工程,或者说是一些文件的集合,以跟踪它们的变化。Git使用Repository来存储这些信息。一个仓库主要包含以下内容(也包括其他内容):

  • 许多commit objects
  • 到commit objects的指针,叫做heads
  • Git的仓库和工程存储在同一个目录下,在一个叫做.git的子目录中

四、GIT操作命令 

创建版本库,英文名 repository

选择一个合适的地方,创建一个空目录。通过 git init 或者git init –-bare命令把这个目录变成 Git 可以管理的仓库(初始化仓库)。

初始化之后目录下面的.git目录外是工作区,.git目录里分为暂存区和Git为我们自动创建的第一个分支 master,以及指向 master 的一个指针叫做 HEAD;图片、视频、Word文档这些二进制文件可以由版本控制系统管理,但没办法跟踪文件的变化,只能知道图片从100KB改成了120KB,但改了什么版本控制系统不知道。

git init和git init –-bare区别:

git init 是多一个.git 文件夹,而git所有的文件都是.git文件夹下,而git init –bare 则是将git的文件直接放在仓库根目录下。 
所以git init –bare 创建的仓库是裸仓库,没有项目的源文件,只有git的文件,这个仓库是不能执行git的命令,没有git add ,git commit 等等。你也无法修改编辑项目的文件。所以他只是一个共享的储存空间而已。

而git init 创建的普通仓库,里面是有项目源文件的。所以git init 创建的普通仓库是有工作空间的,就是work-tree ,而git init –bare是没有工作空间的。

这里还要注意,我们一般使用git init –bare 比较好,git init 有两点不好:

1.因为使用git init 创建的仓库是可以用git操作的嘛,如果当前master正在被用户操作,那么分支如果 git push master:master 那么就会       爆炸,上传不上去。master不能同时被两个人操作,对吧。

2.分支push到远程仓库之后,我们在仓库里是没有办法看到最新的内容的,必须要

            git reset --hard 
    执行这个命令,在仓库的目录下,也就是工作区,才会更新,看到最新修改的内容。 
    git reset –hard 是撤回到历史版本,本地源码会变成上一个版本的内容。每次更新都要 执行。

在用git init 创建的仓库的时候,你git push 会遇到 ! [remote rejected] master -> master (branch is currently checked out)**

需要运行git config receive.denycurrentbranch ignore这个是允许接受远程文件。有时候push不上去,是因为文件夹没有权限,需要chomd 7777 文件

把文件往 Git 版本库里面添加的时候,是分两步执行的:

1.用 git add 把文件添加进去,实际上就是把文件添加到暂存区;
2.用 git commit 提交更改,实际上就是把暂存区的所有内容提交到当前分支,不管工作区的内容。使用命令 git commit -m “XXX” 告诉git,把文件 提交 到仓库,-m 后面跟的是本次提交的注释说明,注释说明不要用中文。因为 commit 一次可以提交很多文件,所以可以使用多次 add 不同的文件。

注:因为我们创建 Git 版本库时候,Git 自动为我们创建了唯一一个 master 分支,所以,现在, git commit 就是往 master 分支上提交        更改

常用commit提交注释规范
用一空行分隔标题与正文。
标题使用大写字母。
标题不超过50个字符。
标题使用祈使语气。
标题不要使用句号结尾。
正文解释是什么和为什么,而不是如何做

查看仓库当前的状态git status
查看文件差异,可以看到工作区和暂存区的区别git diff readme.txt
比较的是暂存区和历史区的差异git diff --cached
可以查看工作区和版本库里面的区别git diff head – readme.txt
可以查看所有提交的比较详细的历史纪录

git log --pretty=oneline

git log --graph --pretty=oneline

为当前版本打标签
为历史版本打标签
指定标签说明
查看所有标签
查看某一标签
删除某一标签

git tag 标签名

git tag 标签名 该版本ID

git tag –a 标签名 –m "标签说明" [可选:版本ID]

git tag

git show 标签名

git tag –d 标签名

撤销暂存区的修改git reset HEAD 文件名

可以回退版本,把暂存区的修改退回到工作区

在 git 中,用 HEAD 表示当前版本,上一个版本就是 HEAD^ ,上上个版本就是 HEAD^^ ,往前一百个版本为 HEAD~100。

 

回到上一个版本为 git reset --hard “HEAD^” (实测不区分大小写)
回到上上个版本为 git reset --hard “head^^” (实测不区分大小写)

假如知道版本号,回到某一个版本为 git reset --hard 126378(版本号,写前几位就行)

记录了你之前操作的每一次命令,可以查看版本号,知道了版本号就可以随意回退版本了git reflog

可以丢弃工作区的修改,这里有两种情况:
一种是 readme.txt 自修改后还 没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态。
一种是 readme.txt 已经 添加到暂存区后,又做了修改,现在,撤销修改就回到添加到暂存区后的状态

git checkout   – readme.txt

没有 – ,就变成了切换到另一个分支

查看远程分支,这条命令并没有每一次都从远程更新仓库信息,这样子做是为了效率,我们可以手动更新一下远程分支

git fetch origin //更新远程仓库

git branch -a //查看远程分支

拉取远程分支、并创建本地分支,使用该方式会在本地新建分支x,并自动切换到该本地分支x

git checkout -b 本地分支XXX origin/远程分支XXX

git checkout -b test origin/test //将远程的分支 test 拉取到本地 test 分支,并且切换到本地 test 分支

拉取远程分支、并创建本地分支,使用该方式会在本地新建分支x,但是不会自动切换到该本地分支x,需要手动checkout

git fetch origin 远程分支XXX:本地分支XXX

git fetch origin test:test //将远程的分支 test 拉取到本地 test分支,但是不会自动切换到本地的 test 分支

添加远程仓库git remote add origin git@192.168.0.1/test.git
把本地库的所有内容推送到远程仓库上,由于远程仓库是空的,我们第一次推送的 master 分支时候,加上了 -u 参数,git 不但会把本地的 master 分支推送到远程新的 master 分支,还会把本地的 master分支和远程的 master 分支关联起来,在以后的推送或者拉取的时候可以简化命令。git push -u origin master

克隆一个仓库

Git 支持多种协议,包括 https ,但是通过 ssh 支持的原生 git 协议最快。默认的 git:// 使用 ssh,但也可以使用 https 等其他协议。使用 https 除了速度慢以外,还有个最大的麻烦就是每次推送必须输入口令,只是在某些只开放 http 端口的公司内部就无法使用 ssh 协议而只能用 https

git clone git@192.168.0.1/test.git
创建与合并分支

git checkout -b dev

git checkout 命令上加 -b 参数表示创建并且切换,相当于下面两条命令:

  • git branch dev 创建一个叫 dev 的分支。
  • git checkout dev 切换到 dev 分支
查看当前所在分支 ,该命令会列出所有分支,并且在当前的分支前面加 * git branch 
用于合并指定分支到当前分支

git merge dev 将 dev 分支合并到当前的 merge 分支上

git merge --abort //将刚才合并操作撤销

合并之后,可以放心删除 dev 分支git branch -d dev

强制合并,禁用快速合并

 

git merge --no-ff -m
删除暂存区,使用--cached 表示只删除缓存区中的内容git rm -r --cached .

按照上述方法定义后发现并未生效,原因是 .gitignore 只能忽略那些原来没有被 track 的文件,如果某些文件已经被纳入了版本管理中,则修改 .gitignore 是无效的

 

git add . git commit -m 'update .gitignore'

对文件重命名git mv README.txt README
Git提供了一个stash功能,可以把当前工作现场 ”隐藏起来”,等以后恢复现场后继续工作

git stash apply恢复,恢复后,stash内容并不删除,你需要使用命令git stash drop来删除

git stash pop,恢复的同时把stash内容也删除了删除list里的储藏内容记录

 

查看远程库的信息

查看远程库的详细信息

git remote

git remote -v

获取当前登录的用户git config --global user.name
获取当前登录用户的邮箱git config --global user.email
查看git的版本信息git --version
设置git账户,userName为你的git账号git config --global user.name 'userName' 
  
  
  

     

           

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凤舞飘伶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值