type
status
date
slug
summary
tags
category
titleIcon
password
icon
insider
🎮

参考资料

  • 截止2025.11.27的41节内容
notion image
notion image
Git基本原理介绍(1)——代码仓库的初始化_哔哩哔哩_bilibili
打算开几期视频讲讲Git的基本原理,我相信很多Git的初学者虽然会使用Git,但是对其背后的一些基本原理了解甚少,那么本系列就主要介绍一下。也欢迎大家关注我的微信公众号“卖逗搞IT”,获取最新更新视频和消息。这一节,主要介绍了git init命令背后到底发生了什么,可能很多git初学者并没有太多了解,甚至有些初学者不经常使用Git命令行,而是习惯于鼠标点击使用各种图形界面,这对初学者其实不是一个好, 视频播放量 21961、弹幕量 9、点赞数 559、投硬币枚数 515、收藏人数 1399、转发人数 213, 视频作者 麦兜搞IT, 作者简介 ,相关视频:Telegraf/Prometheus/Grafana用于网络监控的学习环境搭建#docker#dockercon2022,[中英熟肉] 你不需要 GitHub:任何 SSH 服务器都是一个 Git 服务器 | Тsфdiиg,Git基本原理介绍(34)——git-submodule,Git基本原理介绍(8)——Branch和HEAD,Git基本原理介绍(35)——git worktree,Git基本原理介绍(38)——再谈pre-commit,Git基本原理介绍(10)——checkout特定的commit,Git基本原理介绍(26)——Git Fetch&Git Pull,Git技巧——如何快速clone一个大仓库,Git基本原理介绍(22)——什么是git rebase
Git基本原理介绍(1)——代码仓库的初始化_哔哩哔哩_bilibili
基于此系列视频的学习笔记
 

git核心工作原理

先导知识

hash算法

  • git中用作存放于objects目录下对象的标记(指针)
  • git默认sha1,带碰撞检测的版本,可以手动指定sha256,在浏览器(浏览器中使用SHA1存在伪造签名的风险(哈希碰撞)),Docker等其他地方一般更多使用sha256
notion image
notion image
  • 两个不同的文件在sha1下哈希冲突示例
notion image
  • 换为sha256,不再冲突
notion image
  • 验证git的sha1不会冲突
notion image

辅助命令

  • git cat-file
    • -t 哈希值(前几位即可) 查看objects中文件的类型
      • 常见4种,按命令引入分开写
      • git add → 引入blob,在不执行压缩命令情况下一个blob全量存放一个文件的一个版本的内容
      • git commit → 引入tree与commit,commit指向commit命令时的tree,tree指向commit时目录下所有文件最新版本的blob以及作为子目录的tree
      • git tag -a ‘’ → 引入tag,tag静态指向关联的commit,区分于branch的动态(永远指向在对应分支下最新的commit)
      • 附图参考各自命令对应版块
    • -p 查看objects下二进制文件内容
    • -s 查看文件长度
notion image
notion image
  • git ls-files -s
  • 权限 SHA1哈希值 文件名
 
 
 
git add
blob类型 长度 内容
在index存放文件名
 

(git add - blob | git commit - tree,commit) git objects文件与关系

git add

  • 关键行为:index文件中存入文件名等元信息,objects下创建blob文件
  • objects文件夹下,哈希值前两位命名的文件夹+后续38位命名的文件(blob类型,存储内容为压缩头+压缩后内容,采用zlib压缩,哈希值源于对“blog 数据长度\0数据“SHA1运算,不存冗余,一样的内容objects不会有额外文件)
notion image
notion image
  • 验证SHA1生成源 - blob {size}\0{content} (注:echo生成的字符串末尾带\n)
notion image
  • 验证zlib压缩的解压过程
notion image
notion image

关系总览

  • git objects下各文件(blob,tree,commit,均用hash索引到)与关系
  • HEAD → 当前分支 → 分支对应最新commit(同时带parent commit) → tree(文件目录) → 文件/子tree(子目录)
notion image
notion image

文件内容

  • blob存放文件的不同版本内容
notion image
  • tree存放
    • 权限(040000-文件夹,100644-一般文件,owner读写,others读) 类型 对应版本的hash 文件名 (通过hash找对应版本)
notion image
  • commit存放
    • 对应tree
    • parent commit
    • 作者信息 时间戳 时区
    • 提交信息
notion image

git checkout 切换分支

  • 通过checkout命令移动HEAD指向,可切换到某个分支(间接指向某个commit)或具体commit(直接指向,此时为detached HEAD)
notion image
notion image
notion image
  • 在detached HEAD下保留commit,git checkout -b 新分支(在新分支上提交),提示的方法是使用git switch -c 分支名(如果已经提交了)

git branch -d/-D 删除分支

  • 删除分支只删除了分支本身(分支本身内容为commit的hash),也就是仅删除了指向某一commit的指针,不影响objects目录下的commit、tree、blob,如果在未合并下误删某分支,可以进入detached HEAD状态(checkout到对应commit的哈希值,要查找删除的分支对应commit的hash参见下方git reflog),然后重新创建分支(方法参见上方)
notion image

git reflog 查找过往提交的分支hash

  • 比如此处已经删除的dev分支上的最近一次提交,ab2fb9f
notion image
notion image
  • 切换后对应分支上的新文件(对应commit下add引入的新文件)恢复
notion image
  • 重新checkout -b 分支恢复
notion image
notion image

git status 文件状态

notion image

git branch

  • git branch查看所有分支(无参 - 本地,-a 本地 + 远程)
  • git branch 分支名 创建分支(不切换)
notion image
  • 从当前分支创建出的分支与当前branch指向同一个commit
notion image
  • checkout改变HEAD指针,指向新的分支
notion image
  • -d删除分支(报错未合并分支),-D强制删除
notion image
notion image
notion image
  • git branch -vv,详细信息,含与远程的tracking关系
 

git diff

    git gc

    • 从对每个版本的全量存储变为
     
     
    • .idx
    • .pack
    • git add后创建的objects(commit,blob,tree)默认全量存储(整个文件内容),每个版本都是以完整文件存储。
    notion image
    gc压缩前pack info 0B
    notion image
    pack info
    notion image
    参数给.idx .pack都可
    git verify-pack -v ./git/objects/pack/pack-hash.idx
    tree和blob都有基线版本,commit没有
    notion image
    后续blob存储增量(delta),最后跟初始版本hash
    git clone时已经压缩(git push)
    notion image
    notion image
    notion image
    12objects → 4次commit 单次3个对象(blob | tree | commit)
    delta 3 → 4次commit 3次增量更新
    notion image
    idx索引,压缩后仍可便捷地按原本的哈希值查看文件内容(压缩前)
    notion image
    notion image
    notion image
     
    notion image
     
    notion image
     
    notion image
    index二进制文件,其中包含文件名
    notion image
    notion image
    notion image
    notion image
    notion image
    notion image
     
     
    notion image
     
     
    notion image
    notion image
     
     
    notion image
    notion image
     
    notion image
     
    notion image
     
     
    notion image
    notion image
    notion image
    notion image
    notion image
     
     
    • git clone网络传输会进行压缩,git clone下来objects下pack与info两文件夹不为空
    中间add状态无效,产生垃圾blob(无tree引用)
    只有最后一次add有效
    notion image
    notion image
    notion image
    git prune -n → dry run,提示作用对象
    notion image
    git fsck 找出未引用blob
    git prune清除未引用对象
    notion image
    除了中间状态的add,其他产生垃圾的情况
    新分支下提交新文件,删除此分支,确定不恢复分支,对应commit,tree,独有的blob均为垃圾
    notion image
    notion image
    git prune不会删除
    notion image
    git gc复用旧有,同时压缩新的3个(垃圾对象)
    notion image
    从git fsck和git prune行为看出,git不认为是垃圾对象
    notion image
    notion image
    清除错误添加的内容(大文件,隐私文件)
     
     

    git merge

    fast forward

    notion image
    仅做指针移动
    仅master分出的bugfix做修改
    master不变
    notion image
    17 files → 18 files
    notion image
    ORIG_HEAD head的之前状态
    notion image
    notion image
     
     
     
     
     
     
     
     
     
     
     
     
     

    3 way merge

    notion image
    notion image
    notion image
    notion image
    ORIG_HEAD master分支前一次
    notion image
    应是类似菱形的效果,但git log线性展示
    可使用git log —graph或其他可视化工具
    notion image
    notion image
    notion image
    notion image
    notion image
    notion image
    notion image
    notion image
    notion image
    notion image
    git commit产生merge commit,有两个parent commit
    notion image
     
     
    fast forward线性历史合并,隐藏被合并分支的信息,不易看出(给主分支的变化(添加的commit)?合并与修改时间?)
    notion image
    3 way merge仍然保留
    notion image
     
     
    已经分叉的情况下做fast forward(分叉改线性,不产生一个有两个parent的merge commit)→ rebase
    fast forward的条件是,待合并的分支修改是基于当前分支的最新commit做的
    如果不是基于最新,要使用fast forward就rebase这些修改到最新的commit上
    被合并分支上的commit哈希值会重新生成
    notion image
    notion image
    不创建merge commit保持线性历史
    会对历史有影响 → 对移动的commits会生成新的hash(如果之前相关历史已经push,会在rebase后push出错,需要强制push,历史结构的改变会影响其他人工作,不适宜在仅自身使用的分支以外的分支,以及主分支上进行)

    git tag

    • branch是指向commit的指针,内容为commit的hash,但branch是动态的,永远指向最新的commit,如果需要静态的指针,仅与某一commit一直关联在一起,需要tag,git tag为轻量级tag,即只在refs/tags下创建对应tag,不在objects下产生文件,进而不能存储元信息(日期,tag信息,创建人)
    notion image
    notion image
    notion image
    • objects下的tag类型文件
    notion image
    • 只删除tags下文件,不删除objects下内容
    notion image
    • 时间不一样,hash不一样(name与message相同也不会撞)
    notion image
    notion image

    git clone

    • 远程refs信息压缩到packed-refs里
    notion image
    notion image
    notion image
    git branch -r查看远程分支
    notion image
    packed-refs下远程master不保证最新 → git fetch取到最新(检查远程分支情况并同步每个分支最新)
     
     
    新分支与分支新commit
    notion image
     
     
    检查远程分支与本地关联情况
    notion image
    git fetch
    notion image
    压缩的packed-refs可能滞后,git fetch后refs remotes的会更新
    notion image
    • 远程超前,git log看不到了
    notion image
    git branch -a查看本地与远程分支
    notion image
    git branch -r 未看到新分支
    notion image
    notion image
    notion image
    notion image
    notion image
    notion image
    new tracked
    git branch -r
    notion image
     
    notion image
    不同步本地不修改,git remote show origin
     
     
     
     
    git fetch对每个对应远程分支拉取新的commit,但对于远程删除不做处理(对本地没有,远程有的拉取,但对本地有远程没有的不做处理)
    notion image
    stale状态,git remote prune
    notion image
    git fetch —prune
    notion image
    notion image
    git branch -vv
    没有与远程关联的分支
    notion image
    notion image
    notion image
     

    git pull | git fetch & git merge | git clone | git push 本地与远程仓库交互

    添加远程源

    • git remote add 远程源名 url
    notion image
    • 对应会在.git/config的本地配置下添加对应内容
    notion image
    • git push时会进行对象压缩,便于网络传输
    notion image

    git fetch与git pull

    • git fetch,按fetch的字面义,不是同步,是用于获取每个远程分支(如origin/master → 远程源/远程分支)在远程有而本地没有的内容
    • git pull → git fetch & git merge二合一
    notion image
    notion image
    notion image
    • fast forward merge情形(直接完成)
    notion image
    • 3 way merge情形(处理冲突,弹出文件要求编辑commit信息)
    notion image

    git clone

     
     
     
     
     
    notion image
    无冲突下自动merge commit,git pull合并3 4 步
    notion image
    notion image
    notion image
    一个是本地直接的提交(平级),一个是merge commit
    notion image
    notion image
     
    notion image
    notion image
    notion image
    FETCH_HEAD
    notion image
    FETCH_HEAD记录远程分支最新commit
    notion image
    notion image
     
    notion image
     
     
    notion image
    notion image
    notion image
    notion image
    notion image
    notion image
    回滚merge
    notion image
    远程关联创建
    远程删除
     
     
     
     
     

    git push

    • git push → 对默认源的当前分支(需要预先关联)提交
    • git push -u 源 分支,提交对应分支到指定源,并关联本地与远程分支(同名)
    • git push 源 -d 分支,删除远程对应分支,不需要关联上
      • notion image
        notion image
        notion image
    • 如不使用-u(对本地有远程没有的分支首次push而言),本地与远程的分支不会关联上,后续的git pull与git push不能省略参数,均需要手动指明源与分支
    • 直接git push,不指明源与分支,被拒绝
    notion image
    • 新分支初次push使用-u 关联,之后可以省略参数
    notion image
    notion image

    hooks

    • 生命周期图
    notion image
    • 默认实现语言为shell,可换
    • 去掉.sample后即生效
    notion image
    notion image
    notion image
    • 如果exit 0仍会执行操作,如果exit 1则不执行操作退出
    notion image
    notion image
    • hooks不会推送到远程
    notion image
     
     
     
     
     
     
     
     
    git cherry-pick
    notion image
    notion image
     
    notion image
     
    notion image
    notion image
    历史不同hash不同,但内容一致
    notion image
    notion image
     
    git patch | apply
    git format-patch
     
     
     
    最后几次提交
     
    邮件头
    git diff内容
    git version内容
    notion image
     
    git apply .patch文件路径
    notion image
    notion image
    apply后相当于改了文件,但仍需要add与commit
    notion image
    git send-email .patch文件路径
    notion image
     
     
     
     
     
     
     
     
    notion image
     
     
    notion image
    notion image
     
     
     
    notion image
    notion image
     
    notion image
     
    notion image
     
     
    notion image
     
     
     
     
     
     
     
     
    notion image
     
    改本地的
     
     
     
     
     
     
     
    notion image
     
    notion image
    notion image
     
    notion image
     
    notion image
     
     
     
     
     
     
     
    notion image
    notion image
    notion image
    notion image
     
     
    notion image
    notion image
    notion image
    notion image
    notion image
    notion image
     
    notion image
     
     
    pull fetch push
     
     
    git stash & git worktree
     
    git cherry-pick
     
    hooks pre-commit
     
     

    git config

    配置读取优先级

    • 优先级上local(当前仓库配置.git/config) → global(全局配置 ~/.gitconfig) → system(win下安装目录/etc/gitconfig)
    notion image
    • system一般不做修改,主要修改全局global与本地,适宜global的常见配置项:
      • 代理http.proxy https.proxy
      • 命令别名alias
      • 信任文件夹safe.directory

    修改设置

    • 直接修改对应级别的配置文件
    • 使用命令:
      • 写入:git config (—global) 配置项(如http.proxy) 内容(如http://127.0.0.1:7898)
      • 删除:git config (—global) —unset 配置项
      • 查看:git config (—global,筛选级别,不写展示global + system) -l(或—list)(—show-origin对应配置的来源文件)
        • notion image

    多用户身份

    • 区分工作与个人账户

    alias 命令别名

      git worktree 分支并行 | git stash 暂存修改

      git stash

      • 应用场景:当前分支有未完成的工作,不打算提交,需要暂停工作,先切其他分支完成对应工作,再切回来继续
      • 问题:如果直接切会将文件状态带到切换的分支
      notion image
      notion image
      • git stash暂存后切换分支
      notion image
      • 完成工作切换回来,git stash pop复原暂存内容
      notion image

      git worktree

      • 把某个分支创出一个单独的文件夹
      notion image
      • 工作完成后回到原目录
      notion image

      其他少见的

      git unpack-objects 解压压缩后的对象

      • git unpack-objects < .pack文件(已有的不会unpack,需移动pack文件位置)
      notion image
      notion image

      git submodule

      • 共享依赖
      • 结合worktree分支并行
      notion image
      notion image

      git format-patch & git apply & git send-email

         
         
         
         
         

        git diff

         
         
        notion image
        notion image
        notion image
        notion image
        notion image
        notion image
        左索引区 右工作区(有哈希值,没有文件)
        • 显示从 -(索引区)的第四行开始共7行的内容
        notion image
        notion image
        • 对比索引区与代码仓库不同
        notion image
        notion image
        notion image
         
         
         
         
         
         
         
         
         
         
         
         
         
         
        notion image
        notion image
        notion image
        从项目实践中总结Git的使用从2s到0.9s的博客优化复盘
        Loading...
        2024-2025CamelliaV.

        CamelliaV | Java;前端;AI;ACGN;