Pro Git --- 读书笔记 (Chaptero3)

Git 分支

  • 在执行提交操作的时候,Git会保存一个提交对象,该对象包含一个指向暂存内容快照的指针,以及它的父对象的我指针。
  • 暂存操作会为每一个文件计算校验和,然后把当前版本的文件快照保存到Git仓库中,最终将校验和加入到暂存区等待提交
  • 当使用提交操作时,Git会先计算每一个子目录的校验和,然后在Git仓库中保存这些校验和为树对象,随后,Git会创建一个提交对象,它包含指向这个树对象的指针
  • 现在Git仓库中有五个对象:三个blob对象(保存文件快照)、一个树对象(记录目录结构和blob对象索引)以及一个提交对象(包含着指向树对象的指针和所有提交信息)

  • git的分支,其实本质上仅仅是指向提交对象的可变指针

分支创建

git branch <branch>
  • 创建一个分支,本质是创建一个新的可以移动的指针

  • HEAD指针表示当前分支的特殊指针

分支切换

git checkout <branch>
  • 切换到某一个分支,这样HEAD指针就会指向那个分支

  • 然后再次提交之后,分支会向前移动,但是另一个分支却没有
  • 分支切换会改变工作目录中的文件

  • 项目分叉

  • 注意,切换分支之前,要留意工作目录和暂存区中还没有被提交的修改,它可能会和即将检出的分支产生冲突从而阻止Git切换分支,最好在切换分支之前保持一个干净的状态

  • 请牢记:当你切换分支的时候,Git会重置你的工作目录,使其看起来像回到了你在那个分支上最后一次提交的样子,Git会自动添加、删除、修改文件以确保此时你的工作目录和这个分支最后一次提交时的样子一模一样

分支合并

git merge <branch>
  • 合并分支
git branch -d <branch>
  • 删除分支

分支管理

git branch
  • 列出所有的分支
git branch -v
  • 查看每一个分支的最后一次提交
git branch --no-merged <branch>
  • 查看还没有合并到特定分支的其他分支

远程分支

远程引用是对远程仓库的引用(指针),常用做法是利用远程跟踪分支。
远程跟踪分支是远程分支状态的引用,它们是无法移动的本地引用,一旦进行了网络通信,Git就会帮你移动它们以精确反映远程仓库的状态,可以当作书签。它们以<remote>/<branch>的形式命名。

  • 克隆之后远程与本地的两个master指针

  • 远程仓库有其他人更新了

  • 本地执行git fetch <remote>之后,拉取了远程仓库的更新,远程指针发生移动

  • 推送本地分支到远程仓库之前,别人是看不见你的私人分支的,公开分支是需要你主动推送才可以公开
git push <remote> <branch>
// 或者
git push <remote> <local-branch>:<remote-branch>
  • 在fetch之后,就算有新的远程跟踪分支,本地是不会自动生成一份可编辑的副本。换句话说,这种情况下,不会有一个新的<branch>出现,只有一个不可修改的<remote>/<branch>指针

  • 当需要这个分支的时候,需要主动执行git merge <remote>/<branch>指令,将这些工作合并到当前所在分支

  • 如果想要在自己的分支上工作,可以将其建立在远程跟踪分支上

git checkout -b <branch> <remote>/<branch>
// 这个指令本地分支会有一个“跟踪分支”
  • 从一个远程跟踪分支检出一个本地分支会自动创建所谓的“跟踪分支”(它跟踪的分支叫做“上游分支”)。如果在一个跟踪分支上执行git pull,Git能自动识别到哪一个分支上抓取,合并到哪一个分支

  • 修改已有本地分支的上游分支

git branch -u <remote>/<branch>
  • 可以使用@{upstream}或者@{u}来引用它的上游分支
git merge <remote>/<branch>
等价于
git merge @{u}
  • 查看设置的所有跟踪分支
git branch -vv
  • 删除远程分支
git push <remote> --delete <branch>

变基

// 以<baseBranch>为基底,将<topicBranch>的补丁重放一遍
git rebase <baseBranch> <topicBranch>
  • 整合分支最容易的方法是merge命令,它会把两个分支的最新快照以及二者最近的共同祖先进行三方合并,合并的结果是生成一个新的快照

  • 还有另外一种方法就是rebase指令,它是通过提取需要合并的分支从共同祖先提交开始的所有引入的补丁和修改,然后在当前分支的基础上应用一次。也就是将某一分支上的所有修改都转移到另一分支上,就像“重新播放”一样
// branch1当前分支,branch2变基操作的目标基底分支
git checkout <branch1>
git rebase <branch2>

// 再进行一次快进合并
git checkout <branch2>
git merge <branch1>

  • 与直接merge相比较,最终结果都是一样的,但是经过变基使得提交历史更加整洁

  • 一般这样做的目的是为了确保在向远程分支推送的时候能保持提交历史的整洁

git rebase --onto master server client
  • 以上指令的意思是“取出client分支,找出它从server分支分歧之后的补丁,然后把这些补丁在master分支上重放一遍,让client看起来像是直接基于master修改一样”

变基的风险

  • 如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基

  • 变基操作的本质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。如果你已经将提交推送到某个仓库,而其他人也已经从该仓库拉取提交并进行了后续工作,此时,如果你用git rebase重新整理了提交并再次推送,你的同伴将不得不再次将他们手头的工作于你的提交进行整合,如果接下来你还要拉取并整合他们修改过的提交,事情将会变得一团糟

  • 如果真的出现了这个情况“有人推送了经过变基的提交,并丢弃了你的本地开发所基于的一些提交”,那么我们应该执行git rebase <remote>/<branch>,Git将会做一些操作

    1. 检查哪些提交是我们分支上独有的
    2. 检查其中哪些提交不是合并操作的结果
    3. 检查哪些提交在对方覆盖更新时并没有被纳入目标分支
    4. 把这些提交应用在<remote>/<branch>上面

  • 面对的情况

  • 执行merge之后,会变得混乱

  • 再次变基之后,Git自动计算之后,会生成友好结果

  • 牢记:只对尚未推送或分享给别人的本地修改执行变基清理历史,从不对已推送至别处的提交执行变基操作

posted @   huang1993  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示