zoukankan      html  css  js  c++  java
  • git原理整体理解

    背景

    从刚开始工作使用svn时就一直对代码提交产生冲突有很大的恐惧感。因为公司提交代码频率低,工作模块划分明晰,所以日常也不太容易遇到冲突。就算偶尔遇到冲突,就到网上找命令一顿自己也看不懂的操作解决冲突,就长呼一口气便不再深究。

    最近一个项目要使用git,git之前用过但是也仅仅是用过,对它了使用也仅仅是pull push add commit这些最基本的命令。正好这两天还没开始开发,就打算把git深究一下。

    一开始我就是百度各种命令然后用github模拟敲着玩,发现大多数博客都是管中窥豹,都是在解释一个命令或者一个点,很少能把git从头到尾的流程讲的很明晰。但是git这个东西你要是不了解整体,使用的时候会有很多莫名其妙的疑问和坑。所以我打算把我自己的理解在这里记录一下。


    准备工作

    学习git的第一步不应该是学习花样繁多的命令使用,而是了解git的文件结构,知道git的版本控制原理。这样就可以知道在什么时候用什么命令,有的放矢。

    这里有一篇很好的博客,可以先看一下。https://zhuanlan.zhihu.com/p/98679880,我主要参考这篇博客,然后添加一些自己的理解。

    文章导读

    • Git的跟踪范围
    • Git的分区
    • Git原理
    • Git分支
    • Git冲突解决

    一.Git的跟踪范围

      1.1 什么是Git的跟踪范围

      Git是一个版本控制工具,它像一个智能生物一样能感知到被它跟踪的文件的变更状态。

      1.2 Git的跟踪范围

      那么有哪些文件可以被感知到呢-->除了刚刚新增还未git add的所有文件,也就是除了Untracked files(未跟踪的文件),其他都在跟踪范围。

    二.Git的分区

      本章主要从基础入手,先介绍git的本地三分区本地四分区git五大块

      本地三分区是大家共识,本地四分区和git五大块是我自己总结的,首先讲本地三分区

      2.1 本地三分区

      当我们git clone把代码拉下来或者使用git init的时候,就存在了分区的概念。

      

       其中git_demo是git仓库所在根目录,.git 隐藏文件中存放了关于该git仓库的一切信息。

    • 工作区,也叫Working Directory
    • 暂存区,也叫stage,index
    • 本地仓库

      工作区

      工作区这个最好理解,因为我们可以直观的看见并且编辑的区域。其实就是git_demo目录中,.git文件夹外的所有区域都是工作区,如README.md现在就是在工作区中。

      暂存区

      暂存区就不是很好理解了,通常的理解就是我们在工作区中新增了一个文件,然后通过git add ${fileName}命令操作后,这个文件就进入的暂存区。可以理解为数据还没进入本地仓库之前暂时存放的区域。

      但是其实对于暂存区里有什么,很多人理解都是错误或者完全不清楚的。暂存区里不仅仅有我们git add添加的文件,其实暂存区里还包含了所有被跟踪的文件并且记录了还未commit进本地仓库的所有变更。可以理解为本地仓库和当前修改的merge

      注:存放在 ".git目录下" 下的index文件(.git/index)中,但是无法直接查看。

      暂存区可以用 git ls-files --cached 命令查看

      

      版本库

      版本库就是本地的代码仓库,可以理解为存放着代码所有的版本信息,包括文件信息,文件变更记录。通常理解就是将暂存区的代码通过git commit提交的代码会被放进版本库中,也就是在 这个时候你改的代码才真正的被成为一个版本,只是你的本地版本,其他开发人员无法感知。

       注:存放在工作区中“.git”目录下

      查看本地仓库文件目录可以用 git ls-tree  ${branchName} 查看

      

       下面这张图看看就行了,很不好理解。

      

      2.2本地四分区

        四分区是我无意中看到的一个博客中讲的一句话然后我自己测试之后总结的。

        

        2.2.2.哪本地四分区

          本地四分区 = 本地三分区 + 远程仓库副本

          怎么知道有这个副本

          

            当我git fetch之后

             

        2.2.3 什么是远程分区副本

          这里很重要,不知道远程仓库副本,很多东西理解不了。测试之后发现,不是像大家理解的那样远程代码库直接连接本地代码库,而是在远程和本地代码库之间还存在在一个远程代 码库副本。之前我们以为git pull就直接把远程代码库的代码更新到了本地代码库,其实git pull = git fetch + git merge  。 git fetch是将远程库更新到本地远程库副本,保证副本版本与              远程库一致,然后git merge合并副本和本地代码库,保证本地代码库的版本与远程库相同或者高于远程库。这样就能确保git push的时候不会因为本地库版本低于远程库版本而覆盖其他              开发成员先于我们提交的代码,(理解这里超级重要)。

        我们所说的冲突就是发生在这里,我们就是通过git fetch更新本地远程库副本与远程库最新版本,然后git merge 合并本地库修改产生高于远程库版本,保证merge之后的版本为整个项   目代码的最高版本。

        2.2.4 git五大块

        git五大块也是我自己总结的,这是从git整体上来看的。

        git五大块 = 远程代码库 + (本地远程库副本 + 本地三分区)

        我画了张图,应该可以理解了:

        

        2.2.5 五大块之间对比指令

        

    三.Git原理 

      参考上面博客

    四.Git分支

        Git原理和Git分支就看上面的那篇博客吧,讲的很好。

        综合理解来说就是git其实就保存三种类型文件,Blob,Tree,Commit。

        Commit

        commint就是每次commit或者merge的时候都会新增一个commit文件,每次commit其实就是git版本中的一个变更节点。文件中保存本次commit生成的文件目录树,可以通过这个目录 树获知明确的文件及文件结构(这不就是版本控制的核心吗)。

        Blob

        blob就是文件,每次新增或者更新都会保存一个文件副本,是单纯增量不是覆盖或者在源文件上修改。可以通过目录树查找到这个文件。

        Tree

        Tree文件保存的就是文件目录树。每次新增一个commit文件就会生成一个tree文件,和commit是对应的。

        commit ==== 一对一 ===》 tree === 一对多 ===》 blob

        

        git分支实际上保存的就类似于指针索引这类的东西,指向的是commit文件hash。

    五.冲突解决

      5.1当merge的时候产生冲突有几种情况

        5.1.1 merge之后发现有冲突我不想merge了,想取消本次merge

          可以使用git merge --abort 取消本次merge

          

        5.1.2 冲突之后我想全盘用我的文件覆盖远程库上的文件,或者用远程库上的文件覆盖我的文件。

          我的覆盖远程库:git checkout --ours ${fileName}

          远程库覆盖我的:git checkout --theirs ${fileName}

          

      

          5.1.3 冲突之后我想整合两边代码

          那么你只能手动改,想怎么改怎么改。

          最后

          必须把所有的both modified文件都按照你的意思改完之后,-->git add -->git commit 到你的本地库,这个时候你的本地库就是在merge之后的最新版本了,比本地远程库副本版本要新,但是注意不一定比远程库版本新,因为你有可能没git fetch,所以你还不一定可以git push。

          

           5.2 关于merge的一点理解

           merge有点类似于java中的锁,你git merge之后,假如没有冲突,你merge成功。但是假如有冲突失败了,那么你之后啥都不能做,除非你要么做了5.1.1取消本次merge,要么   5.1.2,5.1.3处理完冲突然后commit之后,才能进行其他操作。

          

          5.3 关于先pull还是先commit的问题

            我认为可以大胆的git commit,大胆的git fetch,小心的git merge。因为commit和fetch两者之前操作毫无关系,两者是通过git merge解决冲突的。

            建议:建议每次先commit 后 pull  。

            但是为了减少merge时候的冲突,push不应该间隔太长时间。

          最后,还有一些其他的想版本回滚,版本暂存都是小玩意了,理解了原理操作起来就有迹可循。

          这上面只是我的个人理解,但是我的理解是建立在看git文件目录和操作测试上面的,可能有些错误,但是大方向应该是没问题的,如果有问题欢迎指教。over~~~

          

           

        

        

        

      

  • 相关阅读:
    采用商业智能提升企业的数字营销策略
    采用商业智能提升企业的数字营销策略
    《PostgreSQL服务器编程》一一1.3 超越简单函数
    《PostgreSQL服务器编程》一一1.3 超越简单函数
    《PostgreSQL服务器编程》一一1.3 超越简单函数
    《PostgreSQL服务器编程》一一1.3 超越简单函数
    2017 全球半导体预估跳增 11.5%,存储器最夯
    2017 全球半导体预估跳增 11.5%,存储器最夯
    如何从零学习PostgreSQL Page结构
    转成json必须是unicdoe字符
  • 原文地址:https://www.cnblogs.com/qingshan-tang/p/12618556.html
Copyright © 2011-2022 走看看