本文已参与「新人创作礼」活动,一起开启掘金创作之路。
分支在工作中的使用
在实际开发中, 分支管理应该按照如下几个基本原则:
① master 分支只能用来发布新版本, 平时不能直接在上面开发.
② 开发任务都在 dev 分支上进行,开发完毕后,合并到 qa test 等分支,测试通过,需要上线时,再合并到 master 分支。
每个人都在 dev 分支上干活, 每个人都有自己的分支, 时不时地往 dev 分支上合并就可以了. 所以, 团队合作的分支看起来就像这样:
③ 平时接到任务,创建新分支时,应该以 master 分支为基础分支,进行分支的创建。
④ 建议 每个 bug 都可以通过创建一个新的 bug 分支,bug 修复后, 合并到 master 分支, 然后将临时分支删除.
注意:master 分支上的这个 bug 修复了, 但是其他的 dev 等分支是早期从 master 分支分出来的, 所以, 这个 bug 其实在当前 dev 等分支上也存在. 所以还需要将本次修改提交,git cherry-pick commit 复制到 dev 分支上,这样 dev 分支上这个 bug 就解决了。
⑤ Git 的分支无论创建, 切换和删除, 都能迅速完成.
因为创建, 合并和删除分支非常快, 所以 Git 建议使用分支完成某个任务, 合并后再删掉分支, 这和直接在 master 分支上工作效果是一样的, 但过程更安全.
多人协作
当你从远程仓库克隆时, 实际上 Git 自动把本地的 master 分支和远程的 master 分支对应起来了, 并且, 远程仓库的默认名称是 origin.
使用 git remote 或者 git remote -v 查看远程库的信息.
① 推送分支
推送分支, 就是把该分支上的所有本地提交推送到远程库. 推送时, 要指定本地分支, 这样, Git 就会把该分支推送到远程库对应的远程分支上.
使用命令 git push origin 本地分支名 来推送分支.
- 推送主分支 :
$ git push origin master - 推送其他分支, 比如 dev:
$ git push origin dev
并不是一定要把本地分支往远程推送, 那么, 哪些分支需要推送, 哪些不需要呢?
- master 分支是主分支, 因此要时刻与远程同步.
- dev 分支是开发分支, 团队所有成员都需要在上面工作, 所以也需要与远程同步.
- bug 分支只用于在本地修复 bug, 就没必要推到远程了.
- feature 分支是否推到远程, 取决于你是否和你的小伙伴合作在上面开发.
总之, 就是在 Git 中, 分支完全可以在本地自己藏着玩, 是否推送, 视你的心情而定!
② 抓取分支
多人协作时, 大家都会往 master 和 dev 分支上推送各自的修改.
当你的小伙伴从远程库 clone 时, 默认情况下, 你的小伙伴只能看到本地的 master 分支.
现在, 你的小伙伴要在 dev 分支上开发, 就必须创建远程 origin 的 dev 分支到本地, 通过命令 git checkout -b dev origin/dev
现在, 他就可以在 dev 上继续修改, 然后, 时不时地把 dev 分支 push 到远程.
③ 分支冲突
你的小伙伴已经向 origin/dev 分支推送了他的提交, 而碰巧你也对同样的文件作了修改, 并试图推送.
这时候会推送失败, 因为你的小伙伴的最新提交和你试图推送的提交有冲突, 解决办法也很简单 : 先用 git pull 把最新的提交从 origin/dev 抓下来, 然后, 在本地合并, 解决冲突, 再推送.
git pull 也失败了, 原因是没有指定本地 dev 分支与远程 origin/dev 分支的链接, 根据提示, 设置 dev 和 origin/dev 的链接:
$ git branch --set-upstream-to=origin/dev dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.
再次 pull:
$ git pull
Auto-merging env.txt
CONFLICT (add/add): Merge conflict in env.txt
Automatic merge failed; fix conflicts and then commit the result.
这回 git pull 成功, 但是合并有冲突, 需要手动解决, 解决的方法和分支管理中的解决冲突完全一样. 解决后, 提交, 再 push.
多人协作的工作模式通常是这样:
- 首先, 可以试图用
git push origin 分支名推送自己的修改. - 如果推送失败, 则因为远程分支比你的本地更新, 需要先用
git pull试图合并. - 如果合并有冲突, 则
解决冲突, 并在本地提交. - 没有冲突或者解决掉冲突后, 再用 git push origin 分支名 推送就能成功!
如果 git pull 提示 no tracking information, 则说明本地分支和远程分支的链接关系没有创建, 用命令 git branch --set-upstream-to 分支名 origin/分支名 建立联系.
这就是多人协作的工作模式, 一旦熟悉了, 就非常简单.
分支的查看
1.分支列表
git branch列出所有本地分支 ( 分支名前面有 * 的表示当前所在分支 )git branch -r: 列出所有远程分支git branch -a: 列出所有本地分支和远程分支
2.切换分支
git checkout 分支名切换到指定分支, 并更新工作目录git switch 分支名也是分支切换, 新命令.
3.刷新本地的远程分支列表
git remote update origin --prune远程分支上,删除掉了分支 a, 但是本地使用 git branch -a 查看时,还存在分支 a, 或者远程分支上,新创建了 分支 b ,但是本地使用 git branch -a 查看时,没有分支 b. 使用该命令刷新列表。
4.查看分支创建时间,以及 base 分支:
切换到要查询的分支下:git reflog --date=iso --all | grep 分支名
结果如下,最后的一条 checkout: moving from xxx to xxx,表示当前分支的 base 分支。
分支的创建
创建本地分支( 切记,需要以 master 分支作为基础分支,即从 master 上 checkout )
git branch 分支名新建分支, 但停留在当前分支git checkout -b 分支名: 新建分支, 并切换到新分支
从远程分支创建本地分支
git checkout -b 本地分支名 远程分支全名从远程分支上新建本地分支
推送本地分支到远程
git push origin 本地分支名:远程分支名- 或者简化为
git push origin 分支名远程分支也使用本地分支名
分支的合并
分支合并
在目标分支上,执行 git merge 被合并的分支 即可将被合并的分支合并到当前分支. 比如在分支 a 上执行 git merge b,则表示将分支 b 上的代码合并到分支 a 上。
每次提交, Git 都把提交历史串成一条时间线, 这条时间线就是一个分支. 在不创建任何分支的情况下, Git 默认与一个名为 master 的主分支.
Git 用 master 指向主分支的最新的提交位置.Git 用 HEAD 指向的当前所在的分支位置
① 一开始的时候, master 分支是一条线 :
② 每次提交, master分支都会向前移动一步, 随着你的不断提交, master分支的线也越来越长.
③ 当我们创建一个新的分支, 假如叫做 dev 开发分支. 并且切换到 dev 分支时 :
Git 会创建一个指针叫 dev ( 指针名和分支名相同 ), 指向 master 所指向的位置, 再把 HEAD 指向 dev, 就表示当前分支在 dev 分支上.
Git 创建一个分支很快的原因就是, 只是增加一个 分支指针, 然后改变 HEAD 的指向而已, 工作区的文件没有任何变化.
④ 在 dev 分支上, 进行一次新提交后, dev 指针向前移动一步, 而 master 指针不变:
⑤ 现在把 dev 分支合并到 master 分支上去.
首先切换到 master 分支, 如上图中所示, HEAD 指向 matser 分支, 此时, 你在 master 分支上是看不到 dev 分支上进行的文件改动的, 因为在时间线上, master 分支当前所在的位置是要比 dev 分支的提交位置要晚的. 然后进行分支的合并.
分支合并, 需要先切换到 master 分支上, 所以 HEAD 指向 master, 然后直接把 master 指向 dev 的当前提交, 就完成了分支的合并. 所以 Git 合并分支也很快!也只是改动指针, 工作区的文件不改变.
⑥ 合并完分支后, 就可以删除 dev 分支. 删除 dev 分支就是把 dev 指针删掉, 删掉后, 就剩下了一条 master 分支.
分支合并策略
查看:Git 分支的合并策略
分支合并冲突-解决
两个人同时在一个分支上开发时,或者合并到一个分支时,如果修改的代码没有交集,则可以正常合并,如果修改了同一块代码,则极有可能发生代码冲突。
如果发生了冲突, 就必须先手动解决冲突后再提交. 解决冲突就是把 Git 合并失败的文件手动编辑为我们希望的内容.
分支合并冲突-回退
git merge --abort如果分支合并时发生了冲突,也可以选择取消本次分支合并,放弃合并,恢复如初。
分支合并错了
有时候可能会合并错分支,可以如下方式取消分支的合并:
(1) 还没有推送到远程
如果没有别的操作,直接回到上一次提交就可以了,在 a 分支执行git reset --hard HEAD~ 会回到没有 merge 前的状态。
或者 git log 看一下 merge 之前的 commit 号,然后直接 git reset --hard commit 即可. 然后再去重新 merge 分支吧.
(2) 已经推送到远程
先 git reflog,然后 git reset --hard commit
代码写错分支了
写了一天的代码准备提交了,忽然发现写在了错误的分支上,怎么把这些修改转移到正确的分支上去呢?
例如需要在 dev 分支上开发,现在代码全都写在了 master 分支上,
首先把所有修改都 git add 进暂存区,先不要 git commit,然后:
git stash //把暂存区内的修改存储起来
git checkout dev //切换到正确的分支
git stash pop //将存储的修改取出来
就可以继续愉快的开发啦。
到那时如果已经提交了呢?先 git reset HEAD^,撤回到刚刚提交之前的状态,然后继续之前的步骤就可以啦。
分支重命名
git branch -m 旧分支名 新分支名
分支的删除
1.删除本地分支
需要先切换到其他分支,再执行删除。
git branch -d 分支名
git branch -D 分支名强行删除分支。删除时,有时候会删除失败,这是因为该分支上还有没有合并的代码,Git 不允许删除没有被合并过的分支 使用 -D 可强行删除.
2.删除远程分支
git push origin --delete 分支名 谨慎使用