git学习(2)-分支管理
分支管理
查看分支
要对分支操作,那一定得知道有哪些分支,当前我们处于哪一条分支上,可以使用命令:
$ git branch * master
这是我们创建完仓库时候分支的状态。其中 git 为我们创建了一个默认的 master 分支,也叫主分支。
可以看到 master 前边有一个 *
号,它指明,我们现在处在master分支上。
创建分支
上边我们已经知道了master分支,如何创建一条新的分支?
使用命令格式git branch <分支名>
:
$ git branch dev
运行命令,会发现没有任何的提示内容,但我们的分支其实已经创建成功了。
查看一下:
$ git branch dev * master
可以看到原本多了一个我们新创建的 dev 分支。
切换分支
上边我们也说到了,分支前边有 *
号才代表当前处于哪一条分支上,那怎么切换到新创建的 dev 分支上呢?
使用命令:
$ git checkout dev Switched to branch ‘dev‘ $ git branch * dev master
看到提示有人会有疑问,既然是切换分支 switch
不是更恰当。git 的开发者后来就想到了这点,加上了 git switch <分支名>
用法:
$ git switch master Switched to branch ‘master‘ $ git branch dev * master
不过git switch
对 git 的版本有限制版本在 v2.23 及以上的才可以使用, 它是后来加入的。
创建并切换分支
有两种方式:
- 使用
git checkout -b <分支名>
- 使用
git switch -c <分支名>
$ git checkout -b cb Switched to a new branch ‘cb‘ $ git branch * cb dev master $ git switch -c sb Switched to a new branch ‘sb‘ $ git branch cb dev master * sb
删除分支
有创建就有删除,删除分支命令git branch -d <分支名>
:
$ git branch -d dev Deleted branch dev (was b17d20e). $ git branch * master
上边命令的意思是删除(delete)掉 dev
分支。
有时候我们不需要将一些功能分支合并到主分支,但我们需要删除掉它,一般应用在一些新功能上。(一般是 future 分支)
$ git branch -d feature-b error: The branch ‘feature-vulcan‘ is not fully merged. If you are sure you want to delete it, run ‘git branch -D feature-vulcan‘.
删除没有被合并过的分支,git会给我们提示 error ,此分支没有合并,如果要删除 使用 git branch -d <分支名>
注意是 -D
, 意为强行删除。
$ git branch -D feature-vulcan Deleted branch feature-vulcan (was 287773e).
合并分支
正常工作中,每个人都是在自己的分支上开发,完成后会将分支进行合并git merge <分支名>
:
$ git merge dev Updating d46f35e..b17d20e Fast-forward readme.txt | 1 + 1 file changed, 1 insertion(+)
合并分支是将目标分支合并到当前分支上,上述场景就是在master分支上,我们想要将dev分支合并到master分支上。
合并冲突
当两个不同的分支对同一文件进行了修改后,合并分支操作会发生冲突,让我们来创造一个冲突:
$ git init # 创建一个空仓库 $ vim afile # 文件内容自己定义 $ git add . # 将当前文件添加到版本仓库暂存区 $ git commit -m "first master commit"
这里我们只写了语句,创建空仓库,并想版本仓库里添加了一个文件。
创建并切换分支:
$ git checkout -b dev $ git branch # 查看一下是不是在dev分支上
我们会发现,当我们创建分支后,dev分支上的文件 master分支上的文件是一样的。
现在做一些修改:
$ vim afile # 添加或者删除一行文本 只要对文件修改即可 $ git add . $ git commit -m "first dev commit" $ git checkout master # 切换回 master 分支
现在我们在 master 分支上修改同一个文件 afile,当我们打开的时候会发现dev上修改的内容没有出现在这,还是原来的内容。
$ vim afile # 添加或者删除一行文本 只要对文件修改即可 $ git add . $ git commit -m "sec master commit"
将 dev 分支合并到 master 上来。
$ git merge dev # 这种方式属于快速合并 Auto-merging afile CONFLICT (content): Merge conflict in afile Automatic merge failed; fix conflicts and then commit the result.
git给予了我们友好的提示,说自动合并失败了。需要修正冲突然后提交结果。此时,查看文件会发现我们修改的地方出现了这样的标志:
... <<<<<<< HEAD ... ======= ... >>>>>>> dev
这是git 为我们标注出来的不同分支的内容,
将这些内容取舍之后按照正常顺序提交到版本仓库就可以了。
$ git add . $ git commit -m "fix merge conflicts" $ git log --oneline --graph # 查看一下 * 0596be5 (HEAD -> master) fix merge failed || * fe1b4d6 (dev) change line from dev branch * | 4a3a9d6 change from master branch |/ * a5dadd6 add file
Fast forward模式
一般合并分支的时候 git 会使用fast forward模式,这种模式下,删除分支会丢失分支信息。如果仅用 fast forward 模式,git在 merge 合并分支的时候生成一个新的 commit,这样,从分支历史上就可以看出分支信息。
禁用 fast forward 模式 只需要用 git merge --no-ff -m "message for commit" <分支名>
$ git log --graph --pretty=oneline --abbrev-commit * e1e9c68 (HEAD -> master) merge with no-ff |\ | * f52c633 (dev) add merge |/ * cf810e4 conflict fixed ...
分支工作现场
某些场景下,需要暂时保存一下工作现场去做别的事情,例如修复bug。
git 提供了 stash 功能,可以将当前工作现场“保存”下来,等到需要的时候再拿出来。
保存工作现场:
$ git stash Saved working directory and index state WIP on dev: f52c633 add merge
查看工作现场:
$ git stash list {0}: WIP on dev: f5fd63b first master commit
当做完某些操作之后,需要回来继续工作,就将工作区的东西拿出来。
$ git stash pop
pop 只会pop出 stash 中第一个,也是最近我们保存的stash。
而 stash 可以有多个,可以使用 git stash apply <stash 编号>
来恢复指定的stash
$ git stash apply {0}
某一次的改动应用到分支其它分支上
当修复bug之后,我们 master 分支上已经合并上来bug分支。现在我们回到dev分支继续开发,还是需要将修改应用到dev分支,一种最笨的方式就是我们将bug分支代码重新再dev上写一遍,另一种则更加简单,只用git cherry-pick <commit id>
来将 bug 分支上的代码应用到dev 分支上,此外,git还会自动帮助我们提交这次的修改。
$ git cherry-pick 4c805e2 [master 1d4b803] fix bug 101 1 file changed, 1 insertion(+), 1 deletion(-)
多人协作 远程仓库里来解释