这是Git系列的第一篇,主要会介绍Git的特点以及内部数据结构设计,和完成一次完整提交流程的时候数据是如何变化的。 Git有什么特点?...最重要的是:HEAD文件、(尚待创建的)index文件,和objects目录、refs目录。这些条目是Git的核心组成部分。...mkdir -p参数是能直接创建一个不存在的目录下的子目录: $ mkdir -p .git/refs/heads .git/refs/tags .git/objects $ echo 'ref: refs... index.txt 这个时候再看HEAD: $ cat .git/HEAD $ ref: refs/heads/master 继续查看refs/heads/master: $ cat .git/refs.../heads/master $ 750d7c0f7f998d3e2ce2d71ec801902f69bf6a39 所以整个指向关系就是:HEAD里面的内容是当前的ref,而当前ref的内容是commit
HEAD 引用 现在的问题是,当你执行 git branch (branchname) 时,Git 如何知道最新提交的 SHA-1 值呢? 答案是 HEAD 文件。...如果查看 HEAD 文件的内容,一般而言我们看到的类似这样: $ cat .git/HEAD ref: refs/heads/master 如果执行 git checkout test,Git 会像这样更新...HEAD 文件: $ cat .git/HEAD ref: refs/heads/test 当我们执行 git commit 时,该命令会创建一个提交对象,并用 HEAD 文件中那个引用所指向的 SHA...可以借助此命令来查看 HEAD 引用对应的值: $ git symbolic-ref HEAD refs/heads/master 同样可以设置 HEAD 引用的值: $ git symbolic-ref...HEAD refs/heads/test $ cat .git/HEAD ref: refs/heads/test 不能把符号引用设置为一个不符合引用格式的值: $ git symbolic-ref
作为开发者,在本地的git hook中加配置可以做到在commit和push操作时做对应的检查 禁止在master分支上Commit #!.../bin/sh protected_branch='master' current_branch=$(git rev-parse --symbolic --abbrev-ref HEAD) if [.../bin/sh protected_branch='master' current_branch=$(git rev-parse --symbolic --abbrev-ref HEAD) if [..." == "$remote_ref" ]; then echo ".git/hooks: Do not commit to $protected_branch branch" exit 1...还是有办法:git配置是可以根据不同目录使用不同配置的 比如我只想统一管理~/yy目录下的所有项目,那就修改~/.gitconfig文件加入以下内容 [includeIf "gitdir:~/yy/"]
branch 的 head,HEAD 也可以通过 git checkout 命令被直接设置到一个特定的 commit 上,这种情况被称之为 detached HEAD objects:这里是真正保存 Git...对象的目录,包括三类对象 commit,tree 和 blob(具体这三类对象是什么,慢慢往下看就知道了) refs:用来保存 branch 和 tag 对应的 commit Git 三大对象 目前...这几个对象的对应关系如下图所示: Git Brach 和 Tag 现在来看下 HEAD 中的内容,前面说过,HEAD 中存储的是工作目录当前状态对应的 commit: $ git:(master) cat....git/HEAD ref: refs/heads/master $ git:(master) cat .git/refs/heads/master c5bc98b8990bedd7444da537320559e601eba87b...master 是一个分支名,所以分支(branch)的本质是一个指向 commit 的指针 我们切一个新分支 feat/work: 查看下 refs/heads/master 和 refs/heads
.git/refs .git/refs/heads .git/refs/tags 1.3.1 创建一个引用 $ echo “1a410efbd13591db07496601ebc7a059dd55cfe9...更新某个引用 $ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9 比如新建一个分支(git分支的本质:...HEAD 始终指向当前分支的最近提交,不像普通引用那样包含一个 如: $ cat .git/HEAD ref: refs/heads/master 若执行 $ git checkout test,git...会这样更新HEAD文件 ref:refs/heads/test ORIG_HEAD 某些操作(如:merge、reset),会把调整为新值之前的先前版本的HEAD记录到OERG_HEAD中,只用其可以恢复或回滚之前的状态或做个比较...refs/heads/master 确定HEAD引用,明确检出至工作目录的内容 => GET HEAD ref: refs/heads/master 以上说明完成抓取后需要检出master分支 从info
1、git bash 获取分支信息 # 获取当前分支名 git rev-parse --abbrev-ref HEAD git branch --show-current # 获取当前hash git...rev-parse HEAD git rev-parse --short HEAD # 短的 上面的代码是通过git命令获取的分支信息,怎么可以在项目代码里面获取分支信息呢?...// 以下是res输出 curbranch== master { command: 'git rev-parse --abbrev-ref HEAD', escapedCommand: 'git...rev-parse --abbrev-ref HEAD', exitCode: 0, stdout: 'master', # 命令执行结果输出 stderr: '', failed:...可以看一下项目中 .git/HEAD 文件中的内容 HEAD指向最新放入仓库的版本 ref: refs/heads/dev_0922 编写脚本 #!
至于为什么又自己开发了 git ,看完下边对 Linus 的采访就明白了。 你为什么要开发 Git?...我们将 commit 对象的 key 值写入 .git/refs/heads/master 文件中 echo 44d318147e6b7bf2c3a5268018390440b2beae56 > .git...ref: refs/heads/master 他保存了一个引用,refs/heads/master 文件保存的就是当前分支最新的 commit 对象的 key 值。...查看 refs/heads/master 文件中的内容是 b1be33b8a27e1fcfa2c9f01b0fcb76a28b091071 ,和我们刚刚 FETCH_HEAD 中远端 mater 分支的.../master 看一下会是什么情况。
需要我们重点关注的是HEAD和index文件以及objects和refs目录。其中index中保存了暂存区的一些信息,这里不做过多介绍。...HEAD 新建分支的时候,Git是怎么知道我们当前是在哪个分支的,Git又是如何实现分支切换的呢?答案就在HEAD这个文件中。...$ cat .git/HEAD ref: refs/heads/master $ git checkout test Switched to branch 'test' $ cat .git/HEAD...ref: refs/heads/test 很明显,HEAD文件存储的就是我们当前分支的引用,当我们切换分支后再次进行提交操作时,Git就会读取HEAD对应引用的值,作为此次commit的parent...我们也可以通过symbolic-ref命令手动设置HEAD的值,但是不能设置refs以外的形式。 Packfiles 到这里我们在文章开头所说的重点关注的目录和文件都介绍完毕了。
什么是 Git 的 ref 和 head? 在进入正题解释“什么是Detatched HEAD?”之前,让我们先来回顾一下 Git 的基础知识“什么是 Git 的 ref 和 head?”。...ref:Git 的 ref 是适合人类阅读和记忆的,指向某 commit ID 的指针。 分支(branch)的名字(例如:master、dev)就是一种 ref。...注:Git 的 ref 存储在项目本地仓库中的 .git/refs/ 目录下,文件内容是 ref 所指向的 commit ID。...head:Git 的 head 也是一种 ref,并且它们就是代表我们本地分支(例如:master、dev等)的 ref。...什么是 Git 的 HEAD 注意前面说的 Git 的 head(注意是小写的 head)指代的是分支,而且指向其所指代分支的头部提交,即:.git/refs/heads/master 即指向 master
(1)更新某个引用 # 方式一 $ echo "1b63b62c89014812fb7d00c6c47b80abcec286e0" > .git/refs/heads/master # 方式二 $ git...3.2 HEAD引用 HEAD 文件是一个符号引用(symbolic reference),指向目前所在的分支。...$ cat .git/HEAD ref: refs/heads/master # 切换到test分支 $ git checkout test $ cat .git/HEAD ref: refs/heads...# 查看HEAD引用对应的值 $ git symbolic-ref HEAD refs/heads/master # 设置HEAD引用的值 $ git symbolic-ref HEAD refs/heads.../test $ cat .git/HEAD refs/heads/test # 查看当前分支 $ git branch -a master * test remotes/origin/master
cat .git/HEAD ref: refs/heads/master cat .git/ refs/heads/master 6fcd5346a1af366e7ac8226540616f8f51051537...回忆前面git reset HEAD -- xx 为什么能撤销暂存区(即git add的逆操作?)...,重置暂存区,不动工作区(默认模式) git reset HEAD 就是移动HEAD到HEAD(什么都没做),(选择性)重置暂存区,即撤销暂存区的更改。...把HEAD指向当前分支游标(什么都没做),用暂存区内容覆盖工作区(对比git add .) git checkout把HEAD指向当前分支游标(什么都没做),那就汇总一下工作区、暂存区与HEAD的差异吧...925c7aabcb4433f5616ae6248a3a333dd2fe7bba refs/tags/tt 其中以refs/heads开头的是分支,以refs/remotes开头的是远程分支,以refs
例子 要显示所有称为“master”的引用,无论是标记还是标题或其他任何内容,并且无论它们的引用命名层次结构有多深,请使用: git show-ref master 如果存在这样的引用,这将显示“refs...使用--verify标志时,该命令需要一个确切的路径: git show-ref --verify refs/heads/master 只会匹配名为“master”的确切分支。...符号引用是一个常规文件,用于存储以ref: refs/开头的字符串。例如,您的.git/HEAD是一个常规文件,其内容为ref: refs/heads/master。...-m 更新的 reflog 与。这仅在创建或更新符号引用时有效。 笔记 在过去,.git/HEAD是指向refs/heads/master的符号链接。...一般来说,使用 git update-ref HEAD "$head" 应该是 _ 很多 _ 比做更安全 echo "$head" > "$GIT_DIR/HEAD" 从符合条件的符号链接和两者都是错误检查的立场
,然后一一解决、回答它们 .git版本库里的文件/目录是干什么的?...Git是如何存储文件信息的? 当我们执行git add、git commit时,Git背后做了什么? Git分支的本质是什么?...Git提供了一个API让我们更新引用-update-ref,示例如下 $ git update-ref refs/heads/master 2616 # 2616为之前浮现commit log创建的commit...我们可以查看之前clone下来的Explore-Git的HEAD文件 $ cat .git/HEAD ref: refs/heads/master 当我们checkout到某个分支时,HEAD文件内容如下...$ git branch yeshan $ git checkout yeshan Switched to branch 'yeshan' $ cat .git/HEAD ref: refs/heads
./.git/hooks/update.sample .git/HEAD - 当前代码仓库的分支指针 ➜ cat .git/HEAD ref: refs/heads/master .git/refs...图片 图片 Branch 和 HEAD 的意义 执行完成了 git branch 命令,究竟做了什么呢? 到底什么是分支?分支切换又是怎么一回事?...当我们从 master 切换分支到 dev 的时候,HEAD 文件也会随即切换,即指向 dev 这个指针。设计就是这么美丽,不愧是鬼才,好脑袋。...图片 # 左边执行 $ cat .git/HEAD $ cat .git/refs/heads/master $ git cat-file -t 1711e01 # 右边执行 $ glo = git...在 Git 里面,将 HEAD 文件没有指向 master 的这个现象称之为 detached HEAD。
HEAD 包含存储库的当前头。根据您设置的“默认”分支,它将是 refs/heads/master 或 refs/heads/main 或您设置的任何其他分支。...其中之一是包含文件新内容的 blob 对象,一个是树对象,最后一个是提交对象。 让我们从 HEAD 或 refs/heads/master 再次追踪它们。...git 中的分支确实很便宜。标签的行为方式也相同,只不过它们是在 refs/tags 下创建的。 在logs目录下也添加了一个文件,用于存储类似于master分支的提交历史数据。...$ cat .git/HEAD ref: refs/heads/fix-url 如果我们在这里,做出commit。我需要这个来展示稍后合并的作用。...在这种情况下,您只需更新一个分支指向另一个分支指向的提交。这几乎涉及将 refs/heads/fix-url 中的哈希复制到 refs/heads/master。 第二个是变基合并。
├── hooks ├── info ├── objects └── refs 8 directories, 4 files .git/HEAD 文件保存当前所在的分支名,刚出始化完成,其内容为 master...我们再看看 .git/HEAD 的内容: $ cat .git/HEAD ref: refs/heads/master .git/HEAD 保存了当前分支对应的 refs 路径。...再回到 master 分支做一点改动: $ git checkout master $ echo c >> a.txt $ echo d >> b/b.txt $ git add a.txt b/b.txt...git reset 是把当前分支强制回退到某个版本,其实质就是修改当前分支对应的 .git/refs/head/ 文件内容,并没有什么魔法。...而我们常用的 git push 就是将本地的 objects 和 .git/refs/head 的内容同步到远端,对应的反向操作是 git fetch。 就说这些吧,希望对大家有所启发。
$ cat .git/HEAD ref: refs/heads/master cat .git/refs/heads/master b767d7115ef57666c9d279c7acc955f86f298a8d...branch和tag 从refs/heads/master的内容可以看到,branch是一个指向commit的指针,master branch实际是指向了b767d7这个commit。...$ cat .git/HEAD ref: refs/heads/work huabing@huabing-xubuntu:~/work$ cat .git/refs/heads/work .git/refs...命令将这些改动“暂存”在了一个“堆栈”中,让我们来看看.git目录发生了什么变化。...注意这里HEAD是一个指向当前branch最后一个commit指针,因此HEAD~1表示之前的一个commit。git reset命令也可以直接使用commit号作为命令参数。
主要原理说明 git 的管理依赖于在你本地仓库的目录中存在一个 .git 目录的,里面有 config、HEAD 等文件。...HEAD 里面是标识当前所在的分支,内容如下,表示当前在 dev 分支下,之后的拉取和推送都是在 dev 分支下完成: ref: refs/heads/dev config 里配置一些参数,如仓库地址、...fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs.../heads/master 其中,url 参数是重点,表示远程仓库地址,正常的远程仓库格式为https://github.com/huzhicheng/test__11.git,而这里,并且包括下面用到的都是...意思是说,获取新版本尝试自动合并,但是合并失败,请修复冲突并提交。 这时我们打开冲突的文件,会看到有 HEAD 、=======、>>>>>>> 这些符号,留下要合并的最后内容。
Git 是一个 “分布式版本管理工具”,简单的理解版本管理工具:大家在写东西的时候都用过 “回撤” 这个功能,但是回撤只能回撤几步,假如想要找回我三天之前的修改,光用 “回撤” 是找不回来的。...git update-ref -d HEAD 展示工作区和暂存区的不同 输出工作区和暂存区的 different(不同)。...git diff HEAD 快速切换到上一个分支 git checkout - 删除已经合并到 master 的分支 git branch --merged master | grep -v '^\*\...for-each-ref --sort=-committerdate --format='%(refname:short)' refs/heads/ 在 commit log 中查找相关内容 通过 grep...主要有以下组成: 标题行:必填,描述主要修改类型和内容 主题内容:描述为什么修改,做了什么样的修改,以及开发的思路等等 页脚注释:放 Breaking Changes 或 Closed Issues 常用的修改项
领取专属 10元无门槛券
手把手带您无忧上云