日常编程中Git是一项必不可少的技能,本文是个人对于Git分支的一些理解和看法,文中有任何问题请给与指正!

分支简介

学习Git手册得知,Git 和其它版本控制系统的主要差别在于Git对待数据的方法

  • Git:直接记录快照,而非差异比较。
  • 其他系统:一组基本文件和每个文件随时间逐步累积的差异。

在进行提交操作时,Git 会保存一个提交对象(commit object)。该提交对象会包含一个指向暂存内容快照的指针,分支其实就是这个指针,多个分支就意味着指针是可变的。Git 的默认分支名字是 master,由 git init 命令所得到。

常规操作

常规的分支操作有创建,切换,删除,合并。
首先,我们创建dev分支,然后切换到dev分支:

$ git checkout -b dev
Switched to a new branch 'dev'

git checkout命令加上-b参数表示创建并切换,相当于git branch 加上git checkout两条命令,然后我们查看分支:

$ git branch
* dev
master

git branch命令会列出本地所有分支,当前分支前面会标一个*号,如果想要查看远程分支可以加上-r参数,查看所有分支加上-a参数,效果如下:

$ git branch -r
origin/master
$ git branch -a
* dev
master
remotes/origin/master

然后,我们在新创建的dev分支上开发,这里假装改了一个bug,然后提交,我们假装dev分支已经开发完毕,现在切换到master分支:

$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.

此时我们会发现之前dev分支修改的文件在目前的master分支并没有变化,之前说过多分支就相当于指针指向不同,当前 masterdev 分支指向不同的提交对象,这就是Git 处理分支的方式。
现在,我们把dev分支的代码合并到master分支上:

$ git merge dev
Updating 4c4afe7..3d7922a
Fast-forward
readme.md | 2 --
1 file changed, 2 deletions(-)

git merge命令用于合并指定分支到当前分支。合并后,刚才我们在dev分支的最新提交就同步到了master分支中。同时,可以看到Fast-forward这个词。 可以理解成Git直接把master指向dev的最新提交,因为这种情况下的合并操作没有需要解决的冲突,所以合并速度很快,这就叫做快进模式。
最后,我们删除dev分支:

$ git branch -d dev
Deleted branch dev (was 3d7922a).
$ git branch
* master

解决冲突

有时候合并分支不会很顺利。 如果我们在两个不同的分支中,对同一文件的同一部分进行了不同的修改,Git 就没法干净的合并它们,此时就会产生冲突:

$ git merge dev
Auto-merging readme.md
CONFLICT (content): Merge conflict in readme.md
Automatic merge failed; fix conflicts and then commit the result.

Git 提示Merge conflict in readme.md,这表示此文件有冲突,需要我们手动解决合并产生的冲突。 我们也可以使用 git status 命令查看那些因包含合并冲突而处于未合并(unmerged)状态的文件:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)

You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)

Unmerged paths:
(use "git add <file>..." to mark resolution)

        both modified:   readme.md

no changes added to commit (use "git add" and/or "git commit -a")

我们打开冲突文件查看问题所在:

<<<<<<< HEAD
31321321321321
sadsadsadsa
sadasdasdwqeqw
=======
564654654564
>>>>>>> dev

这表示 HEAD 所指示的版本(也就是我们的 master 分支,因为在运行 merge 命令的时候已经检出到了这个分支)在这个区段的上半部分(======= 的上半部分),而 dev 分支所指示的版本在 ======= 的下半部分。 为了解决冲突,我们必须根据实际开发的情况选择两部分中的一个,或者也可以自行修改这些内容,然后提交。最后我们可以使用git log命令查看提交记录:

$ git log
commit 9594d0c5781228e0ec1e13465cc86f9960e16d1a (HEAD -> master)
Merge: f4ce078 f40042d
Author: oscar-mx <oscarmx0912@outlook.com>
Date:   Sat Nov 16 17:18:00 2019 +0800

    add

commit f4ce0786df61fe4f67e07580fa124e30064618be
Author: oscar-mx <oscarmx0912@outlook.com>
Date:   Sat Nov 16 17:05:07 2019 +0800

    add

commit f40042d92750502fb7b62f3965dbb606c74136e3 (dev)
Author: oscar-mx <oscarmx0912@outlook.com>
Date:   Sat Nov 16 17:04:28 2019 +0800

最新的一条log就是我们刚才合并分支的记录。

多人开发中的分支策略

实际项目开发如果是多人协作,分支的管理的使用就变得尤为重要,这里也仅仅谈下自己的看法。
个人认为的分支开发工作流是这样的:

  • master 分支上保留完全稳定的代码,比如已经发布或即将发布的代码,需要和远程同步。
  • develop/dev分支作为开发分支,一旦开发结束测试完毕,就可以被合并到 master 分支了,最好也和远程同步。
  • 当然,实际情况中可能会有更多的特性分支,比如修复bug,实现单一的功能,这种分支可能仅仅只会存在很短时间,是一种短期分支

Bug分支

开发过程中,bug很常见,严格来说,每个bug需要创建短期分支来修复,修复后,合并分支,然后将其删除。但是我在工作中经常遇到要同时负责多个分支的代码编写,工作进行一半需要临时切换分支,这时就会用到git stash储藏功能:

$ git stash
Saved working directory and index state WIP on master: 9594d0c add

再次切换会开发分支,可以使用git stash pop取出之前储藏的内容,同时也会把stash内容删除:

$ git stash pop
On branch master
Your branch is ahead of 'origin/master' by 3 commits.
(use "git push" to publish your local commits)

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

        modified:   readme.md

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (24c08595ee874d6658d8694448463eafa61cea25)

同样我们也可以使用git stash list查看当前所储藏的内容文件

Git相关命令

点击下图到Git官网查看更多知识

🤣以上就是个人对于Git分支的一些理解和看法,文中有任何问题请给与指正!
记录生活,一起成长❤️