Git

Git 协作模式

Posted by Nutlee on 2017-02-27

进新公司第二周,完全是从未接触过的工作氛围,只能说“非常兴奋”。坦率的讲,在纯技术型公司太幸福了,有点理解之前雷军说「我要写一辈子的代码」的意味了。

经过了接连踩坑,有必要记录下点点滴滴,原来自己之前对 Git 的使用是有误解的,我之在只在意 Git 的语法(虽然Git 命令也没熟到哪里),并没有理解 Git 最核心的是协作思想,至于各种命令只是副产物。下面我要先从反面讲我之前的误区,然后结合公司的实践进入正题「Git协作模式

需要澄清的误区

一直以来我的认知的 Git branch 结构是如下:

1
2
3
4
|-- master 主分支
|-- dev 开发分支
|-- bug
|-- feature

这里没有错,但是重点在于,我的理解是每个人根据自己的工作内容新建不同的分支,进而合并到 devdev 再合并到 master(或者直接合并到master),表面上看是条理的,然而自己想想这样真的很蛋疼,意味着你的每次 feature 或者 fix 都要走这么一个流程,且不说流程的复杂,至少在多人协作的时候,你合并到了 dev,我也合并过去,再到 master,出了问题怎么排查?

所以,我对 Git 的理解纯属 YY,那么问题来了,怎么样用 Git 才是正确的“姿势”呢?

正确的模式

首页,分支的结构和上面说的基本一致,重点在于:

  • master 只有一个,主分支,只能 merge 进去,绝对不能直接操作,有冲突先将 master 合并到冲突分支,解决冲突后再合并到 master
  • develop 只有一个,是“脏分支”,可以任意合并,用于内部测试、预览(alpha 环境)
  • feature/XXXXX 每个人开发的时候从最新的 master 切出来的,开发阶段可以合并到 develop 分支测试、预览,开发完成需合并到 master
  • fix/XXXXX 修复指定问题或者 bug的分支,类似 feature 分支,开发阶段可以合并到 develop 分支测试、预览,开发完成需合并到 master
  • 如果有其他类型的分支,操作习惯等同于 feature

需要注意的是:

  • 绝对不能直接直接对 master 分支进行操作!!!master 分支只存在其他分支合并进去这种可能,当然如果有冲突先在自己分支解决冲突
  • 创建任何需要提交的分支一定来自是来自 master 分支的 checkout

Git 姿势

以下是几个常用的 Git “痛点”

  1. 缓存工作区

    众所周知,当前工作区修改后没有提交时直接切换分支,Git 会有警告不让你直接切换,一般的做法就是把当前的修改 addcommit 到仓库再切换,其实用 stash 更优雅。

    1
    2
    3
    4
    # 缓存当前的工作区
    git stash
    # 取出缓存的修改
    git stash apply

    尤其是暂时性切换到别的分支,再切回来的时候,使用 stash 非常方便,但是友情提醒,如果是多个分支来回切换并且长时间工作,建议还是 commit 到仓库吧,因为时间久了你可能会忘记 stash 的是哪个分支的何种修改。

  2. 版本回滚

    通常情况下用 checkout 回滚文件,用 reset 回滚版本

    1
    2
    3
    4
    5
    6
    7
    # 丢弃工作区文件
    git checkout -- file
    # 暂存区放回工作区
    git reset HEAD file
    # 版本回退 HEAD 指当前版本,HEAD^ 指上一版本
    # 完全舍弃当前的修改
    git reset --hard HEAD

    特殊情况 revert 可以回滚到指定版本并生成一次回滚提交,主要用与 master 等核心分支,体现完整的开发记录。

    1
    2
    # 回滚到倒数第二个版本
    git revert HEAD~2
  3. 遴选

    遴选这个功能是为了防止“手抖”,有时候你可能会不注意直接在 develop 分支修改了,并且提交到了代码仓库,一般情况下的处理方式就是到自己的分支上再改一遍了。遴选就是为了处理这种情况的,通过查看 develop 分支的 log,然后根据 commit-id 可以挑出来某次提交,再切换到自己的分支合并。

    1
    2
    # 切换到自己的分支
    git cherry-pick commit-id
  4. 远端仓库

    1
    2
    # 取远端仓库并创建分支
    git fetch origin master: feature/XXX
  5. 其他

    1
    2
    3
    # 创建分支
    git checkout -b [new branch]
    git checkout -D [branch]

参考资料:
5.2 代码回滚:Reset、Checkout、Revert的选择