Git 基础及 Check-in Dance

Check-in Dance

流程

  • (1) Run tests in local

    本地运行测试,保证测试通过,如果有失败就立即修复,直至测试成功:$ mvn test

  • (2) Check CI status
    检查 CI 状态,确认现在可以拉取代码

  • (3) Pull
    开发新代码之前,从 CI 完全成功的那个最新版本检出代码:$ git pull --rebase

  • (4) Run tests in local
    本地运行测试,保证测试通过,如果有失败就立即修复,直至测试成功:$ mvn test

  • (5) Make changes
    按照 red -> green -> refactor 方式编写代码;

    • red:根据 Task 拆分,添加一个新的测试 (由于目前没有实现代码,测试失败)
    • green:添加最少的实现代码,使测试通过
    • refactor:识别代码中的 bad smell,重构代码
  • (6) Run tests in local
    完成一个小特性以后,本地运行测试通过,如果有失败就立即修复,直至测试成功:$ mvn test

  • (7) Review Changes
    在 IntelliJ 下 Alt + 9 review Local Changes

  • (8) Commit to local
    本地提交,小步提交,写清楚 Story 编号有意义的提交信息;

$ git add .
$ git commit -m "[US27149] Add entity validation in creation process"
  • (9) Check CI status
    检查 CI 状态,确认现在可以拉取代码;

  • (10) Pull
    从远端拉取最新代码:$ git pull --rebase
    如果有冲突,修复有冲突的文件,然后

$ git add .
$ git rebase --continue
  • (11) Run tests in local
    本地运行测试,保证测试通过,如果又失败就立即修复,直至测试成功:$ mvn test

  • (12) Push
    本地 commit 通过测试之后,尽早 push 到远端,以便团队其他人员在新代码库上工作:$ git push

  • (13) Check CI status
    查看自己 push 之后,CI 状态正常

注意事项

  • (1) 在步骤10中,频繁与远端代码库合并,避免 big bang conflict。如果本地已经较长时间没有拉取代码库的代码,并且观察到其他成员已经进行了较多 commit,而本地有未完成工作不能 commit,如何同步远端代码库的代码呢?

我们可以先暂存目前的工作,拉取远端的最新代码,然后取回目前的工作与远端代码进行合并。这样可以将合并前移,尽量避免 big bang conflict。

$ git stash
$ git pull --rebase
$ git stash pop
  • (2) 本地测试通过之后,尽早 push,避免big bang conflict

Git 简介

基础知识

Git 有三种状态,你的文件可能处于其中之一:已提交(committed)、已修改(modified)和已暂存(staged)。 已提交表示数据已经安全的保存在本地数据库中。 已修改表示修改了文件,但还没保存到数据库中。 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。

由此引入 Git 项目的三个工作区域的概念:Git 仓库、工作目录以及暂存区域。

git-area.png

常用命令

$ git status                      # 查看文件处于什么状态
$ git log                         # 查看提交历史
$ git add               # 将需要提交的文件从 Working Directory 添加到 Staging Area
$ git commit -m          # 将 Staging Area 中的文件快照永久性移动到 Repository
$ git commit --amend              # 修改上次提交
$ git pull --rebase               # 拉取远端代码,将本地修改衍合到本地最新代码上
$ git push                        # 将本地提交推送到远端仓库
$ git merge           # 合并分支
$ git checkout -b     # 新建并切换 Working Directory 到新分支
$ git checkout --       # 丢弃文件修改,还原文件状态到上次提交的状态
$ git revert HEAD~        # 找到倒数第个提交,并创建一个新的提交来撤销之后的更改
$ git reset HEAD^       # 将当前的某个 file 从缓存区移出,不影响工作目录对其进行的修改
$ git reset --hard HEAD~  # 移除最后个提交,并将缓存区和工作目录同步到指定的提交 

代码回滚

Revert

Revert 撤销一个提交的同时会创建一个新的提交。这是一个安全的方法,因为它不会重写提交历史。比如,下面的命令会找出倒数第二个提交,然后创建一个新的提交来撤销这些更改,然后把这个提交加入项目中。

$ git checkout hotfix
$ git revert HEAD~2
reverting.png

在提交层面上,reset 将一个分支的末端指向另一个提交。这可以用来移除当前分支的一些提交。比如,下面这两条命令让 hotfix 分支向后回退了两个提交。

$ git checkout hotfix
$ git reset HEAD~2

hotfix 分支末端的两个提交现在变成了悬挂提交。也就是说,下次 Git 执行垃圾回收的时候,这两个提交会被删除。换句话说,如果你想扔掉这两个提交,你可以这么做。reset 操作如下图所示:

resetting.png

如果你的更改还没有共享给别人,git reset 是撤销这些更改的简单方法。当你开发一个功能的时候发现「糟糕,我做了什么?我应该重新来过!」时,reset 就像是 go-to 命令一样。

除了在当前分支上操作,你还可以通过传入这些标记来修改你的缓存区或工作目录:

--soft – 缓存区和工作目录都不会被改变
--mixed – 默认选项。缓存区和你指定的提交同步,但工作目录不受影响
--hard – 缓存区和工作目录都同步到你指定的提交

把这些标记想成定义 git reset 操作的作用域就容易理解多了。

scope-of-reset.png

当你传入 HEAD 以外的其他提交的时候要格外小心,因为 reset 操作会重写当前分支的历史。正如 rebase 黄金法则所说的,在公共分支上这样做可能会引起严重的后果。下表总结了 reset、checkout 和 revert 应用到文件层面和提交层面的常用场景。

命令 作用域 常用情景
git reset 提交层面 在私有分支上舍弃一些没有提交的更改
git reset 文件层面 将文件从缓存区中移除
git checkout 提交层面 切换分支或查看旧版本
git checkout 文件层面 舍弃工作目录中的更改
git revert 提交层面 在公共分支上回滚更改
git revert 文件层面 (然而并没有)

CI 变红之后的操作指导

责任人

  • (1) 提交之后 Working Directory 或 Stage Area 是否存在未 commit 的修改

    • 如果存在未 commit 的修改
$ git stash  # 保存目前的修改,工作区和暂存区内容回到问题提交点的状态 
$ git status # 确认状态是否正确 
  • (2) 运行测试

    • 测试未通过,说明 push 之前没有在本地运行测试,未按照 check-in dance 的步骤提交代码

      可以自己打脸提醒一下,不要再犯,暂时放下其他工作,开始全力 Debug 吧

    • 测试通过,说明很有可能是因为本地环境与 CI 环境不同,比如数据不一致等原因

      可以自己打脸清醒一下,暂时放下其他工作,开始全力 Debug 吧

  • (3) bug 修复流程
$ git checkout -b hot-fix   # 创建并切换到 hot-fix 分支,在该分支修复 bug
  • (4) 15分钟之内,是否完成了 bug 修复

完成了 bug 修复,并在本地经过了测试验证

$ git add .                   # 将修改保存到暂存区,准备提交
$ git commit -m      # 将修改提交到 hot-fix 分支
$ git checkout master         # 切换到 master 分支
$ git rebase master hot-fix   # 将 bug 修改过程在 master 分支重演
$ git pull --rebase           # 原则上 CI 红了其他人不能提交,这一步可以忽略
$ git push                    # 将修改提交到远端

未完成 bug 修复

$ git stash                   # 保存在 hot-fix 分支未完成的修复工作
$ git checkout master         # 切换到 master 分支
$ git revert     # 创建一个 revert 提交撤销引入 bug 的修改
$ git pull --rebase           # 原则上 CI 红了其他人不能提交,这一步可以忽略
$ git push                    # 回退 CI 的代码,先修复 CI,保证其他人可以提交
$ git checkout hot-fix        # 切换回 hot-fix 分支
$ git stash pop               # 恢复目前已经进行的修复工作,继续修复
$ git add .                   # 修复完成,将修改保存到暂存区,准备提交
$ git commit -m      # 将修改提交到 hot-fix 分支
$ git checkout master         # 切换到 master 分支
$ git rebase master hot-fix   # 将 bug 修改过程在 master 分支重演
$ git pull --rebase           # 原则上 CI 红了其他人不能提交,这一步可以忽略
$ git push                    # 将修改提交到远端    

其他成员

  1. CI 变红之后暂停提交代码,直至 CI 变绿

  2. CI 变绿之后

$ git stash                        # 保存目前的工作,如果工作区和暂存区是干净的,忽略此步骤
$ git pull --rebase                # 拉取最新的修复之后的代码
$ git stash pop                    # 恢复当前工作区,继续工作

参考文献

  1. 代码回滚:Reset、Checkout、Revert-的选择
  2. Git Branch and Merging

你可能感兴趣的:(Git 基础及 Check-in Dance)