Git 事故处理手册
从 staing 分支签出了一个开发分支, 然后将此开发分支 merge 到了 master 分支
master 分支是我的部署分支,staging 分支是我的测试分支,客户给我提了一个 ticket#10001,
然后我不小心从 staging 分支签出了一个 10001_fix_xxx_issue 分支, 这是一种错误的做法
# 从 staging 分支签出了 10001_fix_xxx_issue
git checkout -b 10001_fix_xxx_issue
我本应该从 master 分支签出 10001_fix_xxx_issue, 我一直没有发现这个问题,我在
10001_fix_xxx_issue 分支上处理好问题后,测试无误,然后将代码 merge 到 master
分支后,发现了一大堆代码的改动,此时我才发现出问题了, 此时我已经把 staging 的代码合并到了
master 分支,这是不被允许的。那怎么办呢? 处理过程如下:
-
幸好 master 代码没有提交到远程仓库, 先到远程仓库找到 master 分支上最近的 commit 假设这个 commit 是:
axxxxxx
-
将 10001_fix_xxx_issue 分支做的修改导出来保存在一个文件里, 我是手工将代码拷贝出来的
-
在本地签出 master 分支
$ git checkout master
- 在本地确认下这个 commit 相关的信息
git log | grep 'axxxxxx' -C 20
-
git reset –hard axxxxxx
-
删除 10001_fix_xxx_issue 分支
$ git branch -D 10001_fix_xxx_issue
- 从 master 分支签出 10001_fix_xxx_issue 分支
$ git checkout master
$ git checkout -b 10001_fix_xxx_issue
- 在 10001_fix_xxx_issue 做好开发,完成测试,然后再合并到 master
$ git checkout staging
$ git merge 10001_fix_xxx_issue
$ git push origin staging
# 在 staging 上完成测试后, 将 10001_fix_xxx_issue 分支 merge 到 master
$ git checkout master
$ git merge 10001_fix_xxx_issue
$ git push origin master
在 master 分支上执行: git pull origin staging
一不留神,在 master 分支执行了,
$ git pull origin staging
我们知道 git pull
会做两件事情: git fetch
和 git merge
, 所以结果是我把 staging 的代码合并到了 master, 很不幸,这
是一个错误,解决方法如下:
- 使用
git-reflog
找到git pull
前的状态,
$ git reflog
f0ad90e HEAD@{0}: pull origin staging: Fast-forward
49e0c86 HEAD@{1}: merge 7011_new_reports: Fast-forward
a6981a2 HEAD@{2}: checkout: moving from staging to master
f0ad90e HEAD@{3}: merge 7011_new_reports: Merge made by the 'recursive' strategy.
e5a33d0 HEAD@{4}: checkout: moving from 7011_new_reports to staging
49e0c86 HEAD@{5}: commit: #7011 update
....
打印出了一堆东西,其中 49e0c86 HEAD@{1}: merge 7011_new_reports: Fast-forward
是我们需要的信息
- 使用
git reset --hard
重置到git pull
之前的状态,
$ git reset --hard 49e0c86
- 为了确认 master 分支已经正确,我们可以从本地的 master 分支签出一个 check_master 分支, 然后做一个 Pull Request 和远程仓库的 master 分支做比较 如果 diff 的内容是正确的,则表示改正成功,
$ git co master
$ git co -b check_master
$ git push origin check_master:check_master
没有使用 git fetch, 导致本地的 staging 分支不干净
这段时间我每次将本地的 staging 分支 push 到远程 git 仓库,都会导致网站的注册功能失效, 这样其他同事的一些测试无法进行。
$ git push origin staging
然后同事将 staging 分支删除,重建 staging 分支, 我在本地也会将 staging 分支删除,然后 ‘重建’ staging 分支。
$ git branch -D staging
$ git checkout --track origin/staging
在合并了一些我的开发分支后,我将本地的 staging 分支重新 push 到远程,
$ git push origin staging
结果又导致注册失效,经过分析,原来是我没有执行 git fetch
导致, 然后我重新删除本地的 staging 分支,
$ git branch -D staging
$ git fetch origin
$ git checkout --track origin/staging
最后将 staging 分支 push 到远程时就没有问题了。
重建 staging
staging 分支经常出现一些诡异,无法解释的现象,于是重建 staging 分支很必要
$ git checkout master
$ git push origin :staging
$ git branch -D staging
$ git checkout -b staging
$ git push origin staging
查看特定 commit 的代码改动
$ git diff COMMIT^ COMMIT
比如,
git diff d55e20f^ d55e20f
master 分支合并了一个待废弃的分支, 此时产生了很多冲突
$ git reset HEAD ./ # Unstage conflicts
$ git checkout -- ./ # Unstage deletions and reset everything back to master