学习中心/工程实践/Git/Git 进阶:改历史之前,先别动别人的 main

· Git · 进阶

Git 进阶:改历史之前,先别动别人的 main

rebase、revert、reflog、cherry-pick。进阶是为了把历史整理干净,不是炫技。

正在加载录音…

已经推上去的 main,不是你的草稿纸

进阶命令能改历史。改自己还没推的分支,可以。改大家正在用的 main,是事故。默认:revert 公开历史,rebase 只动本地。

  1. 本地rebase -i
  2. 公开git revert
  3. 找回git reflog
  4. 摘一次cherry-pick

1. 本地整理:rebase -i

合进 main 之前,把「修一下」「再修一下」收成几条说得清的提交。只对自己的短分支做。

  • 把当前分支接到 main 上,并打开待办:pick / squash / rewordgit rebase -i main
  • 乱了就停。历史回到这条命令之前git rebase --abort

2. 撤掉一次已经发布的:revert

reset 是把指针往后拨,别人已经拉走的提交会对不上。revert 是新增一次「反过来」的提交,公开线上用这个。

  • 用一次新提交,抵消最新那次。不改别人已经拿到的历史git revert HEAD
  • 本地丢弃最新一次。没推过才能这样。推过了不要对共享分支用git reset --hard HEAD~1

3. 找回来:reflog

HEAD 最近去过哪,reflog 都记着。rebase 错了、reset 错了,先看这里,再 checkout 那个 SHA。

  • 看:当前仓库里 HEAD 的每一步git reflog
  • 从那个还在的提交开一条恢复分支git switch -c recover abcdef1

4. 只要那一次:cherry-pick

  • 找到要摘的那次提交git log --oneline
  • 把那一次接到当前分支,不必整条分支 mergegit cherry-pick abcdef1

5. 必须覆盖远程时

rebase 过已经推过的短分支,有时要强推。用 --force-with-lease,有人先推了会拒绝。不要 git push --force 对 main。

  • 覆盖远程,但别人先推了就停git push --force-with-lease

6. 谁引入的:bisect

  • 开始对分。再标一个坏的、一个好的git bisect start
  • 当前这次是坏的git bisect bad
  • 这个标签还是好的。Git 会检出中间点让你测git bisect good v1.2.0
  • 查完,回到 bisect 之前git bisect reset

7. 两份目录同时干活:worktree

同一仓库两份工作区,分支互不覆盖。HiPMMCode 的 Legion 默认也走这条。修热问题和做大改可以并行。

  • 在隔壁目录检出 hotfix/login,原来的目录不动git worktree add ../repo-hotfix hotfix/login
  • 看现在挂了几份工作区git worktree list

进阶是为了不把同事的历史弄乱。会 revert、会 reflog、会 force-with-lease,就够在团队里用了。

同模块

工程实践 →