一.Git介绍

Git是目前世界上最先进的分布式版本控制器。Svn CVS

版本控制器:就是用来追溯自己书写的代码的记录信息。好处:可以非常方便的记录何时何地何人操作了哪些代码。

什么是分布式版本控制器?

集中式:对于集中式的版本控制器,需要搭建一个中央服务器,然后在这个中央服务器里面作为代码的仓库。

分布式:就是每个用户的电脑都是一个独立的仓库,可以记录代码的变化,即使不联网,完全也可以自己独立开发。

二.Git安装

https://git-for-windows.github.io/

安装完后还需要最后一步设置,在命令行输入:告诉你是谁

$ git config --global user.name "Your Name"

$ git config --global user.email "email@example.com"

三.Git操作

1.创建仓库

1).创建仓库目录

2).通过git init命令把这个目录变成Git可以管理的仓库

注意:Git仓库创建好后,会在该文件存在一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。

注意:如果你没有看到.git目录,那是因为这个目录默认是隐藏的,用ls -ah命令就可以看见。

小结:git init 初始化仓库

2.添加文件到版本库

把文件添加到版本分两步,首先将文件添加到暂存区,然后再提交到版本库

1).创建文件并把文件添加到暂存区(git add

git add . 表示将当前目录下的所有文件都添加到暂存区

2).将文件从暂存区提交到版本库

-m 表示本次提交的描述

小结:

                   git add xxx 添加单个文件到暂存区

                   git add .   将当前文件夹下的所有文件都添加到暂存区

                   git commit -m ‘xxx’ 将文件提交到版本库  -m 表示描述

3.修改文件查看状态与不同

此时我们将文件内容修改

1).查看状态

git status 命可以让我们时刻掌握仓库当前的状态,上面的命令告诉我们,readme.txt被修改过了,但还没有准备提交的修改。

2).查看此次修改的文件与之前的不同

git diff顾名思义就是查看difference,可以从上面的命令输出看到,我们添加了一行hello单词

知道了对readme.txt作了什么修改后,再把它提交到仓库就放心多了,提前命令与之前相同。

小结:

                   git status 查看仓库状态

                  git diff   查看修改后文件与之前的不同。

4.版本回退

如果此时我们因为某种原因想回退到之前的某个版本该怎么办?

1).首先通过git log 查看之前的提交日志

如果嫌这样看着太乱的话可以试试加上—pretty=oneline参数

其中85d58ac82a21e8c587da900edff9a21566b1d708和78c5b099e84439c9b640a5028ee1fcb224432576 代表的是commit id(版本号),

它是通过SHA1计算出来的一个非常大的数字,用十六进制表示,而且你的commit id 和我的肯定不一样,实际以你自己的为准。

2).回退到之前某个版本

知道了之前的提交日志那如何回退到之前的版本呢?

首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交85d58ac82a21e8c587da900edff9a21566b1d708(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。

我们现在回退到上一版本使用命令:git reset –hard HEAD^

查看此时的文件:cat readme.txt

通过查看文件发现确实是回到了上一个版本,那么我们再通过git log查看此时版本库的状态。

最新的“修改readme.txt文件”这个版本已经不见了,就相当于我们坐了时光机一样,穿越到了之前的版本,

3).回退到未来某个版本

现在肯定又有人想我穿越到了过去,那我再怎么穿越回来呢?

在Git中,总是有后悔药可以吃的。当你用$ git reset --hard HEAD^回退到”添加readme.txt文件”版本时,再想恢复到”修改readme.txt文件”,就必须找到”修改readme.txt文件”的commit id。Git提供了一个命令git reflog用来记录你的每一次命令:

然后通过git reset –hard 85d58ac回退到”修改readme.txt文件”版本。

我们再通过查看文件内容,和历史提交记录发现又回到了”修改readme.txt文件”的版本

小结:

                   git log 查看提交历史记录,以便确认回退到历史哪个版本。

                   git reflog 查看命令历史,以便确定要回到未来哪个版本

                   git reset –hard commit_id 版本之间的穿梭回退

 

 

5.工作区与暂存区

1).工作区:

                   就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区:

2).暂存区:

是逻辑上的一个概念,是看不到的。

3).版本库:

工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

分支和HEAD的概念我们以后再讲。

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

第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;

第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

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

你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。

俗话说,实践出真知。现在,我们再练习一遍,先对readme.txt做个修改,比如加上一行内容:

然后,在工作区新增一个LICENSE文本文件(内容随便写)。

先用git status查看一下状态:

Git非常清楚地告诉我们,readme.txt被修改了,而LICENSE还从来没有被添加过,所以它的状态是Untracked

现在,使用两次命令git add,把readme.txtLICENSE都添加后,用git status再查看一下:

现在,暂存区的状态就变成这样了:

所以,git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。

一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:

现在版本库变成了这样,暂存区就没有任何内容了:

 

 

小结:

         工作区是指我们本地能够目录,暂存区是逻辑上的定义,我们想提交某个文件时,需要将工作区的文件放入到暂存区(git add),然后再提交。

6.管理修改

场景:比如说你修改readme.txt文件,并且git add 了,随后你又修改了readme.txt文件,但是此时你没有git add,直接git commit的了,这种情况下,你的第二次修改将不会被提交。

原因是你第二次修改没有放入暂存区,而git commit 是将暂存区的内容提交到版本库的。

下面实际操作一下:

1)第一次修改readme.txt文件:添加一行first update

2)git add 此次的修改

3)第二次修改readme.txt文件,添加一行second update

4)直接git commit 提交

发现第二次的修改没有被提交。验证了上面的结论,只有在暂存区的数据才能被提交。所以要想被提交必须先将文件放入到暂存区,然后再提交

我们在修改了某些文件时,也可以直接使用git commit -a -m ‘xxxx’ 提交。-a就相当于git add .操作,将当前目录下所有修改了的文件放入暂存区。

小结:

         在暂存区的数据才能被提交到版本库。

         修改了某些文件时,也可以直接使用git commit -a -m ‘xxxx’ 提交

7.撤销修改

场景1:修改了工作区的某个文件内容如何丢弃修改?

场景2:不但修改了工作区的某个文件内容,而且还添加到了暂存区,如何丢弃修改?

场景3:不但添加到了暂存区而且还提交到了版本库,如何丢弃修改?

场景1:修改了工作区的某个文件内容如何丢弃修改?

1.修改readme.txt文件  添加一行working undo

2.git status 查看状态

你可以发现git会提示你,git checkout – file 可以丢弃工作区的修改

3.git checkout – file 丢弃修改

场景2:不但修改了工作区的某个文件内容,而且还添加到了暂存区,如何丢弃修改?

1.修改readme.txt文件  添加一行stage undo

2.git status查看状态

Git同样告诉我们,用命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区.

3.git reset HEAD file 撤销暂存区的修改,重放回工作区。

此时修改的文件已经被放回到工作区。

4.从工作区中撤销本次修改

此时修改内容已被丢弃。

场景3:不但添加到了暂存区而且还提交到了版本库,如何丢弃修改?

这种情况就需要参考版本回退这一节了,回退到上一个版本

  1. 修改readme.txt文件,添加一行repository undo
  1. 提交到版本库
  1. 回退到上一个版本

小结:

                   对于只在工作区修改了文件内容,撤销此次修改使用 git checkout – file撤销

                   对于提交到了暂存区的文件内容修改,撤销此次修改需要分两步,第一步:git reset HEAD file 重放回工作区,第二步:git checkout – file 从工作区中撤销。

                   对于已经提交到版本库的文件内容修改,撤销需要回退到上一个版本,使用git reset –hard commit_id.

 

 

8.删除文件

如何将已经提交到版本库的文件删除?

  1. 添加文件到版本库
  1. 从版本库中删除

小结:

将文件从版本库删除也是分为两步:

                            第一步:git rm file 从版本库删除

                            第二步:git commit -m ‘xxx’ 提交本次的操作

四.远程仓库

1.添加远程仓库

以Github为例

1).在github上创建仓库

创建完成之后

仓库创建完成之后,github会提示我们从这个仓库里克隆出新的仓库,或者创建新的仓库与之个管理,或者推送已存在的仓库与之关联。

2).把本地的仓库与github仓库关联。

origin 是远程库的名字,github的默认叫法

3).把本地仓库的内容推送到github仓库

-u 的意思是如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机,这样后面就可以不加任何参数使用Git push

推送完成后,github上就有了你提交的内容

从现在起,只要本地作了提交,就可以通过命令:

git push origin master

把本地master分支的最新修改推送至github上。

小结:

                   git remote add origin xxx关联一个远程库

                   git push -u origin master 第一次将master分支的所有内容推送到远程库

                   git push origin master 上面命令第一次推送之后,以后的每次本地提交,使用不带-u 参数的即可。

 

 

2克隆远程仓库

上面讲了如何将本地仓库与远程仓库关联,还有一种情况就是将远程仓库克隆到本地

 

此时我将仓库克隆到了E盘

这样你的E盘就会出现你克隆的那个仓库。

小结:

                   要克隆一个仓库,首先你必须要知道仓库的地址,然后使用git clone命令克隆

 

 

 

五.分支管理

分支:是指在开发主线上又开辟了一条线,这样能在不影响主线的同时继续工作

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分支:

实战:

1).创建并切换分支

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

git branch dev

git checkout dev

2).查看当前分支

git branch命令会列出所有分支,当前分支前面会标一个*号。

3).修改文件内容提交

4).切换回主分支

切换回master分支后,再查看一个readme.txt文件,刚才添加的内容不见了!因为那个提交是在dev分支上,而master分支此刻的提交点并没有变:

5).将dev分支合并到master分支

git merge命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。

注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。

当然,也不是每次合并都能Fast-forward,我们后面会讲其他方式的合并。

合并完成后,就可以放心地删除dev分支了:

6).删除dev分支

删除后,再看branch,就只剩下master分支了。

小结:

                   查看分支:git branch

创建分支:git branch <name>

切换分支:git checkout <name>

创建+切换分支:git checkout -b <name>

合并某分支到当前分支:git merge <name>

删除分支:git branch -d <name>

2.     解决冲突

场景:你新建并切换到了分支feature1,然后修改了readme.txt文件并提交。随后你又切换到了master分支,同样修改了readme.txt文件并提交

这时如果你要合并feature1分支时,即会产生冲突。

模拟并解决:

1).创建并切换分支feature1,修改readme.txt文件,最后提交

2).切换到主分支,修改readme.txt文件,并提交

现在,master分支和feature1分支各自都分别有新的提交,变成了这样:

3).合并分支

这是git告诉我们 readme.txt文件产生冲突,必须手动解决冲突后再提交

git status 也告诉我们冲突的文件。

4).查看冲突文件

Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,我们修改如下后保存

5).修改文件,手动解决冲突

6).查看分支合并情况

7).删除分支

扩展:

git merge xxx 默认是使用fast-forward,fast-forward方式就是当条件允许的时候,git直接把HEAD指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建commit。

git merge --no-ff xxx  其中—no-ff指的是强行关闭fast-forward方式,使得合并分支后能够保留分支的commit的历史记录。

小结:

                   当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。

用git log --graph命令可以看到分支合并图。

 

 

3.     Bug分支

bug在软件开发中就像家常便饭一样,有了bug就需要修复,而git又特别提倡使用分支,所以每个bug都可以通过创建一个临时分支来修复,修复后,合并分支,然后再删除临时分支。

场景:当你接到线上环境代号为007的bug时,很自然的会去创建一个bug分支,分支名为bug007,但是,此时你正在dev分支上进行工作还没有提交,并不是你不想提交,而是你的工作还没完成还没法提交,但是现在这个bug又非常紧急,要求你尽快解决,这时我们该怎么办?

模拟并解决:

1).创建bug007分支

2).模拟在dev上正在工作还没有提交

3).git提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作

使用git stash将当前dev正在开发的工作储藏起来

再通过git status查看发现工作区现在是干净的了。

此时我们就可以切换到bug分支进行bug修复

4).切换到bug007分支修复bug

此时bug已经修改,那么我们就可以很放心的合并到主分支并将bug007分支删掉。

因为bug007是在主分支上建立的,所以此时需要切换到主分支上删除

5).合并并删除bug007分支

6).之前为了修改bug,我们将dev的内容储藏起来了,那么现在我们怎么恢复呢?

首先通过git stash list 查看

我们发现之前的工作现场还在。

那我们可以通过git stash pop来恢复现场

7).恢复工作现场

再git stash list 发现已经没有内容了。

小结:

                            修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;

当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。

4.Feature分支

软件开发中,总有无穷无尽的新的功能要不断添加进来。

添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。

现在你收到了一个新需求,要求你完成一个书籍管理的功能,

于是准备开发创建feature分支

半天后你开发完毕:

切换回dev分支准备合并

如果一切顺利的话,合并删除分支。

但是就在这时,接到上级命令说这个功能必须取消。

于是我们使用git branch -d 命令删除这个feature分支

这时git会提示我们,feature_book没有被合并,如果真的要强行删除使用git branck -D 命令来删除

删除成功

小结:

         开发一个新feature,最好新建一个分支;

如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>强行删除。

细说GIT分布式版本控制器的更多相关文章

  1. Git分布式版本控制器使用

    前言: 使用Git版本控制器差不多有一年多的时间了,在这一年多的时间里对这个传说的的分布式版本控制工具有了一定的了解.在实战项目开发中,对关于如何在通过Git提交项目,以及如何使用Git命令对提交的文 ...

  2. iOS:Git分布式版本控制器系统

    Git的使用 1.Git简介: Git是一个开源的分布式版本控制系统.与SVN.CVS相比 分布式    不需要中心仓库 Git的版本号都是生成的一个哈希值,比如:bbaf6fb5060b4875b1 ...

  3. Git分布式版本控制器安装注意点及其常用命令

    将git按照默认选项下载安装后,打开git bach版面进行git命令行操作(记住在安装的过程中文件夹中不能存在中文):注:Windows下,路径名不要包含中文,因为Git对中文支持不给力,可能会存在 ...

  4. GIT分布式版本控制器的前后今生

    Git的入门与安装 GIT基础操作 GIT的分支应用 GITLAB应用 gitlab与pycharm应用 GITHUB使用

  5. GIT分布式版本控制系统

    Git诞生历史 我想大家还记得Linus torvalds在1991年时发布了Linux操作系统吧,从那以后Linux系统变不断发展壮大,因为Linux系统开源的特性,所以一直接受着来自全球Linux ...

  6. Git ——分布式版本控制系统

    Git ——分布式版本控制系统 本人git主页地址:https://github.com/lendoon/test.git git使用心得:初次接触git在课堂上,老师给我们提供了一个代码托管的场所, ...

  7. 手把手教你玩转Git分布式版本控制系统! (转载)

    目录 Git诞生历史 Git环境准备 Git安装部署 Git常用命令 Git基本操作 Git管理分支结构 Git管理标签 GitLab安装部署 GitHub托管服务 Git客户端工具 Git诞生历史 ...

  8. 手把手教你玩转Git分布式版本控制系统!

    目录 Git诞生历史 Git环境准备 Git安装部署 Git常用命令 Git基本操作 Git管理分支结构 Git管理标签 GitLab安装部署 GitHub托管服务 Git客户端工具 1 Git诞生历 ...

  9. g4e基础篇#2 Git分布式版本控制系统的优势

    g4e 是 Git for Enterprise Developer的简写,这个系列文章会统一使用g4e作为标识,便于大家查看和搜索. 章节目录 前言 1. 基础篇: 为什么要使用版本控制系统 Git ...

随机推荐

  1. 设计模式入门——Head First

    设计模式是被前人发现.经过总结形成了一套某一类问题的一般性解决方案.使用模式最好的方式是:把模式装进脑子,然后在设计和已有的应用中,寻找何处可以使用它们.以往是代码复用,现在是经验复用. 从模拟鸭子游 ...

  2. Go语言学习笔记(1)

    包 package 声明包,import 导入包,导入的包名要用"",包中导出的名字以大写字母打头. package main import "fmt" imp ...

  3. Python使用xlwt模块 操作Excel文件

    导出Excel文件     1. 使用xlwt模块 import xlwt import xlwt    # 导入xlwt # 新建一个excel文件 file = xlwt.Workbook() # ...

  4. linux初始化

    [Linux 系统启动过程] Linux的启动其实和windows的启动过程很类似,不过windows我们是无法看到启动信息的,而linux启动时我们会看到许多启动信息,例如某个服务是否启动. Lin ...

  5. C# winform进度条 (异步)

    进度条页面: http://www.cnblogs.com/Deckard/archive/2009/06/24/1510451.html //============================ ...

  6. [PHP]防止表单重复提交的几种方法

    --------------------------------------------------------------------------------------------------- ...

  7. editable : false与 readonly 的区别

    editable : false 不能输入 readonly:不可操作,只能看

  8. vue 语法糖

    el:element 需要获取的元素,一定是HTML中的根容器元素data:用于数据的存储methods:用于存储各种方法数据绑定字面量只加载一次{{* msg}}data里面可以进行简单的运算:me ...

  9. 03_java基础(一)之计算机应用知识普及

    1.计算机(Computer) 全称:电子计算机,俗称电脑.是一种能够按照程序运行,自动.高速处理海量数据的现代化智能电子设备.由硬件和软件所组成,没有安装任何软件的计算机称为裸机.常见的形式有台式计 ...

  10. javascript 执行环境,作用域、作用域链、闭包

    1.执行环境 执行环境是JavaScript中国最为重要的一个概念.执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行为.每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数 ...