假设有有个名为number.txt
的文件,文件内容是:first
,该文件路径为/test/alpha
。
在/test/alpha
下运行git init
来将该目录设立为 git 仓库。
运行git add number.txt
来将number.txt
文件添加置 git 缓冲区(index)。缓冲区是 git 用来跟踪所有文件的一个列表,该列表通过文件名来映射文件内容。此时,缓冲区有了 number.txt -> first 这样的一个映射;在运行 add 命令的同时,我们也在git 仓库里添加了一个包含 “first”的 blob 对象。
运行git commit -m first
命令时,git 做了3件事情。
1.0 创建了一个 tree 对象,该对象是一个 /test/alpha 下的所有文件的一个列表;该对象有一个指针指向了在 运行 git add 命令是创建的 first”的 blob 对象。
2.0 创建了一个commit 对象,该对象记录了你刚刚提交时的版本信息;该对象有一个指针指向了1.0创建的 tree 对象。
3.0 将 master 分支 指向了 2.0 中创建的 commit 对象。
运行git clone . ../beta
命令将建立一个名为beta的目录,并初始化为git仓库。该命令将alpha仓库中的所有对象拷贝一份至beta目录下。当前仓库的master分支指向的commit点和alpha的master分支一样。同时,会建立缓冲区(index),该缓冲区是 first commit 内容的镜像。于此同时,会将 number.txt 文件映射到缓冲区。
在/test/beta
下,将number.txt
内容“first”
修改为“second”
。
运行命令git add number.txt
和git commit - m second
。当前创建的commit 对象 的指针指向了它的父亲节点——first commit对象;同时,将当前分支master 的指针指向了当前commit对象。
回到/test/alpha
目录,运行git remote add beta ../beta
将beta仓库设置为 alpha 的远程仓库。
运行git pull beta master
。该命令做了2件事:
1.0 git底层运行了 git fetch beta master。该命令发现beta仓库多了一个 second commit 对象,于是拷贝该对象置alpha仓库。在alpha仓库下记录beta仓库master分支已指向second commit对象,同时更新标志 FETCH_HEAD,该标志显示从远程仓库beta拉取的master分支。
2.0 git底层运行了 git merge FETCH_HEAD。该命令读取了1.0中记录的beta仓库master分支指向的second commit 对象,而此时alpha仓库的master分支还指向first commit 对象——second commit对象的父亲节点。这就意味着,为了完成合并,就要调整master分支指向second commit 对象。调整后,继续更新缓存区(index)和工作区(working copy)索引为second commit。
运行git branch red
,将建立一个指向second commit对象的red 分支。
运行git checkout red。该命令将HEAD由之前指向的master分支换成指向red分支,使得red分支成为当前分支。
打开number.txt
文件,将“second”
修改为“third”
,运行git add number.txt
和个git commit -m third
。
运行git push beta red
。该命令发现了third commit 对象并将其拷贝至远程仓库beta。此时,beta仓库里有了red分支,且该分支指向了third commit对象。