Git 仓库 

    1.1Git 基本概念   

在Git中,我们将需要进行版本控制的文件目录叫做一个仓库(repository),每个仓库可以简单理解成一个目录,这个目录里面的所有文件都通过Git来实现版本管理,Git都能跟踪并记录在该目录中发生的所有更新。

现在我们已经知道什么是repository(缩写repo)了,假如我们现在建立一个仓库(repo),那么在建立仓库的这个目录中有一个“.git”的文件夹。这个文件夹非常重要,所有的版本信息,更新记录,以及Git进行仓库管理的相关信息

全部保存在这个文件夹里面。所以,不要修改/删除其中的文件,以免造成数据的丢失。

进一步的讲解请参考下面一张图,大概展示出了我们需要了解的基本知识。

    

根据上面的图片,下面给出了每个部分的简要说明:

  • Directory:使用Git管理的一个目录,也就是一个仓库,包含我们的工作空间和Git的管理空间。
  • WorkSpace:需要通过Git进行版本控制的目录和文件,这些目录和文件组成了工作空间,除了.git之外的都属于工作区。
  • .git:存放Git管理信息的目录,初始化仓库的时候自动创建。
  • Index/Stage:暂存区,或者叫待提交更新区,在提交进入repo之前,我们可以把所有的更新放在暂存区。
  • Local Repo:本地仓库,一个存放在本地的版本库;HEAD会只是当前的开发分支(branch)。
  • Stash:是一个工作状态保存栈,用于保存/恢复WorkSpace中的临时状态。

有了上面概念的了解,下面简单介绍仓库的文件结构。

该目录下有可能还有其他文件,但这是一个全新的 git init 生成的库,所以默认情况下这些就是你能看到的结构。新版本的 Git 不再使用 branches 目录,description 文件仅供 GitWeb 程序使用,所以不用关心这些内容。config 文件包含了项目特有的配置选项,info 目录保存了一份不希望在 .gitignore 文件中管理的忽略模式 (ignored patterns) 的全局可执行文件。hooks 目录保存了客户端或服务端钩子脚本。

另外还有四个重要的文件或目录:HEAD 及 index 文件,objects 及 refs 目录。这些是 Git 的核心部分。

  • objects 目录存储所有数据内容
  • refs 目录存储指向数据 (分支) 的提交对象的指针,里面即有stash栈指针以及tag等
  • HEAD 文件指向当前分支
  • index 文件保存了暂存区域信息

    1.2 简单的代码提交流程

        这里不对每一条命令做详尽的解释,这些命令或类似命令贯穿我们顺利的一个完整提交,关于其他情况以及这些命令的详细解释留待后面叙述。

(1)git status //查看工作区代码相对于暂存区的差别,

(2)git add . // 将当前目录下修改的所有代码从工作区添加到暂存区 . 代表当前目录

(3)git commit -m “commit-message” //将暂存区的代码提交到本地版本库

(4)git push origin master // 将本地版本库推送到远程服务器,origin是远程主机,master表示是远程服务器上的master分支,分支名是可以修改的。

  1.3 GIT的基本操作:

  

版本管理的挑战

虽然有这么优秀的版本管理工具,但是我们面对版本管理的时候,依然有非常大得挑战,我们都知道大家工作在同一个仓库上,那么彼此的代码协作必然带来很多问题和挑战,如下:

  1. 如何开始一个Feature的开发,而不影响别的Feature?
  2. 由于很容易创建新分支,分支多了如何管理,时间久了,如何知道每个分支是干什么的?
  3. 哪些分支已经合并回了主干?
  4. 如何进行Release的管理?开始一个Release的时候如何冻结Feature, 如何在Prepare Release的时候,开发人员可以继续开发新的功能?
  5. 线上代码出Bug了,如何快速修复?而且修复的代码要包含到开发人员的分支以及下一个Release?

大部分开发人员现在使用Git就只是用三个甚至两个分支,一个是Master, 一个是Develop, 还有一个是基于Develop打得各种分支。这个在小项目规模的时候还勉强可以支撑,因为很多人做项目就只有一个Release, 但是人员一多,而且项目周期一长就会出现各种问题。

Git Flow

就像代码需要代码规范一样,代码管理同样需要一个清晰的流程和规范

Vincent Driessen 同学为了解决这个问题提出了 A Successful Git Branching Model

下面是Git Flow的流程图

上面的图你理解不了? 没关系,这不是你的错,我觉得这张图本身有点问题,这张图应该左转90度,大家应该就很用以理解了。

Git Flow常用的分支

  • Production 分支

也就是我们经常使用的Master分支,这个分支最近发布到生产环境的代码,最近发布的Release, 这个分支只能从其他分支合并,不能在这个分支直接修改

  • Develop 分支

这个分支是我们是我们的主开发分支,包含所有要发布到下一个Release的代码,这个主要合并与其他分支,比如Feature分支

  • Feature 分支

这个分支主要是用来开发一个新的功能,一旦开发完成,我们合并回Develop分支进入下一个Release

  • Release分支

当你需要一个发布一个新Release的时候,我们基于Develop分支创建一个Release分支,完成Release后,我们合并到Master和Develop分支

  • Hotfix分支

当我们在Production发现新的Bug时候,我们需要创建一个Hotfix, 完成Hotfix后,我们合并回Master和Develop分支,所以Hotfix的改动会进入下一个Release

Git Flow如何工作

初始分支

所有在Master分支上的Commit应该Tag

Feature 分支

分支名 feature/*

Feature分支做完后,必须合并回Develop分支, 合并完分支后一般会删点这个Feature分支,但是我们也可以保留

Release分支

分支名 release/*

Release分支基于Develop分支创建,打完Release分之后,我们可以在这个Release分支上测试,修改Bug等。同时,其它开发人员可以基于开发新的Feature (记住:一旦打了Release分支之后不要从Develop分支上合并新的改动到Release分支)

发布Release分支时,合并Release到Master和Develop, 同时在Master分支上打个Tag记住Release版本号,然后可以删除Release分支了。

维护分支 Hotfix

分支名 hotfix/*

hotfix分支基于Master分支创建,开发完后需要合并回Master和Develop分支,同时在Master上打一个tag

Git Flow代码示例

a. 创建develop分支

git branch develop
git push -u origin develop

b. 开始新Feature开发

git checkout -b some-feature develop
# Optionally, push branch to origin:
git push -u origin some-feature # 做一些改动
git status
git add some-file
git commit

c. 完成Feature

git pull origin develop
git checkout develop
git merge --no-ff some-feature
git push origin develop git branch -d some-feature # If you pushed branch to origin:
git push origin --delete some-feature

d. 开始Relase

git checkout -b release-0.1.0 develop

# Optional: Bump version number, commit
# Prepare release, commit

e. 完成Release

git checkout master
git merge --no-ff release-0.1.0
git push git checkout develop
git merge --no-ff release-0.1.0
git push git branch -d release-0.1.0 # If you pushed branch to origin:
git push origin --delete release-0.1.0 git tag -a v0.1.0 master
git push --tags

f. 开始Hotfix

git checkout -b hotfix-0.1.1 master    

g. 完成Hotfix

git checkout master
git merge --no-ff hotfix-0.1.1
git push git checkout develop
git merge --no-ff hotfix-0.1.1
git push git branch -d hotfix-0.1.1 git tag -a v0.1.1 master
git push --tags

Git flow工具

实际上,当你理解了上面的流程后,你完全不用使用工具,但是实际上我们大部分人很多命令就是记不住呀,流程就是记不住呀,肿么办呢?

总有聪明的人创造好的工具给大家用, 那就是Git flow script.

安装

  • OS X

brew install git-flow

  • Linux

apt-get install git-flow

  • Windows

wget -q -O - --no-check-certificate https://github.com/nvie/gitflow/raw/develop/contrib/gitflow-installer.sh | bash

使用

  • 初始化: git flow init

  • 开始新Feature: git flow feature start MYFEATURE

  • Publish一个Feature(也就是push到远程): git flow feature publish MYFEATURE

  • 获取Publish的Feature: git flow feature pull origin MYFEATURE

  • 完成一个Feature: git flow feature finish MYFEATURE

  • 开始一个Release: git flow release start RELEASE [BASE]

  • Publish一个Release: git flow release publish RELEASE
  • 发布Release: git flow release finish RELEASE
    别忘了git push --tags

  • 开始一个Hotfix: git flow hotfix start VERSION [BASENAME]

  • 发布一个Hotfix: git flow hotfix finish VERSION

Git Flow GUI

上面讲了这么多,我知道还有人记不住,那么又有人做出了GUI 工具,你只需要点击下一步就行,工具帮你干这些事!!!

SourceTree

当你用Git-flow初始化后,基本上你只需要点击git flow菜单选择start feature, release或者hotfix, 做完后再次选择git flow菜单,点击Done Action. 我勒个去,我实在想不到还有比这更简单的了。

目前SourceTree支持Mac, Windows, Linux.

这么好的工具请问多少钱呢? 免费!!!!

Git flow for visual studio

广大VS的福音
GitFlow for Visual Studio

GIT基础知识:

1.文件系统:我们可以把硬盘理解成一本汉语词典,词典前面的目录索引就是文件系 统,能帮助我们快速找到文件内容的具体位置,通常我们也只会通过索引去找文件,windows中的我的电脑就是一个索引系统,索引里面没有的文件我们就 “找不到”。我们知道从操作系统删除文件,其实只是删除了索引,具体文件内容还是存在硬盘上的,虽然我们通过索引找不到,但是我们可以通过内容去查找(利 用一些恢复工具)。

2.git仓库:就是用来存放备份文件的地方,但是备份文件存入仓库的时候会压缩, 这些压缩的备份文件存放在.git/objects目录中,直接打开是乱码,而且为了节省空间,仓库不会存放重复的文件,只有新增和修改过的文件才会存入 git仓库,删除的时候并不会从仓库移除文件,不然我们怎么恢复呢。

3.HEAD:git的版本日志或版本号,通过git log 我们可以看到很多的编号,我们通过修改head指针来切换版本,每个版本关联一份快照,每个关照关联一系列文件,就是“HEAD->快照->仓库文件”这样一个关系链,我们可以很轻松的通过移动HEAD指针来改变我们的工作区文件。

4.暂存区/缓冲区:暂存区并不存放文件内容,暂存区仅仅是一份处于编辑状态的快照(索引文件),这份快照没有编号。commit就是把暂存区保存到版本库,并给版本日志新增一个编号(HEAD/版本号)指向这个快照副本。

5.git快照:我们知道git是通过快照来管理版本的,快照就是git的文件系统,就是我们说的汉语词典的索引,每次commit就是创建一份快照,并给快照起一个编号,这个编号就是HEAD。

6.工作区:工作区就是除开.git目录的其他东西。通过操作系统的文件索引来管理的内容。就是我们正常使用电脑的时候所看到,能编辑的内容。

7.分支:分支其实就是上面说到的版本日志,一个分支就是一个版本分组,每个分支记录该分支上的所有HEAD,“分支->HEAD->快照->仓库文件”

同学们可以通过下面的图片来理解以上几个概念,下图中的每个方块都是存放在硬盘上的文件,git就是建立了这样一个关系库来管理版本的(途中的缓冲区就是暂存区)。

大家不要被上图的复杂线条缩困扰,你只需要弄清HEAD就行了,我们移动HEAD指针其实就是通过HEAD编号找到快照,再通过快照找到这个HEAD的所有文件。

git命令的理解:

1、status

1.1、对比暂存区跟工作区,对比结果主要存在3种情况:

1.1.1、【删】暂存区记录的文件在工作区没有,add的时候会从暂存区移除对应的文件索引,但并不影响git仓库的内容。

1.1.2、【增】工作区已有的文件在暂存区没有记录的,add的时候会把对应的文件拷贝到仓库中,并在暂存区建立一条索引指向仓库中对应的文件。

1.1.3、【改】对工作区的文件内容进行算法得出校验值与暂存区记录的校验值不同,add的时候会把对应的文件拷贝到仓库中,并更新暂存区该条索引的信息。

1.2、对比暂存区与当前HEAD所指向的快照,对比结果也是增、删、改3种情况

2、add

add会执行2个任务,第一是把【增】【改】的文件拷贝到仓库,第二个是维护暂存区索引,保证暂存区索引跟操作系统的文件索引内容一致,快照索引指向的是仓库中的文件,操作系统索引指向的是工作区的文件。

3、commit

commit做的事情就简单些了,先对比暂存区与工作区,当暂存区与工作区内容相同的时候,直接保存暂存区为一份新的快照、并给这个快照生成1个编号,并把当前分支HEAD改成这个编号。

4、reset

reset分2情况:

4.1、reset文件:reset    b86563   b.txt ,将b86563这份快照中b.txt索引复制到暂存区的b.txt的索引。仅仅是对暂存区的索引进行修改,不影响文件内容,仅仅是修改了文件的关联。

4.2、reset HEAD:reset    b86563

4.2.1、参数–soft:仅仅修改HEAD/版本号。

4.2.2、参数–mixed:默认参数,修改当前HEAD/版本号,然后用指定的快照覆盖暂存区,工作区不变。

4.2.3、参数–hard:修改当前分支HEAD,用参数HEAD关联 的快照覆盖暂存区,并把工作区恢复到快照创建时的工作区状态,实际就是对比这份“历史快照”与工作区,快照中没有的文件,从工作区删除,校验码不同以及工 作区没有的文件,通过快照找到关联的文件(仓库中的),并复制到工作区。

5、checkout

reset分2情况:

4.1、checkout HEAD:用HEAD关联的快照覆盖暂存区,并把工作区恢复到快照创建时的工作区状态,checkout 快照与reset –hard的区别就是:checkout是可恢复,reset是不可恢复(后期会删除仓库中的文件,checkout不会)

4.2、checkout分支:checkout   dev ,切换到dev分支,并修改当前版本号为dev上最后一个版本号。如果dev分支不存在,创建一个名为dev的分支,版本号不变。

6、revert

revert就是创建一个新快照,并把分支HEAD修改为新创建快照的编号,用该快照覆盖暂存区,并把工作区恢复到快照创建时的工作区状态。checkout和reset会“丢弃”一些版本日志,cover不会。

总结:

1.暂存区、快照=git的文件系统=索引;仓库、工作区=我们真正需要的文件内容。

2.安全性:revert>checkout>reset,revert不会影响过去,checkout会丢弃掉一些版本号,reset会丢弃版本号和仓库中的某些备份文件。

7、远程仓库

工作区的文件是可以编辑的,git仓库的文件是不能编辑的,git上传到远程仓库或从远程仓库下载的时候,并不是下载或上传全部文件。

7.1、上传的时候,远程仓库的最新快照编号肯定是包含在本地的快照日志中的, 如果不存在,则证明远程仓库在上次下载后有改动,这时候要求先pull。反之,git会把本地新增的文件上传到远程仓库,并把新增的快照上传到远程快照。 通过图1,我们可以看出git是怎么通过HEAD轻松的找到新增的快照和文件的。

7.2、下载的时候与上传同理…

Git 仓库结构 (一)***的更多相关文章

  1. Git 仓库结构 (二)***

    一.GIT工作流程 了解git,首先要弄清楚对象在被git管理过程中所处的4个阶段,分别是: 工作目录 index(又称为暂存区) 本地仓库 远程仓库. 从时间先后来讲,工作目录的内容是你当前看到的, ...

  2. 多本地代码工作点更新到2个远端GIT仓库

    摘要:本文介绍了笔者多个本地工作节点(地方)的多台电脑(PC/笔记本电脑)同步源码到2个远端的GIT(一个GITHUB国外强制公开,一个oschina国内可不公开). 作者:太初 转载说明:请指明原作 ...

  3. Git学习记录--git仓库

    Git是一款强大的版本控制工具,与svn相比git的分布式提交,本地仓库等在使用时确实比较方便.当然两者之间各有优劣,我在这里不多做比较.由于之前少有接触git,只是零星大致地了解一点,所以找时间系统 ...

  4. 批量修改git仓库地址脚本

    前言   公司的代码都存放在自己搭建的gitlab上面.之前由于老板升级gitlab.导致下面有个叫做"api"的groups无法访问.通过无所不能的谷歌才知道.在gitlab在某 ...

  5. 取得项目的 Git 仓库

    有两种取得 Git 项目仓库的方法.第一种是在现存的目录下,通过导入所有文件来创建新的 Git 仓库.第二种是从已有的 Git 仓库克隆出一个新的镜像仓库来. 在工作目录中初始化新仓库 要对现有的某个 ...

  6. [原创]SSH密钥访问Git仓库配置

    SSH密钥并非为了解决拉取git仓库代码时,需要频繁输入密码的问题. SSH是一种比较安全的协议,可以用来免去远程登录Linux等服务器时需要输入密码的繁琐过程. 命令: ssh user@serve ...

  7. 创建Git仓库

    创建Git仓库 一.什么是版本仓库 什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改.删除,Git都能 ...

  8. 抛砖系列之git仓库拆分工具git-filter-repo

    最近负责把团队内的git仓库做了一次分拆,解锁一个好用的工具git-filter-repo,给大伙抛砖一波,希望以后遇到类似场景时可以信手拈来. 背景 笔者团队目前是把业务相关的java项目都放到了一 ...

  9. Git中如何利用生成SSH个人公钥访问git仓库

    Git中如何利用生成SSH个人公钥访问git仓库方法(这里以coding平台为例): 1. 获取 SSH 协议地址 在项目的代码页面点击 SSH 切换到 SSH 协议, 获得访问地址, 请使用这个地址 ...

随机推荐

  1. POJ3528移石头

    题目大意: 河道两旁直线上有两块石头不能移动,距离为L,但中间放置了N块石头并列出这N块石头到起点的距离,可以移走M块,那么移走石头后每次牛跨石头的最小距离如何达到最大值,输出这个最大值 让最小距离的 ...

  2. 【收藏】实战Nginx与PHP(FastCGI)的安装、配置与优化

    拜读南非蚂蚁大牛的文章真是有所收获 http://ixdba.blog.51cto.com/2895551/806622 一.什么是 FastCGI FastCGI是一个可伸缩地.高速地在HTTP s ...

  3. 【HDOJ6333】Harvest of Apples(莫队)

    题意: 给定T组询问,每组有两个数字n和m,求sigma i=0..m c(n,i) 答案对1e9+7取模 T<=1e5 1<=n,m<=1e5 思路: 注意要先变n再变m,否则会因 ...

  4. CF778A:String Game

    给出字符串s和t,以及s的长度n的一个全排列,求按照这个排列依次删除s的字符,删到何时s中不含子序列t. 解法一: t中的每个字符的位置在s中跳啊跳,合法的情况下t中的字符在s中的位置应该是单调递增的 ...

  5. tiles

    参考博客:https://blog.csdn.net/aosica321/article/details/68948915 https://blog.csdn.net/it_faquir/articl ...

  6. Multiply Strings(字符串乘法模拟,包含了加法模拟)

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  7. Mysql 数据库允许远程连接 服务器连接错误 Host 'XXX' is not allowed to connect to this MySQL server

    如果连接数据库的时候出现这个问题 Host 'XXX' is not allowed to connect to this MySQL server 说明 Mysql数据库 不允许远程连接, 需要修改 ...

  8. spring/spring boot/spring mvc中用到的注解

    在spring Boot中几乎可以完全弃用xml配置文件,本文的主题是分析常用的注解. Spring最开始是为了解决EJB等大型企业框架对应用程序的侵入性,因此大量依靠配置文件来“非侵入式”得给POJ ...

  9. Spring中基于AOP的@AspectJ

    以下内容引用自http://wiki.jikexueyuan.com/project/spring/aop-with-spring-framenwork/aspectj-based-aop-with- ...

  10. 【Nginx】发送响应

    请求处理完毕后,需要向用户发送http响应,告知客户端Nginx的执行结果.http响应主要包括响应行.响应头部.包体三部分.发送http响应时需要执行发送http头部(发送http头部时也会发送响应 ...