> 文档中心 > 【Git版本控制管理】Git的杀手级特性 —— Git分支

【Git版本控制管理】Git的杀手级特性 —— Git分支


Git的杀手级特性 —— Git分支

文章目录

  • Git的杀手级特性 —— Git分支
    • 分支创建
    • 分支切换
    • 分支的合并
    • 分支管理
    • 远程分支

前言 : 分支是从项目的主开发线中独立出来的一条开发线路的常见方法,它能让开发在多个方向同时进行,又不干扰主线的开发,能让项目有多个版本。Git分支被称作Git的杀手级特性是因为Git轻量级处理分支的方式,能让创建新分支和切换分支十分快速!并且Git鼓励在工作流程中频繁使用分支与合并。

  • Git分支本质是指向提交对象的可变指针。
  • Git默认分支名是master
    • 在每次提交操作之后都会有一个指向最后提交对象的master分支
    • master分支会在每次提交时自动向前移动

Git 的 master 分支并不是一个特殊分支。 它就跟其它分支完全没有区别。 之所以几乎每一个仓库都有 master 分支,是因为 git init 命令默认创建它,并且大多数人都默认它为主分支。像GitHub上的默认会创建一个main分支作为主分支, 只是名字不一样, 本质都一样。

请添加图片描述

分支创建

  • 使用git branch命令

    # 分支创建git branch <分支名># 比如创建分支devgit branch dev# 查看所有分支git branch# 删除分支git branch -d <分支名>

【Git版本控制管理】Git的杀手级特性 —— Git分支

  • Git中特殊指针HEAD, 它指向当前所在的本地分支, 当你切换分支的时候HEAD指针也会指向指定的分支

  • Git分支只是创建了一个可以移动的新指针

  • git branch 命令只是创建了新分支, 并没有自动切换到新的分支中去

  • 新创建的分支和当前所在的分支所指的对象都是一样的, 不一样的是HEAD指针只指向当前所在的分支
    请添加图片描述

分支切换

  • 使用git checkout 命令

    # 切换分支git checkout <分支名># 比如切换到dev分支git checkout dev# 新建分支并切换到该分支git checkout -b <分支名>

    请添加图片描述

  • 分支的切换本质就是HEAD指针指向对应的分支
    请添加图片描述

  • 在新的分支上进行开发,分支会向后移

    请添加图片描述

  • 切换到主分支进行另一个版本的开发

    请添加图片描述

需要注意的是两条分支的开发路线是不同的, 当然最后可以进行合并, 稍后再细说合并

  • 分支的切换需要留意工作目录和暂存区里那些还没有被提交的修改, 它可能会和切换到的分支产生冲突从而阻止 Git 切换到该分支, 需要将所有修改进行提交再切换分支

    请添加图片描述

    注 : 并不是说修改文件没提交就一定会被阻止分支切换, 而是两个分支中存在相同的文件, 被修改后产生差异就会让git捕捉到, 并阻止你分支切换, 因为工作目录和添加到暂存区的文件,如果没提交本地仓库,在切换分支后, 就会遗留到切换的分支中;这样是怕你无意之间修改了别的分支的内容, 因此在分支切换的时候一定要将文件提交完,再进行分支切换。

  • 当切换分支的时候,Git 会重置工作目录,使其变回原来那个分支上最后一次提交的样子

    • Git 会自动添加、删除、修改文件以确保此时工作目录和这个分支最后一次提交时的样子一模一样

分支的合并

分支合并是将不同的两个分支合并为一个分支, 一般在开发中将开发测试的分支合并到主分支中。因为主分支是确保稳定的分支, 一般都是在其他的分支进行开发测试的, 最后都弄好后再合并到主分支中。 【比如有些软件或者项目就会有正式版和测试版(有时候会叫beta版),这就好比Git中的master主分支和dev测试分支, 最后的测试好的分支再合并到主分支中】

  • 使用git merge 命令进行合并

    # 先切换到合并入的分支git checkout <分支名># 在将要合并的分支合并到该分支git merge <分支名> -m '提交说明'# 举个栗子将dev分支合并到master分支# 先切换到master分支git checkout master# 再合并dev分支git merge dev -m '将dev分支合并到master分支'
  • 假设一种情况是 master分支和dev分支在同一条开发线上

请添加图片描述

  • 因为此时的master分支和dev分支是在同一条开发线上, 也就是master分支可以顺着分支走到另一个分支, 那么在合并的时候, Git只会将master指针向前推进, 这种情况下没有需要解决的分歧, 这也叫做快进(fast-forward)

请添加图片描述

  • 另一种就是master分支和dev分支在不同的开发线上

    请添加图片描述

  • 合并分支就是

    请添加图片描述

  • 分支合并后, 被合并的分支并没有消失, 如果不需要该分支的话可以删除掉

    # 删除的分支git branch -d <分支名># 比如删除dev分支git branch -s dev
  • 每次冲突合并都会记录到日志文件中, 可以通过git log 进行查看

遇到冲突的分支合并

合并操作往往不会顺利进行, 因为在不同的分支中,对同一个文件的同一部分进行了不同的修改, Git就没办法将他们干净的合并, 因为它不知道你要那一部分的内容, 这时Git就会告知你有合并冲突产生。

  • 当冲突产生时, Git也会将不冲突的部分进行合并, 但是它不会自动创建一个新的合并进行提交, 而是暂停下来, 等待你解决冲突。

    • 使用git status可以查看那些未合并文件的状态(unmerge)
      请添加图片描述
  • 可以通过cat命令查看git为你标出的冲突文件

请添加图片描述

  • 也可以通过git mergetool, 启动可视化的合并工具, 这个本身就是vim编辑器

请添加图片描述

  • 修改完后使用git status进行查看是否已解决冲突
  • 然后可以使用git commit进行提交即可完成冲突合并

分支管理

  • git branch命令很有帮助

    # 列出所有分支git branch# 查看已合并到当前分支的分支git branch --merged# 查看未合并到当前分支的分支git branch --no-merged# 删除分支git branch -d# 强制删除分支git branch -D <分支名>

注意 :当你做这么多操作的时候,这些分支全部都存于本地。 当你新建和合并分支的时候,所有这一切都只发生在你本地的 Git 版本库中 —— 没有与服务器发生交互。

远程分支

远程引用是对远程仓库的引用(指针),包括分支、标签等等。

注意: 要使用远程分支, 需要先与远程仓库建立连接 ,具体查看 远程仓库的使用

  • 远程仓库的信息查看

    # 查看所连接的仓库git remote# 列出远程仓库引用的完整列表git ls-remote <remote># 获取远程分支的信息git remote show <remote>

    比如 :
    请添加图片描述

  • 推送分支

    当你想要公开分享一个分支时,需要将其推送到有写入权限的远程仓库上。 本地的分支并不会自动与远程仓库同步——你必须显式地推送想要分享的分支。 这样,你就可以把不愿意分享的内容放到私人分支上,而将需要和别人协作的内容推送到公开分支。

    git push <remote> <branch>
  • 更新远程仓库的分支(即同步数据)

    git fetch 命令从服务器上抓取本地没有的数据时,它并不会修改工作目录中的内容。 它只会获取数据然后让你自己合并。 然而,有一个命令叫作 git pull 在大多数情况下它的含义是一个 git fetch 紧接着一个git merge 命令。

    # 从服务器上抓取本地没有的数据时,但并不会修改工作目录中的内容git fetch <remote># 从服务器中抓取你需要同步的分支, 若有冲突则需要解决冲突才能覆盖到本地的工作目录中git pull <remote> <branch>
  • 删除远程分支

    git push <remote> --delete <branch>

    基本上这个命令做的只是从服务器上移除这个指针。 Git 服务器通常会保留数据一段时间直到垃圾回收运行,所以如果不小心删除掉了,通常是很容易恢复的


参考文献 :
《Git版本控制管理 第二版》人民邮电出版社
《Pro Git》Git官网的pdf下载 ; 在线中文文档查看