如何优雅地回退代码
先介绍一下这种场景,我们一个项目从 N 版本升到 A 版本时引入了另一项目的 jar 包,又陆续发布了 B、C 版本,
但在 C 版本后忽然发现了 A 版本引入的 jar 包有极大的性能问题,B、C 版本都是基于 A 版本发布的,要修复 jar
包性能问题,等 jar 包再发版还得几天,可此时线上又有紧急的 Bug 要修,于是就陷入了进退两难的境地。最后
决定先将代码回退到 A 版本之前,再基于旧版本修复 Bug。
我们模拟上面的场景,先构造一个相同的场景:
echo init > init.txt
git add init.txt
git commit -m "add init.txt"
echo n > n.txt
git add n.txt
git commit -m "add n.txt,version N"
echo a > a.txt
git add a.txt
git commit -m "add a.txt,version A"
echo b > b.txt
git add b.txt
git commit -m "add b.txt,version B"
echo c > c.txt
git add c.txt
git commit -m "add c.txt,version C"
$ git log --oneline
fac2ffb (HEAD -> master) add c.txt,version C
012b123 add b.txt,version B
4770e60 add a.txt,version A
8e99b28 add n.txt,version N
0e40135 add init.txt
1、revert
revert 适合需要回退的历史提交不多,且无合并冲突的情景。
$ git revert commit
# 想要回到A版本之前需要进行三次回退
# 具体操作
# 第一次回退
$ git revert fac2ffb
Removing c.txt
[master 9eb6417] Revert "add c.txt,version C"
1 file changed, 1 deletion(-)
delete mode 100644 c.txt
$ ls
a.txt b.txt init.txt n.txt
# 第二次回退
$ git revert 012b123
Removing b.txt
[master febe804] Revert "add b.txt,version B"
1 file changed, 1 deletion(-)
delete mode 100644 b.txt
$ ls
a.txt init.txt n.txt
# 第三次回退
$ git revert 4770e60
Removing a.txt
[master 17205dd] Revert "add a.txt,version A"
1 file changed, 1 deletion(-)
delete mode 100644 a.txt
$ ls
init.txt n.txt
2、reset
如果你可以向 master 强推代码,且想让 git log 里不再出现被回退代码的痕迹,可以使用:
$ git reset --hard commit_id
$ git push --force origin master
$ git reset --hard 8e99b28
HEAD is now at 8e99b28 add n.txt,version N
$ git log --oneline
8e99b28 (HEAD -> master) add n.txt,version N
0e40135 add init.txt
$ ls
init.txt n.txt
3、rebase + revert
如果你追求用正规而正统的方式来回退代码, rebase + revert 满足你的需求。
可以先使用 rebase 把多个提交合并成一个提交,再使用 revert 产生一次反提交,这种方法的思路非常清晰,把
revert 和 rebase 两个命令搭配得很好,相当于使用 revert 回退的升级版。
rebase 是变基的意思,这里的基,在我理解是指多次 commit 形成的 git workflow,使用 rebase,我们可以改
变这些历史提交,修改 commit 信息,将多个 commit 进行组合。
具体的步骤:
使用 revert 要进行 3 次回退,下面我们进行如下操作,只需要回退 1 次。
先进行 rebase ,然后在进行 revert。
$ git rebase -i HEAD~3
[detached HEAD c40393f] add a.txt,version A
Date: Thu Jun 1 16:33:48 2023 +0800
3 files changed, 3 insertions(+)
create mode 100644 a.txt
create mode 100644 b.txt
create mode 100644 c.txt
Successfully rebased and updated refs/heads/master.
# 需要修改的内容
pick 4770e60 add a.txt,version A
pick 012b123 add b.txt,version B
pick fac2ffb add c.txt,version C
# 改为
pick 4770e60 add a.txt,version A
s 012b123 add b.txt,version B
s fac2ffb add c.txt,version C
$ git log --oneline
c40393f (HEAD -> master) add a.txt,version A
8e99b28 add n.txt,version N
0e40135 add init.txt
$ ls
a.txt b.txt c.txt init.txt n.txt
$ git revert c40393f
Removing c.txt
Removing b.txt
Removing a.txt
[master c3c19ce] Revert "add a.txt,version A"
3 files changed, 3 deletions(-)
delete mode 100644 a.txt
delete mode 100644 b.txt
delete mode 100644 c.txt
$ ls
init.txt n.txt
$ git log --oneline
c3c19ce (HEAD -> master) Revert "add a.txt,version A"
c40393f add a.txt,version A
8e99b28 add n.txt,version N
0e40135 add init.txt