Git使用教程

版本控制

用我的话来说,版本控制就是记录项目代码的变换,它能记录项目修改的历史版本记录,能让我们快速方便版本切换。

版本控制工具

集中式版本控制工具,如CVS、SVN等。是多台电脑客服端把代码文件放置在一台中央的服务器。好处是大家都是能看见项目的每一个版本,其他人的工作也能看见。项目管理员也好方便管理,开放代码的权限。缺点是有单点故障,如果服务器出现故障一个小时,那么这一个小时大家都不能提交代码。

分布式版本控制工具,经典的就是Git。像Git这种分布式版本控制工具,客户端提取的不是最新版本的文件快照,而是把代码仓库完整地镜像下来(本地库),这样任何一处协同工作用的文件发生故障,事后都可以用其他客户端的本地仓库进行修复。因为每个客户端的每一次文件提取操作,实际上是一次对整个仓库文件的完整备份。分布式的版本控制系统出现之后,解决了集中式版本控制系统的缺陷。如下图所示。

个人理解,分布式由于每个客户端保存的都是完整的,这样即使服务器挂了,随便找一个客户端充当新的服务器就行了,而集中式由于客户端保存的都是最新版本,服务器挂了,没有一个客户端有完整的项目。

Git工作机制和代码托管中心

Git工作机制

大概分为三个部分,工作区暂存区本地库

  • 工作区:可以删掉。它就是你在电脑里能看到的目录。(新建gitdemo目录里的文件)
  • 暂存区:临时存储,也可以删掉。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
  • 本地库:代码提交到这里了,一般删不掉了,生成了历史版本。工作区有一个隐藏目录 .git,这个不算工作区,也是 Git 的版本库(本地库)。

代码托管中心

是基于网络服务器的远程代码仓库,就叫远程库。一般用push命令推送到远程库。

具体的中心有:局域网下的GitLab服务器(公司可以自己搭建)。互联网下的GitHub(外网),Gitee码云(国内网站)。

Git常用命令

git和linux的命令很多通用。如vim、cat指令等等。

命令名称作用
git config --global user.name 用户名设置用户签名(区分不同操作者身份,确认本次提交是谁做的,git首次安装必须设置一下用户签名,否则之后无法提交代码)
git config --global user.email 邮箱设置用户签名(区分不同操作者身份,确认本次提交是谁做的,git首次安装必须设置一下用户签名,否则无法提交代码)
git init初始化本地库
git status查看本地库状态
git add 文件名添加暂存区(状态会从红色变绿色,删除了还在工作区)
git commit -m "日志信息" 文件名提交本地库(要先gitadd才能用这个)
git reflog查看历史记录(如果查不到,可能是自己没用户签名)
git reset --hard 版本号(最前面的数字)版本穿梭
git reflog

查看版本信息(HEAD->master)指针指向哪个版本

git log查看版本详细信息(AUTHOR DATE)

本质是git的底层指针在指向master,具体流程如图:

 

 

 Git分支

 什么是分支?

几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。 在很多版本控制系统中,这是一个略微低效的过程——常常需要完全创建一个源代码目录的副本。对于大项目来说,这样的过程会耗费很多时间。

有人把 Git 的分支模型称为它的“必杀技特性”,也正因为这一特性,使得 Git 从众多版本控制系统中脱颖而出。 为何 Git 的分支模型如此出众呢? Git 处理分支的方式可谓是难以置信的轻量,创建新分支这一操作几乎能在瞬间完成,并且在不同分支之间的切换操作也是一样便捷。 与许多其它版本控制系统不同,Git 鼓励在工作流程中频繁地使用分支与合并,哪怕一天之内进行许多次。 理解和精通这一特性,你便会意识到 Git 是如此的强大而又独特,并且从此真正改变你的开发方式。

分支简介

为了真正理解 Git 处理分支的方式,我们需要回顾一下 Git 是如何保存数据的。

或许你还记得 起步 的内容, Git 保存的不是文件的变化或者差异,而是一系列不同时刻的 快照 。

在进行提交操作时,Git 会保存一个提交对象(commit object)。 知道了 Git 保存数据的方式,我们可以很自然的想到——该提交对象会包含一个指向暂存内容快照的指针。 但不仅仅是这样,该提交对象还包含了作者的姓名和邮箱、提交时输入的信息以及指向它的父对象的指针。 首次提交产生的提交对象没有父对象,普通提交操作产生的提交对象有一个父对象, 而由多个分支合并产生的提交对象有多个父对象,

为了更加形象地说明,我们假设现在有一个工作目录,里面包含了三个将要被暂存和提交的文件。 暂存操作会为每一个文件计算校验和(使用我们在 起步 中提到的 SHA-1 哈希算法),然后会把当前版本的文件快照保存到 Git 仓库中 (Git 使用 blob 对象来保存它们),最终将校验和加入到暂存区域等待提交:

$ git add README test.rb LICENSE
$ git commit -m 'The initial commit of my project'

 

当使用 git commit 进行提交操作时,Git 会先计算每一个子目录(本例中只有项目根目录)的校验和, 然后在 Git 仓库中这些校验和保存为树对象。随后,Git 便会创建一个提交对象, 它除了包含上面提到的那些信息外,还包含指向这个树对象(项目根目录)的指针。 如此一来,Git 就可以在需要的时候重现此次保存的快照。

现在,Git 仓库中有五个对象:三个 blob 对象(保存着文件快照)、一个  对象 (记录着目录结构和 blob 对象索引)以及一个 提交 对象(包含着指向前述树对象的指针和所有提交信息)。

分支创建

Git 是怎么创建新分支的呢? 很简单,它只是为你创建了一个可以移动的新的指针。 比如,创建一个 testing 分支, 你需要使用 git branch 命令:

$ git branch testing

这会在当前所在的提交对象上创建一个指针。

 

两个指向相同提交历史的分支

那么,Git 又是怎么知道当前在哪一个分支上呢? 也很简单,它有一个名为 HEAD 的特殊指针。 请注意它和许多其它版本控制系统(如 Subversion 或 CVS)里的 HEAD 概念完全不同。 在 Git 中,它是一个指针,指向当前所在的本地分支(译注:将 HEAD 想象为当前分支的别名)。 在本例中,你仍然在 master 分支上。 因为 git branch 命令仅仅 创建 一个新分支,并不会自动切换到新分支中去。

 分支切换

要切换到一个已存在的分支,你需要使用 git checkout 命令。 我们现在切换到新创建的 testing 分支去:

$ git checkout testing

 

HEAD 指向当前所在的分支

那么,这样的实现方式会给我们带来什么好处呢? 现在不妨再提交一次:

$ vim test.rb
$ git commit -a -m 'made a change'

HEAD 分支随着提交操作自动向前移动

如图所示,你的 testing 分支向前移动了,但是 master 分支却没有,它仍然指向运行 git checkout 时所指的对象。 这就有意思了,现在我们切换回 master 分支看看:

$ git checkout master

检出时 HEAD 随之移动。

这条命令做了两件事。 一是使 HEAD 指回 master 分支,二是将工作目录恢复成 master 分支所指向的快照内容。 也就是说,你现在做修改的话,项目将始于一个较旧的版本。 本质上来讲,这就是忽略 testing 分支所做的修改,以便于向另一个方向进行开发。

分支切换会改变你工作目录中的文件

在切换分支时,一定要注意你工作目录里的文件会被改变。 如果是切换到一个较旧的分支,你的工作目录会恢复到该分支最后一次提交时的样子。 如果 Git 不能干净利落地完成这个任务,它将禁止切换分支。

分支合并

命令:git merge 分支名

  git merge 工具用来合并一个或者多个分支到你已经检出的分支中。 然后它将当前分支指针移动到合并结果上。如果你想把hot-fix版本合并到master上,你得先check out 到master上,然后git merge hot-fix。这样就完成了没有冲突。

分支冲突合并

产生冲突的原因:合并分支时,两个分支在同一个文件的同一个位置有两套完全不同的修改。git无法替我们决定使用哪一个。必须人为决定新代码内容。(Git版本2.33新增了merge默认选项strategy="ort",就不会报错)总结:不能同文件里,分支本来是用来修改原来的问题的,你要是建一个新的分支还在master上改就会有冲突。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值