从 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 分支,这是不被允许的。那怎么办呢? 处理过程如下:

  1. 幸好 master 代码没有提交到远程仓库, 先到远程仓库找到 master 分支上最近的 commit 假设这个 commit 是: axxxxxx

  2. 将 10001_fix_xxx_issue 分支做的修改导出来保存在一个文件里, 我是手工将代码拷贝出来的

  3. 在本地签出 master 分支

 $ git checkout master
  1. 在本地确认下这个 commit 相关的信息
 git log | grep 'axxxxxx' -C 20
  1. git reset –hard axxxxxx

  2. 删除 10001_fix_xxx_issue 分支

 $ git branch -D 10001_fix_xxx_issue
  1. 从 master 分支签出 10001_fix_xxx_issue 分支
 $ git checkout master
 $ git checkout -b 10001_fix_xxx_issue
  1. 在 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 fetchgit merge, 所以结果是我把 staging 的代码合并到了 master, 很不幸,这 是一个错误,解决方法如下:

  1. 使用 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 是我们需要的信息

  1. 使用 git reset --hard 重置到 git pull 之前的状态,
  $ git reset --hard 49e0c86
  1. 为了确认 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