具体请参考:https://git-scm.com/book/zh/v1/Git-%E5%88%86%E6%94%AF-%E4%BD%95%E8%B0%93%E5%88%86%E6%94%AF
Git 中的分支,其实本质上仅仅是个指向 commit 对象的可变指针。Git 会使用 master 作为分支的默认名字。在若干次提交后,你其实已经有了一个指向最后一次提交对象的 master 分支,它在每次提交的时候都会自动向前移动。
如下图所示,在你提交了三次后,Git 中的默认分支(主分支)移动到了第三个提交对象上。图中绿色的方框代表一个提交对象,紫色的可以看做是每个提交对象的有关操作(下面内容并不涉及到,可以忽略),灰色的是目前的分支。
$ git branch branchName //创建的是本地分支,当该分支已经存在时会提示已经存在了
创建新分支时会在当前分支的代码上复制一份放到新分支上。
这会在当前 commit 对象上新建一个分支指针,如下图:
我们可以通过 HEAD 指针来知道当前工作在哪个分支上。在 Git 中,它是一个指向你正在工作中的本地分支的指针(可以将 HEAD 想象为当前分支的别名。)。
运行 git branch
命令,仅仅是建立了一个新的分支,但不会自动切换到这个分支中去。如上例中我们仍然是在 master 分支上工作,如果继续提交也将会只提交在 master 分支上。
要切换到其他分支,可以执行 git checkout
命令。
$ git checkout testing //切换到 testing 分支上 $ git checkout -b testing //新建testing分支并切换到该分支上,相当于同时执行了 git branch testing 和 git checkout testing
这样 HEAD 就指向了 testing 分支
如果我们继续在 testing 分支上工作时,比如新提交了一次,结果如下图所示:
每次提交后 HEAD 随着分支一起向前移动,现在 testing 分支向前移动了一格,而 master 分支仍然指向原先 git checkout
时所在的 commit 对象。
切换回 master 分支,git checkout master ,结果是如下图的:
这条命令做了两件事。它把 HEAD 指针移回到 master 分支,并把工作目录中的文件换成了 master 分支所指向的快照内容(你的工作目录上的文件将会自动变成在 master 分支上最新的提交版本一样)。也就是说,现在开始所做的改动,将始于本项目中一个较老的版本。它的主要作用是将 testing 分支里作出的修改暂时取消,这样你就可以向另一个方向进行开发。
如果我们在 master 分支上工作,比如在 master 分支上提交了一次之后,我们的项目提交历史产生了分叉,因为刚才我们创建了一个分支,转换到其中进行了一些工作,然后又回到原来的主分支进行了另外一些工作。这些改变分别孤立在不同的分支里:我们可以在不同分支里反复切换,并在时机成熟时把它们合并到一起。如下图:
在Git中创建和销毁分支,在分支上切换等速度非常快,Git 鼓励开发者频繁使用分支
假设我们正在项目的本地 master 分支上工作(一般本地master分支也关联远程master分支),并且已经提交了几次更新
但是项目出现了点问题,为了解决该问题,新建了一个新分支并取名为 iss53,希望在该分支上解决问题过后再合并到master分支上。
$ git checkout -b iss53
接着你开始尝试修复问题,在提交了若干次更新后,iss53
分支的指针也会随着向前推进,因为它就是当前分支
这时项目上出现一个紧急 bug 必须修改,这时我们正在 iss53分支上工作,我们并不需要把目前的工作 push 到远程仓库,唯一需要的仅仅是切换回 master
分支去修改 bug 然后再提交到远程仓库的master分支上。
(不过在切换分支之前,我们必须先把目前所在的分支的修改提交 commit ,否则会报错,切换分支的时最好保持一个清洁的工作区域)
此时工作目录中的内容和你在解决问题 #53 之前一模一样,你可以集中精力进行紧急修补。这一点值得牢记:Git 会把工作目录的内容恢复为检出某分支时它所指向的那个提交对象的快照。它会自动添加、删除和修改文件以确保目录的内容和你当时提交时完全一样。
接下来我们进行修补bug,我们一般会在 master 分支上新建一个分支来修改 bug ,而不会直接在 master 分支上进行修改。比如创建了一个用来修补 bug 的 hotfix 分支,并在该分支上进行了一系列修补工作:
$ git checkout -b hotfix
当我们确保在hotfix 上的分支修补是成功的后就可以回到 master
分支将它给合并起来,然后发布到远程仓库上。用 git merge
命令来进行合并(git merge
命令用于合并指定分支到当前所处的分支)
$ git checkout master
$ git merge hotfix
(请注意,合并时将可能出现“Fast forward”的提示。由于当前 master
分支所在的提交对象是要并入的 hotfix
分支的直接上游,Git 只需把 master
分支指针直接右移。换句话说,如果顺着一个分支走下去可以到达另一个分支的话,那么 Git 在合并两者时,只会简单地把指针右移,因为这种单线的历史分支不存在任何需要解决的分歧,所以这种合并过程可以称为快进(Fast forward)。)
合并之后最新的修改都已经在 master 分支上了,我们就可以将 master 分支push 到远程仓库上。
在改完 bug 以后,你想要继续回去修改 iss53 的问题。由于当前 hotfix
分支和 master
都指向相同的提交对象,所以 hotfix
已经完成了历史使命,可以删掉了。使用 git branch
的 -d
选项执行删除操作
$ git branch -d hotfix //删除 hotfix 分支 $ git checkout iss53 //回到 iss53 分支继续工作
注意:之前 hotfix
分支的修改内容尚未包含到 iss53
中来。如果需要纳入此次修补,可以切换到 iss53 分支用 git merge master
把 master 分支合并到 iss53
;或者等 iss53
完成之后,再将 iss53
分支中的更新并入 master 也行
。
如果某一分支暂未被合并简单地用 git branch -d
删除该分支会提示错误,因为那样做会丢失数据。这时如果我们仍然想删除该分支的话可以使用强制删除命令,比如在 hotfix 分支未被合并到 master 分支前将其删除:
$ git branch -D hotfix
原文:https://www.cnblogs.com/wenxuehai/p/10409517.html