简述 Git 分支管理中的常用命令以及处理冲突分支、Bug 分支、多人协作中分支管理等问题。
Git 将所有的提交串成一条时间线,这条时间线就是一个分支,默认初始分支为 master
分支。HEAD
指向当前分支,而 master
指向提交。随着每次提交,master
分支会向前移动一步,master
分支线也就越来越长。
(分支创建)当创建出一个新的分支 new_branch
时,Git 新建了一个指针叫 new_branch
,指向 master
相同的提交,并把 HEAD
指向 new_branch
,就表示当前分支在dev
上。随着基于 new_branch
分支上进行提交,new_branch
会向前移动,而 master
分支不变。
(分支合并)当在 new_branch
分支上工作完成,可以将该分支合并到 master
上。合并方法有很多,如:将 master
指向 new_branch
指向的提交(Fast-forward
模式)。
一般用 master
来发布新版本,开发工作在其他分支上进行。
注意:GitHub 中默认初始分支为 mian ,Gitee 中默认分支为 master。
常用命令
因为 Git 的分支必须指向一个提交,如果没有任何提交就没有任何分支,自然命令输出结果也会为空。第一个提交后 Git 会自动创建 master 分支。
命令 | 说明 |
---|---|
git brach |
查看分支 |
git branch <branch_name> |
创建分支 |
git switch <name> or git checkout <name> |
切换分支 |
git checkout -b <name> or git switch -c <name> |
创建并切换分支 |
git branch -d <name> |
删除分支 |
git merge <name> |
将 name 分支合并当前分支 |
git log --graph |
查看分支合并图 |
git branch -M <new_name> |
重命名当前分支为 <new_name> |
git stash |
将被追踪但未提交的文件全部储藏,确保:nothing to commit, working tree clean |
git stash list |
显示所有的 stash |
git stash apply stash@{index} |
恢复指定的一个 stash 。git stash drop 恢复第一个 stash |
git stash drop stash@{index} |
删除指定的一个 stash 。git stash drop 删除第一个 stash |
git stash pop |
恢复第一个 stash 的同时把 stash 内容也删 |
git stash clear |
清除存储列表中的所有 stash |
git cherry-pick <commit_id> |
复制 commit_id 的提交到当前分支 |
git branch -D <name> |
强行删除分支 <name> |
分支合并 git merge
分支合并有三中策略:Fast-forward
、--no-ff
(禁用 Fast forward
)、--squash
Fast-forward
策略:直接移动 master
指针,指向最新的一次提交。所有提交之间线性相连,一旦删除分支或者分支指针往前走,很难确定某处提交是合并自某个分支。
shell
# 将 <branch_name> 分支合并到当前分支
git merge <branch_name>
--no-ff
(禁用 Fast forward
)策略:合并前,创建一个新的提交,master
指向最新的提交。能看出来曾经做过合并。
shell
# 将 <branch_name> 分支合并到当前分支
git merge --no-ff -m "commit描述" <branch_name>
分支管理中的操作流
- 分支冲突
- 正在一个新分支上做开发,预计还需要很长时间才能提交,但此时亟需修改
master
分支中的一个 bug,如何操作?如果 bug 在当前工作的 dev 分支上也存在,如何修复 bug? - 多人协作
分支冲突
基于 master
分支创建两个的分支 branch1
和 branch2
。首先在分支 branch1
作修改,并与 master
分支合并,而后在 branch2
作修改,此时如果将 branch2
分支合并到 master
分支上,那么就会出现分支冲突信息:
shell
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.
产生的原因是 master
分支和 branch2
分支各自分别有新的提交,修改处未知,难以直接合并。
解决方法:手动合并提交。假设 file
为冲突文件
shell
# 查看文件
cat file # Git用<<<<<<<,=======,>>>>>>>,标记出不同分支的内容
# 手动修改冲突文件
vi file
# 提交
git add file
git commit -m "confilct fixed"
Bug 分支
需求:正在一个新分支上做开发,预计还需要很长时间才能提交,但此时亟需修改 master
分支中的一个 bug,如何操作?
操作:利用 stash
功能,将正在开发的分支储藏起来,然后创建另一个分支来修复 bug,修复 bug 并完成分支合并后,再恢复储藏的内容,继续开发。
shell
# 储藏所有被追踪但未提交的文件
git stash
# 在存在 bug 的分支(假定在 master 分支)上创建新分支
git switch -c issue-001
# 修改 bug 并提交
git add readme.txt
git commit -m "fix bug 001"
# 合并分支到 master,修复 bug
git switch master
git merge --no-ff -m "merged bug fix 001" issue-001 # 假定 commit-id 为 123456......
# 回到开发分支 dev 上
git switch dev
# 恢复储藏文件
git stash list
# 恢复指定的stash
git stash apply stash@{0}
# 继续开发......
如果 bug 在当前工作的 dev 分支上也存在,如何修复 bug?
shell
# 将 master 中修改 bug 的一次提交"复制"到 dev 分支上
git cherry-pick 123456
多人协作
多人协作的工作模式:
- 首先,可以试图用
git push origin <branch-name>
推送自己的修改; - 如果推送失败,则说明远程分支比你的本地更新,需要先用
git pull
试图合并; - 如果合并有冲突,则解决冲突,并在本地提交;
- 没有冲突或者解决掉冲突后,再用
git push origin <branch-name>
推送。
如果 git pull
提示 no tracking information
,则说明本地分支和远程分支的链接关系没有创建,用命令 git branch --set-upstream-to <branch-name> origin/<branch-name>
。
参考: